356 * id shouldn't be -1 since we use the same dictionary as graph.c, but
357 * just in case.
358 */
359 inst->ri_id = (id != -1 ? id : dict_insert(name));
360
361 special_online_hooks_get(name, &inst->ri_pre_online_hook,
362 &inst->ri_post_online_hook, &inst->ri_post_offline_hook);
363
364 scf_svc = safe_scf_service_create(h);
365 scf_inst = safe_scf_instance_create(h);
366 pg = safe_scf_pg_create(h);
367 svc_name = startd_alloc(max_scf_name_size);
368 inst_name = startd_alloc(max_scf_name_size);
369
370 rep_retry:
371 if (snap != NULL)
372 scf_snapshot_destroy(snap);
373 if (inst->ri_logstem != NULL)
374 startd_free(inst->ri_logstem, PATH_MAX);
375 if (inst->ri_common_name != NULL)
376 startd_free(inst->ri_common_name, max_scf_value_size);
377 if (inst->ri_C_common_name != NULL)
378 startd_free(inst->ri_C_common_name, max_scf_value_size);
379 snap = NULL;
380 inst->ri_logstem = NULL;
381 inst->ri_common_name = NULL;
382 inst->ri_C_common_name = NULL;
383
384 if (scf_handle_decode_fmri(h, name, NULL, scf_svc, scf_inst, NULL,
385 NULL, SCF_DECODE_FMRI_EXACT) != 0) {
386 switch (scf_error()) {
387 case SCF_ERROR_CONNECTION_BROKEN:
388 libscf_handle_rebind(h);
389 goto rep_retry;
390
391 case SCF_ERROR_NOT_FOUND:
392 goto deleted;
393 }
394
395 uu_die("Can't decode FMRI %s: %s\n", name,
396 scf_strerror(scf_error()));
397 }
398
512
513 case ECANCELED:
514 goto deleted;
515
516 case ENOENT:
517 /*
518 * This is odd, because the graph engine should have required
519 * the general property group. So we'll just use default
520 * flags in anticipation of the graph engine sending us
521 * REMOVE_INSTANCE when it finds out that the general property
522 * group has been deleted.
523 */
524 inst->ri_flags = RINST_CONTRACT;
525 break;
526
527 default:
528 assert(0);
529 abort();
530 }
531
532 switch (libscf_get_template_values(scf_inst, snap,
533 &inst->ri_common_name, &inst->ri_C_common_name)) {
534 case 0:
535 break;
536
537 case ECONNABORTED:
538 libscf_handle_rebind(h);
539 goto rep_retry;
540
541 case ECANCELED:
542 goto deleted;
543
544 case ECHILD:
545 case ENOENT:
546 break;
547
548 default:
549 assert(0);
550 abort();
551 }
552
553 switch (libscf_read_method_ids(h, scf_inst, inst->ri_i.i_fmri,
661
662 log_framework(LOG_DEBUG, "%s: inserted instance into restarter list\n",
663 name);
664
665 return (0);
666
667 deleted:
668 MUTEX_UNLOCK(&instance_list.ril_lock);
669 startd_free(inst_name, max_scf_name_size);
670 startd_free(svc_name, max_scf_name_size);
671 if (snap != NULL)
672 scf_snapshot_destroy(snap);
673 scf_pg_destroy(pg);
674 scf_instance_destroy(scf_inst);
675 scf_service_destroy(scf_svc);
676 startd_free((void *)inst->ri_i.i_fmri, strlen(inst->ri_i.i_fmri) + 1);
677 uu_list_destroy(inst->ri_queue);
678 if (inst->ri_logstem != NULL)
679 startd_free(inst->ri_logstem, PATH_MAX);
680 if (inst->ri_common_name != NULL)
681 startd_free(inst->ri_common_name, max_scf_value_size);
682 if (inst->ri_C_common_name != NULL)
683 startd_free(inst->ri_C_common_name, max_scf_value_size);
684 startd_free(inst->ri_utmpx_prefix, max_scf_value_size);
685 startd_free(inst, sizeof (restarter_inst_t));
686 return (ENOENT);
687 }
688
689 static void
690 restarter_delete_inst(restarter_inst_t *ri)
691 {
692 int id;
693 restarter_inst_t *rip;
694 void *cookie = NULL;
695 restarter_instance_qentry_t *e;
696
697 assert(MUTEX_HELD(&ri->ri_lock));
698
699 /*
700 * Must drop the instance lock so we can pick up the instance_list
701 * lock & remove the instance.
702 */
703 id = ri->ri_id;
723 /*
724 * We can lock the instance without holding the instance_list lock
725 * since we removed the instance from the list.
726 */
727 MUTEX_LOCK(&ri->ri_lock);
728 MUTEX_LOCK(&ri->ri_queue_lock);
729
730 if (ri->ri_i.i_primary_ctid >= 1)
731 contract_hash_remove(ri->ri_i.i_primary_ctid);
732
733 while (ri->ri_method_thread != 0 || ri->ri_method_waiters > 0)
734 (void) pthread_cond_wait(&ri->ri_method_cv, &ri->ri_lock);
735
736 while ((e = uu_list_teardown(ri->ri_queue, &cookie)) != NULL)
737 startd_free(e, sizeof (*e));
738 uu_list_destroy(ri->ri_queue);
739
740 startd_free((void *)ri->ri_i.i_fmri, strlen(ri->ri_i.i_fmri) + 1);
741 startd_free(ri->ri_logstem, PATH_MAX);
742 if (ri->ri_common_name != NULL)
743 startd_free(ri->ri_common_name, max_scf_value_size);
744 if (ri->ri_C_common_name != NULL)
745 startd_free(ri->ri_C_common_name, max_scf_value_size);
746 startd_free(ri->ri_utmpx_prefix, max_scf_value_size);
747 (void) pthread_mutex_destroy(&ri->ri_lock);
748 (void) pthread_mutex_destroy(&ri->ri_queue_lock);
749 startd_free(ri, sizeof (restarter_inst_t));
750 }
751
752 /*
753 * instance_is_wait_style()
754 *
755 * Returns 1 if the given instance is a "wait-style" service instance.
756 */
757 int
758 instance_is_wait_style(restarter_inst_t *inst)
759 {
760 assert(MUTEX_HELD(&inst->ri_lock));
761 return ((inst->ri_flags & RINST_STYLE_MASK) == RINST_WAIT);
762 }
763
764 /*
765 * instance_is_transient_style()
1824 /* delete the event */
1825 uu_list_remove(rip->ri_queue, event);
1826 startd_free(event, sizeof (restarter_instance_qentry_t));
1827 }
1828
1829 assert(rip != NULL);
1830
1831 /*
1832 * Try to preserve the thread for a little while for future use.
1833 */
1834 to.tv_sec = 3;
1835 to.tv_nsec = 0;
1836 (void) pthread_cond_reltimedwait_np(&rip->ri_queue_cv,
1837 &rip->ri_queue_lock, &to);
1838
1839 if (uu_list_first(rip->ri_queue) != NULL)
1840 goto again;
1841
1842 rip->ri_queue_thread = 0;
1843 MUTEX_UNLOCK(&rip->ri_queue_lock);
1844 out:
1845 (void) scf_handle_unbind(h);
1846 scf_handle_destroy(h);
1847 free(fmri);
1848 return (NULL);
1849 }
1850
1851 static int
1852 is_admin_event(restarter_event_type_t t) {
1853
1854 switch (t) {
1855 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
1856 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
1857 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1858 case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1859 case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
1860 case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1861 return (1);
1862 default:
1863 return (0);
|
356 * id shouldn't be -1 since we use the same dictionary as graph.c, but
357 * just in case.
358 */
359 inst->ri_id = (id != -1 ? id : dict_insert(name));
360
361 special_online_hooks_get(name, &inst->ri_pre_online_hook,
362 &inst->ri_post_online_hook, &inst->ri_post_offline_hook);
363
364 scf_svc = safe_scf_service_create(h);
365 scf_inst = safe_scf_instance_create(h);
366 pg = safe_scf_pg_create(h);
367 svc_name = startd_alloc(max_scf_name_size);
368 inst_name = startd_alloc(max_scf_name_size);
369
370 rep_retry:
371 if (snap != NULL)
372 scf_snapshot_destroy(snap);
373 if (inst->ri_logstem != NULL)
374 startd_free(inst->ri_logstem, PATH_MAX);
375 if (inst->ri_common_name != NULL)
376 startd_free(inst->ri_common_name,
377 strlen(inst->ri_common_name) + 1);
378 if (inst->ri_C_common_name != NULL)
379 startd_free(inst->ri_C_common_name,
380 strlen(inst->ri_C_common_name) + 1);
381 snap = NULL;
382 inst->ri_logstem = NULL;
383 inst->ri_common_name = NULL;
384 inst->ri_C_common_name = NULL;
385
386 if (scf_handle_decode_fmri(h, name, NULL, scf_svc, scf_inst, NULL,
387 NULL, SCF_DECODE_FMRI_EXACT) != 0) {
388 switch (scf_error()) {
389 case SCF_ERROR_CONNECTION_BROKEN:
390 libscf_handle_rebind(h);
391 goto rep_retry;
392
393 case SCF_ERROR_NOT_FOUND:
394 goto deleted;
395 }
396
397 uu_die("Can't decode FMRI %s: %s\n", name,
398 scf_strerror(scf_error()));
399 }
400
514
515 case ECANCELED:
516 goto deleted;
517
518 case ENOENT:
519 /*
520 * This is odd, because the graph engine should have required
521 * the general property group. So we'll just use default
522 * flags in anticipation of the graph engine sending us
523 * REMOVE_INSTANCE when it finds out that the general property
524 * group has been deleted.
525 */
526 inst->ri_flags = RINST_CONTRACT;
527 break;
528
529 default:
530 assert(0);
531 abort();
532 }
533
534 r = libscf_get_template_values(scf_inst, snap,
535 &inst->ri_common_name, &inst->ri_C_common_name);
536
537 /*
538 * Copy our names to smaller buffers to reduce our memory footprint.
539 */
540 if (inst->ri_common_name != NULL) {
541 char *tmp = safe_strdup(inst->ri_common_name);
542 startd_free(inst->ri_common_name, max_scf_value_size);
543 inst->ri_common_name = tmp;
544 }
545
546 if (inst->ri_C_common_name != NULL) {
547 char *tmp = safe_strdup(inst->ri_C_common_name);
548 startd_free(inst->ri_C_common_name, max_scf_value_size);
549 inst->ri_C_common_name = tmp;
550 }
551
552 switch (r) {
553 case 0:
554 break;
555
556 case ECONNABORTED:
557 libscf_handle_rebind(h);
558 goto rep_retry;
559
560 case ECANCELED:
561 goto deleted;
562
563 case ECHILD:
564 case ENOENT:
565 break;
566
567 default:
568 assert(0);
569 abort();
570 }
571
572 switch (libscf_read_method_ids(h, scf_inst, inst->ri_i.i_fmri,
680
681 log_framework(LOG_DEBUG, "%s: inserted instance into restarter list\n",
682 name);
683
684 return (0);
685
686 deleted:
687 MUTEX_UNLOCK(&instance_list.ril_lock);
688 startd_free(inst_name, max_scf_name_size);
689 startd_free(svc_name, max_scf_name_size);
690 if (snap != NULL)
691 scf_snapshot_destroy(snap);
692 scf_pg_destroy(pg);
693 scf_instance_destroy(scf_inst);
694 scf_service_destroy(scf_svc);
695 startd_free((void *)inst->ri_i.i_fmri, strlen(inst->ri_i.i_fmri) + 1);
696 uu_list_destroy(inst->ri_queue);
697 if (inst->ri_logstem != NULL)
698 startd_free(inst->ri_logstem, PATH_MAX);
699 if (inst->ri_common_name != NULL)
700 startd_free(inst->ri_common_name,
701 strlen(inst->ri_common_name) + 1);
702 if (inst->ri_C_common_name != NULL)
703 startd_free(inst->ri_C_common_name,
704 strlen(inst->ri_C_common_name) + 1);
705 startd_free(inst->ri_utmpx_prefix, max_scf_value_size);
706 startd_free(inst, sizeof (restarter_inst_t));
707 return (ENOENT);
708 }
709
710 static void
711 restarter_delete_inst(restarter_inst_t *ri)
712 {
713 int id;
714 restarter_inst_t *rip;
715 void *cookie = NULL;
716 restarter_instance_qentry_t *e;
717
718 assert(MUTEX_HELD(&ri->ri_lock));
719
720 /*
721 * Must drop the instance lock so we can pick up the instance_list
722 * lock & remove the instance.
723 */
724 id = ri->ri_id;
744 /*
745 * We can lock the instance without holding the instance_list lock
746 * since we removed the instance from the list.
747 */
748 MUTEX_LOCK(&ri->ri_lock);
749 MUTEX_LOCK(&ri->ri_queue_lock);
750
751 if (ri->ri_i.i_primary_ctid >= 1)
752 contract_hash_remove(ri->ri_i.i_primary_ctid);
753
754 while (ri->ri_method_thread != 0 || ri->ri_method_waiters > 0)
755 (void) pthread_cond_wait(&ri->ri_method_cv, &ri->ri_lock);
756
757 while ((e = uu_list_teardown(ri->ri_queue, &cookie)) != NULL)
758 startd_free(e, sizeof (*e));
759 uu_list_destroy(ri->ri_queue);
760
761 startd_free((void *)ri->ri_i.i_fmri, strlen(ri->ri_i.i_fmri) + 1);
762 startd_free(ri->ri_logstem, PATH_MAX);
763 if (ri->ri_common_name != NULL)
764 startd_free(ri->ri_common_name,
765 strlen(ri->ri_common_name) + 1);
766 if (ri->ri_C_common_name != NULL)
767 startd_free(ri->ri_C_common_name,
768 strlen(ri->ri_C_common_name) + 1);
769 startd_free(ri->ri_utmpx_prefix, max_scf_value_size);
770 (void) pthread_mutex_destroy(&ri->ri_lock);
771 (void) pthread_mutex_destroy(&ri->ri_queue_lock);
772 startd_free(ri, sizeof (restarter_inst_t));
773 }
774
775 /*
776 * instance_is_wait_style()
777 *
778 * Returns 1 if the given instance is a "wait-style" service instance.
779 */
780 int
781 instance_is_wait_style(restarter_inst_t *inst)
782 {
783 assert(MUTEX_HELD(&inst->ri_lock));
784 return ((inst->ri_flags & RINST_STYLE_MASK) == RINST_WAIT);
785 }
786
787 /*
788 * instance_is_transient_style()
1847 /* delete the event */
1848 uu_list_remove(rip->ri_queue, event);
1849 startd_free(event, sizeof (restarter_instance_qentry_t));
1850 }
1851
1852 assert(rip != NULL);
1853
1854 /*
1855 * Try to preserve the thread for a little while for future use.
1856 */
1857 to.tv_sec = 3;
1858 to.tv_nsec = 0;
1859 (void) pthread_cond_reltimedwait_np(&rip->ri_queue_cv,
1860 &rip->ri_queue_lock, &to);
1861
1862 if (uu_list_first(rip->ri_queue) != NULL)
1863 goto again;
1864
1865 rip->ri_queue_thread = 0;
1866 MUTEX_UNLOCK(&rip->ri_queue_lock);
1867
1868 out:
1869 (void) scf_handle_unbind(h);
1870 scf_handle_destroy(h);
1871 free(fmri);
1872 return (NULL);
1873 }
1874
1875 static int
1876 is_admin_event(restarter_event_type_t t) {
1877
1878 switch (t) {
1879 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
1880 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
1881 case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1882 case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1883 case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
1884 case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1885 return (1);
1886 default:
1887 return (0);
|