4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright (c) 2015, Syneto S.R.L. All rights reserved.
25 * Copyright 2016 Toomas Soome <tsoome@me.com>
26 * Copyright 2016 RackTop Systems.
27 */
28
29 /*
30 * graph.c - master restarter graph engine
31 *
32 * The graph engine keeps a dependency graph of all service instances on the
33 * system, as recorded in the repository. It decides when services should
34 * be brought up or down based on service states and dependencies and sends
35 * commands to restarters to effect any changes. It also executes
36 * administrator commands sent by svcadm via the repository.
37 *
38 * The graph is stored in uu_list_t *dgraph and its vertices are
39 * graph_vertex_t's, each of which has a name and an integer id unique to
40 * its name (see dict.c). A vertex's type attribute designates the type
41 * of object it represents: GVT_INST for service instances, GVT_SVC for
42 * service objects (since service instances may depend on another service,
43 * rather than service instance), GVT_FILE for files (which services may
3832 vertex_send_event(v,
3833 RESTARTER_EVENT_TYPE_START);
3834 else
3835 v->gv_start_f(v);
3836 }
3837
3838 console_login_ready = B_FALSE;
3839 }
3840
3841 return (0);
3842 }
3843
3844 /*
3845 * The sulogin thread runs sulogin while can_come_up() is false. run_sulogin()
3846 * keeps sulogin from stepping on console-login's toes.
3847 */
3848 /* ARGSUSED */
3849 static void *
3850 sulogin_thread(void *unused)
3851 {
3852 MUTEX_LOCK(&dgraph_lock);
3853
3854 assert(sulogin_thread_running);
3855
3856 do {
3857 (void) run_sulogin("Console login service(s) cannot run\n");
3858 } while (!can_come_up());
3859
3860 sulogin_thread_running = B_FALSE;
3861 MUTEX_UNLOCK(&dgraph_lock);
3862
3863 return (NULL);
3864 }
3865
3866 /* ARGSUSED */
3867 void *
3868 single_user_thread(void *unused)
3869 {
3870 uint_t left;
3871 scf_handle_t *h;
3872 scf_instance_t *inst;
3873 scf_property_t *prop;
3874 scf_value_t *val;
3875 const char *msg;
3876 char *buf;
3877 int r;
3878
3879 MUTEX_LOCK(&single_user_thread_lock);
3880 single_user_thread_count++;
3881
3882 if (!booting_to_single_user)
3883 kill_user_procs();
3884
3885 if (go_single_user_mode || booting_to_single_user) {
3886 msg = "SINGLE USER MODE\n";
3887 } else {
3888 assert(go_to_level1);
3889
3890 fork_rc_script('1', "start", B_TRUE);
3891
3892 uu_warn("The system is ready for administration.\n");
3893
3894 msg = "";
3895 }
3896
3897 MUTEX_UNLOCK(&single_user_thread_lock);
3898
5762 log_error(LOG_WARNING,
5763 "graph_event_loop received an unknown event: %d\n",
5764 e->gpe_type);
5765 break;
5766 }
5767
5768 return (0);
5769 }
5770
5771 /*
5772 * graph_event_thread()
5773 * Wait for state changes from the restarters.
5774 */
5775 /*ARGSUSED*/
5776 void *
5777 graph_event_thread(void *unused)
5778 {
5779 scf_handle_t *h;
5780 int err;
5781
5782 h = libscf_handle_create_bound_loop();
5783
5784 /*CONSTCOND*/
5785 while (1) {
5786 graph_protocol_event_t *e;
5787
5788 MUTEX_LOCK(&gu->gu_lock);
5789
5790 while (gu->gu_wakeup == 0)
5791 (void) pthread_cond_wait(&gu->gu_cv, &gu->gu_lock);
5792
5793 gu->gu_wakeup = 0;
5794
5795 while ((e = graph_event_dequeue()) != NULL) {
5796 MUTEX_LOCK(&e->gpe_lock);
5797 MUTEX_UNLOCK(&gu->gu_lock);
5798
5799 while ((err = handle_graph_update_event(h, e)) ==
5800 ECONNABORTED)
5801 libscf_handle_rebind(h);
6121
6122 out:
6123 startd_free(fmri, max_scf_fmri_size);
6124 scf_value_destroy(val);
6125 scf_property_destroy(prop);
6126 scf_instance_destroy(inst);
6127 }
6128
6129 /*
6130 * void *graph_thread(void *)
6131 *
6132 * Graph management thread.
6133 */
6134 /*ARGSUSED*/
6135 void *
6136 graph_thread(void *arg)
6137 {
6138 scf_handle_t *h;
6139 int err;
6140
6141 h = libscf_handle_create_bound_loop();
6142
6143 if (st->st_initial)
6144 set_initial_milestone(h);
6145
6146 MUTEX_LOCK(&dgraph_lock);
6147 initial_milestone_set = B_TRUE;
6148 err = pthread_cond_broadcast(&initial_milestone_cv);
6149 assert(err == 0);
6150 MUTEX_UNLOCK(&dgraph_lock);
6151
6152 libscf_populate_graph(h);
6153
6154 if (!st->st_initial)
6155 set_restart_milestone(h);
6156
6157 MUTEX_LOCK(&st->st_load_lock);
6158 st->st_load_complete = 1;
6159 (void) pthread_cond_broadcast(&st->st_load_cv);
6160 MUTEX_UNLOCK(&st->st_load_lock);
6777
6778 end_inst_fmri[0] = '\0';
6779
6780 (void) dgraph_remove_instance(fmri, h);
6781 }
6782
6783 free(lfmri);
6784 }
6785
6786 /*ARGSUSED*/
6787 void *
6788 repository_event_thread(void *unused)
6789 {
6790 scf_handle_t *h;
6791 scf_propertygroup_t *pg;
6792 scf_instance_t *inst;
6793 char *fmri = startd_alloc(max_scf_fmri_size);
6794 char *pg_name = startd_alloc(max_scf_value_size);
6795 int r;
6796
6797 h = libscf_handle_create_bound_loop();
6798
6799 pg = safe_scf_pg_create(h);
6800 inst = safe_scf_instance_create(h);
6801
6802 retry:
6803 if (_scf_notify_add_pgtype(h, SCF_GROUP_FRAMEWORK) != SCF_SUCCESS) {
6804 if (scf_error() == SCF_ERROR_CONNECTION_BROKEN) {
6805 libscf_handle_rebind(h);
6806 } else {
6807 log_error(LOG_WARNING,
6808 "Couldn't set up repository notification "
6809 "for property group type %s: %s\n",
6810 SCF_GROUP_FRAMEWORK, scf_strerror(scf_error()));
6811
6812 (void) sleep(1);
6813 }
6814
6815 goto retry;
6816 }
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2018 Joyent, Inc.
25 * Copyright (c) 2015, Syneto S.R.L. All rights reserved.
26 * Copyright 2016 Toomas Soome <tsoome@me.com>
27 * Copyright 2016 RackTop Systems.
28 */
29
30 /*
31 * graph.c - master restarter graph engine
32 *
33 * The graph engine keeps a dependency graph of all service instances on the
34 * system, as recorded in the repository. It decides when services should
35 * be brought up or down based on service states and dependencies and sends
36 * commands to restarters to effect any changes. It also executes
37 * administrator commands sent by svcadm via the repository.
38 *
39 * The graph is stored in uu_list_t *dgraph and its vertices are
40 * graph_vertex_t's, each of which has a name and an integer id unique to
41 * its name (see dict.c). A vertex's type attribute designates the type
42 * of object it represents: GVT_INST for service instances, GVT_SVC for
43 * service objects (since service instances may depend on another service,
44 * rather than service instance), GVT_FILE for files (which services may
3833 vertex_send_event(v,
3834 RESTARTER_EVENT_TYPE_START);
3835 else
3836 v->gv_start_f(v);
3837 }
3838
3839 console_login_ready = B_FALSE;
3840 }
3841
3842 return (0);
3843 }
3844
3845 /*
3846 * The sulogin thread runs sulogin while can_come_up() is false. run_sulogin()
3847 * keeps sulogin from stepping on console-login's toes.
3848 */
3849 /* ARGSUSED */
3850 static void *
3851 sulogin_thread(void *unused)
3852 {
3853 (void) pthread_setname_np(pthread_self(), "sulogin");
3854
3855 MUTEX_LOCK(&dgraph_lock);
3856
3857 assert(sulogin_thread_running);
3858
3859 do {
3860 (void) run_sulogin("Console login service(s) cannot run\n");
3861 } while (!can_come_up());
3862
3863 sulogin_thread_running = B_FALSE;
3864 MUTEX_UNLOCK(&dgraph_lock);
3865
3866 return (NULL);
3867 }
3868
3869 /* ARGSUSED */
3870 void *
3871 single_user_thread(void *unused)
3872 {
3873 uint_t left;
3874 scf_handle_t *h;
3875 scf_instance_t *inst;
3876 scf_property_t *prop;
3877 scf_value_t *val;
3878 const char *msg;
3879 char *buf;
3880 int r;
3881
3882 (void) pthread_setname_np(pthread_self(), "single_user");
3883
3884 MUTEX_LOCK(&single_user_thread_lock);
3885 single_user_thread_count++;
3886
3887 if (!booting_to_single_user)
3888 kill_user_procs();
3889
3890 if (go_single_user_mode || booting_to_single_user) {
3891 msg = "SINGLE USER MODE\n";
3892 } else {
3893 assert(go_to_level1);
3894
3895 fork_rc_script('1', "start", B_TRUE);
3896
3897 uu_warn("The system is ready for administration.\n");
3898
3899 msg = "";
3900 }
3901
3902 MUTEX_UNLOCK(&single_user_thread_lock);
3903
5767 log_error(LOG_WARNING,
5768 "graph_event_loop received an unknown event: %d\n",
5769 e->gpe_type);
5770 break;
5771 }
5772
5773 return (0);
5774 }
5775
5776 /*
5777 * graph_event_thread()
5778 * Wait for state changes from the restarters.
5779 */
5780 /*ARGSUSED*/
5781 void *
5782 graph_event_thread(void *unused)
5783 {
5784 scf_handle_t *h;
5785 int err;
5786
5787 (void) pthread_setname_np(pthread_self(), "graph_event");
5788
5789 h = libscf_handle_create_bound_loop();
5790
5791 /*CONSTCOND*/
5792 while (1) {
5793 graph_protocol_event_t *e;
5794
5795 MUTEX_LOCK(&gu->gu_lock);
5796
5797 while (gu->gu_wakeup == 0)
5798 (void) pthread_cond_wait(&gu->gu_cv, &gu->gu_lock);
5799
5800 gu->gu_wakeup = 0;
5801
5802 while ((e = graph_event_dequeue()) != NULL) {
5803 MUTEX_LOCK(&e->gpe_lock);
5804 MUTEX_UNLOCK(&gu->gu_lock);
5805
5806 while ((err = handle_graph_update_event(h, e)) ==
5807 ECONNABORTED)
5808 libscf_handle_rebind(h);
6128
6129 out:
6130 startd_free(fmri, max_scf_fmri_size);
6131 scf_value_destroy(val);
6132 scf_property_destroy(prop);
6133 scf_instance_destroy(inst);
6134 }
6135
6136 /*
6137 * void *graph_thread(void *)
6138 *
6139 * Graph management thread.
6140 */
6141 /*ARGSUSED*/
6142 void *
6143 graph_thread(void *arg)
6144 {
6145 scf_handle_t *h;
6146 int err;
6147
6148 (void) pthread_setname_np(pthread_self(), "graph");
6149
6150 h = libscf_handle_create_bound_loop();
6151
6152 if (st->st_initial)
6153 set_initial_milestone(h);
6154
6155 MUTEX_LOCK(&dgraph_lock);
6156 initial_milestone_set = B_TRUE;
6157 err = pthread_cond_broadcast(&initial_milestone_cv);
6158 assert(err == 0);
6159 MUTEX_UNLOCK(&dgraph_lock);
6160
6161 libscf_populate_graph(h);
6162
6163 if (!st->st_initial)
6164 set_restart_milestone(h);
6165
6166 MUTEX_LOCK(&st->st_load_lock);
6167 st->st_load_complete = 1;
6168 (void) pthread_cond_broadcast(&st->st_load_cv);
6169 MUTEX_UNLOCK(&st->st_load_lock);
6786
6787 end_inst_fmri[0] = '\0';
6788
6789 (void) dgraph_remove_instance(fmri, h);
6790 }
6791
6792 free(lfmri);
6793 }
6794
6795 /*ARGSUSED*/
6796 void *
6797 repository_event_thread(void *unused)
6798 {
6799 scf_handle_t *h;
6800 scf_propertygroup_t *pg;
6801 scf_instance_t *inst;
6802 char *fmri = startd_alloc(max_scf_fmri_size);
6803 char *pg_name = startd_alloc(max_scf_value_size);
6804 int r;
6805
6806 (void) pthread_setname_np(pthread_self(), "repository_event");
6807
6808 h = libscf_handle_create_bound_loop();
6809
6810 pg = safe_scf_pg_create(h);
6811 inst = safe_scf_instance_create(h);
6812
6813 retry:
6814 if (_scf_notify_add_pgtype(h, SCF_GROUP_FRAMEWORK) != SCF_SUCCESS) {
6815 if (scf_error() == SCF_ERROR_CONNECTION_BROKEN) {
6816 libscf_handle_rebind(h);
6817 } else {
6818 log_error(LOG_WARNING,
6819 "Couldn't set up repository notification "
6820 "for property group type %s: %s\n",
6821 SCF_GROUP_FRAMEWORK, scf_strerror(scf_error()));
6822
6823 (void) sleep(1);
6824 }
6825
6826 goto retry;
6827 }
|