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