xref: /titanic_44/usr/src/cmd/svc/startd/restarter.c (revision e4b86885570d77af552e9cf94f142f4d744fb8c8)
1 /*
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  * restarter.c - service manipulation
30  *
31  * This component manages services whose restarter is svc.startd, the standard
32  * restarter.  It translates restarter protocol events from the graph engine
33  * into actions on processes, as a delegated restarter would do.
34  *
35  * The master restarter manages a number of always-running threads:
36  *   - restarter event thread: events from the graph engine
37  *   - timeout thread: thread to fire queued timeouts
38  *   - contract thread: thread to handle contract events
39  *   - wait thread: thread to handle wait-based services
40  *
41  * The other threads are created as-needed:
42  *   - per-instance method threads
43  *   - per-instance event processing threads
44  *
45  * The interaction of all threads must result in the following conditions
46  * being satisfied (on a per-instance basis):
47  *   - restarter events must be processed in order
48  *   - method execution must be serialized
49  *   - instance delete must be held until outstanding methods are complete
50  *   - contract events shouldn't be processed while a method is running
51  *   - timeouts should fire even when a method is running
52  *
53  * Service instances are represented by restarter_inst_t's and are kept in the
54  * instance_list list.
55  *
56  * Service States
57  *   The current state of a service instance is kept in
58  *   restarter_inst_t->ri_i.i_state.  If transition to a new state could take
59  *   some time, then before we effect the transition we set
60  *   restarter_inst_t->ri_i.i_next_state to the target state, and afterwards we
61  *   rotate i_next_state to i_state and set i_next_state to
62  *   RESTARTER_STATE_NONE.  So usually i_next_state is _NONE when ri_lock is not
63  *   held.  The exception is when we launch methods, which are done with
64  *   a separate thread.  To keep any other threads from grabbing ri_lock before
65  *   method_thread() does, we set ri_method_thread to the thread id of the
66  *   method thread, and when it is nonzero any thread with a different thread id
67  *   waits on ri_method_cv.
68  *
69  * Method execution is serialized by blocking on ri_method_cv in
70  * inst_lookup_by_id() and waiting for a 0 value of ri_method_thread.  This
71  * also prevents the instance structure from being deleted until all
72  * outstanding operations such as method_thread() have finished.
73  *
74  * Lock ordering:
75  *
76  * dgraph_lock [can be held when taking:]
77  *   utmpx_lock
78  *   dictionary->dict_lock
79  *   st->st_load_lock
80  *   wait_info_lock
81  *   ru->restarter_update_lock
82  *     restarter_queue->rpeq_lock
83  *   instance_list.ril_lock
84  *     inst->ri_lock
85  *   st->st_configd_live_lock
86  *
87  * instance_list.ril_lock
88  *   graph_queue->gpeq_lock
89  *   gu->gu_lock
90  *   st->st_configd_live_lock
91  *   dictionary->dict_lock
92  *   inst->ri_lock
93  *     graph_queue->gpeq_lock
94  *     gu->gu_lock
95  *     tu->tu_lock
96  *     tq->tq_lock
97  *     inst->ri_queue_lock
98  *       wait_info_lock
99  *       bp->cb_lock
100  *     utmpx_lock
101  *
102  * single_user_thread_lock
103  *   wait_info_lock
104  *   utmpx_lock
105  *
106  * gu_freeze_lock
107  *
108  * logbuf_mutex nests inside pretty much everything.
109  */
110 
111 #include <sys/contract/process.h>
112 #include <sys/ctfs.h>
113 #include <sys/stat.h>
114 #include <sys/time.h>
115 #include <sys/types.h>
116 #include <sys/uio.h>
117 #include <sys/wait.h>
118 #include <assert.h>
119 #include <errno.h>
120 #include <fcntl.h>
121 #include <libcontract.h>
122 #include <libcontract_priv.h>
123 #include <libintl.h>
124 #include <librestart.h>
125 #include <librestart_priv.h>
126 #include <libuutil.h>
127 #include <limits.h>
128 #include <poll.h>
129 #include <port.h>
130 #include <pthread.h>
131 #include <stdarg.h>
132 #include <stdio.h>
133 #include <strings.h>
134 #include <unistd.h>
135 
136 #include "startd.h"
137 #include "protocol.h"
138 
139 static uu_list_pool_t *restarter_instance_pool;
140 static restarter_instance_list_t instance_list;
141 
142 static uu_list_pool_t *restarter_queue_pool;
143 
144 /*ARGSUSED*/
145 static int
146 restarter_instance_compare(const void *lc_arg, const void *rc_arg,
147     void *private)
148 {
149 	int lc_id = ((const restarter_inst_t *)lc_arg)->ri_id;
150 	int rc_id = *(int *)rc_arg;
151 
152 	if (lc_id > rc_id)
153 		return (1);
154 	if (lc_id < rc_id)
155 		return (-1);
156 	return (0);
157 }
158 
159 static restarter_inst_t *
160 inst_lookup_by_name(const char *name)
161 {
162 	int id;
163 
164 	id = dict_lookup_byname(name);
165 	if (id == -1)
166 		return (NULL);
167 
168 	return (inst_lookup_by_id(id));
169 }
170 
171 restarter_inst_t *
172 inst_lookup_by_id(int id)
173 {
174 	restarter_inst_t *inst;
175 
176 	MUTEX_LOCK(&instance_list.ril_lock);
177 	inst = uu_list_find(instance_list.ril_instance_list, &id, NULL, NULL);
178 	if (inst != NULL)
179 		MUTEX_LOCK(&inst->ri_lock);
180 	MUTEX_UNLOCK(&instance_list.ril_lock);
181 
182 	if (inst != NULL) {
183 		while (inst->ri_method_thread != 0 &&
184 		    !pthread_equal(inst->ri_method_thread, pthread_self())) {
185 			++inst->ri_method_waiters;
186 			(void) pthread_cond_wait(&inst->ri_method_cv,
187 			    &inst->ri_lock);
188 			assert(inst->ri_method_waiters > 0);
189 			--inst->ri_method_waiters;
190 		}
191 	}
192 
193 	return (inst);
194 }
195 
196 static restarter_inst_t *
197 inst_lookup_queue(const char *name)
198 {
199 	int id;
200 	restarter_inst_t *inst;
201 
202 	id = dict_lookup_byname(name);
203 	if (id == -1)
204 		return (NULL);
205 
206 	MUTEX_LOCK(&instance_list.ril_lock);
207 	inst = uu_list_find(instance_list.ril_instance_list, &id, NULL, NULL);
208 	if (inst != NULL)
209 		MUTEX_LOCK(&inst->ri_queue_lock);
210 	MUTEX_UNLOCK(&instance_list.ril_lock);
211 
212 	return (inst);
213 }
214 
215 const char *
216 service_style(int flags)
217 {
218 	switch (flags & RINST_STYLE_MASK) {
219 	case RINST_CONTRACT:	return ("contract");
220 	case RINST_TRANSIENT:	return ("transient");
221 	case RINST_WAIT:	return ("wait");
222 
223 	default:
224 #ifndef NDEBUG
225 		uu_warn("%s:%d: Bad flags 0x%x.\n", __FILE__, __LINE__, flags);
226 #endif
227 		abort();
228 		/* NOTREACHED */
229 	}
230 }
231 
232 /*
233  * Fails with ECONNABORTED or ECANCELED.
234  */
235 static int
236 check_contract(restarter_inst_t *inst, boolean_t primary,
237     scf_instance_t *scf_inst)
238 {
239 	ctid_t *ctidp;
240 	int fd, r;
241 
242 	ctidp = primary ? &inst->ri_i.i_primary_ctid :
243 	    &inst->ri_i.i_transient_ctid;
244 
245 	assert(*ctidp >= 1);
246 
247 	fd = contract_open(*ctidp, NULL, "status", O_RDONLY);
248 	if (fd >= 0) {
249 		r = close(fd);
250 		assert(r == 0);
251 		return (0);
252 	}
253 
254 	r = restarter_remove_contract(scf_inst, *ctidp, primary ?
255 	    RESTARTER_CONTRACT_PRIMARY : RESTARTER_CONTRACT_TRANSIENT);
256 	switch (r) {
257 	case 0:
258 	case ECONNABORTED:
259 	case ECANCELED:
260 		*ctidp = 0;
261 		return (r);
262 
263 	case ENOMEM:
264 		uu_die("Out of memory\n");
265 		/* NOTREACHED */
266 
267 	case EPERM:
268 		uu_die("Insufficient privilege.\n");
269 		/* NOTREACHED */
270 
271 	case EACCES:
272 		uu_die("Repository backend access denied.\n");
273 		/* NOTREACHED */
274 
275 	case EROFS:
276 		log_error(LOG_INFO, "Could not remove unusable contract id %ld "
277 		    "for %s from repository.\n", *ctidp, inst->ri_i.i_fmri);
278 		return (0);
279 
280 	case EINVAL:
281 	case EBADF:
282 	default:
283 		assert(0);
284 		abort();
285 		/* NOTREACHED */
286 	}
287 }
288 
289 static int stop_instance(scf_handle_t *, restarter_inst_t *, stop_cause_t);
290 
291 /*
292  * int restarter_insert_inst(scf_handle_t *, char *)
293  *   If the inst is already in the restarter list, return its id.  If the inst
294  *   is not in the restarter list, initialize a restarter_inst_t, initialize its
295  *   states, insert it into the list, and return 0.
296  *
297  *   Fails with
298  *     ENOENT - name is not in the repository
299  */
300 static int
301 restarter_insert_inst(scf_handle_t *h, const char *name)
302 {
303 	int id, r;
304 	restarter_inst_t *inst;
305 	uu_list_index_t idx;
306 	scf_service_t *scf_svc;
307 	scf_instance_t *scf_inst;
308 	scf_snapshot_t *snap = NULL;
309 	scf_propertygroup_t *pg;
310 	char *svc_name, *inst_name;
311 	char logfilebuf[PATH_MAX];
312 	char *c;
313 	boolean_t do_commit_states;
314 	restarter_instance_state_t state, next_state;
315 	protocol_states_t *ps;
316 	pid_t start_pid;
317 
318 	MUTEX_LOCK(&instance_list.ril_lock);
319 
320 	/*
321 	 * We don't use inst_lookup_by_name() here because we want the lookup
322 	 * & insert to be atomic.
323 	 */
324 	id = dict_lookup_byname(name);
325 	if (id != -1) {
326 		inst = uu_list_find(instance_list.ril_instance_list, &id, NULL,
327 		    &idx);
328 		if (inst != NULL) {
329 			MUTEX_UNLOCK(&instance_list.ril_lock);
330 			return (0);
331 		}
332 	}
333 
334 	/* Allocate an instance */
335 	inst = startd_zalloc(sizeof (restarter_inst_t));
336 	inst->ri_utmpx_prefix = startd_alloc(max_scf_value_size);
337 	inst->ri_utmpx_prefix[0] = '\0';
338 
339 	inst->ri_i.i_fmri = startd_alloc(strlen(name) + 1);
340 	(void) strcpy((char *)inst->ri_i.i_fmri, name);
341 
342 	inst->ri_queue = startd_list_create(restarter_queue_pool, inst, 0);
343 
344 	/*
345 	 * id shouldn't be -1 since we use the same dictionary as graph.c, but
346 	 * just in case.
347 	 */
348 	inst->ri_id = (id != -1 ? id : dict_insert(name));
349 
350 	special_online_hooks_get(name, &inst->ri_pre_online_hook,
351 	    &inst->ri_post_online_hook, &inst->ri_post_offline_hook);
352 
353 	scf_svc = safe_scf_service_create(h);
354 	scf_inst = safe_scf_instance_create(h);
355 	pg = safe_scf_pg_create(h);
356 	svc_name = startd_alloc(max_scf_name_size);
357 	inst_name = startd_alloc(max_scf_name_size);
358 
359 rep_retry:
360 	if (snap != NULL)
361 		scf_snapshot_destroy(snap);
362 	if (inst->ri_logstem != NULL)
363 		startd_free(inst->ri_logstem, PATH_MAX);
364 	if (inst->ri_common_name != NULL)
365 		startd_free(inst->ri_common_name, max_scf_value_size);
366 	if (inst->ri_C_common_name != NULL)
367 		startd_free(inst->ri_C_common_name, max_scf_value_size);
368 	snap = NULL;
369 	inst->ri_logstem = NULL;
370 	inst->ri_common_name = NULL;
371 	inst->ri_C_common_name = NULL;
372 
373 	if (scf_handle_decode_fmri(h, name, NULL, scf_svc, scf_inst, NULL,
374 	    NULL, SCF_DECODE_FMRI_EXACT) != 0) {
375 		switch (scf_error()) {
376 		case SCF_ERROR_CONNECTION_BROKEN:
377 			libscf_handle_rebind(h);
378 			goto rep_retry;
379 
380 		case SCF_ERROR_NOT_FOUND:
381 			goto deleted;
382 		}
383 
384 		uu_die("Can't decode FMRI %s: %s\n", name,
385 		    scf_strerror(scf_error()));
386 	}
387 
388 	/*
389 	 * If there's no running snapshot, then we execute using the editing
390 	 * snapshot.  Pending snapshots will be taken later.
391 	 */
392 	snap = libscf_get_running_snapshot(scf_inst);
393 
394 	if ((scf_service_get_name(scf_svc, svc_name, max_scf_name_size) < 0) ||
395 	    (scf_instance_get_name(scf_inst, inst_name, max_scf_name_size) <
396 	    0)) {
397 		switch (scf_error()) {
398 		case SCF_ERROR_NOT_SET:
399 			break;
400 
401 		case SCF_ERROR_CONNECTION_BROKEN:
402 			libscf_handle_rebind(h);
403 			goto rep_retry;
404 
405 		default:
406 			assert(0);
407 			abort();
408 		}
409 
410 		goto deleted;
411 	}
412 
413 	(void) snprintf(logfilebuf, PATH_MAX, "%s:%s", svc_name, inst_name);
414 	for (c = logfilebuf; *c != '\0'; c++)
415 		if (*c == '/')
416 			*c = '-';
417 
418 	inst->ri_logstem = startd_alloc(PATH_MAX);
419 	(void) snprintf(inst->ri_logstem, PATH_MAX, "%s%s", logfilebuf,
420 	    LOG_SUFFIX);
421 
422 	/*
423 	 * If the restarter group is missing, use uninit/none.  Otherwise,
424 	 * we're probably being restarted & don't want to mess up the states
425 	 * that are there.
426 	 */
427 	state = RESTARTER_STATE_UNINIT;
428 	next_state = RESTARTER_STATE_NONE;
429 
430 	r = scf_instance_get_pg(scf_inst, SCF_PG_RESTARTER, pg);
431 	if (r != 0) {
432 		switch (scf_error()) {
433 		case SCF_ERROR_CONNECTION_BROKEN:
434 			libscf_handle_rebind(h);
435 			goto rep_retry;
436 
437 		case SCF_ERROR_NOT_SET:
438 			goto deleted;
439 
440 		case SCF_ERROR_NOT_FOUND:
441 			/*
442 			 * This shouldn't happen since the graph engine should
443 			 * have initialized the state to uninitialized/none if
444 			 * there was no restarter pg.  In case somebody
445 			 * deleted it, though....
446 			 */
447 			do_commit_states = B_TRUE;
448 			break;
449 
450 		default:
451 			assert(0);
452 			abort();
453 		}
454 	} else {
455 		r = libscf_read_states(pg, &state, &next_state);
456 		if (r != 0) {
457 			do_commit_states = B_TRUE;
458 		} else {
459 			if (next_state != RESTARTER_STATE_NONE) {
460 				/*
461 				 * Force next_state to _NONE since we
462 				 * don't look for method processes.
463 				 */
464 				next_state = RESTARTER_STATE_NONE;
465 				do_commit_states = B_TRUE;
466 			} else {
467 				/*
468 				 * Inform the restarter of our state without
469 				 * changing the STIME in the repository.
470 				 */
471 				ps = startd_alloc(sizeof (*ps));
472 				inst->ri_i.i_state = ps->ps_state = state;
473 				inst->ri_i.i_next_state = ps->ps_state_next =
474 				    next_state;
475 
476 				graph_protocol_send_event(inst->ri_i.i_fmri,
477 				    GRAPH_UPDATE_STATE_CHANGE, ps);
478 
479 				do_commit_states = B_FALSE;
480 			}
481 		}
482 	}
483 
484 	switch (libscf_get_startd_properties(scf_inst, snap, &inst->ri_flags,
485 	    &inst->ri_utmpx_prefix)) {
486 	case 0:
487 		break;
488 
489 	case ECONNABORTED:
490 		libscf_handle_rebind(h);
491 		goto rep_retry;
492 
493 	case ECANCELED:
494 		goto deleted;
495 
496 	case ENOENT:
497 		/*
498 		 * This is odd, because the graph engine should have required
499 		 * the general property group.  So we'll just use default
500 		 * flags in anticipation of the graph engine sending us
501 		 * REMOVE_INSTANCE when it finds out that the general property
502 		 * group has been deleted.
503 		 */
504 		inst->ri_flags = RINST_CONTRACT;
505 		break;
506 
507 	default:
508 		assert(0);
509 		abort();
510 	}
511 
512 	switch (libscf_get_template_values(scf_inst, snap,
513 	    &inst->ri_common_name, &inst->ri_C_common_name)) {
514 	case 0:
515 		break;
516 
517 	case ECONNABORTED:
518 		libscf_handle_rebind(h);
519 		goto rep_retry;
520 
521 	case ECANCELED:
522 		goto deleted;
523 
524 	case ECHILD:
525 	case ENOENT:
526 		break;
527 
528 	default:
529 		assert(0);
530 		abort();
531 	}
532 
533 	switch (libscf_read_method_ids(h, scf_inst, inst->ri_i.i_fmri,
534 	    &inst->ri_i.i_primary_ctid, &inst->ri_i.i_transient_ctid,
535 	    &start_pid)) {
536 	case 0:
537 		break;
538 
539 	case ECONNABORTED:
540 		libscf_handle_rebind(h);
541 		goto rep_retry;
542 
543 	case ECANCELED:
544 		goto deleted;
545 
546 	default:
547 		assert(0);
548 		abort();
549 	}
550 
551 	if (inst->ri_i.i_primary_ctid >= 1) {
552 		contract_hash_store(inst->ri_i.i_primary_ctid, inst->ri_id);
553 
554 		switch (check_contract(inst, B_TRUE, scf_inst)) {
555 		case 0:
556 			break;
557 
558 		case ECONNABORTED:
559 			libscf_handle_rebind(h);
560 			goto rep_retry;
561 
562 		case ECANCELED:
563 			goto deleted;
564 
565 		default:
566 			assert(0);
567 			abort();
568 		}
569 	}
570 
571 	if (inst->ri_i.i_transient_ctid >= 1) {
572 		switch (check_contract(inst, B_FALSE, scf_inst)) {
573 		case 0:
574 			break;
575 
576 		case ECONNABORTED:
577 			libscf_handle_rebind(h);
578 			goto rep_retry;
579 
580 		case ECANCELED:
581 			goto deleted;
582 
583 		default:
584 			assert(0);
585 			abort();
586 		}
587 	}
588 
589 	/* No more failures we live through, so add it to the list. */
590 	(void) pthread_mutex_init(&inst->ri_lock, &mutex_attrs);
591 	(void) pthread_mutex_init(&inst->ri_queue_lock, &mutex_attrs);
592 	MUTEX_LOCK(&inst->ri_lock);
593 	MUTEX_LOCK(&inst->ri_queue_lock);
594 
595 	(void) pthread_cond_init(&inst->ri_method_cv, NULL);
596 
597 	uu_list_node_init(inst, &inst->ri_link, restarter_instance_pool);
598 	uu_list_insert(instance_list.ril_instance_list, inst, idx);
599 	MUTEX_UNLOCK(&instance_list.ril_lock);
600 
601 	if (start_pid != -1 &&
602 	    (inst->ri_flags & RINST_STYLE_MASK) == RINST_WAIT) {
603 		int ret;
604 		ret = wait_register(start_pid, inst->ri_i.i_fmri, 0, 1);
605 		if (ret == -1) {
606 			/*
607 			 * Implication:  if we can't reregister the
608 			 * instance, we will start another one.  Two
609 			 * instances may or may not result in a resource
610 			 * conflict.
611 			 */
612 			log_error(LOG_WARNING,
613 			    "%s: couldn't reregister %ld for wait\n",
614 			    inst->ri_i.i_fmri, start_pid);
615 		} else if (ret == 1) {
616 			/*
617 			 * Leading PID has exited.
618 			 */
619 			(void) stop_instance(h, inst, RSTOP_EXIT);
620 		}
621 	}
622 
623 
624 	scf_pg_destroy(pg);
625 
626 	if (do_commit_states)
627 		(void) restarter_instance_update_states(h, inst, state,
628 		    next_state, RERR_NONE, NULL);
629 
630 	log_framework(LOG_DEBUG, "%s is a %s-style service\n", name,
631 	    service_style(inst->ri_flags));
632 
633 	MUTEX_UNLOCK(&inst->ri_queue_lock);
634 	MUTEX_UNLOCK(&inst->ri_lock);
635 
636 	startd_free(svc_name, max_scf_name_size);
637 	startd_free(inst_name, max_scf_name_size);
638 	scf_snapshot_destroy(snap);
639 	scf_instance_destroy(scf_inst);
640 	scf_service_destroy(scf_svc);
641 
642 	log_framework(LOG_DEBUG, "%s: inserted instance into restarter list\n",
643 	    name);
644 
645 	return (0);
646 
647 deleted:
648 	MUTEX_UNLOCK(&instance_list.ril_lock);
649 	startd_free(inst_name, max_scf_name_size);
650 	startd_free(svc_name, max_scf_name_size);
651 	if (snap != NULL)
652 		scf_snapshot_destroy(snap);
653 	scf_pg_destroy(pg);
654 	scf_instance_destroy(scf_inst);
655 	scf_service_destroy(scf_svc);
656 	startd_free((void *)inst->ri_i.i_fmri, strlen(inst->ri_i.i_fmri) + 1);
657 	uu_list_destroy(inst->ri_queue);
658 	if (inst->ri_logstem != NULL)
659 		startd_free(inst->ri_logstem, PATH_MAX);
660 	if (inst->ri_common_name != NULL)
661 		startd_free(inst->ri_common_name, max_scf_value_size);
662 	if (inst->ri_C_common_name != NULL)
663 		startd_free(inst->ri_C_common_name, max_scf_value_size);
664 	startd_free(inst->ri_utmpx_prefix, max_scf_value_size);
665 	startd_free(inst, sizeof (restarter_inst_t));
666 	return (ENOENT);
667 }
668 
669 static void
670 restarter_delete_inst(restarter_inst_t *ri)
671 {
672 	int id;
673 	restarter_inst_t *rip;
674 	void *cookie = NULL;
675 	restarter_instance_qentry_t *e;
676 
677 	assert(PTHREAD_MUTEX_HELD(&ri->ri_lock));
678 
679 	/*
680 	 * Must drop the instance lock so we can pick up the instance_list
681 	 * lock & remove the instance.
682 	 */
683 	id = ri->ri_id;
684 	MUTEX_UNLOCK(&ri->ri_lock);
685 
686 	MUTEX_LOCK(&instance_list.ril_lock);
687 
688 	rip = uu_list_find(instance_list.ril_instance_list, &id, NULL, NULL);
689 	if (rip == NULL) {
690 		MUTEX_UNLOCK(&instance_list.ril_lock);
691 		return;
692 	}
693 
694 	assert(ri == rip);
695 
696 	uu_list_remove(instance_list.ril_instance_list, ri);
697 
698 	log_framework(LOG_DEBUG, "%s: deleted instance from restarter list\n",
699 	    ri->ri_i.i_fmri);
700 
701 	MUTEX_UNLOCK(&instance_list.ril_lock);
702 
703 	/*
704 	 * We can lock the instance without holding the instance_list lock
705 	 * since we removed the instance from the list.
706 	 */
707 	MUTEX_LOCK(&ri->ri_lock);
708 	MUTEX_LOCK(&ri->ri_queue_lock);
709 
710 	if (ri->ri_i.i_primary_ctid >= 1)
711 		contract_hash_remove(ri->ri_i.i_primary_ctid);
712 
713 	while (ri->ri_method_thread != 0 || ri->ri_method_waiters > 0)
714 		(void) pthread_cond_wait(&ri->ri_method_cv, &ri->ri_lock);
715 
716 	while ((e = uu_list_teardown(ri->ri_queue, &cookie)) != NULL)
717 		startd_free(e, sizeof (*e));
718 	uu_list_destroy(ri->ri_queue);
719 
720 	startd_free((void *)ri->ri_i.i_fmri, strlen(ri->ri_i.i_fmri) + 1);
721 	startd_free(ri->ri_logstem, PATH_MAX);
722 	if (ri->ri_common_name != NULL)
723 		startd_free(ri->ri_common_name, max_scf_value_size);
724 	if (ri->ri_C_common_name != NULL)
725 		startd_free(ri->ri_C_common_name, max_scf_value_size);
726 	startd_free(ri->ri_utmpx_prefix, max_scf_value_size);
727 	(void) pthread_mutex_destroy(&ri->ri_lock);
728 	(void) pthread_mutex_destroy(&ri->ri_queue_lock);
729 	startd_free(ri, sizeof (restarter_inst_t));
730 }
731 
732 /*
733  * instance_is_wait_style()
734  *
735  *   Returns 1 if the given instance is a "wait-style" service instance.
736  */
737 int
738 instance_is_wait_style(restarter_inst_t *inst)
739 {
740 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
741 	return ((inst->ri_flags & RINST_STYLE_MASK) == RINST_WAIT);
742 }
743 
744 /*
745  * instance_is_transient_style()
746  *
747  *   Returns 1 if the given instance is a transient service instance.
748  */
749 int
750 instance_is_transient_style(restarter_inst_t *inst)
751 {
752 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
753 	return ((inst->ri_flags & RINST_STYLE_MASK) == RINST_TRANSIENT);
754 }
755 
756 /*
757  * instance_in_transition()
758  * Returns 1 if instance is in transition, 0 if not
759  */
760 int
761 instance_in_transition(restarter_inst_t *inst)
762 {
763 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
764 	if (inst->ri_i.i_next_state == RESTARTER_STATE_NONE)
765 		return (0);
766 	return (1);
767 }
768 
769 /*
770  * returns 1 if instance is already started, 0 if not
771  */
772 static int
773 instance_started(restarter_inst_t *inst)
774 {
775 	int ret;
776 
777 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
778 
779 	if (inst->ri_i.i_state == RESTARTER_STATE_ONLINE ||
780 	    inst->ri_i.i_state == RESTARTER_STATE_DEGRADED)
781 		ret = 1;
782 	else
783 		ret = 0;
784 
785 	return (ret);
786 }
787 
788 /*
789  * Returns
790  *   0 - success
791  *   ECONNRESET - success, but h was rebound
792  */
793 int
794 restarter_instance_update_states(scf_handle_t *h, restarter_inst_t *ri,
795     restarter_instance_state_t new_state,
796     restarter_instance_state_t new_state_next, restarter_error_t err, char *aux)
797 {
798 	protocol_states_t *states;
799 	int e;
800 	uint_t retry_count = 0, msecs = ALLOC_DELAY;
801 	boolean_t rebound = B_FALSE;
802 	int prev_state_online;
803 	int state_online;
804 
805 	assert(PTHREAD_MUTEX_HELD(&ri->ri_lock));
806 
807 	prev_state_online = instance_started(ri);
808 
809 retry:
810 	e = _restarter_commit_states(h, &ri->ri_i, new_state, new_state_next,
811 	    aux);
812 	switch (e) {
813 	case 0:
814 		break;
815 
816 	case ENOMEM:
817 		++retry_count;
818 		if (retry_count < ALLOC_RETRY) {
819 			(void) poll(NULL, 0, msecs);
820 			msecs *= ALLOC_DELAY_MULT;
821 			goto retry;
822 		}
823 
824 		/* Like startd_alloc(). */
825 		uu_die("Insufficient memory.\n");
826 		/* NOTREACHED */
827 
828 	case ECONNABORTED:
829 		libscf_handle_rebind(h);
830 		rebound = B_TRUE;
831 		goto retry;
832 
833 	case EPERM:
834 	case EACCES:
835 	case EROFS:
836 		log_error(LOG_NOTICE, "Could not commit state change for %s "
837 		    "to repository: %s.\n", ri->ri_i.i_fmri, strerror(e));
838 		/* FALLTHROUGH */
839 
840 	case ENOENT:
841 		ri->ri_i.i_state = new_state;
842 		ri->ri_i.i_next_state = new_state_next;
843 		break;
844 
845 	case EINVAL:
846 	default:
847 		bad_error("_restarter_commit_states", e);
848 	}
849 
850 	states = startd_alloc(sizeof (protocol_states_t));
851 	states->ps_state = new_state;
852 	states->ps_state_next = new_state_next;
853 	states->ps_err = err;
854 	graph_protocol_send_event(ri->ri_i.i_fmri, GRAPH_UPDATE_STATE_CHANGE,
855 	    (void *)states);
856 
857 	state_online = instance_started(ri);
858 
859 	if (prev_state_online && !state_online)
860 		ri->ri_post_offline_hook();
861 	else if (!prev_state_online && state_online)
862 		ri->ri_post_online_hook();
863 
864 	return (rebound ? ECONNRESET : 0);
865 }
866 
867 void
868 restarter_mark_pending_snapshot(const char *fmri, uint_t flag)
869 {
870 	restarter_inst_t *inst;
871 
872 	assert(flag == RINST_RETAKE_RUNNING || flag == RINST_RETAKE_START);
873 
874 	inst = inst_lookup_by_name(fmri);
875 	if (inst == NULL)
876 		return;
877 
878 	inst->ri_flags |= flag;
879 
880 	MUTEX_UNLOCK(&inst->ri_lock);
881 }
882 
883 static void
884 restarter_take_pending_snapshots(scf_handle_t *h)
885 {
886 	restarter_inst_t *inst;
887 	int r;
888 
889 	MUTEX_LOCK(&instance_list.ril_lock);
890 
891 	for (inst = uu_list_first(instance_list.ril_instance_list);
892 	    inst != NULL;
893 	    inst = uu_list_next(instance_list.ril_instance_list, inst)) {
894 		const char *fmri;
895 		scf_instance_t *sinst = NULL;
896 
897 		MUTEX_LOCK(&inst->ri_lock);
898 
899 		/*
900 		 * This is where we'd check inst->ri_method_thread and if it
901 		 * were nonzero we'd wait in anticipation of another thread
902 		 * executing a method for inst.  Doing so with the instance_list
903 		 * locked, though, leads to deadlock.  Since taking a snapshot
904 		 * during that window won't hurt anything, we'll just continue.
905 		 */
906 
907 		fmri = inst->ri_i.i_fmri;
908 
909 		if (inst->ri_flags & RINST_RETAKE_RUNNING) {
910 			scf_snapshot_t *rsnap;
911 
912 			(void) libscf_fmri_get_instance(h, fmri, &sinst);
913 
914 			rsnap = libscf_get_or_make_running_snapshot(sinst,
915 			    fmri, B_FALSE);
916 
917 			scf_instance_destroy(sinst);
918 
919 			if (rsnap != NULL)
920 				inst->ri_flags &= ~RINST_RETAKE_RUNNING;
921 
922 			scf_snapshot_destroy(rsnap);
923 		}
924 
925 		if (inst->ri_flags & RINST_RETAKE_START) {
926 			switch (r = libscf_snapshots_poststart(h, fmri,
927 			    B_FALSE)) {
928 			case 0:
929 			case ENOENT:
930 				inst->ri_flags &= ~RINST_RETAKE_START;
931 				break;
932 
933 			case ECONNABORTED:
934 				break;
935 
936 			case EACCES:
937 			default:
938 				bad_error("libscf_snapshots_poststart", r);
939 			}
940 		}
941 
942 		MUTEX_UNLOCK(&inst->ri_lock);
943 	}
944 
945 	MUTEX_UNLOCK(&instance_list.ril_lock);
946 }
947 
948 /* ARGSUSED */
949 void *
950 restarter_post_fsminimal_thread(void *unused)
951 {
952 	scf_handle_t *h;
953 	int r;
954 
955 	h = libscf_handle_create_bound_loop();
956 
957 	for (;;) {
958 		r = libscf_create_self(h);
959 		if (r == 0)
960 			break;
961 
962 		assert(r == ECONNABORTED);
963 		libscf_handle_rebind(h);
964 	}
965 
966 	restarter_take_pending_snapshots(h);
967 
968 	(void) scf_handle_unbind(h);
969 	scf_handle_destroy(h);
970 
971 	return (NULL);
972 }
973 
974 /*
975  * int stop_instance()
976  *
977  *   Stop the instance identified by the instance given as the second argument,
978  *   for the cause stated.
979  *
980  *   Returns
981  *     0 - success
982  *     -1 - inst is in transition
983  */
984 static int
985 stop_instance(scf_handle_t *local_handle, restarter_inst_t *inst,
986     stop_cause_t cause)
987 {
988 	fork_info_t *info;
989 	const char *cp;
990 	int err;
991 	restarter_error_t re;
992 
993 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
994 	assert(inst->ri_method_thread == 0);
995 
996 	switch (cause) {
997 	case RSTOP_EXIT:
998 		re = RERR_RESTART;
999 		cp = "all processes in service exited";
1000 		break;
1001 	case RSTOP_CORE:
1002 		re = RERR_FAULT;
1003 		cp = "process dumped core";
1004 		break;
1005 	case RSTOP_SIGNAL:
1006 		re = RERR_FAULT;
1007 		cp = "process received fatal signal from outside the service";
1008 		break;
1009 	case RSTOP_HWERR:
1010 		re = RERR_FAULT;
1011 		cp = "process killed due to uncorrectable hardware error";
1012 		break;
1013 	case RSTOP_DEPENDENCY:
1014 		re = RERR_RESTART;
1015 		cp = "dependency activity requires stop";
1016 		break;
1017 	case RSTOP_DISABLE:
1018 		re = RERR_RESTART;
1019 		cp = "service disabled";
1020 		break;
1021 	case RSTOP_RESTART:
1022 		re = RERR_RESTART;
1023 		cp = "service restarting";
1024 		break;
1025 	default:
1026 #ifndef NDEBUG
1027 		(void) fprintf(stderr, "Unknown cause %d at %s:%d.\n",
1028 		    cause, __FILE__, __LINE__);
1029 #endif
1030 		abort();
1031 	}
1032 
1033 	/* Services in the disabled and maintenance state are ignored */
1034 	if (inst->ri_i.i_state == RESTARTER_STATE_MAINT ||
1035 	    inst->ri_i.i_state == RESTARTER_STATE_DISABLED) {
1036 		log_framework(LOG_DEBUG,
1037 		    "%s: stop_instance -> is maint/disabled\n",
1038 		    inst->ri_i.i_fmri);
1039 		return (0);
1040 	}
1041 
1042 	/* Already stopped instances are left alone */
1043 	if (instance_started(inst) == 0) {
1044 		log_framework(LOG_DEBUG, "Restarter: %s is already stopped.\n",
1045 		    inst->ri_i.i_fmri);
1046 		return (0);
1047 	}
1048 
1049 	if (instance_in_transition(inst)) {
1050 		/* requeue event by returning -1 */
1051 		log_framework(LOG_DEBUG,
1052 		    "Restarter: Not stopping %s, in transition.\n",
1053 		    inst->ri_i.i_fmri);
1054 		return (-1);
1055 	}
1056 
1057 	log_instance(inst, B_TRUE, "Stopping because %s.", cp);
1058 
1059 	log_framework(re == RERR_FAULT ? LOG_INFO : LOG_DEBUG,
1060 	    "%s: Instance stopping because %s.\n", inst->ri_i.i_fmri, cp);
1061 
1062 	if (instance_is_wait_style(inst) && cause == RSTOP_EXIT) {
1063 		/*
1064 		 * No need to stop instance, as child has exited; remove
1065 		 * contract and move the instance to the offline state.
1066 		 */
1067 		switch (err = restarter_instance_update_states(local_handle,
1068 		    inst, inst->ri_i.i_state, RESTARTER_STATE_OFFLINE, re,
1069 		    NULL)) {
1070 		case 0:
1071 		case ECONNRESET:
1072 			break;
1073 
1074 		default:
1075 			bad_error("restarter_instance_update_states", err);
1076 		}
1077 
1078 		(void) update_fault_count(inst, FAULT_COUNT_RESET);
1079 
1080 		if (inst->ri_i.i_primary_ctid != 0) {
1081 			inst->ri_m_inst =
1082 			    safe_scf_instance_create(local_handle);
1083 			inst->ri_mi_deleted = B_FALSE;
1084 
1085 			libscf_reget_instance(inst);
1086 			method_remove_contract(inst, B_TRUE, B_TRUE);
1087 
1088 			scf_instance_destroy(inst->ri_m_inst);
1089 			inst->ri_m_inst = NULL;
1090 		}
1091 
1092 		switch (err = restarter_instance_update_states(local_handle,
1093 		    inst, inst->ri_i.i_next_state, RESTARTER_STATE_NONE, re,
1094 		    NULL)) {
1095 		case 0:
1096 		case ECONNRESET:
1097 			break;
1098 
1099 		default:
1100 			bad_error("restarter_instance_update_states", err);
1101 		}
1102 
1103 		return (0);
1104 	} else if (instance_is_wait_style(inst) && re == RERR_RESTART) {
1105 		/*
1106 		 * Stopping a wait service through means other than the pid
1107 		 * exiting should keep wait_thread() from restarting the
1108 		 * service, by removing it from the wait list.
1109 		 * We cannot remove it right now otherwise the process will
1110 		 * end up <defunct> so mark it to be ignored.
1111 		 */
1112 		wait_ignore_by_fmri(inst->ri_i.i_fmri);
1113 	}
1114 
1115 	switch (err = restarter_instance_update_states(local_handle, inst,
1116 	    inst->ri_i.i_state, inst->ri_i.i_enabled ? RESTARTER_STATE_OFFLINE :
1117 	    RESTARTER_STATE_DISABLED, RERR_NONE, NULL)) {
1118 	case 0:
1119 	case ECONNRESET:
1120 		break;
1121 
1122 	default:
1123 		bad_error("restarter_instance_update_states", err);
1124 	}
1125 
1126 	info = startd_zalloc(sizeof (fork_info_t));
1127 
1128 	info->sf_id = inst->ri_id;
1129 	info->sf_method_type = METHOD_STOP;
1130 	info->sf_event_type = re;
1131 	inst->ri_method_thread = startd_thread_create(method_thread, info);
1132 
1133 	return (0);
1134 }
1135 
1136 /*
1137  * Returns
1138  *   ENOENT - fmri is not in instance_list
1139  *   0 - success
1140  *   ECONNRESET - success, though handle was rebound
1141  *   -1 - instance is in transition
1142  */
1143 int
1144 stop_instance_fmri(scf_handle_t *h, const char *fmri, uint_t flags)
1145 {
1146 	restarter_inst_t *rip;
1147 	int r;
1148 
1149 	rip = inst_lookup_by_name(fmri);
1150 	if (rip == NULL)
1151 		return (ENOENT);
1152 
1153 	r = stop_instance(h, rip, flags);
1154 
1155 	MUTEX_UNLOCK(&rip->ri_lock);
1156 
1157 	return (r);
1158 }
1159 
1160 static void
1161 unmaintain_instance(scf_handle_t *h, restarter_inst_t *rip,
1162     unmaint_cause_t cause)
1163 {
1164 	ctid_t ctid;
1165 	scf_instance_t *inst;
1166 	int r;
1167 	uint_t tries = 0, msecs = ALLOC_DELAY;
1168 	const char *cp;
1169 
1170 	assert(PTHREAD_MUTEX_HELD(&rip->ri_lock));
1171 
1172 	if (rip->ri_i.i_state != RESTARTER_STATE_MAINT) {
1173 		log_error(LOG_DEBUG, "Restarter: "
1174 		    "Ignoring maintenance off command because %s is not in the "
1175 		    "maintenance state.\n", rip->ri_i.i_fmri);
1176 		return;
1177 	}
1178 
1179 	switch (cause) {
1180 	case RUNMAINT_CLEAR:
1181 		cp = "clear requested";
1182 		break;
1183 	case RUNMAINT_DISABLE:
1184 		cp = "disable requested";
1185 		break;
1186 	default:
1187 #ifndef NDEBUG
1188 		(void) fprintf(stderr, "Uncaught case for %d at %s:%d.\n",
1189 		    cause, __FILE__, __LINE__);
1190 #endif
1191 		abort();
1192 	}
1193 
1194 	log_instance(rip, B_TRUE, "Leaving maintenance because %s.",
1195 	    cp);
1196 	log_framework(LOG_DEBUG, "%s: Instance leaving maintenance because "
1197 	    "%s.\n", rip->ri_i.i_fmri, cp);
1198 
1199 	(void) restarter_instance_update_states(h, rip, RESTARTER_STATE_UNINIT,
1200 	    RESTARTER_STATE_NONE, RERR_RESTART, NULL);
1201 
1202 	/*
1203 	 * If we did ADMIN_MAINT_ON_IMMEDIATE, then there might still be
1204 	 * a primary contract.
1205 	 */
1206 	if (rip->ri_i.i_primary_ctid == 0)
1207 		return;
1208 
1209 	ctid = rip->ri_i.i_primary_ctid;
1210 	contract_abandon(ctid);
1211 	rip->ri_i.i_primary_ctid = 0;
1212 
1213 rep_retry:
1214 	switch (r = libscf_fmri_get_instance(h, rip->ri_i.i_fmri, &inst)) {
1215 	case 0:
1216 		break;
1217 
1218 	case ECONNABORTED:
1219 		libscf_handle_rebind(h);
1220 		goto rep_retry;
1221 
1222 	case ENOENT:
1223 		/* Must have been deleted. */
1224 		return;
1225 
1226 	case EINVAL:
1227 	case ENOTSUP:
1228 	default:
1229 		bad_error("libscf_handle_rebind", r);
1230 	}
1231 
1232 again:
1233 	r = restarter_remove_contract(inst, ctid, RESTARTER_CONTRACT_PRIMARY);
1234 	switch (r) {
1235 	case 0:
1236 		break;
1237 
1238 	case ENOMEM:
1239 		++tries;
1240 		if (tries < ALLOC_RETRY) {
1241 			(void) poll(NULL, 0, msecs);
1242 			msecs *= ALLOC_DELAY_MULT;
1243 			goto again;
1244 		}
1245 
1246 		uu_die("Insufficient memory.\n");
1247 		/* NOTREACHED */
1248 
1249 	case ECONNABORTED:
1250 		scf_instance_destroy(inst);
1251 		libscf_handle_rebind(h);
1252 		goto rep_retry;
1253 
1254 	case ECANCELED:
1255 		break;
1256 
1257 	case EPERM:
1258 	case EACCES:
1259 	case EROFS:
1260 		log_error(LOG_INFO,
1261 		    "Could not remove contract id %lu for %s (%s).\n", ctid,
1262 		    rip->ri_i.i_fmri, strerror(r));
1263 		break;
1264 
1265 	case EINVAL:
1266 	case EBADF:
1267 	default:
1268 		bad_error("restarter_remove_contract", r);
1269 	}
1270 
1271 	scf_instance_destroy(inst);
1272 }
1273 
1274 /*
1275  * enable_inst()
1276  *   Set inst->ri_i.i_enabled.  Expects 'e' to be _ENABLE, _DISABLE, or
1277  *   _ADMIN_DISABLE.  If the event is _ENABLE and inst is uninitialized or
1278  *   disabled, move it to offline.  If the event is _DISABLE or
1279  *   _ADMIN_DISABLE, make sure inst will move to disabled.
1280  *
1281  *   Returns
1282  *     0 - success
1283  *     ECONNRESET - h was rebound
1284  */
1285 static int
1286 enable_inst(scf_handle_t *h, restarter_inst_t *inst, restarter_event_type_t e)
1287 {
1288 	restarter_instance_state_t state;
1289 	int r;
1290 
1291 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
1292 	assert(e == RESTARTER_EVENT_TYPE_ADMIN_DISABLE ||
1293 	    e == RESTARTER_EVENT_TYPE_DISABLE ||
1294 	    e == RESTARTER_EVENT_TYPE_ENABLE);
1295 	assert(instance_in_transition(inst) == 0);
1296 
1297 	state = inst->ri_i.i_state;
1298 
1299 	if (e == RESTARTER_EVENT_TYPE_ENABLE) {
1300 		inst->ri_i.i_enabled = 1;
1301 
1302 		if (state == RESTARTER_STATE_UNINIT ||
1303 		    state == RESTARTER_STATE_DISABLED) {
1304 			/*
1305 			 * B_FALSE: Don't log an error if the log_instance()
1306 			 * fails because it will fail on the miniroot before
1307 			 * install-discovery runs.
1308 			 */
1309 			log_instance(inst, B_FALSE, "Enabled.");
1310 			log_framework(LOG_DEBUG, "%s: Instance enabled.\n",
1311 			    inst->ri_i.i_fmri);
1312 			(void) restarter_instance_update_states(h, inst,
1313 			    RESTARTER_STATE_OFFLINE, RESTARTER_STATE_NONE,
1314 			    RERR_NONE, NULL);
1315 		} else {
1316 			log_framework(LOG_DEBUG, "Restarter: "
1317 			    "Not changing state of %s for enable command.\n",
1318 			    inst->ri_i.i_fmri);
1319 		}
1320 	} else {
1321 		inst->ri_i.i_enabled = 0;
1322 
1323 		switch (state) {
1324 		case RESTARTER_STATE_ONLINE:
1325 		case RESTARTER_STATE_DEGRADED:
1326 			r = stop_instance(h, inst, RSTOP_DISABLE);
1327 			return (r == ECONNRESET ? 0 : r);
1328 
1329 		case RESTARTER_STATE_OFFLINE:
1330 		case RESTARTER_STATE_UNINIT:
1331 			if (inst->ri_i.i_primary_ctid != 0) {
1332 				inst->ri_m_inst = safe_scf_instance_create(h);
1333 				inst->ri_mi_deleted = B_FALSE;
1334 
1335 				libscf_reget_instance(inst);
1336 				method_remove_contract(inst, B_TRUE, B_TRUE);
1337 
1338 				scf_instance_destroy(inst->ri_m_inst);
1339 			}
1340 			/* B_FALSE: See log_instance(..., "Enabled."); above */
1341 			log_instance(inst, B_FALSE, "Disabled.");
1342 			log_framework(LOG_DEBUG, "%s: Instance disabled.\n",
1343 			    inst->ri_i.i_fmri);
1344 			(void) restarter_instance_update_states(h, inst,
1345 			    RESTARTER_STATE_DISABLED, RESTARTER_STATE_NONE,
1346 			    RERR_RESTART, NULL);
1347 			return (0);
1348 
1349 		case RESTARTER_STATE_DISABLED:
1350 			break;
1351 
1352 		case RESTARTER_STATE_MAINT:
1353 			/*
1354 			 * We only want to pull the instance out of maintenance
1355 			 * if the disable is on adminstrative request.  The
1356 			 * graph engine sends _DISABLE events whenever a
1357 			 * service isn't in the disabled state, and we don't
1358 			 * want to pull the service out of maintenance if,
1359 			 * for example, it is there due to a dependency cycle.
1360 			 */
1361 			if (e == RESTARTER_EVENT_TYPE_ADMIN_DISABLE)
1362 				unmaintain_instance(h, inst, RUNMAINT_DISABLE);
1363 			break;
1364 
1365 		default:
1366 #ifndef NDEBUG
1367 			(void) fprintf(stderr, "Restarter instance %s has "
1368 			    "unknown state %d.\n", inst->ri_i.i_fmri, state);
1369 #endif
1370 			abort();
1371 		}
1372 	}
1373 
1374 	return (0);
1375 }
1376 
1377 static void
1378 start_instance(scf_handle_t *local_handle, restarter_inst_t *inst)
1379 {
1380 	fork_info_t *info;
1381 
1382 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
1383 	assert(instance_in_transition(inst) == 0);
1384 	assert(inst->ri_method_thread == 0);
1385 
1386 	log_framework(LOG_DEBUG, "%s: trying to start instance\n",
1387 	    inst->ri_i.i_fmri);
1388 
1389 	/* Services in the disabled and maintenance state are ignored */
1390 	if (inst->ri_i.i_state == RESTARTER_STATE_MAINT ||
1391 	    inst->ri_i.i_state == RESTARTER_STATE_DISABLED ||
1392 	    inst->ri_i.i_enabled == 0) {
1393 		log_framework(LOG_DEBUG,
1394 		    "%s: start_instance -> is maint/disabled\n",
1395 		    inst->ri_i.i_fmri);
1396 		return;
1397 	}
1398 
1399 	/* Already started instances are left alone */
1400 	if (instance_started(inst) == 1) {
1401 		log_framework(LOG_DEBUG,
1402 		    "%s: start_instance -> is already started\n",
1403 		    inst->ri_i.i_fmri);
1404 		return;
1405 	}
1406 
1407 	log_framework(LOG_DEBUG, "%s: starting instance.\n", inst->ri_i.i_fmri);
1408 
1409 	(void) restarter_instance_update_states(local_handle, inst,
1410 	    inst->ri_i.i_state, RESTARTER_STATE_ONLINE, RERR_NONE, NULL);
1411 
1412 	info = startd_zalloc(sizeof (fork_info_t));
1413 
1414 	info->sf_id = inst->ri_id;
1415 	info->sf_method_type = METHOD_START;
1416 	info->sf_event_type = RERR_NONE;
1417 	inst->ri_method_thread = startd_thread_create(method_thread, info);
1418 }
1419 
1420 static void
1421 maintain_instance(scf_handle_t *h, restarter_inst_t *rip, int immediate,
1422     const char *aux)
1423 {
1424 	fork_info_t *info;
1425 
1426 	assert(PTHREAD_MUTEX_HELD(&rip->ri_lock));
1427 	assert(aux != NULL);
1428 	assert(rip->ri_method_thread == 0);
1429 
1430 	log_instance(rip, B_TRUE, "Stopping for maintenance due to %s.", aux);
1431 	log_framework(LOG_DEBUG, "%s: stopping for maintenance due to %s.\n",
1432 	    rip->ri_i.i_fmri, aux);
1433 
1434 	/* Services in the maintenance state are ignored */
1435 	if (rip->ri_i.i_state == RESTARTER_STATE_MAINT) {
1436 		log_framework(LOG_DEBUG,
1437 		    "%s: maintain_instance -> is already in maintenance\n",
1438 		    rip->ri_i.i_fmri);
1439 		return;
1440 	}
1441 
1442 	if (immediate || !instance_started(rip)) {
1443 		if (rip->ri_i.i_primary_ctid != 0) {
1444 			rip->ri_m_inst = safe_scf_instance_create(h);
1445 			rip->ri_mi_deleted = B_FALSE;
1446 
1447 			libscf_reget_instance(rip);
1448 			method_remove_contract(rip, B_TRUE, B_TRUE);
1449 
1450 			scf_instance_destroy(rip->ri_m_inst);
1451 		}
1452 
1453 		(void) restarter_instance_update_states(h, rip,
1454 		    RESTARTER_STATE_MAINT, RESTARTER_STATE_NONE, RERR_RESTART,
1455 		    (char *)aux);
1456 		return;
1457 	}
1458 
1459 	(void) restarter_instance_update_states(h, rip, rip->ri_i.i_state,
1460 	    RESTARTER_STATE_MAINT, RERR_NONE, (char *)aux);
1461 
1462 	log_transition(rip, MAINT_REQUESTED);
1463 
1464 	info = startd_zalloc(sizeof (*info));
1465 	info->sf_id = rip->ri_id;
1466 	info->sf_method_type = METHOD_STOP;
1467 	info->sf_event_type = RERR_RESTART;
1468 	rip->ri_method_thread = startd_thread_create(method_thread, info);
1469 }
1470 
1471 static void
1472 refresh_instance(scf_handle_t *h, restarter_inst_t *rip)
1473 {
1474 	scf_instance_t *inst;
1475 	scf_snapshot_t *snap;
1476 	fork_info_t *info;
1477 	int r;
1478 
1479 	assert(PTHREAD_MUTEX_HELD(&rip->ri_lock));
1480 
1481 	log_instance(rip, B_TRUE, "Rereading configuration.");
1482 	log_framework(LOG_DEBUG, "%s: rereading configuration.\n",
1483 	    rip->ri_i.i_fmri);
1484 
1485 rep_retry:
1486 	r = libscf_fmri_get_instance(h, rip->ri_i.i_fmri, &inst);
1487 	switch (r) {
1488 	case 0:
1489 		break;
1490 
1491 	case ECONNABORTED:
1492 		libscf_handle_rebind(h);
1493 		goto rep_retry;
1494 
1495 	case ENOENT:
1496 		/* Must have been deleted. */
1497 		return;
1498 
1499 	case EINVAL:
1500 	case ENOTSUP:
1501 	default:
1502 		bad_error("libscf_fmri_get_instance", r);
1503 	}
1504 
1505 	snap = libscf_get_running_snapshot(inst);
1506 
1507 	r = libscf_get_startd_properties(inst, snap, &rip->ri_flags,
1508 	    &rip->ri_utmpx_prefix);
1509 	switch (r) {
1510 	case 0:
1511 		log_framework(LOG_DEBUG, "%s is a %s-style service\n",
1512 		    rip->ri_i.i_fmri, service_style(rip->ri_flags));
1513 		break;
1514 
1515 	case ECONNABORTED:
1516 		scf_instance_destroy(inst);
1517 		scf_snapshot_destroy(snap);
1518 		libscf_handle_rebind(h);
1519 		goto rep_retry;
1520 
1521 	case ECANCELED:
1522 	case ENOENT:
1523 		/* Succeed in anticipation of REMOVE_INSTANCE. */
1524 		break;
1525 
1526 	default:
1527 		bad_error("libscf_get_startd_properties", r);
1528 	}
1529 
1530 	if (instance_started(rip)) {
1531 		/* Refresh does not change the state. */
1532 		(void) restarter_instance_update_states(h, rip,
1533 		    rip->ri_i.i_state, rip->ri_i.i_state, RERR_NONE, NULL);
1534 
1535 		info = startd_zalloc(sizeof (*info));
1536 		info->sf_id = rip->ri_id;
1537 		info->sf_method_type = METHOD_REFRESH;
1538 		info->sf_event_type = RERR_REFRESH;
1539 
1540 		assert(rip->ri_method_thread == 0);
1541 		rip->ri_method_thread =
1542 		    startd_thread_create(method_thread, info);
1543 	}
1544 
1545 	scf_snapshot_destroy(snap);
1546 	scf_instance_destroy(inst);
1547 }
1548 
1549 const char *event_names[] = { "INVALID", "ADD_INSTANCE", "REMOVE_INSTANCE",
1550 	"ENABLE", "DISABLE", "ADMIN_DEGRADED", "ADMIN_REFRESH",
1551 	"ADMIN_RESTART", "ADMIN_MAINT_OFF", "ADMIN_MAINT_ON",
1552 	"ADMIN_MAINT_ON_IMMEDIATE", "STOP", "START", "DEPENDENCY_CYCLE",
1553 	"INVALID_DEPENDENCY", "ADMIN_DISABLE"
1554 };
1555 
1556 /*
1557  * void *restarter_process_events()
1558  *
1559  *   Called in a separate thread to process the events on an instance's
1560  *   queue.  Empties the queue completely, and tries to keep the thread
1561  *   around for a little while after the queue is empty to save on
1562  *   startup costs.
1563  */
1564 static void *
1565 restarter_process_events(void *arg)
1566 {
1567 	scf_handle_t *h;
1568 	restarter_instance_qentry_t *event;
1569 	restarter_inst_t *rip;
1570 	char *fmri = (char *)arg;
1571 	struct timespec to;
1572 
1573 	assert(fmri != NULL);
1574 
1575 	h = libscf_handle_create_bound_loop();
1576 
1577 	/* grab the queue lock */
1578 	rip = inst_lookup_queue(fmri);
1579 	if (rip == NULL)
1580 		goto out;
1581 
1582 again:
1583 
1584 	while ((event = uu_list_first(rip->ri_queue)) != NULL) {
1585 		restarter_inst_t *inst;
1586 
1587 		/* drop the queue lock */
1588 		MUTEX_UNLOCK(&rip->ri_queue_lock);
1589 
1590 		/*
1591 		 * Grab the inst lock -- this waits until any outstanding
1592 		 * method finishes running.
1593 		 */
1594 		inst = inst_lookup_by_name(fmri);
1595 		if (inst == NULL) {
1596 			/* Getting deleted in the middle isn't an error. */
1597 			goto cont;
1598 		}
1599 
1600 		assert(instance_in_transition(inst) == 0);
1601 
1602 		/* process the event */
1603 		switch (event->riq_type) {
1604 		case RESTARTER_EVENT_TYPE_ENABLE:
1605 		case RESTARTER_EVENT_TYPE_DISABLE:
1606 		case RESTARTER_EVENT_TYPE_ADMIN_DISABLE:
1607 			(void) enable_inst(h, inst, event->riq_type);
1608 			break;
1609 
1610 		case RESTARTER_EVENT_TYPE_REMOVE_INSTANCE:
1611 			restarter_delete_inst(inst);
1612 			inst = NULL;
1613 			goto cont;
1614 
1615 		case RESTARTER_EVENT_TYPE_STOP:
1616 			(void) stop_instance(h, inst, RSTOP_DEPENDENCY);
1617 			break;
1618 
1619 		case RESTARTER_EVENT_TYPE_START:
1620 			start_instance(h, inst);
1621 			break;
1622 
1623 		case RESTARTER_EVENT_TYPE_DEPENDENCY_CYCLE:
1624 			maintain_instance(h, inst, 0, "dependency_cycle");
1625 			break;
1626 
1627 		case RESTARTER_EVENT_TYPE_INVALID_DEPENDENCY:
1628 			maintain_instance(h, inst, 0, "invalid_dependency");
1629 			break;
1630 
1631 		case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
1632 			maintain_instance(h, inst, 0, "administrative_request");
1633 			break;
1634 
1635 		case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
1636 			maintain_instance(h, inst, 1, "administrative_request");
1637 			break;
1638 
1639 		case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1640 			unmaintain_instance(h, inst, RUNMAINT_CLEAR);
1641 			break;
1642 
1643 		case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1644 			refresh_instance(h, inst);
1645 			break;
1646 
1647 		case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
1648 			log_framework(LOG_WARNING, "Restarter: "
1649 			    "%s command (for %s) unimplemented.\n",
1650 			    event_names[event->riq_type], inst->ri_i.i_fmri);
1651 			break;
1652 
1653 		case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1654 			if (!instance_started(inst)) {
1655 				log_framework(LOG_DEBUG, "Restarter: "
1656 				    "Not restarting %s; not running.\n",
1657 				    inst->ri_i.i_fmri);
1658 			} else {
1659 				/*
1660 				 * Stop the instance.  If it can be restarted,
1661 				 * the graph engine will send a new event.
1662 				 */
1663 				(void) stop_instance(h, inst, RSTOP_RESTART);
1664 			}
1665 			break;
1666 
1667 		case RESTARTER_EVENT_TYPE_ADD_INSTANCE:
1668 		default:
1669 #ifndef NDEBUG
1670 			uu_warn("%s:%d: Bad restarter event %d.  "
1671 			    "Aborting.\n", __FILE__, __LINE__, event->riq_type);
1672 #endif
1673 			abort();
1674 		}
1675 
1676 		assert(inst != NULL);
1677 		MUTEX_UNLOCK(&inst->ri_lock);
1678 
1679 cont:
1680 		/* grab the queue lock */
1681 		rip = inst_lookup_queue(fmri);
1682 		if (rip == NULL)
1683 			goto out;
1684 
1685 		/* delete the event */
1686 		uu_list_remove(rip->ri_queue, event);
1687 		startd_free(event, sizeof (restarter_instance_qentry_t));
1688 	}
1689 
1690 	assert(rip != NULL);
1691 
1692 	/*
1693 	 * Try to preserve the thread for a little while for future use.
1694 	 */
1695 	to.tv_sec = 3;
1696 	to.tv_nsec = 0;
1697 	(void) pthread_cond_reltimedwait_np(&rip->ri_queue_cv,
1698 	    &rip->ri_queue_lock, &to);
1699 
1700 	if (uu_list_first(rip->ri_queue) != NULL)
1701 		goto again;
1702 
1703 	rip->ri_queue_thread = 0;
1704 	MUTEX_UNLOCK(&rip->ri_queue_lock);
1705 out:
1706 	(void) scf_handle_unbind(h);
1707 	scf_handle_destroy(h);
1708 	free(fmri);
1709 	return (NULL);
1710 }
1711 
1712 static int
1713 is_admin_event(restarter_event_type_t t) {
1714 
1715 	switch (t) {
1716 	case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON:
1717 	case RESTARTER_EVENT_TYPE_ADMIN_MAINT_ON_IMMEDIATE:
1718 	case RESTARTER_EVENT_TYPE_ADMIN_MAINT_OFF:
1719 	case RESTARTER_EVENT_TYPE_ADMIN_REFRESH:
1720 	case RESTARTER_EVENT_TYPE_ADMIN_DEGRADED:
1721 	case RESTARTER_EVENT_TYPE_ADMIN_RESTART:
1722 		return (1);
1723 	default:
1724 		return (0);
1725 	}
1726 }
1727 
1728 static void
1729 restarter_queue_event(restarter_inst_t *ri, restarter_protocol_event_t *e)
1730 {
1731 	restarter_instance_qentry_t *qe;
1732 	int r;
1733 
1734 	assert(PTHREAD_MUTEX_HELD(&ri->ri_queue_lock));
1735 	assert(!PTHREAD_MUTEX_HELD(&ri->ri_lock));
1736 
1737 	qe = startd_zalloc(sizeof (restarter_instance_qentry_t));
1738 	qe->riq_type = e->rpe_type;
1739 
1740 	uu_list_node_init(qe, &qe->riq_link, restarter_queue_pool);
1741 	r = uu_list_insert_before(ri->ri_queue, NULL, qe);
1742 	assert(r == 0);
1743 }
1744 
1745 /*
1746  * void *restarter_event_thread()
1747  *
1748  *  Handle incoming graph events by placing them on a per-instance
1749  *  queue.  We can't lock the main part of the instance structure, so
1750  *  just modify the seprarately locked event queue portion.
1751  */
1752 /*ARGSUSED*/
1753 static void *
1754 restarter_event_thread(void *unused)
1755 {
1756 	scf_handle_t *h;
1757 
1758 	/*
1759 	 * This is a new thread, and thus, gets its own handle
1760 	 * to the repository.
1761 	 */
1762 	h = libscf_handle_create_bound_loop();
1763 
1764 	MUTEX_LOCK(&ru->restarter_update_lock);
1765 
1766 	/*CONSTCOND*/
1767 	while (1) {
1768 		restarter_protocol_event_t *e;
1769 
1770 		while (ru->restarter_update_wakeup == 0)
1771 			(void) pthread_cond_wait(&ru->restarter_update_cv,
1772 			    &ru->restarter_update_lock);
1773 
1774 		ru->restarter_update_wakeup = 0;
1775 
1776 		while ((e = restarter_event_dequeue()) != NULL) {
1777 			restarter_inst_t *rip;
1778 			char *fmri;
1779 
1780 			MUTEX_UNLOCK(&ru->restarter_update_lock);
1781 
1782 			/*
1783 			 * ADD_INSTANCE is special: there's likely no
1784 			 * instance structure yet, so we need to handle the
1785 			 * addition synchronously.
1786 			 */
1787 			switch (e->rpe_type) {
1788 			case RESTARTER_EVENT_TYPE_ADD_INSTANCE:
1789 				if (restarter_insert_inst(h, e->rpe_inst) != 0)
1790 					log_error(LOG_INFO, "Restarter: "
1791 					    "Could not add %s.\n", e->rpe_inst);
1792 
1793 				MUTEX_LOCK(&st->st_load_lock);
1794 				if (--st->st_load_instances == 0)
1795 					(void) pthread_cond_broadcast(
1796 					    &st->st_load_cv);
1797 				MUTEX_UNLOCK(&st->st_load_lock);
1798 
1799 				goto nolookup;
1800 			}
1801 
1802 			/*
1803 			 * Lookup the instance, locking only the event queue.
1804 			 * Can't grab ri_lock here because it might be held
1805 			 * by a long-running method.
1806 			 */
1807 			rip = inst_lookup_queue(e->rpe_inst);
1808 			if (rip == NULL) {
1809 				log_error(LOG_INFO, "Restarter: "
1810 				    "Ignoring %s command for unknown service "
1811 				    "%s.\n", event_names[e->rpe_type],
1812 				    e->rpe_inst);
1813 				goto nolookup;
1814 			}
1815 
1816 			/* Keep ADMIN events from filling up the queue. */
1817 			if (is_admin_event(e->rpe_type) &&
1818 			    uu_list_numnodes(rip->ri_queue) >
1819 			    RINST_QUEUE_THRESHOLD) {
1820 				MUTEX_UNLOCK(&rip->ri_queue_lock);
1821 				log_instance(rip, B_TRUE, "Instance event "
1822 				    "queue overflow.  Dropping administrative "
1823 				    "request.");
1824 				log_framework(LOG_DEBUG, "%s: Instance event "
1825 				    "queue overflow.  Dropping administrative "
1826 				    "request.\n", rip->ri_i.i_fmri);
1827 				goto nolookup;
1828 			}
1829 
1830 			/* Now add the event to the instance queue. */
1831 			restarter_queue_event(rip, e);
1832 
1833 			if (rip->ri_queue_thread == 0) {
1834 				/*
1835 				 * Start a thread if one isn't already
1836 				 * running.
1837 				 */
1838 				fmri = safe_strdup(e->rpe_inst);
1839 				rip->ri_queue_thread =  startd_thread_create(
1840 				    restarter_process_events, (void *)fmri);
1841 			} else {
1842 				/*
1843 				 * Signal the existing thread that there's
1844 				 * a new event.
1845 				 */
1846 				(void) pthread_cond_broadcast(
1847 				    &rip->ri_queue_cv);
1848 			}
1849 
1850 			MUTEX_UNLOCK(&rip->ri_queue_lock);
1851 nolookup:
1852 			restarter_event_release(e);
1853 
1854 			MUTEX_LOCK(&ru->restarter_update_lock);
1855 		}
1856 	}
1857 
1858 	/*
1859 	 * Unreachable for now -- there's currently no graceful cleanup
1860 	 * called on exit().
1861 	 */
1862 	(void) scf_handle_unbind(h);
1863 	scf_handle_destroy(h);
1864 	return (NULL);
1865 }
1866 
1867 static restarter_inst_t *
1868 contract_to_inst(ctid_t ctid)
1869 {
1870 	restarter_inst_t *inst;
1871 	int id;
1872 
1873 	id = lookup_inst_by_contract(ctid);
1874 	if (id == -1)
1875 		return (NULL);
1876 
1877 	inst = inst_lookup_by_id(id);
1878 	if (inst != NULL) {
1879 		/*
1880 		 * Since ri_lock isn't held by the contract id lookup, this
1881 		 * instance may have been restarted and now be in a new
1882 		 * contract, making the old contract no longer valid for this
1883 		 * instance.
1884 		 */
1885 		if (ctid != inst->ri_i.i_primary_ctid) {
1886 			MUTEX_UNLOCK(&inst->ri_lock);
1887 			inst = NULL;
1888 		}
1889 	}
1890 	return (inst);
1891 }
1892 
1893 /*
1894  * void contract_action()
1895  *   Take action on contract events.
1896  */
1897 static void
1898 contract_action(scf_handle_t *h, restarter_inst_t *inst, ctid_t id,
1899     uint32_t type)
1900 {
1901 	const char *fmri = inst->ri_i.i_fmri;
1902 
1903 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
1904 
1905 	/*
1906 	 * If startd has stopped this contract, there is no need to
1907 	 * stop it again.
1908 	 */
1909 	if (inst->ri_i.i_primary_ctid > 0 &&
1910 	    inst->ri_i.i_primary_ctid_stopped)
1911 		return;
1912 
1913 	if ((type & (CT_PR_EV_EMPTY | CT_PR_EV_CORE | CT_PR_EV_SIGNAL
1914 	    | CT_PR_EV_HWERR)) == 0) {
1915 		/*
1916 		 * There shouldn't be other events, since that's not how we set
1917 		 * the terms. Thus, just log an error and drive on.
1918 		 */
1919 		log_framework(LOG_NOTICE,
1920 		    "%s: contract %ld received unexpected critical event "
1921 		    "(%d)\n", fmri, id, type);
1922 		return;
1923 	}
1924 
1925 	assert(instance_in_transition(inst) == 0);
1926 
1927 	if (instance_is_wait_style(inst)) {
1928 		/*
1929 		 * We ignore all events; if they impact the
1930 		 * process we're monitoring, then the
1931 		 * wait_thread will stop the instance.
1932 		 */
1933 		log_framework(LOG_DEBUG,
1934 		    "%s: ignoring contract event on wait-style service\n",
1935 		    fmri);
1936 	} else {
1937 		/*
1938 		 * A CT_PR_EV_EMPTY event is an RSTOP_EXIT request.
1939 		 */
1940 		switch (type) {
1941 		case CT_PR_EV_EMPTY:
1942 			(void) stop_instance(h, inst, RSTOP_EXIT);
1943 			break;
1944 		case CT_PR_EV_CORE:
1945 			(void) stop_instance(h, inst, RSTOP_CORE);
1946 			break;
1947 		case CT_PR_EV_SIGNAL:
1948 			(void) stop_instance(h, inst, RSTOP_SIGNAL);
1949 			break;
1950 		case CT_PR_EV_HWERR:
1951 			(void) stop_instance(h, inst, RSTOP_HWERR);
1952 			break;
1953 		}
1954 	}
1955 }
1956 
1957 /*
1958  * void *restarter_contract_event_thread(void *)
1959  *   Listens to the process contract bundle for critical events, taking action
1960  *   on events from contracts we know we are responsible for.
1961  */
1962 /*ARGSUSED*/
1963 static void *
1964 restarter_contracts_event_thread(void *unused)
1965 {
1966 	int fd, err;
1967 	scf_handle_t *local_handle;
1968 
1969 	/*
1970 	 * Await graph load completion.  That is, stop here, until we've scanned
1971 	 * the repository for contract - instance associations.
1972 	 */
1973 	MUTEX_LOCK(&st->st_load_lock);
1974 	while (!(st->st_load_complete && st->st_load_instances == 0))
1975 		(void) pthread_cond_wait(&st->st_load_cv, &st->st_load_lock);
1976 	MUTEX_UNLOCK(&st->st_load_lock);
1977 
1978 	/*
1979 	 * This is a new thread, and thus, gets its own handle
1980 	 * to the repository.
1981 	 */
1982 	if ((local_handle = libscf_handle_create_bound(SCF_VERSION)) == NULL)
1983 		uu_die("Unable to bind a new repository handle: %s\n",
1984 		    scf_strerror(scf_error()));
1985 
1986 	fd = open64(CTFS_ROOT "/process/pbundle", O_RDONLY);
1987 	if (fd == -1)
1988 		uu_die("process bundle open failed");
1989 
1990 	/*
1991 	 * Make sure we get all events (including those generated by configd
1992 	 * before this thread was started).
1993 	 */
1994 	err = ct_event_reset(fd);
1995 	assert(err == 0);
1996 
1997 	for (;;) {
1998 		int efd, sfd;
1999 		ct_evthdl_t ev;
2000 		uint32_t type;
2001 		ctevid_t evid;
2002 		ct_stathdl_t status;
2003 		ctid_t ctid;
2004 		restarter_inst_t *inst;
2005 		uint64_t cookie;
2006 
2007 		if (err = ct_event_read_critical(fd, &ev)) {
2008 			log_error(LOG_WARNING,
2009 			    "Error reading next contract event: %s",
2010 			    strerror(err));
2011 			continue;
2012 		}
2013 
2014 		evid = ct_event_get_evid(ev);
2015 		ctid = ct_event_get_ctid(ev);
2016 		type = ct_event_get_type(ev);
2017 
2018 		/* Fetch cookie. */
2019 		if ((sfd = contract_open(ctid, "process", "status", O_RDONLY))
2020 		    < 0) {
2021 			ct_event_free(ev);
2022 			continue;
2023 		}
2024 
2025 		if (err = ct_status_read(sfd, CTD_COMMON, &status)) {
2026 			log_framework(LOG_WARNING, "Could not get status for "
2027 			    "contract %ld: %s\n", ctid, strerror(err));
2028 
2029 			startd_close(sfd);
2030 			ct_event_free(ev);
2031 			continue;
2032 		}
2033 
2034 		cookie = ct_status_get_cookie(status);
2035 
2036 		log_framework(LOG_DEBUG, "Received event %d for ctid %ld "
2037 		    "cookie %lld\n", type, ctid, cookie);
2038 
2039 		ct_status_free(status);
2040 
2041 		startd_close(sfd);
2042 
2043 		/*
2044 		 * svc.configd(1M) restart handling performed by the
2045 		 * fork_configd_thread.  We don't acknowledge, as that thread
2046 		 * will do so.
2047 		 */
2048 		if (cookie == CONFIGD_COOKIE) {
2049 			ct_event_free(ev);
2050 			continue;
2051 		}
2052 
2053 		inst = NULL;
2054 		if (storing_contract != 0 &&
2055 		    (inst = contract_to_inst(ctid)) == NULL) {
2056 			/*
2057 			 * This can happen for two reasons:
2058 			 * - method_run() has not yet stored the
2059 			 *    the contract into the internal hash table.
2060 			 * - we receive an EMPTY event for an abandoned
2061 			 *    contract.
2062 			 * If there is any contract in the process of
2063 			 * being stored into the hash table then re-read
2064 			 * the event later.
2065 			 */
2066 			log_framework(LOG_DEBUG,
2067 			    "Reset event %d for unknown "
2068 			    "contract id %ld\n", type, ctid);
2069 
2070 			/* don't go too fast */
2071 			(void) poll(NULL, 0, 100);
2072 
2073 			(void) ct_event_reset(fd);
2074 			ct_event_free(ev);
2075 			continue;
2076 		}
2077 
2078 		/*
2079 		 * Do not call contract_to_inst() again if first
2080 		 * call succeeded.
2081 		 */
2082 		if (inst == NULL)
2083 			inst = contract_to_inst(ctid);
2084 		if (inst == NULL) {
2085 			/*
2086 			 * This can happen if we receive an EMPTY
2087 			 * event for an abandoned contract.
2088 			 */
2089 			log_framework(LOG_DEBUG,
2090 			    "Received event %d for unknown contract id "
2091 			    "%ld\n", type, ctid);
2092 		} else {
2093 			log_framework(LOG_DEBUG,
2094 			    "Received event %d for contract id "
2095 			    "%ld (%s)\n", type, ctid,
2096 			    inst->ri_i.i_fmri);
2097 
2098 			contract_action(local_handle, inst, ctid, type);
2099 
2100 			MUTEX_UNLOCK(&inst->ri_lock);
2101 		}
2102 
2103 		efd = contract_open(ct_event_get_ctid(ev), "process", "ctl",
2104 		    O_WRONLY);
2105 		if (efd != -1) {
2106 			(void) ct_ctl_ack(efd, evid);
2107 			startd_close(efd);
2108 		}
2109 
2110 		ct_event_free(ev);
2111 
2112 	}
2113 
2114 	/*NOTREACHED*/
2115 	return (NULL);
2116 }
2117 
2118 /*
2119  * Timeout queue, processed by restarter_timeouts_event_thread().
2120  */
2121 timeout_queue_t *timeouts;
2122 static uu_list_pool_t *timeout_pool;
2123 
2124 typedef struct timeout_update {
2125 	pthread_mutex_t		tu_lock;
2126 	pthread_cond_t		tu_cv;
2127 	int			tu_wakeup;
2128 } timeout_update_t;
2129 
2130 timeout_update_t *tu;
2131 
2132 static const char *timeout_ovr_svcs[] = {
2133 	"svc:/system/manifest-import:default",
2134 	"svc:/network/initial:default",
2135 	"svc:/network/service:default",
2136 	"svc:/system/rmtmpfiles:default",
2137 	"svc:/network/loopback:default",
2138 	"svc:/network/physical:default",
2139 	"svc:/system/device/local:default",
2140 	"svc:/system/metainit:default",
2141 	"svc:/system/filesystem/usr:default",
2142 	"svc:/system/filesystem/minimal:default",
2143 	"svc:/system/filesystem/local:default",
2144 	NULL
2145 };
2146 
2147 int
2148 is_timeout_ovr(restarter_inst_t *inst)
2149 {
2150 	int i;
2151 
2152 	for (i = 0; timeout_ovr_svcs[i] != NULL; ++i) {
2153 		if (strcmp(inst->ri_i.i_fmri, timeout_ovr_svcs[i]) == 0) {
2154 			log_instance(inst, B_TRUE, "Timeout override by "
2155 			    "svc.startd.  Using infinite timeout.");
2156 			return (1);
2157 		}
2158 	}
2159 
2160 	return (0);
2161 }
2162 
2163 /*ARGSUSED*/
2164 static int
2165 timeout_compare(const void *lc_arg, const void *rc_arg, void *private)
2166 {
2167 	hrtime_t t1 = ((const timeout_entry_t *)lc_arg)->te_timeout;
2168 	hrtime_t t2 = ((const timeout_entry_t *)rc_arg)->te_timeout;
2169 
2170 	if (t1 > t2)
2171 		return (1);
2172 	else if (t1 < t2)
2173 		return (-1);
2174 	return (0);
2175 }
2176 
2177 void
2178 timeout_init()
2179 {
2180 	timeouts = startd_zalloc(sizeof (timeout_queue_t));
2181 
2182 	(void) pthread_mutex_init(&timeouts->tq_lock, &mutex_attrs);
2183 
2184 	timeout_pool = startd_list_pool_create("timeouts",
2185 	    sizeof (timeout_entry_t), offsetof(timeout_entry_t, te_link),
2186 	    timeout_compare, UU_LIST_POOL_DEBUG);
2187 	assert(timeout_pool != NULL);
2188 
2189 	timeouts->tq_list = startd_list_create(timeout_pool,
2190 	    timeouts, UU_LIST_SORTED);
2191 	assert(timeouts->tq_list != NULL);
2192 
2193 	tu = startd_zalloc(sizeof (timeout_update_t));
2194 	(void) pthread_cond_init(&tu->tu_cv, NULL);
2195 	(void) pthread_mutex_init(&tu->tu_lock, &mutex_attrs);
2196 }
2197 
2198 void
2199 timeout_insert(restarter_inst_t *inst, ctid_t cid, uint64_t timeout_sec)
2200 {
2201 	hrtime_t now, timeout;
2202 	timeout_entry_t *entry;
2203 	uu_list_index_t idx;
2204 
2205 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
2206 
2207 	now = gethrtime();
2208 
2209 	/*
2210 	 * If we overflow LLONG_MAX, we're never timing out anyways, so
2211 	 * just return.
2212 	 */
2213 	if (timeout_sec >= (LLONG_MAX - now) / 1000000000LL) {
2214 		log_instance(inst, B_TRUE, "timeout_seconds too large, "
2215 		    "treating as infinite.");
2216 		return;
2217 	}
2218 
2219 	/* hrtime is in nanoseconds. Convert timeout_sec. */
2220 	timeout = now + (timeout_sec * 1000000000LL);
2221 
2222 	entry = startd_alloc(sizeof (timeout_entry_t));
2223 	entry->te_timeout = timeout;
2224 	entry->te_ctid = cid;
2225 	entry->te_fmri = safe_strdup(inst->ri_i.i_fmri);
2226 	entry->te_logstem = safe_strdup(inst->ri_logstem);
2227 	entry->te_fired = 0;
2228 	/* Insert the calculated timeout time onto the queue. */
2229 	MUTEX_LOCK(&timeouts->tq_lock);
2230 	(void) uu_list_find(timeouts->tq_list, entry, NULL, &idx);
2231 	uu_list_node_init(entry, &entry->te_link, timeout_pool);
2232 	uu_list_insert(timeouts->tq_list, entry, idx);
2233 	MUTEX_UNLOCK(&timeouts->tq_lock);
2234 
2235 	assert(inst->ri_timeout == NULL);
2236 	inst->ri_timeout = entry;
2237 
2238 	MUTEX_LOCK(&tu->tu_lock);
2239 	tu->tu_wakeup = 1;
2240 	(void) pthread_cond_broadcast(&tu->tu_cv);
2241 	MUTEX_UNLOCK(&tu->tu_lock);
2242 }
2243 
2244 
2245 void
2246 timeout_remove(restarter_inst_t *inst, ctid_t cid)
2247 {
2248 	assert(PTHREAD_MUTEX_HELD(&inst->ri_lock));
2249 
2250 	if (inst->ri_timeout == NULL)
2251 		return;
2252 
2253 	assert(inst->ri_timeout->te_ctid == cid);
2254 
2255 	MUTEX_LOCK(&timeouts->tq_lock);
2256 	uu_list_remove(timeouts->tq_list, inst->ri_timeout);
2257 	MUTEX_UNLOCK(&timeouts->tq_lock);
2258 
2259 	free(inst->ri_timeout->te_fmri);
2260 	free(inst->ri_timeout->te_logstem);
2261 	startd_free(inst->ri_timeout, sizeof (timeout_entry_t));
2262 	inst->ri_timeout = NULL;
2263 }
2264 
2265 static int
2266 timeout_now()
2267 {
2268 	timeout_entry_t *e;
2269 	hrtime_t now;
2270 	int ret;
2271 
2272 	now = gethrtime();
2273 
2274 	/*
2275 	 * Walk through the (sorted) timeouts list.  While the timeout
2276 	 * at the head of the list is <= the current time, kill the
2277 	 * method.
2278 	 */
2279 	MUTEX_LOCK(&timeouts->tq_lock);
2280 
2281 	for (e = uu_list_first(timeouts->tq_list);
2282 	    e != NULL && e->te_timeout <= now;
2283 	    e = uu_list_next(timeouts->tq_list, e)) {
2284 		log_framework(LOG_WARNING, "%s: Method or service exit timed "
2285 		    "out.  Killing contract %ld.\n", e->te_fmri, e->te_ctid);
2286 		log_instance_fmri(e->te_fmri, e->te_logstem, B_TRUE,
2287 		    "Method or service exit timed out.  Killing contract %ld.",
2288 		    e->te_ctid);
2289 		e->te_fired = 1;
2290 		(void) contract_kill(e->te_ctid, SIGKILL, e->te_fmri);
2291 	}
2292 
2293 	if (uu_list_numnodes(timeouts->tq_list) > 0)
2294 		ret = 0;
2295 	else
2296 		ret = -1;
2297 
2298 	MUTEX_UNLOCK(&timeouts->tq_lock);
2299 
2300 	return (ret);
2301 }
2302 
2303 /*
2304  * void *restarter_timeouts_event_thread(void *)
2305  *   Responsible for monitoring the method timeouts.  This thread must
2306  *   be started before any methods are called.
2307  */
2308 /*ARGSUSED*/
2309 static void *
2310 restarter_timeouts_event_thread(void *unused)
2311 {
2312 	/*
2313 	 * Timeouts are entered on a priority queue, which is processed by
2314 	 * this thread.  As timeouts are specified in seconds, we'll do
2315 	 * the necessary processing every second, as long as the queue
2316 	 * is not empty.
2317 	 */
2318 
2319 	/*CONSTCOND*/
2320 	while (1) {
2321 		/*
2322 		 * As long as the timeout list isn't empty, process it
2323 		 * every second.
2324 		 */
2325 		if (timeout_now() == 0) {
2326 			(void) sleep(1);
2327 			continue;
2328 		}
2329 
2330 		/* The list is empty, wait until we have more timeouts. */
2331 		MUTEX_LOCK(&tu->tu_lock);
2332 
2333 		while (tu->tu_wakeup == 0)
2334 			(void) pthread_cond_wait(&tu->tu_cv, &tu->tu_lock);
2335 
2336 		tu->tu_wakeup = 0;
2337 		MUTEX_UNLOCK(&tu->tu_lock);
2338 	}
2339 
2340 	return (NULL);
2341 }
2342 
2343 void
2344 restarter_start()
2345 {
2346 	(void) startd_thread_create(restarter_timeouts_event_thread, NULL);
2347 	(void) startd_thread_create(restarter_event_thread, NULL);
2348 	(void) startd_thread_create(restarter_contracts_event_thread, NULL);
2349 	(void) startd_thread_create(wait_thread, NULL);
2350 }
2351 
2352 
2353 void
2354 restarter_init()
2355 {
2356 	restarter_instance_pool = startd_list_pool_create("restarter_instances",
2357 	    sizeof (restarter_inst_t), offsetof(restarter_inst_t,
2358 	    ri_link), restarter_instance_compare, UU_LIST_POOL_DEBUG);
2359 	(void) memset(&instance_list, 0, sizeof (instance_list));
2360 
2361 	(void) pthread_mutex_init(&instance_list.ril_lock, &mutex_attrs);
2362 	instance_list.ril_instance_list = startd_list_create(
2363 	    restarter_instance_pool, &instance_list, UU_LIST_SORTED);
2364 
2365 	restarter_queue_pool = startd_list_pool_create(
2366 	    "restarter_instance_queue", sizeof (restarter_instance_qentry_t),
2367 	    offsetof(restarter_instance_qentry_t,  riq_link), NULL,
2368 	    UU_LIST_POOL_DEBUG);
2369 
2370 	contract_list_pool = startd_list_pool_create(
2371 	    "contract_list", sizeof (contract_entry_t),
2372 	    offsetof(contract_entry_t,  ce_link), NULL,
2373 	    UU_LIST_POOL_DEBUG);
2374 	contract_hash_init();
2375 
2376 	log_framework(LOG_DEBUG, "Initialized restarter\n");
2377 }
2378