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 2018 Joyent, Inc. 25 * Copyright 2025 OmniOS Community Edition (OmniOSce) Association. 26 */ 27 28 /* 29 * method.c - method execution functions 30 * 31 * This file contains the routines needed to run a method: a fork(2)-exec(2) 32 * invocation monitored using either the contract filesystem or waitpid(3C). 33 * (Plain fork1(2) support is provided in fork.c.) 34 * 35 * Contract Transfer 36 * When we restart a service, we want to transfer any contracts that the old 37 * service's contract inherited. This means that (a) we must not abandon the 38 * old contract when the service dies and (b) we must write the id of the old 39 * contract into the terms of the new contract. There should be limits to 40 * (a), though, since we don't want to keep the contract around forever. To 41 * this end we'll say that services in the offline state may have a contract 42 * to be transfered and services in the disabled or maintenance states cannot. 43 * This means that when a service transitions from online (or degraded) to 44 * offline, the contract should be preserved, and when the service transitions 45 * from offline to online (i.e., the start method), we'll transfer inherited 46 * contracts. 47 */ 48 49 #include <sys/contract/process.h> 50 #include <sys/ctfs.h> 51 #include <sys/stat.h> 52 #include <sys/time.h> 53 #include <sys/types.h> 54 #include <sys/uio.h> 55 #include <sys/wait.h> 56 #include <alloca.h> 57 #include <assert.h> 58 #include <errno.h> 59 #include <fcntl.h> 60 #include <libcontract.h> 61 #include <libcontract_priv.h> 62 #include <libgen.h> 63 #include <librestart.h> 64 #include <libscf.h> 65 #include <limits.h> 66 #include <port.h> 67 #include <sac.h> 68 #include <signal.h> 69 #include <stdlib.h> 70 #include <string.h> 71 #include <strings.h> 72 #include <unistd.h> 73 #include <atomic.h> 74 #include <poll.h> 75 #include <libscf_priv.h> 76 77 #include "startd.h" 78 79 #define SBIN_SH "/sbin/sh" 80 81 /* 82 * Used to tell if contracts are in the process of being 83 * stored into the svc.startd internal hash table. 84 */ 85 volatile uint16_t storing_contract = 0; 86 87 /* 88 * Mapping from restart_on method-type to contract events. Must correspond to 89 * enum method_restart_t. 90 */ 91 static uint_t method_events[] = { 92 /* METHOD_RESTART_ALL */ 93 CT_PR_EV_HWERR | CT_PR_EV_SIGNAL | CT_PR_EV_CORE | CT_PR_EV_EMPTY, 94 /* METHOD_RESTART_EXTERNAL_FAULT */ 95 CT_PR_EV_HWERR | CT_PR_EV_SIGNAL, 96 /* METHOD_RESTART_ANY_FAULT */ 97 CT_PR_EV_HWERR | CT_PR_EV_SIGNAL | CT_PR_EV_CORE 98 }; 99 100 /* 101 * method_record_start(restarter_inst_t *) 102 * Record a service start for rate limiting. Place the current time 103 * in the circular array of instance starts. 104 */ 105 static void 106 method_record_start(restarter_inst_t *inst) 107 { 108 int index = inst->ri_start_index++ % RINST_START_TIMES; 109 110 inst->ri_start_time[index] = gethrtime(); 111 } 112 113 /* 114 * method_rate_critical(restarter_inst_t *) 115 * Return true if the average start interval is less than the permitted 116 * interval. The implicit interval defaults to RINST_FAILURE_RATE_NS and 117 * RINST_START_TIMES but may be overridden with the svc properties 118 * startd/critical_failure_count and startd/critical_failure_period 119 * which represent the number of failures to consider and the amount of 120 * time in seconds in which that number may occur, respectively. Note that 121 * this time is measured as of the transition to 'enabled' rather than wall 122 * clock time. 123 * Implicit success if insufficient measurements for an average exist. 124 */ 125 int 126 method_rate_critical(restarter_inst_t *inst) 127 { 128 hrtime_t critical_failure_period; 129 uint_t critical_failure_count = RINST_START_TIMES; 130 uint_t n = inst->ri_start_index; 131 hrtime_t avg_ns = 0; 132 uint64_t scf_fr, scf_st; 133 scf_propvec_t *prop = NULL; 134 scf_propvec_t restart_critical[] = { 135 { "critical_failure_period", NULL, SCF_TYPE_INTEGER, NULL, 0 }, 136 { "critical_failure_count", NULL, SCF_TYPE_INTEGER, NULL, 0 }, 137 { NULL } 138 }; 139 140 if (instance_is_wait_style(inst)) 141 critical_failure_period = RINST_WT_SVC_FAILURE_RATE_NS; 142 else 143 critical_failure_period = RINST_FAILURE_RATE_NS; 144 145 restart_critical[0].pv_ptr = &scf_fr; 146 restart_critical[1].pv_ptr = &scf_st; 147 148 if (scf_read_propvec(inst->ri_i.i_fmri, "startd", 149 B_TRUE, restart_critical, &prop) != SCF_FAILED) { 150 /* 151 * critical_failure_period is expressed 152 * in seconds but tracked in ns 153 */ 154 critical_failure_period = (hrtime_t)scf_fr * NANOSEC; 155 critical_failure_count = (uint_t)scf_st; 156 } 157 if (inst->ri_start_index < critical_failure_count) 158 return (0); 159 160 avg_ns = 161 (inst->ri_start_time[(n - 1) % critical_failure_count] - 162 inst->ri_start_time[n % critical_failure_count]) / 163 (critical_failure_count - 1); 164 165 return (avg_ns < critical_failure_period); 166 } 167 168 /* 169 * int method_is_transient() 170 * Determine if the method for the given instance is transient, 171 * from a contract perspective. Return 1 if it is, and 0 if it isn't. 172 */ 173 static int 174 method_is_transient(restarter_inst_t *inst, int type) 175 { 176 if (instance_is_transient_style(inst) || type != METHOD_START) 177 return (1); 178 else 179 return (0); 180 } 181 182 /* 183 * void method_store_contract() 184 * Store the newly created contract id into local structures and 185 * the repository. If the repository connection is broken it is rebound. 186 */ 187 static void 188 method_store_contract(restarter_inst_t *inst, int type, ctid_t *cid) 189 { 190 int r; 191 boolean_t primary; 192 193 if (errno = contract_latest(cid)) 194 uu_die("%s: Couldn't get new contract's id", inst->ri_i.i_fmri); 195 196 primary = !method_is_transient(inst, type); 197 198 if (!primary) { 199 if (inst->ri_i.i_transient_ctid != 0) { 200 log_framework(LOG_INFO, 201 "%s: transient ctid expected to be 0 but " 202 "was set to %ld\n", inst->ri_i.i_fmri, 203 inst->ri_i.i_transient_ctid); 204 } 205 206 inst->ri_i.i_transient_ctid = *cid; 207 } else { 208 if (inst->ri_i.i_primary_ctid != 0) { 209 /* 210 * There was an old contract that we transferred. 211 * Remove it. 212 */ 213 method_remove_contract(inst, B_TRUE, B_FALSE); 214 } 215 216 if (inst->ri_i.i_primary_ctid != 0) { 217 log_framework(LOG_INFO, 218 "%s: primary ctid expected to be 0 but " 219 "was set to %ld\n", inst->ri_i.i_fmri, 220 inst->ri_i.i_primary_ctid); 221 } 222 223 inst->ri_i.i_primary_ctid = *cid; 224 inst->ri_i.i_primary_ctid_stopped = 0; 225 226 log_framework(LOG_DEBUG, "Storing primary contract %ld for " 227 "%s.\n", *cid, inst->ri_i.i_fmri); 228 229 contract_hash_store(*cid, inst->ri_id); 230 } 231 232 again: 233 if (inst->ri_mi_deleted) 234 return; 235 236 r = restarter_store_contract(inst->ri_m_inst, *cid, primary ? 237 RESTARTER_CONTRACT_PRIMARY : RESTARTER_CONTRACT_TRANSIENT); 238 switch (r) { 239 case 0: 240 break; 241 242 case ECANCELED: 243 inst->ri_mi_deleted = B_TRUE; 244 break; 245 246 case ECONNABORTED: 247 libscf_handle_rebind(scf_instance_handle(inst->ri_m_inst)); 248 /* FALLTHROUGH */ 249 250 case EBADF: 251 libscf_reget_instance(inst); 252 goto again; 253 254 case ENOMEM: 255 case EPERM: 256 case EACCES: 257 case EROFS: 258 uu_die("%s: Couldn't store contract id %ld", 259 inst->ri_i.i_fmri, *cid); 260 /* NOTREACHED */ 261 262 case EINVAL: 263 default: 264 bad_error("restarter_store_contract", r); 265 } 266 } 267 268 /* 269 * void method_remove_contract() 270 * Remove any non-permanent contracts from internal structures and 271 * the repository, then abandon them. 272 * Returns 273 * 0 - success 274 * ECANCELED - inst was deleted from the repository 275 * 276 * If the repository connection was broken, it is rebound. 277 */ 278 void 279 method_remove_contract(restarter_inst_t *inst, boolean_t primary, 280 boolean_t abandon) 281 { 282 ctid_t * const ctidp = primary ? &inst->ri_i.i_primary_ctid : 283 &inst->ri_i.i_transient_ctid; 284 285 int r; 286 287 assert(*ctidp != 0); 288 289 log_framework(LOG_DEBUG, "Removing %s contract %lu for %s.\n", 290 primary ? "primary" : "transient", *ctidp, inst->ri_i.i_fmri); 291 292 if (abandon) 293 contract_abandon(*ctidp); 294 295 again: 296 if (inst->ri_mi_deleted) { 297 r = ECANCELED; 298 goto out; 299 } 300 301 r = restarter_remove_contract(inst->ri_m_inst, *ctidp, primary ? 302 RESTARTER_CONTRACT_PRIMARY : RESTARTER_CONTRACT_TRANSIENT); 303 switch (r) { 304 case 0: 305 break; 306 307 case ECANCELED: 308 inst->ri_mi_deleted = B_TRUE; 309 break; 310 311 case ECONNABORTED: 312 libscf_handle_rebind(scf_instance_handle(inst->ri_m_inst)); 313 /* FALLTHROUGH */ 314 315 case EBADF: 316 libscf_reget_instance(inst); 317 goto again; 318 319 case ENOMEM: 320 case EPERM: 321 case EACCES: 322 case EROFS: 323 log_error(LOG_INFO, "%s: Couldn't remove contract id %ld: " 324 "%s.\n", inst->ri_i.i_fmri, *ctidp, strerror(r)); 325 break; 326 327 case EINVAL: 328 default: 329 bad_error("restarter_remove_contract", r); 330 } 331 332 out: 333 if (primary) 334 contract_hash_remove(*ctidp); 335 336 *ctidp = 0; 337 } 338 339 static const char *method_names[] = { "start", "stop", "refresh" }; 340 341 /* 342 * int method_ready_contract(restarter_inst_t *, int, method_restart_t, int) 343 * 344 * Activate a contract template for the type method of inst. type, 345 * restart_on, and cte_mask dictate the critical events term of the contract. 346 * Returns 347 * 0 - success 348 * ECANCELED - inst has been deleted from the repository 349 */ 350 static int 351 method_ready_contract(restarter_inst_t *inst, int type, 352 method_restart_t restart_on, uint_t cte_mask) 353 { 354 int tmpl, err, istrans, iswait, ret; 355 uint_t cevents, fevents; 356 357 /* 358 * Correctly supporting wait-style services is tricky without 359 * rearchitecting startd to cope with multiple event sources 360 * simultaneously trying to stop an instance. Until a better 361 * solution is implemented, we avoid this problem for 362 * wait-style services by making contract events fatal and 363 * letting the wait code alone handle stopping the service. 364 */ 365 iswait = instance_is_wait_style(inst); 366 istrans = method_is_transient(inst, type); 367 368 tmpl = open64(CTFS_ROOT "/process/template", O_RDWR); 369 if (tmpl == -1) 370 uu_die("Could not create contract template"); 371 372 /* 373 * We assume non-login processes are unlikely to create 374 * multiple process groups, and set CT_PR_PGRPONLY for all 375 * wait-style services' contracts. 376 */ 377 err = ct_pr_tmpl_set_param(tmpl, CT_PR_INHERIT | CT_PR_REGENT | 378 (iswait ? CT_PR_PGRPONLY : 0)); 379 assert(err == 0); 380 381 if (istrans) { 382 cevents = 0; 383 fevents = 0; 384 } else { 385 assert(restart_on >= 0); 386 assert(restart_on <= METHOD_RESTART_ANY_FAULT); 387 cevents = method_events[restart_on] & ~cte_mask; 388 fevents = iswait ? 389 (method_events[restart_on] & ~cte_mask & CT_PR_ALLFATAL) : 390 0; 391 } 392 393 err = ct_tmpl_set_critical(tmpl, cevents); 394 assert(err == 0); 395 396 err = ct_tmpl_set_informative(tmpl, 0); 397 assert(err == 0); 398 err = ct_pr_tmpl_set_fatal(tmpl, fevents); 399 assert(err == 0); 400 401 err = ct_tmpl_set_cookie(tmpl, istrans ? METHOD_OTHER_COOKIE : 402 METHOD_START_COOKIE); 403 assert(err == 0); 404 405 if (type == METHOD_START && inst->ri_i.i_primary_ctid != 0) { 406 ret = ct_pr_tmpl_set_transfer(tmpl, inst->ri_i.i_primary_ctid); 407 switch (ret) { 408 case 0: 409 break; 410 411 case ENOTEMPTY: 412 /* No contracts for you! */ 413 method_remove_contract(inst, B_TRUE, B_TRUE); 414 if (inst->ri_mi_deleted) { 415 ret = ECANCELED; 416 goto out; 417 } 418 break; 419 420 case EINVAL: 421 case ESRCH: 422 case EACCES: 423 default: 424 bad_error("ct_pr_tmpl_set_transfer", ret); 425 } 426 } 427 428 err = ct_pr_tmpl_set_svc_fmri(tmpl, inst->ri_i.i_fmri); 429 assert(err == 0); 430 err = ct_pr_tmpl_set_svc_aux(tmpl, method_names[type]); 431 assert(err == 0); 432 433 err = ct_tmpl_activate(tmpl); 434 assert(err == 0); 435 436 ret = 0; 437 438 out: 439 err = close(tmpl); 440 assert(err == 0); 441 442 return (ret); 443 } 444 445 static void 446 exec_method(const restarter_inst_t *inst, int type, const char *method, 447 struct method_context *mcp, uint8_t need_session) 448 { 449 char *cmd; 450 const char *errf; 451 char **nenv; 452 int rsmc_errno = 0; 453 454 cmd = uu_msprintf("exec %s", method); 455 456 if (inst->ri_utmpx_prefix != NULL && inst->ri_utmpx_prefix[0] != '\0') 457 (void) utmpx_mark_init(getpid(), inst->ri_utmpx_prefix); 458 459 setlog(inst->ri_logstem); 460 log_instance(inst, B_FALSE, "Executing %s method (\"%s\").", 461 method_names[type], method); 462 463 if (need_session) 464 (void) setpgrp(); 465 466 /* Set credentials. */ 467 rsmc_errno = restarter_set_method_context(mcp, &errf); 468 if (rsmc_errno != 0) { 469 log_instance(inst, B_FALSE, 470 "svc.startd could not set context for method: "); 471 472 if (rsmc_errno == -1) { 473 if (strcmp(errf, "core_set_process_path") == 0) { 474 log_instance(inst, B_FALSE, 475 "Could not set corefile path."); 476 } else if (strcmp(errf, "setproject") == 0) { 477 log_instance(inst, B_FALSE, "%s: a resource " 478 "control assignment failed", errf); 479 } else if (strcmp(errf, "pool_set_binding") == 0) { 480 log_instance(inst, B_FALSE, "%s: a system " 481 "error occurred", errf); 482 } else { 483 #ifndef NDEBUG 484 uu_warn("%s:%d: Bad function name \"%s\" for " 485 "error %d from " 486 "restarter_set_method_context().\n", 487 __FILE__, __LINE__, errf, rsmc_errno); 488 #endif 489 abort(); 490 } 491 492 exit(1); 493 } 494 495 if (errf != NULL && strcmp(errf, "pool_set_binding") == 0) { 496 switch (rsmc_errno) { 497 case ENOENT: 498 log_instance(inst, B_FALSE, "%s: the pool " 499 "could not be found", errf); 500 break; 501 502 case EBADF: 503 log_instance(inst, B_FALSE, "%s: the " 504 "configuration is invalid", errf); 505 break; 506 507 case EINVAL: 508 log_instance(inst, B_FALSE, "%s: pool name " 509 "\"%s\" is invalid", errf, 510 mcp->resource_pool); 511 break; 512 513 default: 514 #ifndef NDEBUG 515 uu_warn("%s:%d: Bad error %d for function %s " 516 "in restarter_set_method_context().\n", 517 __FILE__, __LINE__, rsmc_errno, errf); 518 #endif 519 abort(); 520 } 521 522 exit(SMF_EXIT_ERR_CONFIG); 523 } 524 525 if (errf != NULL && strcmp(errf, "chdir") == 0) { 526 switch (rsmc_errno) { 527 case EACCES: 528 case EFAULT: 529 case EIO: 530 case ELOOP: 531 case ENAMETOOLONG: 532 case ENOENT: 533 case ENOLINK: 534 case ENOTDIR: 535 log_instance(inst, B_FALSE, "%s: %s (\"%s\")", 536 errf, 537 strerror(rsmc_errno), mcp->working_dir); 538 break; 539 540 default: 541 #ifndef NDEBUG 542 uu_warn("%s:%d: Bad error %d for function %s " 543 "in restarter_set_method_context().\n", 544 __FILE__, __LINE__, rsmc_errno, errf); 545 #endif 546 abort(); 547 } 548 549 exit(SMF_EXIT_ERR_CONFIG); 550 } 551 552 if (errf != NULL) { 553 errno = rsmc_errno; 554 perror(errf); 555 556 switch (rsmc_errno) { 557 case EINVAL: 558 case EPERM: 559 case ENOENT: 560 case ENAMETOOLONG: 561 case ERANGE: 562 case ESRCH: 563 exit(SMF_EXIT_ERR_CONFIG); 564 /* NOTREACHED */ 565 566 default: 567 exit(1); 568 } 569 } 570 571 switch (rsmc_errno) { 572 case ENOMEM: 573 log_instance(inst, B_FALSE, "Out of memory."); 574 exit(1); 575 /* NOTREACHED */ 576 577 case ENOENT: 578 log_instance(inst, B_FALSE, "Missing passwd entry for " 579 "user."); 580 exit(SMF_EXIT_ERR_CONFIG); 581 /* NOTREACHED */ 582 583 default: 584 #ifndef NDEBUG 585 uu_warn("%s:%d: Bad miscellaneous error %d from " 586 "restarter_set_method_context().\n", __FILE__, 587 __LINE__, rsmc_errno); 588 #endif 589 abort(); 590 } 591 } 592 593 nenv = set_smf_env(mcp->env, mcp->env_sz, NULL, inst, 594 method_names[type]); 595 596 log_preexec(); 597 598 (void) execle(SBIN_SH, SBIN_SH, "-c", cmd, NULL, nenv); 599 600 (void) fprintf(stderr, "Failed to exec %s -c '%s': %s\n", 601 SBIN_SH, cmd, strerror(errno)); 602 603 exit(10); 604 } 605 606 static void 607 write_status(restarter_inst_t *inst, const char *mname, int stat) 608 { 609 int r; 610 611 again: 612 if (inst->ri_mi_deleted) 613 return; 614 615 r = libscf_write_method_status(inst->ri_m_inst, mname, stat); 616 switch (r) { 617 case 0: 618 break; 619 620 case ECONNABORTED: 621 libscf_reget_instance(inst); 622 goto again; 623 624 case ECANCELED: 625 inst->ri_mi_deleted = 1; 626 break; 627 628 case EPERM: 629 case EACCES: 630 case EROFS: 631 log_framework(LOG_INFO, "Could not write exit status " 632 "for %s method of %s: %s.\n", mname, 633 inst->ri_i.i_fmri, strerror(r)); 634 break; 635 636 case ENAMETOOLONG: 637 default: 638 bad_error("libscf_write_method_status", r); 639 } 640 } 641 642 /* 643 * int method_run() 644 * Execute the type method of instp. If it requires a fork(), wait for it 645 * to return and return its exit code in *exit_code. Otherwise set 646 * *exit_code to 0 if the method succeeds & -1 if it fails. If the 647 * repository connection is broken, it is rebound, but inst may not be 648 * reset. 649 * Returns 650 * 0 - success 651 * EINVAL - A correct method or method context couldn't be retrieved. 652 * EIO - Contract kill failed. 653 * EFAULT - Method couldn't be executed successfully. 654 * ELOOP - Retry threshold exceeded. 655 * ECANCELED - inst was deleted from the repository before method was run 656 * ERANGE - Timeout retry threshold exceeded. 657 * EAGAIN - Failed due to external cause, retry. 658 */ 659 int 660 method_run(restarter_inst_t **instp, int type, int *exit_code) 661 { 662 char *method; 663 int ret_status; 664 pid_t pid; 665 method_restart_t restart_on; 666 uint_t cte_mask; 667 uint8_t need_session; 668 scf_handle_t *h; 669 scf_snapshot_t *snap; 670 const char *mname; 671 mc_error_t *m_error; 672 struct method_context *mcp; 673 int result = 0, timeout_fired = 0; 674 int sig, r; 675 boolean_t transient; 676 uint64_t timeout; 677 uint8_t timeout_retry; 678 ctid_t ctid; 679 int ctfd = -1; 680 restarter_inst_t *inst = *instp; 681 int id = inst->ri_id; 682 int forkerr; 683 684 assert(MUTEX_HELD(&inst->ri_lock)); 685 assert(instance_in_transition(inst)); 686 687 if (inst->ri_mi_deleted) 688 return (ECANCELED); 689 690 *exit_code = SMF_EXIT_OK; 691 692 assert(0 <= type && type <= 2); 693 mname = method_names[type]; 694 695 if (type == METHOD_START) 696 inst->ri_pre_online_hook(); 697 698 h = scf_instance_handle(inst->ri_m_inst); 699 700 snap = scf_snapshot_create(h); 701 if (snap == NULL || 702 scf_instance_get_snapshot(inst->ri_m_inst, "running", snap) != 0) { 703 log_framework(LOG_DEBUG, 704 "Could not get running snapshot for %s. " 705 "Using editing version to run method %s.\n", 706 inst->ri_i.i_fmri, mname); 707 scf_snapshot_destroy(snap); 708 snap = NULL; 709 } 710 711 /* 712 * After this point, we may be logging to the instance log. 713 * Make sure we've noted where that log is as a property of 714 * the instance. 715 */ 716 r = libscf_note_method_log(inst->ri_m_inst, st->st_log_prefix, 717 inst->ri_logstem); 718 if (r != 0) { 719 log_framework(LOG_WARNING, 720 "%s: couldn't note log location: %s\n", 721 inst->ri_i.i_fmri, strerror(r)); 722 } 723 724 if ((method = libscf_get_method(h, type, inst, snap, &restart_on, 725 &cte_mask, &need_session, &timeout, &timeout_retry)) == NULL) { 726 if (errno == LIBSCF_PGROUP_ABSENT) { 727 log_framework(LOG_DEBUG, 728 "%s: instance has no method property group '%s'.\n", 729 inst->ri_i.i_fmri, mname); 730 if (type == METHOD_REFRESH) 731 log_instance(inst, B_TRUE, "No '%s' method " 732 "defined. Treating as :true.", mname); 733 else 734 log_instance(inst, B_TRUE, "Method property " 735 "group '%s' is not present.", mname); 736 scf_snapshot_destroy(snap); 737 return (0); 738 } else if (errno == LIBSCF_PROPERTY_ABSENT) { 739 log_framework(LOG_DEBUG, 740 "%s: instance has no '%s/exec' method property.\n", 741 inst->ri_i.i_fmri, mname); 742 log_instance(inst, B_TRUE, "Method property '%s/exec " 743 "is not present.", mname); 744 scf_snapshot_destroy(snap); 745 return (0); 746 } else { 747 log_error(LOG_WARNING, 748 "%s: instance libscf_get_method failed\n", 749 inst->ri_i.i_fmri); 750 scf_snapshot_destroy(snap); 751 return (EINVAL); 752 } 753 } 754 755 /* open service contract if stopping a non-transient service */ 756 if (type == METHOD_STOP && (!instance_is_transient_style(inst))) { 757 if (inst->ri_i.i_primary_ctid == 0) { 758 /* service is not running, nothing to stop */ 759 log_framework(LOG_DEBUG, "%s: instance has no primary " 760 "contract, no service to stop.\n", 761 inst->ri_i.i_fmri); 762 scf_snapshot_destroy(snap); 763 return (0); 764 } 765 if ((ctfd = contract_open(inst->ri_i.i_primary_ctid, "process", 766 "events", O_RDONLY)) < 0) { 767 result = EFAULT; 768 log_instance(inst, B_TRUE, "Could not open service " 769 "contract %ld. Stop method not run.", 770 inst->ri_i.i_primary_ctid); 771 goto out; 772 } 773 } 774 775 if (restarter_is_null_method(method)) { 776 log_framework(LOG_DEBUG, "%s: null method succeeds\n", 777 inst->ri_i.i_fmri); 778 779 log_instance(inst, B_TRUE, "Executing %s method (null).", 780 mname); 781 782 if (type == METHOD_START) 783 write_status(inst, mname, 0); 784 goto out; 785 } 786 787 sig = restarter_is_kill_method(method); 788 if (sig >= 0) { 789 790 if (inst->ri_i.i_primary_ctid == 0) { 791 log_error(LOG_ERR, "%s: :kill with no contract\n", 792 inst->ri_i.i_fmri); 793 log_instance(inst, B_TRUE, "Invalid use of \":kill\" " 794 "as stop method for transient service."); 795 result = EINVAL; 796 goto out; 797 } 798 799 log_framework(LOG_DEBUG, 800 "%s: :killing contract with signal %d\n", 801 inst->ri_i.i_fmri, sig); 802 803 log_instance(inst, B_TRUE, "Executing %s method (:kill).", 804 mname); 805 806 if (contract_kill(inst->ri_i.i_primary_ctid, sig, 807 inst->ri_i.i_fmri) != 0) { 808 result = EIO; 809 goto out; 810 } else 811 goto assured_kill; 812 } 813 814 log_framework(LOG_DEBUG, "%s: forking to run method %s\n", 815 inst->ri_i.i_fmri, method); 816 817 m_error = restarter_get_method_context(RESTARTER_METHOD_CONTEXT_VERSION, 818 inst->ri_m_inst, snap, mname, method, &mcp); 819 820 if (m_error != NULL) { 821 log_instance(inst, B_TRUE, "%s", m_error->msg); 822 restarter_mc_error_destroy(m_error); 823 result = EINVAL; 824 goto out; 825 } 826 827 r = method_ready_contract(inst, type, restart_on, cte_mask); 828 if (r != 0) { 829 assert(r == ECANCELED); 830 assert(inst->ri_mi_deleted); 831 restarter_free_method_context(mcp); 832 result = ECANCELED; 833 goto out; 834 } 835 836 /* 837 * Validate safety of method contexts, to save children work. 838 */ 839 if (!restarter_rm_libs_loadable()) 840 log_framework(LOG_DEBUG, "%s: method contexts limited " 841 "to root-accessible libraries\n", inst->ri_i.i_fmri); 842 843 /* 844 * For wait-style svc, sanity check that method exists to prevent an 845 * infinite loop. 846 */ 847 if (instance_is_wait_style(inst) && type == METHOD_START) { 848 char *pend; 849 struct stat64 sbuf; 850 851 /* 852 * We need to handle start method strings that have arguments, 853 * such as '/lib/svc/method/console-login %i'. 854 */ 855 if ((pend = strchr(method, ' ')) != NULL) 856 *pend = '\0'; 857 858 if (*method == '/' && stat64(method, &sbuf) == -1 && 859 errno == ENOENT) { 860 log_instance(inst, B_TRUE, "Missing start method (%s), " 861 "changing state to maintenance.", method); 862 restarter_free_method_context(mcp); 863 result = ENOENT; 864 goto out; 865 } 866 if (pend != NULL) 867 *pend = ' '; 868 } 869 870 /* 871 * If the service is restarting too quickly, send it to 872 * maintenance. 873 */ 874 if (type == METHOD_START) { 875 method_record_start(inst); 876 if (method_rate_critical(inst) && 877 !instance_is_wait_style(inst)) { 878 log_instance(inst, B_TRUE, "Restarting too quickly, " 879 "changing state to maintenance."); 880 result = ELOOP; 881 restarter_free_method_context(mcp); 882 goto out; 883 } 884 } 885 886 atomic_add_16(&storing_contract, 1); 887 pid = startd_fork1(&forkerr); 888 if (pid == 0) 889 exec_method(inst, type, method, mcp, need_session); 890 891 if (pid == -1) { 892 atomic_add_16(&storing_contract, -1); 893 if (forkerr == EAGAIN) 894 result = EAGAIN; 895 else 896 result = EFAULT; 897 898 log_error(LOG_WARNING, 899 "%s: Couldn't fork to execute method %s: %s\n", 900 inst->ri_i.i_fmri, method, strerror(forkerr)); 901 902 restarter_free_method_context(mcp); 903 goto out; 904 } 905 906 907 /* 908 * Get the contract id, decide whether it is primary or transient, and 909 * stash it in inst & the repository. 910 */ 911 method_store_contract(inst, type, &ctid); 912 atomic_add_16(&storing_contract, -1); 913 914 restarter_free_method_context(mcp); 915 916 /* 917 * Similarly for the start method PID. 918 */ 919 if (type == METHOD_START && !inst->ri_mi_deleted) 920 (void) libscf_write_start_pid(inst->ri_m_inst, pid); 921 922 if (instance_is_wait_style(inst) && type == METHOD_START) { 923 /* Wait style instances don't get timeouts on start methods. */ 924 if (wait_register(pid, inst->ri_i.i_fmri, 1, 0)) { 925 log_error(LOG_WARNING, 926 "%s: couldn't register %ld for wait\n", 927 inst->ri_i.i_fmri, pid); 928 result = EFAULT; 929 goto contract_out; 930 } 931 write_status(inst, mname, 0); 932 933 } else { 934 int r, err; 935 time_t start_time; 936 time_t end_time; 937 938 /* 939 * Because on upgrade/live-upgrade we may have no chance 940 * to override faulty timeout values on the way to 941 * manifest import, all services on the path to manifest 942 * import are treated the same as INFINITE timeout services. 943 */ 944 945 start_time = time(NULL); 946 if (timeout != METHOD_TIMEOUT_INFINITE && !is_timeout_ovr(inst)) 947 timeout_insert(inst, ctid, timeout); 948 else 949 timeout = METHOD_TIMEOUT_INFINITE; 950 951 /* Unlock the instance while waiting for the method. */ 952 MUTEX_UNLOCK(&inst->ri_lock); 953 954 do { 955 r = waitpid(pid, &ret_status, 0); 956 } while (r == -1 && errno == EINTR); 957 if (r == -1) 958 err = errno; 959 960 /* Re-grab the lock. */ 961 inst = inst_lookup_by_id(id); 962 963 /* 964 * inst can't be removed, as the removal thread waits 965 * for completion of this one. 966 */ 967 assert(inst != NULL); 968 *instp = inst; 969 970 if (inst->ri_timeout != NULL && inst->ri_timeout->te_fired) 971 timeout_fired = 1; 972 973 timeout_remove(inst, ctid); 974 975 log_framework(LOG_DEBUG, 976 "%s method for %s exited with status %d.\n", mname, 977 inst->ri_i.i_fmri, WEXITSTATUS(ret_status)); 978 979 if (r == -1) { 980 log_error(LOG_WARNING, 981 "Couldn't waitpid() for %s method of %s (%s).\n", 982 mname, inst->ri_i.i_fmri, strerror(err)); 983 result = EFAULT; 984 goto contract_out; 985 } 986 987 if (type == METHOD_START) 988 write_status(inst, mname, ret_status); 989 990 /* return ERANGE if this service doesn't retry on timeout */ 991 if (timeout_fired == 1 && timeout_retry == 0) { 992 result = ERANGE; 993 goto contract_out; 994 } 995 996 if (!WIFEXITED(ret_status)) { 997 /* 998 * If method didn't exit itself (it was killed by an 999 * external entity, etc.), consider the entire 1000 * method_run as failed. 1001 */ 1002 if (WIFSIGNALED(ret_status)) { 1003 char buf[SIG2STR_MAX]; 1004 (void) sig2str(WTERMSIG(ret_status), buf); 1005 1006 log_error(LOG_WARNING, "%s: Method \"%s\" " 1007 "failed due to signal %s.\n", 1008 inst->ri_i.i_fmri, method, buf); 1009 log_instance(inst, B_TRUE, "Method \"%s\" " 1010 "failed due to signal %s.", mname, buf); 1011 } else { 1012 log_error(LOG_WARNING, "%s: Method \"%s\" " 1013 "failed with exit status %d.\n", 1014 inst->ri_i.i_fmri, method, 1015 WEXITSTATUS(ret_status)); 1016 log_instance(inst, B_TRUE, "Method \"%s\" " 1017 "failed with exit status %d.", mname, 1018 WEXITSTATUS(ret_status)); 1019 } 1020 result = EAGAIN; 1021 goto contract_out; 1022 } 1023 1024 *exit_code = WEXITSTATUS(ret_status); 1025 if (*exit_code != SMF_EXIT_OK && 1026 *exit_code != SMF_EXIT_NODAEMON && 1027 *exit_code != SMF_EXIT_MON_DEGRADE) { 1028 log_error(LOG_WARNING, 1029 "%s: Method \"%s\" failed with exit status %d.\n", 1030 inst->ri_i.i_fmri, method, WEXITSTATUS(ret_status)); 1031 } 1032 1033 log_instance(inst, B_TRUE, "Method \"%s\" exited with status " 1034 "%d.", mname, *exit_code); 1035 1036 /* Note: we will take this path for SMF_EXIT_NODAEMON */ 1037 if (*exit_code != SMF_EXIT_OK && 1038 *exit_code != SMF_EXIT_MON_DEGRADE) { 1039 goto contract_out; 1040 } 1041 1042 end_time = time(NULL); 1043 1044 /* Give service contract remaining seconds to empty */ 1045 if (timeout != METHOD_TIMEOUT_INFINITE) 1046 timeout -= (end_time - start_time); 1047 } 1048 1049 assured_kill: 1050 /* 1051 * For stop methods, assure that the service contract has emptied 1052 * before returning. 1053 */ 1054 if (type == METHOD_STOP && (!instance_is_transient_style(inst)) && 1055 !(contract_is_empty(inst->ri_i.i_primary_ctid))) { 1056 int times = 0; 1057 1058 if (timeout != METHOD_TIMEOUT_INFINITE) 1059 timeout_insert(inst, inst->ri_i.i_primary_ctid, 1060 timeout); 1061 1062 for (;;) { 1063 /* 1064 * Check frequently at first, then back off. This 1065 * keeps startd from idling while shutting down. 1066 */ 1067 if (times < 20) { 1068 (void) poll(NULL, 0, 5); 1069 times++; 1070 } else { 1071 (void) poll(NULL, 0, 100); 1072 } 1073 if (contract_is_empty(inst->ri_i.i_primary_ctid)) 1074 break; 1075 } 1076 1077 if (timeout != METHOD_TIMEOUT_INFINITE) 1078 if (inst->ri_timeout->te_fired) 1079 result = EFAULT; 1080 1081 timeout_remove(inst, inst->ri_i.i_primary_ctid); 1082 } 1083 1084 contract_out: 1085 /* 1086 * Abandon contracts for transient methods, methods that exit with 1087 * SMF_EXIT_NODAEMON and methods that fail. 1088 * Non-transient degraded services are left alone here. If their 1089 * contract is or later becomes empty, then that will be handled in the 1090 * same way as for any other non-transient service. 1091 */ 1092 transient = method_is_transient(inst, type); 1093 if ((transient || 1094 (*exit_code != SMF_EXIT_OK && *exit_code != SMF_EXIT_MON_DEGRADE) || 1095 result != 0) && 1096 restarter_is_kill_method(method) < 0) { 1097 method_remove_contract(inst, !transient, B_TRUE); 1098 } 1099 1100 out: 1101 if (ctfd >= 0) 1102 (void) close(ctfd); 1103 scf_snapshot_destroy(snap); 1104 free(method); 1105 return (result); 1106 } 1107 1108 /* 1109 * The method thread executes a service method to effect a state transition. 1110 * The next_state of info->sf_id should be non-_NONE on entrance, and it will 1111 * be _NONE on exit (state will either be what next_state was (on success), or 1112 * it will be _MAINT (on error)). 1113 * 1114 * There are six classes of methods to consider: start & other (stop, refresh) 1115 * for each of "normal" services, wait services, and transient services. For 1116 * each, the method must be fetched from the repository & executed. fork()ed 1117 * methods must be waited on, except for the start method of wait services 1118 * (which must be registered with the wait subsystem via wait_register()). If 1119 * the method succeeded (returned 0), then for start methods its contract 1120 * should be recorded as the primary contract for the service. For other 1121 * methods, it should be abandoned. If the method fails, then depending on 1122 * the failure, either the method should be reexecuted or the service should 1123 * be put into maintenance. Either way the contract should be abandoned. 1124 */ 1125 void * 1126 method_thread(void *arg) 1127 { 1128 fork_info_t *info = arg; 1129 restarter_inst_t *inst; 1130 scf_handle_t *local_handle; 1131 scf_instance_t *s_inst = NULL; 1132 int r, exit_code; 1133 boolean_t retryable; 1134 restarter_str_t reason; 1135 1136 (void) pthread_setname_np(pthread_self(), "method"); 1137 1138 assert(0 <= info->sf_method_type && info->sf_method_type <= 2); 1139 1140 /* Get (and lock) the restarter_inst_t. */ 1141 inst = inst_lookup_by_id(info->sf_id); 1142 1143 assert(inst->ri_method_thread != 0); 1144 assert(instance_in_transition(inst) == 1); 1145 1146 /* 1147 * We cannot leave this function with inst in transition, because 1148 * protocol.c withholds messages for inst otherwise. 1149 */ 1150 1151 log_framework(LOG_DEBUG, "method_thread() running %s method for %s.\n", 1152 method_names[info->sf_method_type], inst->ri_i.i_fmri); 1153 1154 local_handle = libscf_handle_create_bound_loop(); 1155 1156 rebind_retry: 1157 /* get scf_instance_t */ 1158 switch (r = libscf_fmri_get_instance(local_handle, inst->ri_i.i_fmri, 1159 &s_inst)) { 1160 case 0: 1161 break; 1162 1163 case ECONNABORTED: 1164 libscf_handle_rebind(local_handle); 1165 goto rebind_retry; 1166 1167 case ENOENT: 1168 /* 1169 * It's not there, but we need to call this so protocol.c 1170 * doesn't think it's in transition anymore. 1171 */ 1172 (void) restarter_instance_update_states(local_handle, inst, 1173 inst->ri_i.i_state, RESTARTER_STATE_NONE, RERR_NONE, 1174 restarter_str_none); 1175 goto out; 1176 1177 case EINVAL: 1178 case ENOTSUP: 1179 default: 1180 bad_error("libscf_fmri_get_instance", r); 1181 } 1182 1183 inst->ri_m_inst = s_inst; 1184 inst->ri_mi_deleted = B_FALSE; 1185 1186 retry: 1187 if (info->sf_method_type == METHOD_START) 1188 log_transition(inst, START_REQUESTED); 1189 1190 r = method_run(&inst, info->sf_method_type, &exit_code); 1191 1192 if (r == 0 && 1193 (exit_code == SMF_EXIT_OK || exit_code == SMF_EXIT_NODAEMON || 1194 exit_code == SMF_EXIT_MON_DEGRADE)) { 1195 /* Success! */ 1196 assert(inst->ri_i.i_next_state != RESTARTER_STATE_NONE); 1197 1198 /* 1199 * When a stop method succeeds, remove the primary contract of 1200 * the service, unless we're going to offline, in which case 1201 * retain the contract so we can transfer inherited contracts to 1202 * the replacement service. 1203 */ 1204 1205 if (info->sf_method_type == METHOD_STOP && 1206 inst->ri_i.i_primary_ctid != 0) { 1207 if (inst->ri_i.i_next_state == RESTARTER_STATE_OFFLINE) 1208 inst->ri_i.i_primary_ctid_stopped = 1; 1209 else 1210 method_remove_contract(inst, B_TRUE, B_TRUE); 1211 } 1212 1213 /* 1214 * For methods that exit with SMF_EXIT_NODAEMON, we already 1215 * called method_remove_contract in method_run. 1216 */ 1217 1218 /* 1219 * When a start method returns with SMF_EXIT_MON_DEGRADE we 1220 * transition the service into degraded. 1221 */ 1222 if (info->sf_method_type == METHOD_START && 1223 exit_code == SMF_EXIT_MON_DEGRADE) { 1224 inst->ri_i.i_next_state = RESTARTER_STATE_DEGRADED; 1225 info->sf_reason = restarter_str_method_failed; 1226 log_transition(inst, START_FAILED_DEGRADED); 1227 } 1228 1229 /* 1230 * We don't care whether the handle was rebound because this is 1231 * the last thing we do with it. 1232 */ 1233 (void) restarter_instance_update_states(local_handle, inst, 1234 inst->ri_i.i_next_state, RESTARTER_STATE_NONE, 1235 info->sf_event_type, info->sf_reason); 1236 1237 (void) update_fault_count(inst, FAULT_COUNT_RESET); 1238 1239 goto out; 1240 } 1241 1242 /* Failure. Retry or go to maintenance. */ 1243 1244 if (r != 0 && r != EAGAIN) { 1245 retryable = B_FALSE; 1246 } else { 1247 switch (exit_code) { 1248 case SMF_EXIT_ERR_CONFIG: 1249 case SMF_EXIT_ERR_NOSMF: 1250 case SMF_EXIT_ERR_PERM: 1251 case SMF_EXIT_ERR_FATAL: 1252 retryable = B_FALSE; 1253 break; 1254 1255 default: 1256 retryable = B_TRUE; 1257 } 1258 } 1259 1260 if (retryable && update_fault_count(inst, FAULT_COUNT_INCR) != 1) 1261 goto retry; 1262 1263 /* maintenance */ 1264 if (r == ELOOP) 1265 log_transition(inst, START_FAILED_REPEATEDLY); 1266 else if (r == ERANGE) 1267 log_transition(inst, START_FAILED_TIMEOUT_FATAL); 1268 else if (exit_code == SMF_EXIT_ERR_CONFIG) 1269 log_transition(inst, START_FAILED_CONFIGURATION); 1270 else if (exit_code == SMF_EXIT_ERR_FATAL) 1271 log_transition(inst, START_FAILED_FATAL); 1272 else 1273 log_transition(inst, START_FAILED_OTHER); 1274 1275 if (r == ELOOP) { 1276 reason = restarter_str_restarting_too_quickly; 1277 } else if (retryable) { 1278 reason = restarter_str_fault_threshold_reached; 1279 } else { 1280 reason = restarter_str_method_failed; 1281 } 1282 1283 (void) restarter_instance_update_states(local_handle, inst, 1284 RESTARTER_STATE_MAINT, RESTARTER_STATE_NONE, RERR_FAULT, 1285 reason); 1286 1287 if (!method_is_transient(inst, info->sf_method_type) && 1288 inst->ri_i.i_primary_ctid != 0) 1289 method_remove_contract(inst, B_TRUE, B_TRUE); 1290 1291 out: 1292 inst->ri_method_thread = 0; 1293 1294 /* 1295 * Unlock the mutex after broadcasting to avoid a race condition 1296 * with restarter_delete_inst() when the 'inst' structure is freed. 1297 */ 1298 (void) pthread_cond_broadcast(&inst->ri_method_cv); 1299 MUTEX_UNLOCK(&inst->ri_lock); 1300 1301 scf_instance_destroy(s_inst); 1302 scf_handle_destroy(local_handle); 1303 startd_free(info, sizeof (fork_info_t)); 1304 return (NULL); 1305 } 1306