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 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * zoneadmd manages zones; one zoneadmd process is launched for each 29 * non-global zone on the system. This daemon juggles four jobs: 30 * 31 * - Implement setup and teardown of the zone "virtual platform": mount and 32 * unmount filesystems; create and destroy network interfaces; communicate 33 * with devfsadmd to lay out devices for the zone; instantiate the zone 34 * console device; configure process runtime attributes such as resource 35 * controls, pool bindings, fine-grained privileges. 36 * 37 * - Launch the zone's init(1M) process. 38 * 39 * - Implement a door server; clients (like zoneadm) connect to the door 40 * server and request zone state changes. The kernel is also a client of 41 * this door server. A request to halt or reboot the zone which originates 42 * *inside* the zone results in a door upcall from the kernel into zoneadmd. 43 * 44 * One minor problem is that messages emitted by zoneadmd need to be passed 45 * back to the zoneadm process making the request. These messages need to 46 * be rendered in the client's locale; so, this is passed in as part of the 47 * request. The exception is the kernel upcall to zoneadmd, in which case 48 * messages are syslog'd. 49 * 50 * To make all of this work, the Makefile adds -a to xgettext to extract *all* 51 * strings, and an exclusion file (zoneadmd.xcl) is used to exclude those 52 * strings which do not need to be translated. 53 * 54 * - Act as a console server for zlogin -C processes; see comments in zcons.c 55 * for more information about the zone console architecture. 56 * 57 * DESIGN NOTES 58 * 59 * Restart: 60 * A chief design constraint of zoneadmd is that it should be restartable in 61 * the case that the administrator kills it off, or it suffers a fatal error, 62 * without the running zone being impacted; this is akin to being able to 63 * reboot the service processor of a server without affecting the OS instance. 64 */ 65 66 #include <sys/param.h> 67 #include <sys/mman.h> 68 #include <sys/types.h> 69 #include <sys/stat.h> 70 #include <sys/sysmacros.h> 71 72 #include <bsm/adt.h> 73 #include <bsm/adt_event.h> 74 75 #include <alloca.h> 76 #include <assert.h> 77 #include <errno.h> 78 #include <door.h> 79 #include <fcntl.h> 80 #include <locale.h> 81 #include <signal.h> 82 #include <stdarg.h> 83 #include <stdio.h> 84 #include <stdlib.h> 85 #include <string.h> 86 #include <strings.h> 87 #include <synch.h> 88 #include <syslog.h> 89 #include <thread.h> 90 #include <unistd.h> 91 #include <wait.h> 92 #include <limits.h> 93 #include <zone.h> 94 #include <libbrand.h> 95 #include <sys/brand.h> 96 #include <libcontract.h> 97 #include <libcontract_priv.h> 98 #include <sys/contract/process.h> 99 #include <sys/ctfs.h> 100 #include <libdladm.h> 101 #include <sys/dls_mgmt.h> 102 103 #include <libzonecfg.h> 104 #include "zoneadmd.h" 105 106 static char *progname; 107 char *zone_name; /* zone which we are managing */ 108 char brand_name[MAXNAMELEN]; 109 boolean_t zone_isnative; 110 boolean_t zone_iscluster; 111 boolean_t zone_islabeled; 112 static zoneid_t zone_id; 113 dladm_handle_t dld_handle = NULL; 114 115 static char pre_statechg_hook[2 * MAXPATHLEN]; 116 static char post_statechg_hook[2 * MAXPATHLEN]; 117 char query_hook[2 * MAXPATHLEN]; 118 119 zlog_t logsys; 120 121 mutex_t lock = DEFAULTMUTEX; /* to serialize stuff */ 122 mutex_t msglock = DEFAULTMUTEX; /* for calling setlocale() */ 123 124 static sema_t scratch_sem; /* for scratch zones */ 125 126 static char zone_door_path[MAXPATHLEN]; 127 static int zone_door = -1; 128 129 boolean_t in_death_throes = B_FALSE; /* daemon is dying */ 130 boolean_t bringup_failure_recovery = B_FALSE; /* ignore certain failures */ 131 132 #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */ 133 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ 134 #endif 135 136 #define DEFAULT_LOCALE "C" 137 138 static const char * 139 z_cmd_name(zone_cmd_t zcmd) 140 { 141 /* This list needs to match the enum in sys/zone.h */ 142 static const char *zcmdstr[] = { 143 "ready", "boot", "forceboot", "reboot", "halt", 144 "note_uninstalling", "mount", "forcemount", "unmount" 145 }; 146 147 if (zcmd >= sizeof (zcmdstr) / sizeof (*zcmdstr)) 148 return ("unknown"); 149 else 150 return (zcmdstr[(int)zcmd]); 151 } 152 153 static char * 154 get_execbasename(char *execfullname) 155 { 156 char *last_slash, *execbasename; 157 158 /* guard against '/' at end of command invocation */ 159 for (;;) { 160 last_slash = strrchr(execfullname, '/'); 161 if (last_slash == NULL) { 162 execbasename = execfullname; 163 break; 164 } else { 165 execbasename = last_slash + 1; 166 if (*execbasename == '\0') { 167 *last_slash = '\0'; 168 continue; 169 } 170 break; 171 } 172 } 173 return (execbasename); 174 } 175 176 static void 177 usage(void) 178 { 179 (void) fprintf(stderr, gettext("Usage: %s -z zonename\n"), progname); 180 (void) fprintf(stderr, 181 gettext("\tNote: %s should not be run directly.\n"), progname); 182 exit(2); 183 } 184 185 /* ARGSUSED */ 186 static void 187 sigchld(int sig) 188 { 189 } 190 191 char * 192 localize_msg(char *locale, const char *msg) 193 { 194 char *out; 195 196 (void) mutex_lock(&msglock); 197 (void) setlocale(LC_MESSAGES, locale); 198 out = gettext(msg); 199 (void) setlocale(LC_MESSAGES, DEFAULT_LOCALE); 200 (void) mutex_unlock(&msglock); 201 return (out); 202 } 203 204 /* PRINTFLIKE3 */ 205 void 206 zerror(zlog_t *zlogp, boolean_t use_strerror, const char *fmt, ...) 207 { 208 va_list alist; 209 char buf[MAXPATHLEN * 2]; /* enough space for err msg with a path */ 210 char *bp; 211 int saved_errno = errno; 212 213 if (zlogp == NULL) 214 return; 215 if (zlogp == &logsys) 216 (void) snprintf(buf, sizeof (buf), "[zone '%s'] ", 217 zone_name); 218 else 219 buf[0] = '\0'; 220 bp = &(buf[strlen(buf)]); 221 222 /* 223 * In theory, the locale pointer should be set to either "C" or a 224 * char array, so it should never be NULL 225 */ 226 assert(zlogp->locale != NULL); 227 /* Locale is per process, but we are multi-threaded... */ 228 fmt = localize_msg(zlogp->locale, fmt); 229 230 va_start(alist, fmt); 231 (void) vsnprintf(bp, sizeof (buf) - (bp - buf), fmt, alist); 232 va_end(alist); 233 bp = &(buf[strlen(buf)]); 234 if (use_strerror) 235 (void) snprintf(bp, sizeof (buf) - (bp - buf), ": %s", 236 strerror(saved_errno)); 237 if (zlogp == &logsys) { 238 (void) syslog(LOG_ERR, "%s", buf); 239 } else if (zlogp->logfile != NULL) { 240 (void) fprintf(zlogp->logfile, "%s\n", buf); 241 } else { 242 size_t buflen; 243 size_t copylen; 244 245 buflen = snprintf(zlogp->log, zlogp->loglen, "%s\n", buf); 246 copylen = MIN(buflen, zlogp->loglen); 247 zlogp->log += copylen; 248 zlogp->loglen -= copylen; 249 } 250 } 251 252 /* 253 * Emit a warning for any boot arguments which are unrecognized. Since 254 * Solaris boot arguments are getopt(3c) compatible (see kernel(1m)), we 255 * put the arguments into an argv style array, use getopt to process them, 256 * and put the resultant argument string back into outargs. 257 * 258 * During the filtering, we pull out any arguments which are truly "boot" 259 * arguments, leaving only those which are to be passed intact to the 260 * progenitor process. The one we support at the moment is -i, which 261 * indicates to the kernel which program should be launched as 'init'. 262 * 263 * A return of Z_INVAL indicates specifically that the arguments are 264 * not valid; this is a non-fatal error. Except for Z_OK, all other return 265 * values are treated as fatal. 266 */ 267 static int 268 filter_bootargs(zlog_t *zlogp, const char *inargs, char *outargs, 269 char *init_file, char *badarg) 270 { 271 int argc = 0, argc_save; 272 int i; 273 int err; 274 char *arg, *lasts, **argv = NULL, **argv_save; 275 char zonecfg_args[BOOTARGS_MAX]; 276 char scratchargs[BOOTARGS_MAX], *sargs; 277 char c; 278 279 bzero(outargs, BOOTARGS_MAX); 280 bzero(badarg, BOOTARGS_MAX); 281 282 /* 283 * If the user didn't specify transient boot arguments, check 284 * to see if there were any specified in the zone configuration, 285 * and use them if applicable. 286 */ 287 if (inargs == NULL || inargs[0] == '\0') { 288 zone_dochandle_t handle; 289 if ((handle = zonecfg_init_handle()) == NULL) { 290 zerror(zlogp, B_TRUE, 291 "getting zone configuration handle"); 292 return (Z_BAD_HANDLE); 293 } 294 err = zonecfg_get_snapshot_handle(zone_name, handle); 295 if (err != Z_OK) { 296 zerror(zlogp, B_FALSE, 297 "invalid configuration snapshot"); 298 zonecfg_fini_handle(handle); 299 return (Z_BAD_HANDLE); 300 } 301 302 bzero(zonecfg_args, sizeof (zonecfg_args)); 303 (void) zonecfg_get_bootargs(handle, zonecfg_args, 304 sizeof (zonecfg_args)); 305 inargs = zonecfg_args; 306 zonecfg_fini_handle(handle); 307 } 308 309 if (strlen(inargs) >= BOOTARGS_MAX) { 310 zerror(zlogp, B_FALSE, "boot argument string too long"); 311 return (Z_INVAL); 312 } 313 314 (void) strlcpy(scratchargs, inargs, sizeof (scratchargs)); 315 sargs = scratchargs; 316 while ((arg = strtok_r(sargs, " \t", &lasts)) != NULL) { 317 sargs = NULL; 318 argc++; 319 } 320 321 if ((argv = calloc(argc + 1, sizeof (char *))) == NULL) { 322 zerror(zlogp, B_FALSE, "memory allocation failed"); 323 return (Z_NOMEM); 324 } 325 326 argv_save = argv; 327 argc_save = argc; 328 329 (void) strlcpy(scratchargs, inargs, sizeof (scratchargs)); 330 sargs = scratchargs; 331 i = 0; 332 while ((arg = strtok_r(sargs, " \t", &lasts)) != NULL) { 333 sargs = NULL; 334 if ((argv[i] = strdup(arg)) == NULL) { 335 err = Z_NOMEM; 336 zerror(zlogp, B_FALSE, "memory allocation failed"); 337 goto done; 338 } 339 i++; 340 } 341 342 /* 343 * We preserve compatibility with the Solaris system boot behavior, 344 * which allows: 345 * 346 * # reboot kernel/unix -s -m verbose 347 * 348 * In this example, kernel/unix tells the booter what file to 349 * boot. We don't want reboot in a zone to be gratuitously different, 350 * so we silently ignore the boot file, if necessary. 351 */ 352 if (argv[0] == NULL) 353 goto done; 354 355 assert(argv[0][0] != ' '); 356 assert(argv[0][0] != '\t'); 357 358 if (argv[0][0] != '-' && argv[0][0] != '\0') { 359 argv = &argv[1]; 360 argc--; 361 } 362 363 optind = 0; 364 opterr = 0; 365 err = Z_OK; 366 while ((c = getopt(argc, argv, "fi:m:s")) != -1) { 367 switch (c) { 368 case 'i': 369 /* 370 * -i is handled by the runtime and is not passed 371 * along to userland 372 */ 373 (void) strlcpy(init_file, optarg, MAXPATHLEN); 374 break; 375 case 'f': 376 /* This has already been processed by zoneadm */ 377 break; 378 case 'm': 379 case 's': 380 /* These pass through unmolested */ 381 (void) snprintf(outargs, BOOTARGS_MAX, 382 "%s -%c %s ", outargs, c, optarg ? optarg : ""); 383 break; 384 case '?': 385 /* 386 * We warn about unknown arguments but pass them 387 * along anyway-- if someone wants to develop their 388 * own init replacement, they can pass it whatever 389 * args they want. 390 */ 391 err = Z_INVAL; 392 (void) snprintf(outargs, BOOTARGS_MAX, 393 "%s -%c", outargs, optopt); 394 (void) snprintf(badarg, BOOTARGS_MAX, 395 "%s -%c", badarg, optopt); 396 break; 397 } 398 } 399 400 /* 401 * For Solaris Zones we warn about and discard non-option arguments. 402 * Hence 'boot foo bar baz gub' --> 'boot'. However, to be similar 403 * to the kernel, we concat up all the other remaining boot args. 404 * and warn on them as a group. 405 */ 406 if (optind < argc) { 407 err = Z_INVAL; 408 while (optind < argc) { 409 (void) snprintf(badarg, BOOTARGS_MAX, "%s%s%s", 410 badarg, strlen(badarg) > 0 ? " " : "", 411 argv[optind]); 412 optind++; 413 } 414 zerror(zlogp, B_FALSE, "WARNING: Unused or invalid boot " 415 "arguments `%s'.", badarg); 416 } 417 418 done: 419 for (i = 0; i < argc_save; i++) { 420 if (argv_save[i] != NULL) 421 free(argv_save[i]); 422 } 423 free(argv_save); 424 return (err); 425 } 426 427 428 static int 429 mkzonedir(zlog_t *zlogp) 430 { 431 struct stat st; 432 /* 433 * We must create and lock everyone but root out of ZONES_TMPDIR 434 * since anyone can open any UNIX domain socket, regardless of 435 * its file system permissions. Sigh... 436 */ 437 if (mkdir(ZONES_TMPDIR, S_IRWXU) < 0 && errno != EEXIST) { 438 zerror(zlogp, B_TRUE, "could not mkdir '%s'", ZONES_TMPDIR); 439 return (-1); 440 } 441 /* paranoia */ 442 if ((stat(ZONES_TMPDIR, &st) < 0) || !S_ISDIR(st.st_mode)) { 443 zerror(zlogp, B_TRUE, "'%s' is not a directory", ZONES_TMPDIR); 444 return (-1); 445 } 446 (void) chmod(ZONES_TMPDIR, S_IRWXU); 447 return (0); 448 } 449 450 /* 451 * Run the brand's pre-state change callback, if it exists. 452 */ 453 static int 454 brand_prestatechg(zlog_t *zlogp, int state, int cmd) 455 { 456 char cmdbuf[2 * MAXPATHLEN]; 457 458 if (pre_statechg_hook[0] == '\0') 459 return (0); 460 461 if (snprintf(cmdbuf, sizeof (cmdbuf), "%s %d %d", pre_statechg_hook, 462 state, cmd) > sizeof (cmdbuf)) 463 return (-1); 464 465 if (do_subproc(zlogp, cmdbuf, NULL) != 0) 466 return (-1); 467 468 return (0); 469 } 470 471 /* 472 * Run the brand's post-state change callback, if it exists. 473 */ 474 static int 475 brand_poststatechg(zlog_t *zlogp, int state, int cmd) 476 { 477 char cmdbuf[2 * MAXPATHLEN]; 478 479 if (post_statechg_hook[0] == '\0') 480 return (0); 481 482 if (snprintf(cmdbuf, sizeof (cmdbuf), "%s %d %d", post_statechg_hook, 483 state, cmd) > sizeof (cmdbuf)) 484 return (-1); 485 486 if (do_subproc(zlogp, cmdbuf, NULL) != 0) 487 return (-1); 488 489 return (0); 490 } 491 492 /* 493 * Bring a zone up to the pre-boot "ready" stage. The mount_cmd argument is 494 * 'true' if this is being invoked as part of the processing for the "mount" 495 * subcommand. 496 */ 497 static int 498 zone_ready(zlog_t *zlogp, zone_mnt_t mount_cmd, int zstate) 499 { 500 int err; 501 502 if (brand_prestatechg(zlogp, zstate, Z_READY) != 0) 503 return (-1); 504 505 if ((err = zonecfg_create_snapshot(zone_name)) != Z_OK) { 506 zerror(zlogp, B_FALSE, "unable to create snapshot: %s", 507 zonecfg_strerror(err)); 508 goto bad; 509 } 510 511 if ((zone_id = vplat_create(zlogp, mount_cmd)) == -1) { 512 if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK) 513 zerror(zlogp, B_FALSE, "destroying snapshot: %s", 514 zonecfg_strerror(err)); 515 goto bad; 516 } 517 if (vplat_bringup(zlogp, mount_cmd, zone_id) != 0) { 518 bringup_failure_recovery = B_TRUE; 519 (void) vplat_teardown(NULL, (mount_cmd != Z_MNT_BOOT), B_FALSE); 520 if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK) 521 zerror(zlogp, B_FALSE, "destroying snapshot: %s", 522 zonecfg_strerror(err)); 523 goto bad; 524 } 525 526 if (brand_poststatechg(zlogp, zstate, Z_READY) != 0) 527 goto bad; 528 529 return (0); 530 531 bad: 532 /* 533 * If something goes wrong, we up the zones's state to the target 534 * state, READY, and then invoke the hook as if we're halting. 535 */ 536 (void) brand_poststatechg(zlogp, ZONE_STATE_READY, Z_HALT); 537 return (-1); 538 } 539 540 int 541 init_template(void) 542 { 543 int fd; 544 int err = 0; 545 546 fd = open64(CTFS_ROOT "/process/template", O_RDWR); 547 if (fd == -1) 548 return (-1); 549 550 /* 551 * For now, zoneadmd doesn't do anything with the contract. 552 * Deliver no events, don't inherit, and allow it to be orphaned. 553 */ 554 err |= ct_tmpl_set_critical(fd, 0); 555 err |= ct_tmpl_set_informative(fd, 0); 556 err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR); 557 err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT); 558 if (err || ct_tmpl_activate(fd)) { 559 (void) close(fd); 560 return (-1); 561 } 562 563 return (fd); 564 } 565 566 typedef struct fs_callback { 567 zlog_t *zlogp; 568 zoneid_t zoneid; 569 boolean_t mount_cmd; 570 } fs_callback_t; 571 572 static int 573 mount_early_fs(void *data, const char *spec, const char *dir, 574 const char *fstype, const char *opt) 575 { 576 zlog_t *zlogp = ((fs_callback_t *)data)->zlogp; 577 zoneid_t zoneid = ((fs_callback_t *)data)->zoneid; 578 boolean_t mount_cmd = ((fs_callback_t *)data)->mount_cmd; 579 char rootpath[MAXPATHLEN]; 580 pid_t child; 581 int child_status; 582 int tmpl_fd; 583 int rv; 584 ctid_t ct; 585 586 /* determine the zone rootpath */ 587 if (mount_cmd) { 588 char zonepath[MAXPATHLEN]; 589 char luroot[MAXPATHLEN]; 590 591 if (zone_get_zonepath(zone_name, 592 zonepath, sizeof (zonepath)) != Z_OK) { 593 zerror(zlogp, B_FALSE, "unable to determine zone path"); 594 return (-1); 595 } 596 597 (void) snprintf(luroot, sizeof (luroot), "%s/lu", zonepath); 598 resolve_lofs(zlogp, luroot, sizeof (luroot)); 599 (void) strlcpy(rootpath, luroot, sizeof (rootpath)); 600 } else { 601 if (zone_get_rootpath(zone_name, 602 rootpath, sizeof (rootpath)) != Z_OK) { 603 zerror(zlogp, B_FALSE, "unable to determine zone root"); 604 return (-1); 605 } 606 } 607 608 if ((rv = valid_mount_path(zlogp, rootpath, spec, dir, fstype)) < 0) { 609 zerror(zlogp, B_FALSE, "%s%s is not a valid mount point", 610 rootpath, dir); 611 return (-1); 612 } else if (rv > 0) { 613 /* The mount point path doesn't exist, create it now. */ 614 if (make_one_dir(zlogp, rootpath, dir, 615 DEFAULT_DIR_MODE, DEFAULT_DIR_USER, 616 DEFAULT_DIR_GROUP) != 0) { 617 zerror(zlogp, B_FALSE, "failed to create mount point"); 618 return (-1); 619 } 620 621 /* 622 * Now this might seem weird, but we need to invoke 623 * valid_mount_path() again. Why? Because it checks 624 * to make sure that the mount point path is canonical, 625 * which it can only do if the path exists, so now that 626 * we've created the path we have to verify it again. 627 */ 628 if ((rv = valid_mount_path(zlogp, rootpath, spec, dir, 629 fstype)) < 0) { 630 zerror(zlogp, B_FALSE, 631 "%s%s is not a valid mount point", rootpath, dir); 632 return (-1); 633 } 634 } 635 636 if ((tmpl_fd = init_template()) == -1) { 637 zerror(zlogp, B_TRUE, "failed to create contract"); 638 return (-1); 639 } 640 641 if ((child = fork()) == -1) { 642 (void) ct_tmpl_clear(tmpl_fd); 643 (void) close(tmpl_fd); 644 zerror(zlogp, B_TRUE, "failed to fork"); 645 return (-1); 646 647 } else if (child == 0) { /* child */ 648 char opt_buf[MAX_MNTOPT_STR]; 649 int optlen = 0; 650 int mflag = MS_DATA; 651 652 (void) ct_tmpl_clear(tmpl_fd); 653 /* 654 * Even though there are no procs running in the zone, we 655 * do this for paranoia's sake. 656 */ 657 (void) closefrom(0); 658 659 if (zone_enter(zoneid) == -1) { 660 _exit(errno); 661 } 662 if (opt != NULL) { 663 /* 664 * The mount() system call is incredibly annoying. 665 * If options are specified, we need to copy them 666 * into a temporary buffer since the mount() system 667 * call will overwrite the options string. It will 668 * also fail if the new option string it wants to 669 * write is bigger than the one we passed in, so 670 * you must pass in a buffer of the maximum possible 671 * option string length. sigh. 672 */ 673 (void) strlcpy(opt_buf, opt, sizeof (opt_buf)); 674 opt = opt_buf; 675 optlen = MAX_MNTOPT_STR; 676 mflag = MS_OPTIONSTR; 677 } 678 if (mount(spec, dir, mflag, fstype, NULL, 0, opt, optlen) != 0) 679 _exit(errno); 680 _exit(0); 681 } 682 683 /* parent */ 684 if (contract_latest(&ct) == -1) 685 ct = -1; 686 (void) ct_tmpl_clear(tmpl_fd); 687 (void) close(tmpl_fd); 688 if (waitpid(child, &child_status, 0) != child) { 689 /* unexpected: we must have been signalled */ 690 (void) contract_abandon_id(ct); 691 return (-1); 692 } 693 (void) contract_abandon_id(ct); 694 if (WEXITSTATUS(child_status) != 0) { 695 errno = WEXITSTATUS(child_status); 696 zerror(zlogp, B_TRUE, "mount of %s failed", dir); 697 return (-1); 698 } 699 700 return (0); 701 } 702 703 /* 704 * If retstr is not NULL, the output of the subproc is returned in the str, 705 * otherwise it is output using zerror(). Any memory allocated for retstr 706 * should be freed by the caller. 707 */ 708 int 709 do_subproc(zlog_t *zlogp, char *cmdbuf, char **retstr) 710 { 711 char buf[1024]; /* arbitrary large amount */ 712 char *inbuf; 713 FILE *file; 714 int status; 715 int rd_cnt; 716 717 if (retstr != NULL) { 718 if ((*retstr = malloc(1024)) == NULL) { 719 zerror(zlogp, B_FALSE, "out of memory"); 720 return (-1); 721 } 722 inbuf = *retstr; 723 rd_cnt = 0; 724 } else { 725 inbuf = buf; 726 } 727 728 file = popen(cmdbuf, "r"); 729 if (file == NULL) { 730 zerror(zlogp, B_TRUE, "could not launch: %s", cmdbuf); 731 return (-1); 732 } 733 734 while (fgets(inbuf, 1024, file) != NULL) { 735 if (retstr == NULL) { 736 if (zlogp != &logsys) 737 zerror(zlogp, B_FALSE, "%s", inbuf); 738 } else { 739 char *p; 740 741 rd_cnt += 1024 - 1; 742 if ((p = realloc(*retstr, rd_cnt + 1024)) == NULL) { 743 zerror(zlogp, B_FALSE, "out of memory"); 744 (void) pclose(file); 745 return (-1); 746 } 747 748 *retstr = p; 749 inbuf = *retstr + rd_cnt; 750 } 751 } 752 status = pclose(file); 753 754 if (WIFSIGNALED(status)) { 755 zerror(zlogp, B_FALSE, "%s unexpectedly terminated due to " 756 "signal %d", cmdbuf, WTERMSIG(status)); 757 return (-1); 758 } 759 assert(WIFEXITED(status)); 760 if (WEXITSTATUS(status) == ZEXIT_EXEC) { 761 zerror(zlogp, B_FALSE, "failed to exec %s", cmdbuf); 762 return (-1); 763 } 764 return (WEXITSTATUS(status)); 765 } 766 767 static int 768 zone_bootup(zlog_t *zlogp, const char *bootargs, int zstate) 769 { 770 zoneid_t zoneid; 771 struct stat st; 772 char zpath[MAXPATHLEN], initpath[MAXPATHLEN], init_file[MAXPATHLEN]; 773 char nbootargs[BOOTARGS_MAX]; 774 char cmdbuf[MAXPATHLEN]; 775 fs_callback_t cb; 776 brand_handle_t bh; 777 zone_iptype_t iptype; 778 boolean_t links_loaded = B_FALSE; 779 dladm_status_t status; 780 char errmsg[DLADM_STRSIZE]; 781 int err; 782 783 if (brand_prestatechg(zlogp, zstate, Z_BOOT) != 0) 784 return (-1); 785 786 if ((zoneid = getzoneidbyname(zone_name)) == -1) { 787 zerror(zlogp, B_TRUE, "unable to get zoneid"); 788 goto bad; 789 } 790 791 cb.zlogp = zlogp; 792 cb.zoneid = zoneid; 793 cb.mount_cmd = B_FALSE; 794 795 /* Get a handle to the brand info for this zone */ 796 if ((bh = brand_open(brand_name)) == NULL) { 797 zerror(zlogp, B_FALSE, "unable to determine zone brand"); 798 goto bad; 799 } 800 801 /* 802 * Get the list of filesystems to mount from the brand 803 * configuration. These mounts are done via a thread that will 804 * enter the zone, so they are done from within the context of the 805 * zone. 806 */ 807 if (brand_platform_iter_mounts(bh, mount_early_fs, &cb) != 0) { 808 zerror(zlogp, B_FALSE, "unable to mount filesystems"); 809 brand_close(bh); 810 goto bad; 811 } 812 813 /* 814 * Get the brand's boot callback if it exists. 815 */ 816 if (zone_get_zonepath(zone_name, zpath, sizeof (zpath)) != Z_OK) { 817 zerror(zlogp, B_FALSE, "unable to determine zone path"); 818 brand_close(bh); 819 goto bad; 820 } 821 (void) strcpy(cmdbuf, EXEC_PREFIX); 822 if (brand_get_boot(bh, zone_name, zpath, cmdbuf + EXEC_LEN, 823 sizeof (cmdbuf) - EXEC_LEN) != 0) { 824 zerror(zlogp, B_FALSE, 825 "unable to determine branded zone's boot callback"); 826 brand_close(bh); 827 goto bad; 828 } 829 830 /* Get the path for this zone's init(1M) (or equivalent) process. */ 831 if (brand_get_initname(bh, init_file, MAXPATHLEN) != 0) { 832 zerror(zlogp, B_FALSE, 833 "unable to determine zone's init(1M) location"); 834 brand_close(bh); 835 goto bad; 836 } 837 838 brand_close(bh); 839 840 err = filter_bootargs(zlogp, bootargs, nbootargs, init_file, 841 bad_boot_arg); 842 if (err == Z_INVAL) 843 eventstream_write(Z_EVT_ZONE_BADARGS); 844 else if (err != Z_OK) 845 goto bad; 846 847 assert(init_file[0] != '\0'); 848 849 /* Try to anticipate possible problems: Make sure init is executable. */ 850 if (zone_get_rootpath(zone_name, zpath, sizeof (zpath)) != Z_OK) { 851 zerror(zlogp, B_FALSE, "unable to determine zone root"); 852 goto bad; 853 } 854 855 (void) snprintf(initpath, sizeof (initpath), "%s%s", zpath, init_file); 856 857 if (stat(initpath, &st) == -1) { 858 zerror(zlogp, B_TRUE, "could not stat %s", initpath); 859 goto bad; 860 } 861 862 if ((st.st_mode & S_IXUSR) == 0) { 863 zerror(zlogp, B_FALSE, "%s is not executable", initpath); 864 goto bad; 865 } 866 867 /* 868 * Exclusive stack zones interact with the dlmgmtd running in the 869 * global zone. dladm_zone_boot() tells dlmgmtd that this zone is 870 * booting, and loads its datalinks from the zone's datalink 871 * configuration file. 872 */ 873 if (vplat_get_iptype(zlogp, &iptype) == 0 && iptype == ZS_EXCLUSIVE) { 874 status = dladm_zone_boot(dld_handle, zoneid); 875 if (status != DLADM_STATUS_OK) { 876 zerror(zlogp, B_FALSE, "unable to load zone datalinks: " 877 " %s", dladm_status2str(status, errmsg)); 878 goto bad; 879 } 880 links_loaded = B_TRUE; 881 } 882 883 /* 884 * If there is a brand 'boot' callback, execute it now to give the 885 * brand one last chance to do any additional setup before the zone 886 * is booted. 887 */ 888 if ((strlen(cmdbuf) > EXEC_LEN) && 889 (do_subproc(zlogp, cmdbuf, NULL) != Z_OK)) { 890 zerror(zlogp, B_FALSE, "%s failed", cmdbuf); 891 goto bad; 892 } 893 894 if (zone_setattr(zoneid, ZONE_ATTR_INITNAME, init_file, 0) == -1) { 895 zerror(zlogp, B_TRUE, "could not set zone boot file"); 896 goto bad; 897 } 898 899 if (zone_setattr(zoneid, ZONE_ATTR_BOOTARGS, nbootargs, 0) == -1) { 900 zerror(zlogp, B_TRUE, "could not set zone boot arguments"); 901 goto bad; 902 } 903 904 if (zone_boot(zoneid) == -1) { 905 zerror(zlogp, B_TRUE, "unable to boot zone"); 906 goto bad; 907 } 908 909 if (brand_poststatechg(zlogp, zstate, Z_BOOT) != 0) 910 goto bad; 911 912 return (0); 913 914 bad: 915 /* 916 * If something goes wrong, we up the zones's state to the target 917 * state, RUNNING, and then invoke the hook as if we're halting. 918 */ 919 (void) brand_poststatechg(zlogp, ZONE_STATE_RUNNING, Z_HALT); 920 if (links_loaded) 921 (void) dladm_zone_halt(dld_handle, zoneid); 922 return (-1); 923 } 924 925 static int 926 zone_halt(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting, int zstate) 927 { 928 int err; 929 930 if (brand_prestatechg(zlogp, zstate, Z_HALT) != 0) 931 return (-1); 932 933 if (vplat_teardown(zlogp, unmount_cmd, rebooting) != 0) { 934 if (!bringup_failure_recovery) 935 zerror(zlogp, B_FALSE, "unable to destroy zone"); 936 return (-1); 937 } 938 939 if ((err = zonecfg_destroy_snapshot(zone_name)) != Z_OK) 940 zerror(zlogp, B_FALSE, "destroying snapshot: %s", 941 zonecfg_strerror(err)); 942 943 if (brand_poststatechg(zlogp, zstate, Z_HALT) != 0) 944 return (-1); 945 946 return (0); 947 } 948 949 /* 950 * Generate AUE_zone_state for a command that boots a zone. 951 */ 952 static void 953 audit_put_record(zlog_t *zlogp, ucred_t *uc, int return_val, 954 char *new_state) 955 { 956 adt_session_data_t *ah; 957 adt_event_data_t *event; 958 int pass_fail, fail_reason; 959 960 if (!adt_audit_enabled()) 961 return; 962 963 if (return_val == 0) { 964 pass_fail = ADT_SUCCESS; 965 fail_reason = ADT_SUCCESS; 966 } else { 967 pass_fail = ADT_FAILURE; 968 fail_reason = ADT_FAIL_VALUE_PROGRAM; 969 } 970 971 if (adt_start_session(&ah, NULL, 0)) { 972 zerror(zlogp, B_TRUE, gettext("audit failure.")); 973 return; 974 } 975 if (adt_set_from_ucred(ah, uc, ADT_NEW)) { 976 zerror(zlogp, B_TRUE, gettext("audit failure.")); 977 (void) adt_end_session(ah); 978 return; 979 } 980 981 event = adt_alloc_event(ah, ADT_zone_state); 982 if (event == NULL) { 983 zerror(zlogp, B_TRUE, gettext("audit failure.")); 984 (void) adt_end_session(ah); 985 return; 986 } 987 event->adt_zone_state.zonename = zone_name; 988 event->adt_zone_state.new_state = new_state; 989 990 if (adt_put_event(event, pass_fail, fail_reason)) 991 zerror(zlogp, B_TRUE, gettext("audit failure.")); 992 993 adt_free_event(event); 994 995 (void) adt_end_session(ah); 996 } 997 998 /* 999 * The main routine for the door server that deals with zone state transitions. 1000 */ 1001 /* ARGSUSED */ 1002 static void 1003 server(void *cookie, char *args, size_t alen, door_desc_t *dp, 1004 uint_t n_desc) 1005 { 1006 ucred_t *uc = NULL; 1007 const priv_set_t *eset; 1008 1009 zone_state_t zstate; 1010 zone_cmd_t cmd; 1011 zone_cmd_arg_t *zargp; 1012 1013 boolean_t kernelcall; 1014 1015 int rval = -1; 1016 uint64_t uniqid; 1017 zoneid_t zoneid = -1; 1018 zlog_t zlog; 1019 zlog_t *zlogp; 1020 zone_cmd_rval_t *rvalp; 1021 size_t rlen = getpagesize(); /* conservative */ 1022 fs_callback_t cb; 1023 brand_handle_t bh; 1024 1025 /* LINTED E_BAD_PTR_CAST_ALIGN */ 1026 zargp = (zone_cmd_arg_t *)args; 1027 1028 /* 1029 * When we get the door unref message, we've fdetach'd the door, and 1030 * it is time for us to shut down zoneadmd. 1031 */ 1032 if (zargp == DOOR_UNREF_DATA) { 1033 /* 1034 * See comment at end of main() for info on the last rites. 1035 */ 1036 exit(0); 1037 } 1038 1039 if (zargp == NULL) { 1040 (void) door_return(NULL, 0, 0, 0); 1041 } 1042 1043 rvalp = alloca(rlen); 1044 bzero(rvalp, rlen); 1045 zlog.logfile = NULL; 1046 zlog.buflen = zlog.loglen = rlen - sizeof (zone_cmd_rval_t) + 1; 1047 zlog.buf = rvalp->errbuf; 1048 zlog.log = zlog.buf; 1049 /* defer initialization of zlog.locale until after credential check */ 1050 zlogp = &zlog; 1051 1052 if (alen != sizeof (zone_cmd_arg_t)) { 1053 /* 1054 * This really shouldn't be happening. 1055 */ 1056 zerror(&logsys, B_FALSE, "argument size (%d bytes) " 1057 "unexpected (expected %d bytes)", alen, 1058 sizeof (zone_cmd_arg_t)); 1059 goto out; 1060 } 1061 cmd = zargp->cmd; 1062 1063 if (door_ucred(&uc) != 0) { 1064 zerror(&logsys, B_TRUE, "door_ucred"); 1065 goto out; 1066 } 1067 eset = ucred_getprivset(uc, PRIV_EFFECTIVE); 1068 if (ucred_getzoneid(uc) != GLOBAL_ZONEID || 1069 (eset != NULL ? !priv_ismember(eset, PRIV_SYS_CONFIG) : 1070 ucred_geteuid(uc) != 0)) { 1071 zerror(&logsys, B_FALSE, "insufficient privileges"); 1072 goto out; 1073 } 1074 1075 kernelcall = ucred_getpid(uc) == 0; 1076 1077 /* 1078 * This is safe because we only use a zlog_t throughout the 1079 * duration of a door call; i.e., by the time the pointer 1080 * might become invalid, the door call would be over. 1081 */ 1082 zlog.locale = kernelcall ? DEFAULT_LOCALE : zargp->locale; 1083 1084 (void) mutex_lock(&lock); 1085 1086 /* 1087 * Once we start to really die off, we don't want more connections. 1088 */ 1089 if (in_death_throes) { 1090 (void) mutex_unlock(&lock); 1091 ucred_free(uc); 1092 (void) door_return(NULL, 0, 0, 0); 1093 thr_exit(NULL); 1094 } 1095 1096 /* 1097 * Check for validity of command. 1098 */ 1099 if (cmd != Z_READY && cmd != Z_BOOT && cmd != Z_FORCEBOOT && 1100 cmd != Z_REBOOT && cmd != Z_HALT && cmd != Z_NOTE_UNINSTALLING && 1101 cmd != Z_MOUNT && cmd != Z_FORCEMOUNT && cmd != Z_UNMOUNT) { 1102 zerror(&logsys, B_FALSE, "invalid command %d", (int)cmd); 1103 goto out; 1104 } 1105 1106 if (kernelcall && (cmd != Z_HALT && cmd != Z_REBOOT)) { 1107 /* 1108 * Can't happen 1109 */ 1110 zerror(&logsys, B_FALSE, "received unexpected kernel upcall %d", 1111 cmd); 1112 goto out; 1113 } 1114 /* 1115 * We ignore the possibility of someone calling zone_create(2) 1116 * explicitly; all requests must come through zoneadmd. 1117 */ 1118 if (zone_get_state(zone_name, &zstate) != Z_OK) { 1119 /* 1120 * Something terribly wrong happened 1121 */ 1122 zerror(&logsys, B_FALSE, "unable to determine state of zone"); 1123 goto out; 1124 } 1125 1126 if (kernelcall) { 1127 /* 1128 * Kernel-initiated requests may lose their validity if the 1129 * zone_t the kernel was referring to has gone away. 1130 */ 1131 if ((zoneid = getzoneidbyname(zone_name)) == -1 || 1132 zone_getattr(zoneid, ZONE_ATTR_UNIQID, &uniqid, 1133 sizeof (uniqid)) == -1 || uniqid != zargp->uniqid) { 1134 /* 1135 * We're not talking about the same zone. The request 1136 * must have arrived too late. Return error. 1137 */ 1138 rval = -1; 1139 goto out; 1140 } 1141 zlogp = &logsys; /* Log errors to syslog */ 1142 } 1143 1144 /* 1145 * If we are being asked to forcibly mount or boot a zone, we 1146 * pretend that an INCOMPLETE zone is actually INSTALLED. 1147 */ 1148 if (zstate == ZONE_STATE_INCOMPLETE && 1149 (cmd == Z_FORCEBOOT || cmd == Z_FORCEMOUNT)) 1150 zstate = ZONE_STATE_INSTALLED; 1151 1152 switch (zstate) { 1153 case ZONE_STATE_CONFIGURED: 1154 case ZONE_STATE_INCOMPLETE: 1155 /* 1156 * Not our area of expertise; we just print a nice message 1157 * and die off. 1158 */ 1159 zerror(zlogp, B_FALSE, 1160 "%s operation is invalid for zones in state '%s'", 1161 z_cmd_name(cmd), zone_state_str(zstate)); 1162 break; 1163 1164 case ZONE_STATE_INSTALLED: 1165 switch (cmd) { 1166 case Z_READY: 1167 rval = zone_ready(zlogp, Z_MNT_BOOT, zstate); 1168 if (rval == 0) 1169 eventstream_write(Z_EVT_ZONE_READIED); 1170 break; 1171 case Z_BOOT: 1172 case Z_FORCEBOOT: 1173 eventstream_write(Z_EVT_ZONE_BOOTING); 1174 if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) 1175 == 0) { 1176 rval = zone_bootup(zlogp, zargp->bootbuf, 1177 zstate); 1178 } 1179 audit_put_record(zlogp, uc, rval, "boot"); 1180 if (rval != 0) { 1181 bringup_failure_recovery = B_TRUE; 1182 (void) zone_halt(zlogp, B_FALSE, B_FALSE, 1183 zstate); 1184 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1185 } 1186 break; 1187 case Z_HALT: 1188 if (kernelcall) /* Invalid; can't happen */ 1189 abort(); 1190 /* 1191 * We could have two clients racing to halt this 1192 * zone; the second client loses, but his request 1193 * doesn't fail, since the zone is now in the desired 1194 * state. 1195 */ 1196 zerror(zlogp, B_FALSE, "zone is already halted"); 1197 rval = 0; 1198 break; 1199 case Z_REBOOT: 1200 if (kernelcall) /* Invalid; can't happen */ 1201 abort(); 1202 zerror(zlogp, B_FALSE, "%s operation is invalid " 1203 "for zones in state '%s'", z_cmd_name(cmd), 1204 zone_state_str(zstate)); 1205 rval = -1; 1206 break; 1207 case Z_NOTE_UNINSTALLING: 1208 if (kernelcall) /* Invalid; can't happen */ 1209 abort(); 1210 /* 1211 * Tell the console to print out a message about this. 1212 * Once it does, we will be in_death_throes. 1213 */ 1214 eventstream_write(Z_EVT_ZONE_UNINSTALLING); 1215 break; 1216 case Z_MOUNT: 1217 case Z_FORCEMOUNT: 1218 if (kernelcall) /* Invalid; can't happen */ 1219 abort(); 1220 if (!zone_isnative && !zone_iscluster && 1221 !zone_islabeled) { 1222 /* 1223 * -U mounts the zone without lofs mounting 1224 * zone file systems back into the scratch 1225 * zone. This is required when mounting 1226 * non-native branded zones. 1227 */ 1228 (void) strlcpy(zargp->bootbuf, "-U", 1229 BOOTARGS_MAX); 1230 } 1231 1232 rval = zone_ready(zlogp, 1233 strcmp(zargp->bootbuf, "-U") == 0 ? 1234 Z_MNT_UPDATE : Z_MNT_SCRATCH, zstate); 1235 if (rval != 0) 1236 break; 1237 1238 eventstream_write(Z_EVT_ZONE_READIED); 1239 1240 /* 1241 * Get a handle to the native brand info. 1242 * We must always use the native brand file system 1243 * list when mounting the zone. 1244 */ 1245 if ((bh = brand_open(NATIVE_BRAND_NAME)) == NULL) { 1246 rval = -1; 1247 break; 1248 } 1249 1250 /* 1251 * Get the list of filesystems to mount from 1252 * the brand configuration. These mounts are done 1253 * via a thread that will enter the zone, so they 1254 * are done from within the context of the zone. 1255 */ 1256 cb.zlogp = zlogp; 1257 cb.zoneid = zone_id; 1258 cb.mount_cmd = B_TRUE; 1259 rval = brand_platform_iter_mounts(bh, 1260 mount_early_fs, &cb); 1261 1262 brand_close(bh); 1263 1264 /* 1265 * Ordinarily, /dev/fd would be mounted inside the zone 1266 * by svc:/system/filesystem/usr:default, but since 1267 * we're not booting the zone, we need to do this 1268 * manually. 1269 */ 1270 if (rval == 0) 1271 rval = mount_early_fs(&cb, 1272 "fd", "/dev/fd", "fd", NULL); 1273 break; 1274 case Z_UNMOUNT: 1275 if (kernelcall) /* Invalid; can't happen */ 1276 abort(); 1277 zerror(zlogp, B_FALSE, "zone is already unmounted"); 1278 rval = 0; 1279 break; 1280 } 1281 break; 1282 1283 case ZONE_STATE_READY: 1284 switch (cmd) { 1285 case Z_READY: 1286 /* 1287 * We could have two clients racing to ready this 1288 * zone; the second client loses, but his request 1289 * doesn't fail, since the zone is now in the desired 1290 * state. 1291 */ 1292 zerror(zlogp, B_FALSE, "zone is already ready"); 1293 rval = 0; 1294 break; 1295 case Z_BOOT: 1296 (void) strlcpy(boot_args, zargp->bootbuf, 1297 sizeof (boot_args)); 1298 eventstream_write(Z_EVT_ZONE_BOOTING); 1299 rval = zone_bootup(zlogp, zargp->bootbuf, zstate); 1300 audit_put_record(zlogp, uc, rval, "boot"); 1301 if (rval != 0) { 1302 bringup_failure_recovery = B_TRUE; 1303 (void) zone_halt(zlogp, B_FALSE, B_TRUE, 1304 zstate); 1305 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1306 } 1307 boot_args[0] = '\0'; 1308 break; 1309 case Z_HALT: 1310 if (kernelcall) /* Invalid; can't happen */ 1311 abort(); 1312 if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate)) 1313 != 0) 1314 break; 1315 eventstream_write(Z_EVT_ZONE_HALTED); 1316 break; 1317 case Z_REBOOT: 1318 case Z_NOTE_UNINSTALLING: 1319 case Z_MOUNT: 1320 case Z_UNMOUNT: 1321 if (kernelcall) /* Invalid; can't happen */ 1322 abort(); 1323 zerror(zlogp, B_FALSE, "%s operation is invalid " 1324 "for zones in state '%s'", z_cmd_name(cmd), 1325 zone_state_str(zstate)); 1326 rval = -1; 1327 break; 1328 } 1329 break; 1330 1331 case ZONE_STATE_MOUNTED: 1332 switch (cmd) { 1333 case Z_UNMOUNT: 1334 if (kernelcall) /* Invalid; can't happen */ 1335 abort(); 1336 rval = zone_halt(zlogp, B_TRUE, B_FALSE, zstate); 1337 if (rval == 0) { 1338 eventstream_write(Z_EVT_ZONE_HALTED); 1339 (void) sema_post(&scratch_sem); 1340 } 1341 break; 1342 default: 1343 if (kernelcall) /* Invalid; can't happen */ 1344 abort(); 1345 zerror(zlogp, B_FALSE, "%s operation is invalid " 1346 "for zones in state '%s'", z_cmd_name(cmd), 1347 zone_state_str(zstate)); 1348 rval = -1; 1349 break; 1350 } 1351 break; 1352 1353 case ZONE_STATE_RUNNING: 1354 case ZONE_STATE_SHUTTING_DOWN: 1355 case ZONE_STATE_DOWN: 1356 switch (cmd) { 1357 case Z_READY: 1358 if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate)) 1359 != 0) 1360 break; 1361 if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) == 0) 1362 eventstream_write(Z_EVT_ZONE_READIED); 1363 else 1364 eventstream_write(Z_EVT_ZONE_HALTED); 1365 break; 1366 case Z_BOOT: 1367 /* 1368 * We could have two clients racing to boot this 1369 * zone; the second client loses, but his request 1370 * doesn't fail, since the zone is now in the desired 1371 * state. 1372 */ 1373 zerror(zlogp, B_FALSE, "zone is already booted"); 1374 rval = 0; 1375 break; 1376 case Z_HALT: 1377 if ((rval = zone_halt(zlogp, B_FALSE, B_FALSE, zstate)) 1378 != 0) 1379 break; 1380 eventstream_write(Z_EVT_ZONE_HALTED); 1381 break; 1382 case Z_REBOOT: 1383 (void) strlcpy(boot_args, zargp->bootbuf, 1384 sizeof (boot_args)); 1385 eventstream_write(Z_EVT_ZONE_REBOOTING); 1386 if ((rval = zone_halt(zlogp, B_FALSE, B_TRUE, zstate)) 1387 != 0) { 1388 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1389 boot_args[0] = '\0'; 1390 break; 1391 } 1392 if ((rval = zone_ready(zlogp, Z_MNT_BOOT, zstate)) 1393 != 0) { 1394 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1395 boot_args[0] = '\0'; 1396 break; 1397 } 1398 rval = zone_bootup(zlogp, zargp->bootbuf, zstate); 1399 audit_put_record(zlogp, uc, rval, "reboot"); 1400 if (rval != 0) { 1401 (void) zone_halt(zlogp, B_FALSE, B_TRUE, 1402 zstate); 1403 eventstream_write(Z_EVT_ZONE_BOOTFAILED); 1404 } 1405 boot_args[0] = '\0'; 1406 break; 1407 case Z_NOTE_UNINSTALLING: 1408 case Z_MOUNT: 1409 case Z_UNMOUNT: 1410 zerror(zlogp, B_FALSE, "%s operation is invalid " 1411 "for zones in state '%s'", z_cmd_name(cmd), 1412 zone_state_str(zstate)); 1413 rval = -1; 1414 break; 1415 } 1416 break; 1417 default: 1418 abort(); 1419 } 1420 1421 /* 1422 * Because the state of the zone may have changed, we make sure 1423 * to wake the console poller, which is in charge of initiating 1424 * the shutdown procedure as necessary. 1425 */ 1426 eventstream_write(Z_EVT_NULL); 1427 1428 out: 1429 (void) mutex_unlock(&lock); 1430 if (kernelcall) { 1431 rvalp = NULL; 1432 rlen = 0; 1433 } else { 1434 rvalp->rval = rval; 1435 } 1436 if (uc != NULL) 1437 ucred_free(uc); 1438 (void) door_return((char *)rvalp, rlen, NULL, 0); 1439 thr_exit(NULL); 1440 } 1441 1442 static int 1443 setup_door(zlog_t *zlogp) 1444 { 1445 if ((zone_door = door_create(server, NULL, 1446 DOOR_UNREF | DOOR_REFUSE_DESC | DOOR_NO_CANCEL)) < 0) { 1447 zerror(zlogp, B_TRUE, "%s failed", "door_create"); 1448 return (-1); 1449 } 1450 (void) fdetach(zone_door_path); 1451 1452 if (fattach(zone_door, zone_door_path) != 0) { 1453 zerror(zlogp, B_TRUE, "fattach to %s failed", zone_door_path); 1454 (void) door_revoke(zone_door); 1455 (void) fdetach(zone_door_path); 1456 zone_door = -1; 1457 return (-1); 1458 } 1459 return (0); 1460 } 1461 1462 /* 1463 * zoneadm(1m) will start zoneadmd if it thinks it isn't running; this 1464 * is where zoneadmd itself will check to see that another instance of 1465 * zoneadmd isn't already controlling this zone. 1466 * 1467 * The idea here is that we want to open the path to which we will 1468 * attach our door, lock it, and then make sure that no-one has beat us 1469 * to fattach(3c)ing onto it. 1470 * 1471 * fattach(3c) is really a mount, so there are actually two possible 1472 * vnodes we could be dealing with. Our strategy is as follows: 1473 * 1474 * - If the file we opened is a regular file (common case): 1475 * There is no fattach(3c)ed door, so we have a chance of becoming 1476 * the managing zoneadmd. We attempt to lock the file: if it is 1477 * already locked, that means someone else raced us here, so we 1478 * lose and give up. zoneadm(1m) will try to contact the zoneadmd 1479 * that beat us to it. 1480 * 1481 * - If the file we opened is a namefs file: 1482 * This means there is already an established door fattach(3c)'ed 1483 * to the rendezvous path. We've lost the race, so we give up. 1484 * Note that in this case we also try to grab the file lock, and 1485 * will succeed in acquiring it since the vnode locked by the 1486 * "winning" zoneadmd was a regular one, and the one we locked was 1487 * the fattach(3c)'ed door node. At any rate, no harm is done, and 1488 * we just return to zoneadm(1m) which knows to retry. 1489 */ 1490 static int 1491 make_daemon_exclusive(zlog_t *zlogp) 1492 { 1493 int doorfd = -1; 1494 int err, ret = -1; 1495 struct stat st; 1496 struct flock flock; 1497 zone_state_t zstate; 1498 1499 top: 1500 if ((err = zone_get_state(zone_name, &zstate)) != Z_OK) { 1501 zerror(zlogp, B_FALSE, "failed to get zone state: %s", 1502 zonecfg_strerror(err)); 1503 goto out; 1504 } 1505 if ((doorfd = open(zone_door_path, O_CREAT|O_RDWR, 1506 S_IREAD|S_IWRITE)) < 0) { 1507 zerror(zlogp, B_TRUE, "failed to open %s", zone_door_path); 1508 goto out; 1509 } 1510 if (fstat(doorfd, &st) < 0) { 1511 zerror(zlogp, B_TRUE, "failed to stat %s", zone_door_path); 1512 goto out; 1513 } 1514 /* 1515 * Lock the file to synchronize with other zoneadmd 1516 */ 1517 flock.l_type = F_WRLCK; 1518 flock.l_whence = SEEK_SET; 1519 flock.l_start = (off_t)0; 1520 flock.l_len = (off_t)0; 1521 if (fcntl(doorfd, F_SETLK, &flock) < 0) { 1522 /* 1523 * Someone else raced us here and grabbed the lock file 1524 * first. A warning here is inappropriate since nothing 1525 * went wrong. 1526 */ 1527 goto out; 1528 } 1529 1530 if (strcmp(st.st_fstype, "namefs") == 0) { 1531 struct door_info info; 1532 1533 /* 1534 * There is already something fattach()'ed to this file. 1535 * Lets see what the door is up to. 1536 */ 1537 if (door_info(doorfd, &info) == 0 && info.di_target != -1) { 1538 /* 1539 * Another zoneadmd process seems to be in 1540 * control of the situation and we don't need to 1541 * be here. A warning here is inappropriate 1542 * since nothing went wrong. 1543 * 1544 * If the door has been revoked, the zoneadmd 1545 * process currently managing the zone is going 1546 * away. We'll return control to zoneadm(1m) 1547 * which will try again (by which time zoneadmd 1548 * will hopefully have exited). 1549 */ 1550 goto out; 1551 } 1552 1553 /* 1554 * If we got this far, there's a fattach(3c)'ed door 1555 * that belongs to a process that has exited, which can 1556 * happen if the previous zoneadmd died unexpectedly. 1557 * 1558 * Let user know that something is amiss, but that we can 1559 * recover; if the zone is in the installed state, then don't 1560 * message, since having a running zoneadmd isn't really 1561 * expected/needed. We want to keep occurences of this message 1562 * limited to times when zoneadmd is picking back up from a 1563 * zoneadmd that died while the zone was in some non-trivial 1564 * state. 1565 */ 1566 if (zstate > ZONE_STATE_INSTALLED) { 1567 zerror(zlogp, B_FALSE, 1568 "zone '%s': WARNING: zone is in state '%s', but " 1569 "zoneadmd does not appear to be available; " 1570 "restarted zoneadmd to recover.", 1571 zone_name, zone_state_str(zstate)); 1572 } 1573 1574 (void) fdetach(zone_door_path); 1575 (void) close(doorfd); 1576 goto top; 1577 } 1578 ret = 0; 1579 out: 1580 (void) close(doorfd); 1581 return (ret); 1582 } 1583 1584 /* 1585 * Setup the brand's pre and post state change callbacks, as well as the 1586 * query callback, if any of these exist. 1587 */ 1588 static int 1589 brand_callback_init(brand_handle_t bh, char *zone_name) 1590 { 1591 char zpath[MAXPATHLEN]; 1592 1593 if (zone_get_zonepath(zone_name, zpath, sizeof (zpath)) != Z_OK) 1594 return (-1); 1595 1596 (void) strlcpy(pre_statechg_hook, EXEC_PREFIX, 1597 sizeof (pre_statechg_hook)); 1598 1599 if (brand_get_prestatechange(bh, zone_name, zpath, 1600 pre_statechg_hook + EXEC_LEN, 1601 sizeof (pre_statechg_hook) - EXEC_LEN) != 0) 1602 return (-1); 1603 1604 if (strlen(pre_statechg_hook) <= EXEC_LEN) 1605 pre_statechg_hook[0] = '\0'; 1606 1607 (void) strlcpy(post_statechg_hook, EXEC_PREFIX, 1608 sizeof (post_statechg_hook)); 1609 1610 if (brand_get_poststatechange(bh, zone_name, zpath, 1611 post_statechg_hook + EXEC_LEN, 1612 sizeof (post_statechg_hook) - EXEC_LEN) != 0) 1613 return (-1); 1614 1615 if (strlen(post_statechg_hook) <= EXEC_LEN) 1616 post_statechg_hook[0] = '\0'; 1617 1618 (void) strlcpy(query_hook, EXEC_PREFIX, 1619 sizeof (query_hook)); 1620 1621 if (brand_get_query(bh, zone_name, zpath, query_hook + EXEC_LEN, 1622 sizeof (query_hook) - EXEC_LEN) != 0) 1623 return (-1); 1624 1625 if (strlen(query_hook) <= EXEC_LEN) 1626 query_hook[0] = '\0'; 1627 1628 return (0); 1629 } 1630 1631 int 1632 main(int argc, char *argv[]) 1633 { 1634 int opt; 1635 zoneid_t zid; 1636 priv_set_t *privset; 1637 zone_state_t zstate; 1638 char parents_locale[MAXPATHLEN]; 1639 brand_handle_t bh; 1640 int err; 1641 1642 pid_t pid; 1643 sigset_t blockset; 1644 sigset_t block_cld; 1645 1646 struct { 1647 sema_t sem; 1648 int status; 1649 zlog_t log; 1650 } *shstate; 1651 size_t shstatelen = getpagesize(); 1652 1653 zlog_t errlog; 1654 zlog_t *zlogp; 1655 1656 int ctfd; 1657 1658 progname = get_execbasename(argv[0]); 1659 1660 /* 1661 * Make sure stderr is unbuffered 1662 */ 1663 (void) setbuffer(stderr, NULL, 0); 1664 1665 /* 1666 * Get out of the way of mounted filesystems, since we will daemonize 1667 * soon. 1668 */ 1669 (void) chdir("/"); 1670 1671 /* 1672 * Use the default system umask per PSARC 1998/110 rather than 1673 * anything that may have been set by the caller. 1674 */ 1675 (void) umask(CMASK); 1676 1677 /* 1678 * Initially we want to use our parent's locale. 1679 */ 1680 (void) setlocale(LC_ALL, ""); 1681 (void) textdomain(TEXT_DOMAIN); 1682 (void) strlcpy(parents_locale, setlocale(LC_MESSAGES, NULL), 1683 sizeof (parents_locale)); 1684 1685 /* 1686 * This zlog_t is used for writing to stderr 1687 */ 1688 errlog.logfile = stderr; 1689 errlog.buflen = errlog.loglen = 0; 1690 errlog.buf = errlog.log = NULL; 1691 errlog.locale = parents_locale; 1692 1693 /* 1694 * We start off writing to stderr until we're ready to daemonize. 1695 */ 1696 zlogp = &errlog; 1697 1698 /* 1699 * Process options. 1700 */ 1701 while ((opt = getopt(argc, argv, "R:z:")) != EOF) { 1702 switch (opt) { 1703 case 'R': 1704 zonecfg_set_root(optarg); 1705 break; 1706 case 'z': 1707 zone_name = optarg; 1708 break; 1709 default: 1710 usage(); 1711 } 1712 } 1713 1714 if (zone_name == NULL) 1715 usage(); 1716 1717 /* 1718 * Because usage() prints directly to stderr, it has gettext() 1719 * wrapping, which depends on the locale. But since zerror() calls 1720 * localize() which tweaks the locale, it is not safe to call zerror() 1721 * until after the last call to usage(). Fortunately, the last call 1722 * to usage() is just above and the first call to zerror() is just 1723 * below. Don't mess this up. 1724 */ 1725 if (strcmp(zone_name, GLOBAL_ZONENAME) == 0) { 1726 zerror(zlogp, B_FALSE, "cannot manage the %s zone", 1727 GLOBAL_ZONENAME); 1728 return (1); 1729 } 1730 1731 if (zone_get_id(zone_name, &zid) != 0) { 1732 zerror(zlogp, B_FALSE, "could not manage %s: %s", zone_name, 1733 zonecfg_strerror(Z_NO_ZONE)); 1734 return (1); 1735 } 1736 1737 if ((err = zone_get_state(zone_name, &zstate)) != Z_OK) { 1738 zerror(zlogp, B_FALSE, "failed to get zone state: %s", 1739 zonecfg_strerror(err)); 1740 return (1); 1741 } 1742 if (zstate < ZONE_STATE_INCOMPLETE) { 1743 zerror(zlogp, B_FALSE, 1744 "cannot manage a zone which is in state '%s'", 1745 zone_state_str(zstate)); 1746 return (1); 1747 } 1748 1749 /* Get a handle to the brand info for this zone */ 1750 if ((zone_get_brand(zone_name, brand_name, sizeof (brand_name)) 1751 != Z_OK) || (bh = brand_open(brand_name)) == NULL) { 1752 zerror(zlogp, B_FALSE, "unable to determine zone brand"); 1753 return (1); 1754 } 1755 zone_isnative = brand_is_native(bh); 1756 zone_iscluster = (strcmp(brand_name, CLUSTER_BRAND_NAME) == 0); 1757 zone_islabeled = (strcmp(brand_name, LABELED_BRAND_NAME) == 0); 1758 1759 /* Get state change brand hooks. */ 1760 if (brand_callback_init(bh, zone_name) == -1) { 1761 zerror(zlogp, B_TRUE, 1762 "failed to initialize brand state change hooks"); 1763 brand_close(bh); 1764 return (1); 1765 } 1766 1767 brand_close(bh); 1768 1769 /* 1770 * Check that we have all privileges. It would be nice to pare 1771 * this down, but this is at least a first cut. 1772 */ 1773 if ((privset = priv_allocset()) == NULL) { 1774 zerror(zlogp, B_TRUE, "%s failed", "priv_allocset"); 1775 return (1); 1776 } 1777 1778 if (getppriv(PRIV_EFFECTIVE, privset) != 0) { 1779 zerror(zlogp, B_TRUE, "%s failed", "getppriv"); 1780 priv_freeset(privset); 1781 return (1); 1782 } 1783 1784 if (priv_isfullset(privset) == B_FALSE) { 1785 zerror(zlogp, B_FALSE, "You lack sufficient privilege to " 1786 "run this command (all privs required)"); 1787 priv_freeset(privset); 1788 return (1); 1789 } 1790 priv_freeset(privset); 1791 1792 if (mkzonedir(zlogp) != 0) 1793 return (1); 1794 1795 /* 1796 * Pre-fork: setup shared state 1797 */ 1798 if ((shstate = (void *)mmap(NULL, shstatelen, 1799 PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, (off_t)0)) == 1800 MAP_FAILED) { 1801 zerror(zlogp, B_TRUE, "%s failed", "mmap"); 1802 return (1); 1803 } 1804 if (sema_init(&shstate->sem, 0, USYNC_PROCESS, NULL) != 0) { 1805 zerror(zlogp, B_TRUE, "%s failed", "sema_init()"); 1806 (void) munmap((char *)shstate, shstatelen); 1807 return (1); 1808 } 1809 shstate->log.logfile = NULL; 1810 shstate->log.buflen = shstatelen - sizeof (*shstate); 1811 shstate->log.loglen = shstate->log.buflen; 1812 shstate->log.buf = (char *)shstate + sizeof (*shstate); 1813 shstate->log.log = shstate->log.buf; 1814 shstate->log.locale = parents_locale; 1815 shstate->status = -1; 1816 1817 /* 1818 * We need a SIGCHLD handler so the sema_wait() below will wake 1819 * up if the child dies without doing a sema_post(). 1820 */ 1821 (void) sigset(SIGCHLD, sigchld); 1822 /* 1823 * We must mask SIGCHLD until after we've coped with the fork 1824 * sufficiently to deal with it; otherwise we can race and 1825 * receive the signal before pid has been initialized 1826 * (yes, this really happens). 1827 */ 1828 (void) sigemptyset(&block_cld); 1829 (void) sigaddset(&block_cld, SIGCHLD); 1830 (void) sigprocmask(SIG_BLOCK, &block_cld, NULL); 1831 1832 if ((ctfd = init_template()) == -1) { 1833 zerror(zlogp, B_TRUE, "failed to create contract"); 1834 return (1); 1835 } 1836 1837 /* 1838 * Do not let another thread localize a message while we are forking. 1839 */ 1840 (void) mutex_lock(&msglock); 1841 pid = fork(); 1842 (void) mutex_unlock(&msglock); 1843 1844 /* 1845 * In all cases (parent, child, and in the event of an error) we 1846 * don't want to cause creation of contracts on subsequent fork()s. 1847 */ 1848 (void) ct_tmpl_clear(ctfd); 1849 (void) close(ctfd); 1850 1851 if (pid == -1) { 1852 zerror(zlogp, B_TRUE, "could not fork"); 1853 return (1); 1854 1855 } else if (pid > 0) { /* parent */ 1856 (void) sigprocmask(SIG_UNBLOCK, &block_cld, NULL); 1857 /* 1858 * This marks a window of vulnerability in which we receive 1859 * the SIGCLD before falling into sema_wait (normally we would 1860 * get woken up from sema_wait with EINTR upon receipt of 1861 * SIGCLD). So we may need to use some other scheme like 1862 * sema_posting in the sigcld handler. 1863 * blech 1864 */ 1865 (void) sema_wait(&shstate->sem); 1866 (void) sema_destroy(&shstate->sem); 1867 if (shstate->status != 0) 1868 (void) waitpid(pid, NULL, WNOHANG); 1869 /* 1870 * It's ok if we die with SIGPIPE. It's not like we could have 1871 * done anything about it. 1872 */ 1873 (void) fprintf(stderr, "%s", shstate->log.buf); 1874 _exit(shstate->status == 0 ? 0 : 1); 1875 } 1876 1877 /* 1878 * The child charges on. 1879 */ 1880 (void) sigset(SIGCHLD, SIG_DFL); 1881 (void) sigprocmask(SIG_UNBLOCK, &block_cld, NULL); 1882 1883 /* 1884 * SIGPIPE can be delivered if we write to a socket for which the 1885 * peer endpoint is gone. That can lead to too-early termination 1886 * of zoneadmd, and that's not good eats. 1887 */ 1888 (void) sigset(SIGPIPE, SIG_IGN); 1889 /* 1890 * Stop using stderr 1891 */ 1892 zlogp = &shstate->log; 1893 1894 /* 1895 * We don't need stdout/stderr from now on. 1896 */ 1897 closefrom(0); 1898 1899 /* 1900 * Initialize the syslog zlog_t. This needs to be done after 1901 * the call to closefrom(). 1902 */ 1903 logsys.buf = logsys.log = NULL; 1904 logsys.buflen = logsys.loglen = 0; 1905 logsys.logfile = NULL; 1906 logsys.locale = DEFAULT_LOCALE; 1907 1908 openlog("zoneadmd", LOG_PID, LOG_DAEMON); 1909 1910 /* 1911 * The eventstream is used to publish state changes in the zone 1912 * from the door threads to the console I/O poller. 1913 */ 1914 if (eventstream_init() == -1) { 1915 zerror(zlogp, B_TRUE, "unable to create eventstream"); 1916 goto child_out; 1917 } 1918 1919 (void) snprintf(zone_door_path, sizeof (zone_door_path), 1920 "%s" ZONE_DOOR_PATH, zonecfg_get_root(), zone_name); 1921 1922 /* 1923 * See if another zoneadmd is running for this zone. If not, then we 1924 * can now modify system state. 1925 */ 1926 if (make_daemon_exclusive(zlogp) == -1) 1927 goto child_out; 1928 1929 1930 /* 1931 * Create/join a new session; we need to be careful of what we do with 1932 * the console from now on so we don't end up being the session leader 1933 * for the terminal we're going to be handing out. 1934 */ 1935 (void) setsid(); 1936 1937 /* 1938 * This thread shouldn't be receiving any signals; in particular, 1939 * SIGCHLD should be received by the thread doing the fork(). 1940 */ 1941 (void) sigfillset(&blockset); 1942 (void) thr_sigsetmask(SIG_BLOCK, &blockset, NULL); 1943 1944 /* 1945 * Setup the console device and get ready to serve the console; 1946 * once this has completed, we're ready to let console clients 1947 * make an attempt to connect (they will block until 1948 * serve_console_sock() below gets called, and any pending 1949 * connection is accept()ed). 1950 */ 1951 if (!zonecfg_in_alt_root() && init_console(zlogp) < 0) 1952 goto child_out; 1953 1954 /* 1955 * Take the lock now, so that when the door server gets going, we 1956 * are guaranteed that it won't take a request until we are sure 1957 * that everything is completely set up. See the child_out: label 1958 * below to see why this matters. 1959 */ 1960 (void) mutex_lock(&lock); 1961 1962 /* Init semaphore for scratch zones. */ 1963 if (sema_init(&scratch_sem, 0, USYNC_THREAD, NULL) == -1) { 1964 zerror(zlogp, B_TRUE, 1965 "failed to initialize semaphore for scratch zone"); 1966 goto child_out; 1967 } 1968 1969 /* open the dladm handle */ 1970 if (dladm_open(&dld_handle) != DLADM_STATUS_OK) { 1971 zerror(zlogp, B_FALSE, "failed to open dladm handle"); 1972 goto child_out; 1973 } 1974 1975 /* 1976 * Note: door setup must occur *after* the console is setup. 1977 * This is so that as zlogin tests the door to see if zoneadmd 1978 * is ready yet, we know that the console will get serviced 1979 * once door_info() indicates that the door is "up". 1980 */ 1981 if (setup_door(zlogp) == -1) 1982 goto child_out; 1983 1984 /* 1985 * Things seem OK so far; tell the parent process that we're done 1986 * with setup tasks. This will cause the parent to exit, signalling 1987 * to zoneadm, zlogin, or whatever forked it that we are ready to 1988 * service requests. 1989 */ 1990 shstate->status = 0; 1991 (void) sema_post(&shstate->sem); 1992 (void) munmap((char *)shstate, shstatelen); 1993 shstate = NULL; 1994 1995 (void) mutex_unlock(&lock); 1996 1997 /* 1998 * zlogp is now invalid, so reset it to the syslog logger. 1999 */ 2000 zlogp = &logsys; 2001 2002 /* 2003 * Now that we are free of any parents, switch to the default locale. 2004 */ 2005 (void) setlocale(LC_ALL, DEFAULT_LOCALE); 2006 2007 /* 2008 * At this point the setup portion of main() is basically done, so 2009 * we reuse this thread to manage the zone console. When 2010 * serve_console() has returned, we are past the point of no return 2011 * in the life of this zoneadmd. 2012 */ 2013 if (zonecfg_in_alt_root()) { 2014 /* 2015 * This is just awful, but mounted scratch zones don't (and 2016 * can't) have consoles. We just wait for unmount instead. 2017 */ 2018 while (sema_wait(&scratch_sem) == EINTR) 2019 ; 2020 } else { 2021 serve_console(zlogp); 2022 assert(in_death_throes); 2023 } 2024 2025 /* 2026 * This is the next-to-last part of the exit interlock. Upon calling 2027 * fdetach(), the door will go unreferenced; once any 2028 * outstanding requests (like the door thread doing Z_HALT) are 2029 * done, the door will get an UNREF notification; when it handles 2030 * the UNREF, the door server will cause the exit. 2031 */ 2032 assert(!MUTEX_HELD(&lock)); 2033 (void) fdetach(zone_door_path); 2034 2035 for (;;) 2036 (void) pause(); 2037 2038 child_out: 2039 assert(pid == 0); 2040 if (shstate != NULL) { 2041 shstate->status = -1; 2042 (void) sema_post(&shstate->sem); 2043 (void) munmap((char *)shstate, shstatelen); 2044 } 2045 2046 /* 2047 * This might trigger an unref notification, but if so, 2048 * we are still holding the lock, so our call to exit will 2049 * ultimately win the race and will publish the right exit 2050 * code. 2051 */ 2052 if (zone_door != -1) { 2053 assert(MUTEX_HELD(&lock)); 2054 (void) door_revoke(zone_door); 2055 (void) fdetach(zone_door_path); 2056 } 2057 2058 if (dld_handle != NULL) 2059 dladm_close(dld_handle); 2060 2061 return (1); /* return from main() forcibly exits an MT process */ 2062 } 2063