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 2011 Joyent Inc.
25 */
26
27 /*
28 * method.c - method execution functions
29 *
30 * This file contains the routines needed to run a method: a fork(2)-exec(2)
31 * invocation monitored using either the contract filesystem or waitpid(2).
32 * (Plain fork1(2) support is provided in fork.c.)
33 *
34 * Contract Transfer
35 * When we restart a service, we want to transfer any contracts that the old
36 * service's contract inherited. This means that (a) we must not abandon the
37 * old contract when the service dies and (b) we must write the id of the old
38 * contract into the terms of the new contract. There should be limits to
39 * (a), though, since we don't want to keep the contract around forever. To
40 * this end we'll say that services in the offline state may have a contract
41 * to be transfered and services in the disabled or maintenance states cannot.
42 * This means that when a service transitions from online (or degraded) to
43 * offline, the contract should be preserved, and when the service transitions
44 * from offline to online (i.e., the start method), we'll transfer inherited
1098 * each, the method must be fetched from the repository & executed. fork()ed
1099 * methods must be waited on, except for the start method of wait services
1100 * (which must be registered with the wait subsystem via wait_register()). If
1101 * the method succeeded (returned 0), then for start methods its contract
1102 * should be recorded as the primary contract for the service. For other
1103 * methods, it should be abandoned. If the method fails, then depending on
1104 * the failure, either the method should be reexecuted or the service should
1105 * be put into maintenance. Either way the contract should be abandoned.
1106 */
1107 void *
1108 method_thread(void *arg)
1109 {
1110 fork_info_t *info = arg;
1111 restarter_inst_t *inst;
1112 scf_handle_t *local_handle;
1113 scf_instance_t *s_inst = NULL;
1114 int r, exit_code;
1115 boolean_t retryable;
1116 restarter_str_t reason;
1117
1118 assert(0 <= info->sf_method_type && info->sf_method_type <= 2);
1119
1120 /* Get (and lock) the restarter_inst_t. */
1121 inst = inst_lookup_by_id(info->sf_id);
1122
1123 assert(inst->ri_method_thread != 0);
1124 assert(instance_in_transition(inst) == 1);
1125
1126 /*
1127 * We cannot leave this function with inst in transition, because
1128 * protocol.c withholds messages for inst otherwise.
1129 */
1130
1131 log_framework(LOG_DEBUG, "method_thread() running %s method for %s.\n",
1132 method_names[info->sf_method_type], inst->ri_i.i_fmri);
1133
1134 local_handle = libscf_handle_create_bound_loop();
1135
1136 rebind_retry:
1137 /* get scf_instance_t */
|
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 */
26
27 /*
28 * method.c - method execution functions
29 *
30 * This file contains the routines needed to run a method: a fork(2)-exec(2)
31 * invocation monitored using either the contract filesystem or waitpid(2).
32 * (Plain fork1(2) support is provided in fork.c.)
33 *
34 * Contract Transfer
35 * When we restart a service, we want to transfer any contracts that the old
36 * service's contract inherited. This means that (a) we must not abandon the
37 * old contract when the service dies and (b) we must write the id of the old
38 * contract into the terms of the new contract. There should be limits to
39 * (a), though, since we don't want to keep the contract around forever. To
40 * this end we'll say that services in the offline state may have a contract
41 * to be transfered and services in the disabled or maintenance states cannot.
42 * This means that when a service transitions from online (or degraded) to
43 * offline, the contract should be preserved, and when the service transitions
44 * from offline to online (i.e., the start method), we'll transfer inherited
1098 * each, the method must be fetched from the repository & executed. fork()ed
1099 * methods must be waited on, except for the start method of wait services
1100 * (which must be registered with the wait subsystem via wait_register()). If
1101 * the method succeeded (returned 0), then for start methods its contract
1102 * should be recorded as the primary contract for the service. For other
1103 * methods, it should be abandoned. If the method fails, then depending on
1104 * the failure, either the method should be reexecuted or the service should
1105 * be put into maintenance. Either way the contract should be abandoned.
1106 */
1107 void *
1108 method_thread(void *arg)
1109 {
1110 fork_info_t *info = arg;
1111 restarter_inst_t *inst;
1112 scf_handle_t *local_handle;
1113 scf_instance_t *s_inst = NULL;
1114 int r, exit_code;
1115 boolean_t retryable;
1116 restarter_str_t reason;
1117
1118 (void) pthread_setname_np(pthread_self(), "method");
1119
1120 assert(0 <= info->sf_method_type && info->sf_method_type <= 2);
1121
1122 /* Get (and lock) the restarter_inst_t. */
1123 inst = inst_lookup_by_id(info->sf_id);
1124
1125 assert(inst->ri_method_thread != 0);
1126 assert(instance_in_transition(inst) == 1);
1127
1128 /*
1129 * We cannot leave this function with inst in transition, because
1130 * protocol.c withholds messages for inst otherwise.
1131 */
1132
1133 log_framework(LOG_DEBUG, "method_thread() running %s method for %s.\n",
1134 method_names[info->sf_method_type], inst->ri_i.i_fmri);
1135
1136 local_handle = libscf_handle_create_bound_loop();
1137
1138 rebind_retry:
1139 /* get scf_instance_t */
|