2 * CDDL HEADER START
3 *
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 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 #pragma ident "%Z%%M% %I% %E% SMI"
27
28 /*
29 * method.c - method execution functions
30 *
31 * This file contains the routines needed to run a method: a fork(2)-exec(2)
32 * invocation monitored using either the contract filesystem or waitpid(2).
33 * (Plain fork1(2) support is provided in fork.c.)
34 *
35 * Contract Transfer
36 * When we restart a service, we want to transfer any contracts that the old
37 * service's contract inherited. This means that (a) we must not abandon the
38 * old contract when the service dies and (b) we must write the id of the old
39 * contract into the terms of the new contract. There should be limits to
40 * (a), though, since we don't want to keep the contract around forever. To
41 * this end we'll say that services in the offline state may have a contract
42 * to be transfered and services in the disabled or maintenance states cannot.
43 * This means that when a service transitions from online (or degraded) to
44 * offline, the contract should be preserved, and when the service transitions
45 * from offline to online (i.e., the start method), we'll transfer inherited
46 * contracts.
47 */
938 log_instance(inst, B_TRUE, "Method \"%s\" exited with status "
939 "%d.", mname, *exit_code);
940
941 if (*exit_code != 0)
942 goto contract_out;
943
944 end_time = time(NULL);
945
946 /* Give service contract remaining seconds to empty */
947 if (timeout != METHOD_TIMEOUT_INFINITE)
948 timeout -= (end_time - start_time);
949 }
950
951 assured_kill:
952 /*
953 * For stop methods, assure that the service contract has emptied
954 * before returning.
955 */
956 if (type == METHOD_STOP && (!instance_is_transient_style(inst)) &&
957 !(contract_is_empty(inst->ri_i.i_primary_ctid))) {
958
959 if (timeout != METHOD_TIMEOUT_INFINITE)
960 timeout_insert(inst, inst->ri_i.i_primary_ctid,
961 timeout);
962
963 for (;;) {
964 (void) poll(NULL, 0, 100);
965 if (contract_is_empty(inst->ri_i.i_primary_ctid))
966 break;
967 }
968
969 if (timeout != METHOD_TIMEOUT_INFINITE)
970 if (inst->ri_timeout->te_fired)
971 result = EFAULT;
972
973 timeout_remove(inst, inst->ri_i.i_primary_ctid);
974 }
975
976 contract_out:
977 /* Abandon contracts for transient methods & methods that fail. */
978 transient = method_is_transient(inst, type);
979 if ((transient || *exit_code != 0 || result != 0) &&
980 (restarter_is_kill_method(method) < 0))
981 method_remove_contract(inst, !transient, B_TRUE);
982
983 out:
984 if (ctfd >= 0)
|
2 * CDDL HEADER START
3 *
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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
24 */
25
26 /*
27 * method.c - method execution functions
28 *
29 * This file contains the routines needed to run a method: a fork(2)-exec(2)
30 * invocation monitored using either the contract filesystem or waitpid(2).
31 * (Plain fork1(2) support is provided in fork.c.)
32 *
33 * Contract Transfer
34 * When we restart a service, we want to transfer any contracts that the old
35 * service's contract inherited. This means that (a) we must not abandon the
36 * old contract when the service dies and (b) we must write the id of the old
37 * contract into the terms of the new contract. There should be limits to
38 * (a), though, since we don't want to keep the contract around forever. To
39 * this end we'll say that services in the offline state may have a contract
40 * to be transfered and services in the disabled or maintenance states cannot.
41 * This means that when a service transitions from online (or degraded) to
42 * offline, the contract should be preserved, and when the service transitions
43 * from offline to online (i.e., the start method), we'll transfer inherited
44 * contracts.
45 */
936 log_instance(inst, B_TRUE, "Method \"%s\" exited with status "
937 "%d.", mname, *exit_code);
938
939 if (*exit_code != 0)
940 goto contract_out;
941
942 end_time = time(NULL);
943
944 /* Give service contract remaining seconds to empty */
945 if (timeout != METHOD_TIMEOUT_INFINITE)
946 timeout -= (end_time - start_time);
947 }
948
949 assured_kill:
950 /*
951 * For stop methods, assure that the service contract has emptied
952 * before returning.
953 */
954 if (type == METHOD_STOP && (!instance_is_transient_style(inst)) &&
955 !(contract_is_empty(inst->ri_i.i_primary_ctid))) {
956 int times = 0;
957
958 if (timeout != METHOD_TIMEOUT_INFINITE)
959 timeout_insert(inst, inst->ri_i.i_primary_ctid,
960 timeout);
961
962 for (;;) {
963 /*
964 * Check frequently at first, then back off. This
965 * keeps startd from idling while shutting down.
966 */
967 if (times < 20) {
968 (void) poll(NULL, 0, 5);
969 times++;
970 } else {
971 (void) poll(NULL, 0, 100);
972 }
973 if (contract_is_empty(inst->ri_i.i_primary_ctid))
974 break;
975 }
976
977 if (timeout != METHOD_TIMEOUT_INFINITE)
978 if (inst->ri_timeout->te_fired)
979 result = EFAULT;
980
981 timeout_remove(inst, inst->ri_i.i_primary_ctid);
982 }
983
984 contract_out:
985 /* Abandon contracts for transient methods & methods that fail. */
986 transient = method_is_transient(inst, type);
987 if ((transient || *exit_code != 0 || result != 0) &&
988 (restarter_is_kill_method(method) < 0))
989 method_remove_contract(inst, !transient, B_TRUE);
990
991 out:
992 if (ctfd >= 0)
|