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