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 2007 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * zoneadm is a command interpreter for zone administration. It is all in 31 * C (i.e., no lex/yacc), and all the argument passing is argc/argv based. 32 * main() calls parse_and_run() which calls cmd_match(), then invokes the 33 * appropriate command's handler function. The rest of the program is the 34 * handler functions and their helper functions. 35 * 36 * Some of the helper functions are used largely to simplify I18N: reducing 37 * the need for translation notes. This is particularly true of many of 38 * the zerror() calls: doing e.g. zerror(gettext("%s failed"), "foo") rather 39 * than zerror(gettext("foo failed")) with a translation note indicating 40 * that "foo" need not be translated. 41 */ 42 43 #include <stdio.h> 44 #include <errno.h> 45 #include <unistd.h> 46 #include <signal.h> 47 #include <stdarg.h> 48 #include <ctype.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <wait.h> 52 #include <zone.h> 53 #include <priv.h> 54 #include <locale.h> 55 #include <libintl.h> 56 #include <libzonecfg.h> 57 #include <bsm/adt.h> 58 #include <sys/brand.h> 59 #include <sys/param.h> 60 #include <sys/types.h> 61 #include <sys/stat.h> 62 #include <sys/statvfs.h> 63 #include <assert.h> 64 #include <sys/sockio.h> 65 #include <sys/mntent.h> 66 #include <limits.h> 67 #include <dirent.h> 68 #include <uuid/uuid.h> 69 70 #include <fcntl.h> 71 #include <door.h> 72 #include <macros.h> 73 #include <libgen.h> 74 #include <fnmatch.h> 75 #include <sys/modctl.h> 76 #include <libbrand.h> 77 #include <libscf.h> 78 #include <procfs.h> 79 80 #include <pool.h> 81 #include <sys/pool.h> 82 #include <sys/priocntl.h> 83 #include <sys/fsspriocntl.h> 84 85 #include "zoneadm.h" 86 87 #define MAXARGS 8 88 89 /* Reflects kernel zone entries */ 90 typedef struct zone_entry { 91 zoneid_t zid; 92 char zname[ZONENAME_MAX]; 93 char *zstate_str; 94 zone_state_t zstate_num; 95 char zbrand[MAXNAMELEN]; 96 char zroot[MAXPATHLEN]; 97 char zuuid[UUID_PRINTABLE_STRING_LENGTH]; 98 } zone_entry_t; 99 100 static zone_entry_t *zents; 101 static size_t nzents; 102 static boolean_t is_native_zone = B_TRUE; 103 104 #define LOOPBACK_IF "lo0" 105 #define SOCKET_AF(af) (((af) == AF_UNSPEC) ? AF_INET : (af)) 106 107 struct net_if { 108 char *name; 109 int af; 110 }; 111 112 /* 0755 is the default directory mode. */ 113 #define DEFAULT_DIR_MODE \ 114 (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) 115 116 struct cmd { 117 uint_t cmd_num; /* command number */ 118 char *cmd_name; /* command name */ 119 char *short_usage; /* short form help */ 120 int (*handler)(int argc, char *argv[]); /* function to call */ 121 122 }; 123 124 #define SHELP_HELP "help" 125 #define SHELP_BOOT "boot [-- boot_arguments]" 126 #define SHELP_HALT "halt" 127 #define SHELP_READY "ready" 128 #define SHELP_REBOOT "reboot [-- boot_arguments]" 129 #define SHELP_LIST "list [-cipv]" 130 #define SHELP_VERIFY "verify" 131 #define SHELP_INSTALL "install [-x nodataset] [brand-specific args]" 132 #define SHELP_UNINSTALL "uninstall [-F]" 133 #define SHELP_CLONE "clone [-m method] [-s <ZFS snapshot>] zonename" 134 #define SHELP_MOVE "move zonepath" 135 #define SHELP_DETACH "detach [-n]" 136 #define SHELP_ATTACH "attach [-F] [-n <path>]" 137 #define SHELP_MARK "mark incomplete" 138 139 #define EXEC_PREFIX "exec " 140 #define EXEC_LEN (strlen(EXEC_PREFIX)) 141 #define RMCOMMAND "/usr/bin/rm -rf" 142 143 static int cleanup_zonepath(char *, boolean_t); 144 145 static int help_func(int argc, char *argv[]); 146 static int ready_func(int argc, char *argv[]); 147 static int boot_func(int argc, char *argv[]); 148 static int halt_func(int argc, char *argv[]); 149 static int reboot_func(int argc, char *argv[]); 150 static int list_func(int argc, char *argv[]); 151 static int verify_func(int argc, char *argv[]); 152 static int install_func(int argc, char *argv[]); 153 static int uninstall_func(int argc, char *argv[]); 154 static int mount_func(int argc, char *argv[]); 155 static int unmount_func(int argc, char *argv[]); 156 static int clone_func(int argc, char *argv[]); 157 static int move_func(int argc, char *argv[]); 158 static int detach_func(int argc, char *argv[]); 159 static int attach_func(int argc, char *argv[]); 160 static int mark_func(int argc, char *argv[]); 161 static int apply_func(int argc, char *argv[]); 162 static int sanity_check(char *zone, int cmd_num, boolean_t running, 163 boolean_t unsafe_when_running, boolean_t force); 164 static int cmd_match(char *cmd); 165 static int verify_details(int, char *argv[]); 166 static int verify_brand(zone_dochandle_t, int, char *argv[]); 167 static int invoke_brand_handler(int, char *argv[]); 168 169 static struct cmd cmdtab[] = { 170 { CMD_HELP, "help", SHELP_HELP, help_func }, 171 { CMD_BOOT, "boot", SHELP_BOOT, boot_func }, 172 { CMD_HALT, "halt", SHELP_HALT, halt_func }, 173 { CMD_READY, "ready", SHELP_READY, ready_func }, 174 { CMD_REBOOT, "reboot", SHELP_REBOOT, reboot_func }, 175 { CMD_LIST, "list", SHELP_LIST, list_func }, 176 { CMD_VERIFY, "verify", SHELP_VERIFY, verify_func }, 177 { CMD_INSTALL, "install", SHELP_INSTALL, install_func }, 178 { CMD_UNINSTALL, "uninstall", SHELP_UNINSTALL, 179 uninstall_func }, 180 /* mount and unmount are private commands for admin/install */ 181 { CMD_MOUNT, "mount", NULL, mount_func }, 182 { CMD_UNMOUNT, "unmount", NULL, unmount_func }, 183 { CMD_CLONE, "clone", SHELP_CLONE, clone_func }, 184 { CMD_MOVE, "move", SHELP_MOVE, move_func }, 185 { CMD_DETACH, "detach", SHELP_DETACH, detach_func }, 186 { CMD_ATTACH, "attach", SHELP_ATTACH, attach_func }, 187 { CMD_MARK, "mark", SHELP_MARK, mark_func }, 188 { CMD_APPLY, "apply", NULL, apply_func } 189 }; 190 191 /* global variables */ 192 193 /* set early in main(), never modified thereafter, used all over the place */ 194 static char *execname; 195 static char target_brand[MAXNAMELEN]; 196 static char *locale; 197 char *target_zone; 198 static char *target_uuid; 199 200 /* used in do_subproc() and signal handler */ 201 static volatile boolean_t child_killed; 202 static int do_subproc_cnt = 0; 203 204 /* 205 * Used to indicate whether this zoneadm instance has another zoneadm 206 * instance in its ancestry. 207 */ 208 static boolean_t zoneadm_is_nested = B_FALSE; 209 210 /* used to track nested zone-lock operations */ 211 static int zone_lock_cnt = 0; 212 213 /* used to communicate lock status to children */ 214 #define LOCK_ENV_VAR "_ZONEADM_LOCK_HELD" 215 static char zoneadm_lock_held[] = LOCK_ENV_VAR"=1"; 216 static char zoneadm_lock_not_held[] = LOCK_ENV_VAR"=0"; 217 218 char * 219 cmd_to_str(int cmd_num) 220 { 221 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX); 222 return (cmdtab[cmd_num].cmd_name); 223 } 224 225 /* This is a separate function because of gettext() wrapping. */ 226 static char * 227 long_help(int cmd_num) 228 { 229 assert(cmd_num >= CMD_MIN && cmd_num <= CMD_MAX); 230 switch (cmd_num) { 231 case CMD_HELP: 232 return (gettext("Print usage message.")); 233 case CMD_BOOT: 234 return (gettext("Activates (boots) specified zone. See " 235 "zoneadm(1m) for valid boot\n\targuments.")); 236 case CMD_HALT: 237 return (gettext("Halts specified zone, bypassing shutdown " 238 "scripts and removing runtime\n\tresources of the zone.")); 239 case CMD_READY: 240 return (gettext("Prepares a zone for running applications but " 241 "does not start any user\n\tprocesses in the zone.")); 242 case CMD_REBOOT: 243 return (gettext("Restarts the zone (equivalent to a halt / " 244 "boot sequence).\n\tFails if the zone is not active. " 245 "See zoneadm(1m) for valid boot\n\targuments.")); 246 case CMD_LIST: 247 return (gettext("Lists the current zones, or a " 248 "specific zone if indicated. By default,\n\tall " 249 "running zones are listed, though this can be " 250 "expanded to all\n\tinstalled zones with the -i " 251 "option or all configured zones with the\n\t-c " 252 "option. When used with the general -z <zone> and/or -u " 253 "<uuid-match>\n\toptions, lists only the specified " 254 "matching zone, but lists it\n\tregardless of its state, " 255 "and the -i and -c options are disallowed. The\n\t-v " 256 "option can be used to display verbose information: zone " 257 "name, id,\n\tcurrent state, root directory and options. " 258 "The -p option can be used\n\tto request machine-parsable " 259 "output. The -v and -p options are mutually\n\texclusive." 260 " If neither -v nor -p is used, just the zone name is " 261 "listed.")); 262 case CMD_VERIFY: 263 return (gettext("Check to make sure the configuration " 264 "can safely be instantiated\n\ton the machine: " 265 "physical network interfaces exist, etc.")); 266 case CMD_INSTALL: 267 return (gettext("Install the configuration on to the system. " 268 "The -x nodataset option\n\tcan be used to prevent the " 269 "creation of a new ZFS file system for the\n\tzone " 270 "(assuming the zonepath is within a ZFS file system).\n\t" 271 "All other arguments are passed to the brand installation " 272 "function;\n\tsee brand(4) for more information.")); 273 case CMD_UNINSTALL: 274 return (gettext("Uninstall the configuration from the system. " 275 "The -F flag can be used\n\tto force the action.")); 276 case CMD_CLONE: 277 return (gettext("Clone the installation of another zone. " 278 "The -m option can be used to\n\tspecify 'copy' which " 279 "forces a copy of the source zone. The -s option\n\t" 280 "can be used to specify the name of a ZFS snapshot " 281 "that was taken from\n\ta previous clone command. The " 282 "snapshot will be used as the source\n\tinstead of " 283 "creating a new ZFS snapshot.")); 284 case CMD_MOVE: 285 return (gettext("Move the zone to a new zonepath.")); 286 case CMD_DETACH: 287 return (gettext("Detach the zone from the system. The zone " 288 "state is changed to\n\t'configured' (but the files under " 289 "the zonepath are untouched).\n\tThe zone can subsequently " 290 "be attached, or can be moved to another\n\tsystem and " 291 "attached there. The -n option can be used to specify\n\t" 292 "'no-execute' mode. When -n is used, the information " 293 "needed to attach\n\tthe zone is sent to standard output " 294 "but the zone is not actually\n\tdetached.")); 295 case CMD_ATTACH: 296 return (gettext("Attach the zone to the system. The zone " 297 "state must be 'configured'\n\tprior to attach; upon " 298 "successful completion, the zone state will be\n\t" 299 "'installed'. The system software on the current " 300 "system must be\n\tcompatible with the software on the " 301 "zone's original system.\n\tSpecify -F to force the attach " 302 "and skip software compatibility tests.\n\tThe -n option " 303 "can be used to specify 'no-execute' mode. When -n is\n\t" 304 "used, the information needed to attach the zone is read " 305 "from the\n\tspecified path and the configuration is only " 306 "validated. The path can\n\tbe '-' to specify standard " 307 "input.")); 308 case CMD_MARK: 309 return (gettext("Set the state of the zone. This can be used " 310 "to force the zone\n\tstate to 'incomplete' " 311 "administratively if some activity has rendered\n\tthe " 312 "zone permanently unusable. The only valid state that " 313 "may be\n\tspecified is 'incomplete'.")); 314 default: 315 return (""); 316 } 317 /* NOTREACHED */ 318 return (NULL); 319 } 320 321 /* 322 * Called with explicit B_TRUE when help is explicitly requested, B_FALSE for 323 * unexpected errors. 324 */ 325 326 static int 327 usage(boolean_t explicit) 328 { 329 int i; 330 FILE *fd = explicit ? stdout : stderr; 331 332 (void) fprintf(fd, "%s:\t%s help\n", gettext("usage"), execname); 333 (void) fprintf(fd, "\t%s [-z <zone>] [-u <uuid-match>] list\n", 334 execname); 335 (void) fprintf(fd, "\t%s {-z <zone>|-u <uuid-match>} <%s>\n", execname, 336 gettext("subcommand")); 337 (void) fprintf(fd, "\n%s:\n\n", gettext("Subcommands")); 338 for (i = CMD_MIN; i <= CMD_MAX; i++) { 339 if (cmdtab[i].short_usage == NULL) 340 continue; 341 (void) fprintf(fd, "%s\n", cmdtab[i].short_usage); 342 if (explicit) 343 (void) fprintf(fd, "\t%s\n\n", long_help(i)); 344 } 345 if (!explicit) 346 (void) fputs("\n", fd); 347 return (Z_USAGE); 348 } 349 350 static void 351 sub_usage(char *short_usage, int cmd_num) 352 { 353 (void) fprintf(stderr, "%s:\t%s\n", gettext("usage"), short_usage); 354 (void) fprintf(stderr, "\t%s\n", long_help(cmd_num)); 355 } 356 357 /* 358 * zperror() is like perror(3c) except that this also prints the executable 359 * name at the start of the message, and takes a boolean indicating whether 360 * to call libc'c strerror() or that from libzonecfg. 361 */ 362 363 void 364 zperror(const char *str, boolean_t zonecfg_error) 365 { 366 (void) fprintf(stderr, "%s: %s: %s\n", execname, str, 367 zonecfg_error ? zonecfg_strerror(errno) : strerror(errno)); 368 } 369 370 /* 371 * zperror2() is very similar to zperror() above, except it also prints a 372 * supplied zone name after the executable. 373 * 374 * All current consumers of this function want libzonecfg's strerror() rather 375 * than libc's; if this ever changes, this function can be made more generic 376 * like zperror() above. 377 */ 378 379 void 380 zperror2(const char *zone, const char *str) 381 { 382 (void) fprintf(stderr, "%s: %s: %s: %s\n", execname, zone, str, 383 zonecfg_strerror(errno)); 384 } 385 386 /* PRINTFLIKE1 */ 387 void 388 zerror(const char *fmt, ...) 389 { 390 va_list alist; 391 392 va_start(alist, fmt); 393 (void) fprintf(stderr, "%s: ", execname); 394 if (target_zone != NULL) 395 (void) fprintf(stderr, "zone '%s': ", target_zone); 396 (void) vfprintf(stderr, fmt, alist); 397 (void) fprintf(stderr, "\n"); 398 va_end(alist); 399 } 400 401 static void * 402 safe_calloc(size_t nelem, size_t elsize) 403 { 404 void *r = calloc(nelem, elsize); 405 406 if (r == NULL) { 407 zerror(gettext("failed to allocate %lu bytes: %s"), 408 (ulong_t)nelem * elsize, strerror(errno)); 409 exit(Z_ERR); 410 } 411 return (r); 412 } 413 414 static void 415 zone_print(zone_entry_t *zent, boolean_t verbose, boolean_t parsable) 416 { 417 static boolean_t firsttime = B_TRUE; 418 419 assert(!(verbose && parsable)); 420 if (firsttime && verbose) { 421 firsttime = B_FALSE; 422 (void) printf("%*s %-16s %-14s %-30s %-10s\n", ZONEID_WIDTH, 423 "ID", "NAME", "STATUS", "PATH", "BRAND"); 424 } 425 if (!verbose) { 426 char *cp, *clim; 427 428 if (!parsable) { 429 (void) printf("%s\n", zent->zname); 430 return; 431 } 432 if (zent->zid == ZONE_ID_UNDEFINED) 433 (void) printf("-"); 434 else 435 (void) printf("%lu", zent->zid); 436 (void) printf(":%s:%s:", zent->zname, zent->zstate_str); 437 cp = zent->zroot; 438 while ((clim = strchr(cp, ':')) != NULL) { 439 (void) printf("%.*s\\:", clim - cp, cp); 440 cp = clim + 1; 441 } 442 (void) printf("%s:%s:%s\n", cp, zent->zuuid, zent->zbrand); 443 return; 444 } 445 if (zent->zstate_str != NULL) { 446 if (zent->zid == ZONE_ID_UNDEFINED) 447 (void) printf("%*s", ZONEID_WIDTH, "-"); 448 else 449 (void) printf("%*lu", ZONEID_WIDTH, zent->zid); 450 (void) printf(" %-16s %-14s %-30s %-10s\n", zent->zname, 451 zent->zstate_str, zent->zroot, zent->zbrand); 452 } 453 } 454 455 static int 456 lookup_zone_info(const char *zone_name, zoneid_t zid, zone_entry_t *zent) 457 { 458 char root[MAXPATHLEN], *cp; 459 int err; 460 uuid_t uuid; 461 462 (void) strlcpy(zent->zname, zone_name, sizeof (zent->zname)); 463 (void) strlcpy(zent->zroot, "???", sizeof (zent->zroot)); 464 (void) strlcpy(zent->zbrand, "???", sizeof (zent->zbrand)); 465 zent->zstate_str = "???"; 466 467 zent->zid = zid; 468 469 if (zonecfg_get_uuid(zone_name, uuid) == Z_OK && 470 !uuid_is_null(uuid)) 471 uuid_unparse(uuid, zent->zuuid); 472 else 473 zent->zuuid[0] = '\0'; 474 475 /* 476 * For labeled zones which query the zone path of lower-level 477 * zones, the path needs to be adjusted to drop the final 478 * "/root" component. This adjusted path is then useful 479 * for reading down any exported directories from the 480 * lower-level zone. 481 */ 482 if (is_system_labeled() && zent->zid != ZONE_ID_UNDEFINED) { 483 if (zone_getattr(zent->zid, ZONE_ATTR_ROOT, zent->zroot, 484 sizeof (zent->zroot)) == -1) { 485 zperror2(zent->zname, 486 gettext("could not get zone path.")); 487 return (Z_ERR); 488 } 489 cp = zent->zroot + strlen(zent->zroot) - 5; 490 if (cp > zent->zroot && strcmp(cp, "/root") == 0) 491 *cp = 0; 492 } else { 493 if ((err = zone_get_zonepath(zent->zname, root, 494 sizeof (root))) != Z_OK) { 495 errno = err; 496 zperror2(zent->zname, 497 gettext("could not get zone path.")); 498 return (Z_ERR); 499 } 500 (void) strlcpy(zent->zroot, root, sizeof (zent->zroot)); 501 } 502 503 if ((err = zone_get_state(zent->zname, &zent->zstate_num)) != Z_OK) { 504 errno = err; 505 zperror2(zent->zname, gettext("could not get state")); 506 return (Z_ERR); 507 } 508 zent->zstate_str = zone_state_str(zent->zstate_num); 509 510 /* 511 * A zone's brand is only available in the .xml file describing it, 512 * which is only visible to the global zone. This causes 513 * zone_get_brand() to fail when called from within a non-global 514 * zone. Fortunately we only do this on labeled systems, where we 515 * know all zones are native. 516 */ 517 if (getzoneid() != GLOBAL_ZONEID) { 518 assert(is_system_labeled() != 0); 519 (void) strlcpy(zent->zbrand, NATIVE_BRAND_NAME, 520 sizeof (zent->zbrand)); 521 } else if (zone_get_brand(zent->zname, zent->zbrand, 522 sizeof (zent->zbrand)) != Z_OK) { 523 zperror2(zent->zname, gettext("could not get brand name")); 524 return (Z_ERR); 525 } 526 527 return (Z_OK); 528 } 529 530 /* 531 * fetch_zents() calls zone_list(2) to find out how many zones are running 532 * (which is stored in the global nzents), then calls zone_list(2) again 533 * to fetch the list of running zones (stored in the global zents). This 534 * function may be called multiple times, so if zents is already set, we 535 * return immediately to save work. 536 */ 537 538 static int 539 fetch_zents(void) 540 { 541 zoneid_t *zids = NULL; 542 uint_t nzents_saved; 543 int i, retv; 544 FILE *fp; 545 boolean_t inaltroot; 546 zone_entry_t *zentp; 547 548 if (nzents > 0) 549 return (Z_OK); 550 551 if (zone_list(NULL, &nzents) != 0) { 552 zperror(gettext("failed to get zoneid list"), B_FALSE); 553 return (Z_ERR); 554 } 555 556 again: 557 if (nzents == 0) 558 return (Z_OK); 559 560 zids = safe_calloc(nzents, sizeof (zoneid_t)); 561 nzents_saved = nzents; 562 563 if (zone_list(zids, &nzents) != 0) { 564 zperror(gettext("failed to get zone list"), B_FALSE); 565 free(zids); 566 return (Z_ERR); 567 } 568 if (nzents != nzents_saved) { 569 /* list changed, try again */ 570 free(zids); 571 goto again; 572 } 573 574 zents = safe_calloc(nzents, sizeof (zone_entry_t)); 575 576 inaltroot = zonecfg_in_alt_root(); 577 if (inaltroot) 578 fp = zonecfg_open_scratch("", B_FALSE); 579 else 580 fp = NULL; 581 zentp = zents; 582 retv = Z_OK; 583 for (i = 0; i < nzents; i++) { 584 char name[ZONENAME_MAX]; 585 char altname[ZONENAME_MAX]; 586 587 if (getzonenamebyid(zids[i], name, sizeof (name)) < 0) { 588 zperror(gettext("failed to get zone name"), B_FALSE); 589 retv = Z_ERR; 590 continue; 591 } 592 if (zonecfg_is_scratch(name)) { 593 /* Ignore scratch zones by default */ 594 if (!inaltroot) 595 continue; 596 if (fp == NULL || 597 zonecfg_reverse_scratch(fp, name, altname, 598 sizeof (altname), NULL, 0) == -1) { 599 zerror(gettext("could not resolve scratch " 600 "zone %s"), name); 601 retv = Z_ERR; 602 continue; 603 } 604 (void) strcpy(name, altname); 605 } else { 606 /* Ignore non-scratch when in an alternate root */ 607 if (inaltroot && strcmp(name, GLOBAL_ZONENAME) != 0) 608 continue; 609 } 610 if (lookup_zone_info(name, zids[i], zentp) != Z_OK) { 611 zerror(gettext("failed to get zone data")); 612 retv = Z_ERR; 613 continue; 614 } 615 zentp++; 616 } 617 nzents = zentp - zents; 618 if (fp != NULL) 619 zonecfg_close_scratch(fp); 620 621 free(zids); 622 return (retv); 623 } 624 625 static int 626 zone_print_list(zone_state_t min_state, boolean_t verbose, boolean_t parsable) 627 { 628 int i; 629 zone_entry_t zent; 630 FILE *cookie; 631 char *name; 632 633 /* 634 * First get the list of running zones from the kernel and print them. 635 * If that is all we need, then return. 636 */ 637 if ((i = fetch_zents()) != Z_OK) { 638 /* 639 * No need for error messages; fetch_zents() has already taken 640 * care of this. 641 */ 642 return (i); 643 } 644 for (i = 0; i < nzents; i++) 645 zone_print(&zents[i], verbose, parsable); 646 if (min_state >= ZONE_STATE_RUNNING) 647 return (Z_OK); 648 /* 649 * Next, get the full list of zones from the configuration, skipping 650 * any we have already printed. 651 */ 652 cookie = setzoneent(); 653 while ((name = getzoneent(cookie)) != NULL) { 654 for (i = 0; i < nzents; i++) { 655 if (strcmp(zents[i].zname, name) == 0) 656 break; 657 } 658 if (i < nzents) { 659 free(name); 660 continue; 661 } 662 if (lookup_zone_info(name, ZONE_ID_UNDEFINED, &zent) != Z_OK) { 663 free(name); 664 continue; 665 } 666 free(name); 667 if (zent.zstate_num >= min_state) 668 zone_print(&zent, verbose, parsable); 669 } 670 endzoneent(cookie); 671 return (Z_OK); 672 } 673 674 static zone_entry_t * 675 lookup_running_zone(char *str) 676 { 677 zoneid_t zoneid; 678 char *cp; 679 int i; 680 681 if (fetch_zents() != Z_OK) 682 return (NULL); 683 684 for (i = 0; i < nzents; i++) { 685 if (strcmp(str, zents[i].zname) == 0) 686 return (&zents[i]); 687 } 688 errno = 0; 689 zoneid = strtol(str, &cp, 0); 690 if (zoneid < MIN_ZONEID || zoneid > MAX_ZONEID || 691 errno != 0 || *cp != '\0') 692 return (NULL); 693 for (i = 0; i < nzents; i++) { 694 if (zoneid == zents[i].zid) 695 return (&zents[i]); 696 } 697 return (NULL); 698 } 699 700 /* 701 * Check a bit in a mode_t: if on is B_TRUE, that bit should be on; if 702 * B_FALSE, it should be off. Return B_TRUE if the mode is bad (incorrect). 703 */ 704 static boolean_t 705 bad_mode_bit(mode_t mode, mode_t bit, boolean_t on, char *file) 706 { 707 char *str; 708 709 assert(bit == S_IRUSR || bit == S_IWUSR || bit == S_IXUSR || 710 bit == S_IRGRP || bit == S_IWGRP || bit == S_IXGRP || 711 bit == S_IROTH || bit == S_IWOTH || bit == S_IXOTH); 712 /* 713 * TRANSLATION_NOTE 714 * The strings below will be used as part of a larger message, 715 * either: 716 * (file name) must be (owner|group|world) (read|writ|execut)able 717 * or 718 * (file name) must not be (owner|group|world) (read|writ|execut)able 719 */ 720 switch (bit) { 721 case S_IRUSR: 722 str = gettext("owner readable"); 723 break; 724 case S_IWUSR: 725 str = gettext("owner writable"); 726 break; 727 case S_IXUSR: 728 str = gettext("owner executable"); 729 break; 730 case S_IRGRP: 731 str = gettext("group readable"); 732 break; 733 case S_IWGRP: 734 str = gettext("group writable"); 735 break; 736 case S_IXGRP: 737 str = gettext("group executable"); 738 break; 739 case S_IROTH: 740 str = gettext("world readable"); 741 break; 742 case S_IWOTH: 743 str = gettext("world writable"); 744 break; 745 case S_IXOTH: 746 str = gettext("world executable"); 747 break; 748 } 749 if ((mode & bit) == (on ? 0 : bit)) { 750 /* 751 * TRANSLATION_NOTE 752 * The first parameter below is a file name; the second 753 * is one of the "(owner|group|world) (read|writ|execut)able" 754 * strings from above. 755 */ 756 /* 757 * The code below could be simplified but not in a way 758 * that would easily translate to non-English locales. 759 */ 760 if (on) { 761 (void) fprintf(stderr, gettext("%s must be %s.\n"), 762 file, str); 763 } else { 764 (void) fprintf(stderr, gettext("%s must not be %s.\n"), 765 file, str); 766 } 767 return (B_TRUE); 768 } 769 return (B_FALSE); 770 } 771 772 /* 773 * We want to make sure that no zone has its zone path as a child node 774 * (in the directory sense) of any other. We do that by comparing this 775 * zone's path to the path of all other (non-global) zones. The comparison 776 * in each case is simple: add '/' to the end of the path, then do a 777 * strncmp() of the two paths, using the length of the shorter one. 778 */ 779 780 static int 781 crosscheck_zonepaths(char *path) 782 { 783 char rpath[MAXPATHLEN]; /* resolved path */ 784 char path_copy[MAXPATHLEN]; /* copy of original path */ 785 char rpath_copy[MAXPATHLEN]; /* copy of original rpath */ 786 struct zoneent *ze; 787 int res, err; 788 FILE *cookie; 789 790 cookie = setzoneent(); 791 while ((ze = getzoneent_private(cookie)) != NULL) { 792 /* Skip zones which are not installed. */ 793 if (ze->zone_state < ZONE_STATE_INSTALLED) { 794 free(ze); 795 continue; 796 } 797 /* Skip the global zone and the current target zone. */ 798 if (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0 || 799 strcmp(ze->zone_name, target_zone) == 0) { 800 free(ze); 801 continue; 802 } 803 if (strlen(ze->zone_path) == 0) { 804 /* old index file without path, fall back */ 805 if ((err = zone_get_zonepath(ze->zone_name, 806 ze->zone_path, sizeof (ze->zone_path))) != Z_OK) { 807 errno = err; 808 zperror2(ze->zone_name, 809 gettext("could not get zone path")); 810 free(ze); 811 continue; 812 } 813 } 814 (void) snprintf(path_copy, sizeof (path_copy), "%s%s", 815 zonecfg_get_root(), ze->zone_path); 816 res = resolvepath(path_copy, rpath, sizeof (rpath)); 817 if (res == -1) { 818 if (errno != ENOENT) { 819 zperror(path_copy, B_FALSE); 820 free(ze); 821 return (Z_ERR); 822 } 823 (void) printf(gettext("WARNING: zone %s is installed, " 824 "but its %s %s does not exist.\n"), ze->zone_name, 825 "zonepath", path_copy); 826 free(ze); 827 continue; 828 } 829 rpath[res] = '\0'; 830 (void) snprintf(path_copy, sizeof (path_copy), "%s/", path); 831 (void) snprintf(rpath_copy, sizeof (rpath_copy), "%s/", rpath); 832 if (strncmp(path_copy, rpath_copy, 833 min(strlen(path_copy), strlen(rpath_copy))) == 0) { 834 /* 835 * TRANSLATION_NOTE 836 * zonepath is a literal that should not be translated. 837 */ 838 (void) fprintf(stderr, gettext("%s zonepath (%s) and " 839 "%s zonepath (%s) overlap.\n"), 840 target_zone, path, ze->zone_name, rpath); 841 free(ze); 842 return (Z_ERR); 843 } 844 free(ze); 845 } 846 endzoneent(cookie); 847 return (Z_OK); 848 } 849 850 static int 851 validate_zonepath(char *path, int cmd_num) 852 { 853 int res; /* result of last library/system call */ 854 boolean_t err = B_FALSE; /* have we run into an error? */ 855 struct stat stbuf; 856 struct statvfs64 vfsbuf; 857 char rpath[MAXPATHLEN]; /* resolved path */ 858 char ppath[MAXPATHLEN]; /* parent path */ 859 char rppath[MAXPATHLEN]; /* resolved parent path */ 860 char rootpath[MAXPATHLEN]; /* root path */ 861 zone_state_t state; 862 863 if (path[0] != '/') { 864 (void) fprintf(stderr, 865 gettext("%s is not an absolute path.\n"), path); 866 return (Z_ERR); 867 } 868 if ((res = resolvepath(path, rpath, sizeof (rpath))) == -1) { 869 if ((errno != ENOENT) || 870 (cmd_num != CMD_VERIFY && cmd_num != CMD_INSTALL && 871 cmd_num != CMD_CLONE && cmd_num != CMD_MOVE)) { 872 zperror(path, B_FALSE); 873 return (Z_ERR); 874 } 875 if (cmd_num == CMD_VERIFY) { 876 /* 877 * TRANSLATION_NOTE 878 * zoneadm is a literal that should not be translated. 879 */ 880 (void) fprintf(stderr, gettext("WARNING: %s does not " 881 "exist, so it could not be verified.\nWhen " 882 "'zoneadm %s' is run, '%s' will try to create\n%s, " 883 "and '%s' will be tried again,\nbut the '%s' may " 884 "fail if:\nthe parent directory of %s is group- or " 885 "other-writable\nor\n%s overlaps with any other " 886 "installed zones.\n"), path, 887 cmd_to_str(CMD_INSTALL), cmd_to_str(CMD_INSTALL), 888 path, cmd_to_str(CMD_VERIFY), 889 cmd_to_str(CMD_VERIFY), path, path); 890 return (Z_OK); 891 } 892 /* 893 * The zonepath is supposed to be mode 700 but its 894 * parent(s) 755. So use 755 on the mkdirp() then 895 * chmod() the zonepath itself to 700. 896 */ 897 if (mkdirp(path, DEFAULT_DIR_MODE) < 0) { 898 zperror(path, B_FALSE); 899 return (Z_ERR); 900 } 901 /* 902 * If the chmod() fails, report the error, but might 903 * as well continue the verify procedure. 904 */ 905 if (chmod(path, S_IRWXU) != 0) 906 zperror(path, B_FALSE); 907 /* 908 * Since the mkdir() succeeded, we should not have to 909 * worry about a subsequent ENOENT, thus this should 910 * only recurse once. 911 */ 912 return (validate_zonepath(path, cmd_num)); 913 } 914 rpath[res] = '\0'; 915 if (strcmp(path, rpath) != 0) { 916 errno = Z_RESOLVED_PATH; 917 zperror(path, B_TRUE); 918 return (Z_ERR); 919 } 920 if ((res = stat(rpath, &stbuf)) != 0) { 921 zperror(rpath, B_FALSE); 922 return (Z_ERR); 923 } 924 if (!S_ISDIR(stbuf.st_mode)) { 925 (void) fprintf(stderr, gettext("%s is not a directory.\n"), 926 rpath); 927 return (Z_ERR); 928 } 929 if ((strcmp(stbuf.st_fstype, MNTTYPE_TMPFS) == 0) || 930 (strcmp(stbuf.st_fstype, MNTTYPE_XMEMFS) == 0)) { 931 (void) printf(gettext("WARNING: %s is on a temporary " 932 "file system.\n"), rpath); 933 } 934 if (crosscheck_zonepaths(rpath) != Z_OK) 935 return (Z_ERR); 936 /* 937 * Try to collect and report as many minor errors as possible 938 * before returning, so the user can learn everything that needs 939 * to be fixed up front. 940 */ 941 if (stbuf.st_uid != 0) { 942 (void) fprintf(stderr, gettext("%s is not owned by root.\n"), 943 rpath); 944 err = B_TRUE; 945 } 946 err |= bad_mode_bit(stbuf.st_mode, S_IRUSR, B_TRUE, rpath); 947 err |= bad_mode_bit(stbuf.st_mode, S_IWUSR, B_TRUE, rpath); 948 err |= bad_mode_bit(stbuf.st_mode, S_IXUSR, B_TRUE, rpath); 949 err |= bad_mode_bit(stbuf.st_mode, S_IRGRP, B_FALSE, rpath); 950 err |= bad_mode_bit(stbuf.st_mode, S_IWGRP, B_FALSE, rpath); 951 err |= bad_mode_bit(stbuf.st_mode, S_IXGRP, B_FALSE, rpath); 952 err |= bad_mode_bit(stbuf.st_mode, S_IROTH, B_FALSE, rpath); 953 err |= bad_mode_bit(stbuf.st_mode, S_IWOTH, B_FALSE, rpath); 954 err |= bad_mode_bit(stbuf.st_mode, S_IXOTH, B_FALSE, rpath); 955 956 (void) snprintf(ppath, sizeof (ppath), "%s/..", path); 957 if ((res = resolvepath(ppath, rppath, sizeof (rppath))) == -1) { 958 zperror(ppath, B_FALSE); 959 return (Z_ERR); 960 } 961 rppath[res] = '\0'; 962 if ((res = stat(rppath, &stbuf)) != 0) { 963 zperror(rppath, B_FALSE); 964 return (Z_ERR); 965 } 966 /* theoretically impossible */ 967 if (!S_ISDIR(stbuf.st_mode)) { 968 (void) fprintf(stderr, gettext("%s is not a directory.\n"), 969 rppath); 970 return (Z_ERR); 971 } 972 if (stbuf.st_uid != 0) { 973 (void) fprintf(stderr, gettext("%s is not owned by root.\n"), 974 rppath); 975 err = B_TRUE; 976 } 977 err |= bad_mode_bit(stbuf.st_mode, S_IRUSR, B_TRUE, rppath); 978 err |= bad_mode_bit(stbuf.st_mode, S_IWUSR, B_TRUE, rppath); 979 err |= bad_mode_bit(stbuf.st_mode, S_IXUSR, B_TRUE, rppath); 980 err |= bad_mode_bit(stbuf.st_mode, S_IWGRP, B_FALSE, rppath); 981 err |= bad_mode_bit(stbuf.st_mode, S_IWOTH, B_FALSE, rppath); 982 if (strcmp(rpath, rppath) == 0) { 983 (void) fprintf(stderr, gettext("%s is its own parent.\n"), 984 rppath); 985 err = B_TRUE; 986 } 987 988 if (statvfs64(rpath, &vfsbuf) != 0) { 989 zperror(rpath, B_FALSE); 990 return (Z_ERR); 991 } 992 if (strcmp(vfsbuf.f_basetype, MNTTYPE_NFS) == 0) { 993 /* 994 * TRANSLATION_NOTE 995 * Zonepath and NFS are literals that should not be translated. 996 */ 997 (void) fprintf(stderr, gettext("Zonepath %s is on an NFS " 998 "mounted file system.\n" 999 "\tA local file system must be used.\n"), rpath); 1000 return (Z_ERR); 1001 } 1002 if (vfsbuf.f_flag & ST_NOSUID) { 1003 /* 1004 * TRANSLATION_NOTE 1005 * Zonepath and nosuid are literals that should not be 1006 * translated. 1007 */ 1008 (void) fprintf(stderr, gettext("Zonepath %s is on a nosuid " 1009 "file system.\n"), rpath); 1010 return (Z_ERR); 1011 } 1012 1013 if ((res = zone_get_state(target_zone, &state)) != Z_OK) { 1014 errno = res; 1015 zperror2(target_zone, gettext("could not get state")); 1016 return (Z_ERR); 1017 } 1018 /* 1019 * The existence of the root path is only bad in the configured state, 1020 * as it is *supposed* to be there at the installed and later states. 1021 * However, the root path is expected to be there if the zone is 1022 * detached. 1023 * State/command mismatches are caught earlier in verify_details(). 1024 */ 1025 if (state == ZONE_STATE_CONFIGURED && cmd_num != CMD_ATTACH) { 1026 if (snprintf(rootpath, sizeof (rootpath), "%s/root", rpath) >= 1027 sizeof (rootpath)) { 1028 /* 1029 * TRANSLATION_NOTE 1030 * Zonepath is a literal that should not be translated. 1031 */ 1032 (void) fprintf(stderr, 1033 gettext("Zonepath %s is too long.\n"), rpath); 1034 return (Z_ERR); 1035 } 1036 if ((res = stat(rootpath, &stbuf)) == 0) { 1037 if (zonecfg_detached(rpath)) 1038 (void) fprintf(stderr, 1039 gettext("Cannot %s detached " 1040 "zone.\nUse attach or remove %s " 1041 "directory.\n"), cmd_to_str(cmd_num), 1042 rpath); 1043 else 1044 (void) fprintf(stderr, 1045 gettext("Rootpath %s exists; " 1046 "remove or move aside prior to %s.\n"), 1047 rootpath, cmd_to_str(cmd_num)); 1048 return (Z_ERR); 1049 } 1050 } 1051 1052 return (err ? Z_ERR : Z_OK); 1053 } 1054 1055 /* 1056 * The following two routines implement a simple locking mechanism to 1057 * ensure that only one instance of zoneadm at a time is able to manipulate 1058 * a given zone. The lock is built on top of an fcntl(2) lock of 1059 * [<altroot>]/var/run/zones/<zonename>.zoneadm.lock. If a zoneadm instance 1060 * can grab that lock, it is allowed to manipulate the zone. 1061 * 1062 * Since zoneadm may call external applications which in turn invoke 1063 * zoneadm again, we introduce the notion of "lock inheritance". Any 1064 * instance of zoneadm that has another instance in its ancestry is assumed 1065 * to be acting on behalf of the original zoneadm, and is thus allowed to 1066 * manipulate its zone. 1067 * 1068 * This inheritance is implemented via the _ZONEADM_LOCK_HELD environment 1069 * variable. When zoneadm is granted a lock on its zone, this environment 1070 * variable is set to 1. When it releases the lock, the variable is set to 1071 * 0. Since a child process inherits its parent's environment, checking 1072 * the state of this variable indicates whether or not any ancestor owns 1073 * the lock. 1074 */ 1075 static void 1076 release_lock_file(int lockfd) 1077 { 1078 /* 1079 * If we are cleaning up from a failed attempt to lock the zone for 1080 * the first time, we might have a zone_lock_cnt of 0. In that 1081 * error case, we don't want to do anything but close the lock 1082 * file. 1083 */ 1084 assert(zone_lock_cnt >= 0); 1085 if (zone_lock_cnt > 0) { 1086 assert(getenv(LOCK_ENV_VAR) != NULL); 1087 assert(atoi(getenv(LOCK_ENV_VAR)) == 1); 1088 if (--zone_lock_cnt > 0) { 1089 assert(lockfd == -1); 1090 return; 1091 } 1092 if (putenv(zoneadm_lock_not_held) != 0) { 1093 zperror(target_zone, B_TRUE); 1094 exit(Z_ERR); 1095 } 1096 } 1097 assert(lockfd >= 0); 1098 (void) close(lockfd); 1099 } 1100 1101 static int 1102 grab_lock_file(const char *zone_name, int *lockfd) 1103 { 1104 char pathbuf[PATH_MAX]; 1105 struct flock flock; 1106 1107 /* 1108 * If we already have the lock, we can skip this expensive song 1109 * and dance. 1110 */ 1111 if (zone_lock_cnt > 0) { 1112 zone_lock_cnt++; 1113 *lockfd = -1; 1114 return (Z_OK); 1115 } 1116 assert(getenv(LOCK_ENV_VAR) != NULL); 1117 assert(atoi(getenv(LOCK_ENV_VAR)) == 0); 1118 1119 if (snprintf(pathbuf, sizeof (pathbuf), "%s%s", zonecfg_get_root(), 1120 ZONES_TMPDIR) >= sizeof (pathbuf)) { 1121 zerror(gettext("alternate root path is too long")); 1122 return (Z_ERR); 1123 } 1124 if (mkdir(pathbuf, S_IRWXU) < 0 && errno != EEXIST) { 1125 zerror(gettext("could not mkdir %s: %s"), pathbuf, 1126 strerror(errno)); 1127 return (Z_ERR); 1128 } 1129 (void) chmod(pathbuf, S_IRWXU); 1130 1131 /* 1132 * One of these lock files is created for each zone (when needed). 1133 * The lock files are not cleaned up (except on system reboot), 1134 * but since there is only one per zone, there is no resource 1135 * starvation issue. 1136 */ 1137 if (snprintf(pathbuf, sizeof (pathbuf), "%s%s/%s.zoneadm.lock", 1138 zonecfg_get_root(), ZONES_TMPDIR, zone_name) >= sizeof (pathbuf)) { 1139 zerror(gettext("alternate root path is too long")); 1140 return (Z_ERR); 1141 } 1142 if ((*lockfd = open(pathbuf, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) { 1143 zerror(gettext("could not open %s: %s"), pathbuf, 1144 strerror(errno)); 1145 return (Z_ERR); 1146 } 1147 /* 1148 * Lock the file to synchronize with other zoneadmds 1149 */ 1150 flock.l_type = F_WRLCK; 1151 flock.l_whence = SEEK_SET; 1152 flock.l_start = (off_t)0; 1153 flock.l_len = (off_t)0; 1154 if ((fcntl(*lockfd, F_SETLKW, &flock) < 0) || 1155 (putenv(zoneadm_lock_held) != 0)) { 1156 zerror(gettext("unable to lock %s: %s"), pathbuf, 1157 strerror(errno)); 1158 release_lock_file(*lockfd); 1159 return (Z_ERR); 1160 } 1161 zone_lock_cnt = 1; 1162 return (Z_OK); 1163 } 1164 1165 static boolean_t 1166 get_doorname(const char *zone_name, char *buffer) 1167 { 1168 return (snprintf(buffer, PATH_MAX, "%s" ZONE_DOOR_PATH, 1169 zonecfg_get_root(), zone_name) < PATH_MAX); 1170 } 1171 1172 /* 1173 * system daemons are not audited. For the global zone, this occurs 1174 * "naturally" since init is started with the default audit 1175 * characteristics. Since zoneadmd is a system daemon and it starts 1176 * init for a zone, it is necessary to clear out the audit 1177 * characteristics inherited from whomever started zoneadmd. This is 1178 * indicated by the audit id, which is set from the ruid parameter of 1179 * adt_set_user(), below. 1180 */ 1181 1182 static void 1183 prepare_audit_context() 1184 { 1185 adt_session_data_t *ah; 1186 char *failure = gettext("audit failure: %s"); 1187 1188 if (adt_start_session(&ah, NULL, 0)) { 1189 zerror(failure, strerror(errno)); 1190 return; 1191 } 1192 if (adt_set_user(ah, ADT_NO_AUDIT, ADT_NO_AUDIT, 1193 ADT_NO_AUDIT, ADT_NO_AUDIT, NULL, ADT_NEW)) { 1194 zerror(failure, strerror(errno)); 1195 (void) adt_end_session(ah); 1196 return; 1197 } 1198 if (adt_set_proc(ah)) 1199 zerror(failure, strerror(errno)); 1200 1201 (void) adt_end_session(ah); 1202 } 1203 1204 static int 1205 start_zoneadmd(const char *zone_name) 1206 { 1207 char doorpath[PATH_MAX]; 1208 pid_t child_pid; 1209 int error = Z_ERR; 1210 int doorfd, lockfd; 1211 struct door_info info; 1212 1213 if (!get_doorname(zone_name, doorpath)) 1214 return (Z_ERR); 1215 1216 if (grab_lock_file(zone_name, &lockfd) != Z_OK) 1217 return (Z_ERR); 1218 1219 /* 1220 * Now that we have the lock, re-confirm that the daemon is 1221 * *not* up and working fine. If it is still down, we have a green 1222 * light to start it. 1223 */ 1224 if ((doorfd = open(doorpath, O_RDONLY)) < 0) { 1225 if (errno != ENOENT) { 1226 zperror(doorpath, B_FALSE); 1227 goto out; 1228 } 1229 } else { 1230 if (door_info(doorfd, &info) == 0 && 1231 ((info.di_attributes & DOOR_REVOKED) == 0)) { 1232 error = Z_OK; 1233 (void) close(doorfd); 1234 goto out; 1235 } 1236 (void) close(doorfd); 1237 } 1238 1239 if ((child_pid = fork()) == -1) { 1240 zperror(gettext("could not fork"), B_FALSE); 1241 goto out; 1242 } else if (child_pid == 0) { 1243 const char *argv[6], **ap; 1244 1245 /* child process */ 1246 prepare_audit_context(); 1247 1248 ap = argv; 1249 *ap++ = "zoneadmd"; 1250 *ap++ = "-z"; 1251 *ap++ = zone_name; 1252 if (zonecfg_in_alt_root()) { 1253 *ap++ = "-R"; 1254 *ap++ = zonecfg_get_root(); 1255 } 1256 *ap = NULL; 1257 1258 (void) execv("/usr/lib/zones/zoneadmd", (char * const *)argv); 1259 /* 1260 * TRANSLATION_NOTE 1261 * zoneadmd is a literal that should not be translated. 1262 */ 1263 zperror(gettext("could not exec zoneadmd"), B_FALSE); 1264 _exit(Z_ERR); 1265 } else { 1266 /* parent process */ 1267 pid_t retval; 1268 int pstatus = 0; 1269 1270 do { 1271 retval = waitpid(child_pid, &pstatus, 0); 1272 } while (retval != child_pid); 1273 if (WIFSIGNALED(pstatus) || (WIFEXITED(pstatus) && 1274 WEXITSTATUS(pstatus) != 0)) { 1275 zerror(gettext("could not start %s"), "zoneadmd"); 1276 goto out; 1277 } 1278 } 1279 error = Z_OK; 1280 out: 1281 release_lock_file(lockfd); 1282 return (error); 1283 } 1284 1285 static int 1286 ping_zoneadmd(const char *zone_name) 1287 { 1288 char doorpath[PATH_MAX]; 1289 int doorfd; 1290 struct door_info info; 1291 1292 if (!get_doorname(zone_name, doorpath)) 1293 return (Z_ERR); 1294 1295 if ((doorfd = open(doorpath, O_RDONLY)) < 0) { 1296 return (Z_ERR); 1297 } 1298 if (door_info(doorfd, &info) == 0 && 1299 ((info.di_attributes & DOOR_REVOKED) == 0)) { 1300 (void) close(doorfd); 1301 return (Z_OK); 1302 } 1303 (void) close(doorfd); 1304 return (Z_ERR); 1305 } 1306 1307 static int 1308 call_zoneadmd(const char *zone_name, zone_cmd_arg_t *arg) 1309 { 1310 char doorpath[PATH_MAX]; 1311 int doorfd, result; 1312 door_arg_t darg; 1313 1314 zoneid_t zoneid; 1315 uint64_t uniqid = 0; 1316 1317 zone_cmd_rval_t *rvalp; 1318 size_t rlen; 1319 char *cp, *errbuf; 1320 1321 rlen = getpagesize(); 1322 if ((rvalp = malloc(rlen)) == NULL) { 1323 zerror(gettext("failed to allocate %lu bytes: %s"), rlen, 1324 strerror(errno)); 1325 return (-1); 1326 } 1327 1328 if ((zoneid = getzoneidbyname(zone_name)) != ZONE_ID_UNDEFINED) { 1329 (void) zone_getattr(zoneid, ZONE_ATTR_UNIQID, &uniqid, 1330 sizeof (uniqid)); 1331 } 1332 arg->uniqid = uniqid; 1333 (void) strlcpy(arg->locale, locale, sizeof (arg->locale)); 1334 if (!get_doorname(zone_name, doorpath)) { 1335 zerror(gettext("alternate root path is too long")); 1336 free(rvalp); 1337 return (-1); 1338 } 1339 1340 /* 1341 * Loop trying to start zoneadmd; if something goes seriously 1342 * wrong we break out and fail. 1343 */ 1344 for (;;) { 1345 if (start_zoneadmd(zone_name) != Z_OK) 1346 break; 1347 1348 if ((doorfd = open(doorpath, O_RDONLY)) < 0) { 1349 zperror(gettext("failed to open zone door"), B_FALSE); 1350 break; 1351 } 1352 1353 darg.data_ptr = (char *)arg; 1354 darg.data_size = sizeof (*arg); 1355 darg.desc_ptr = NULL; 1356 darg.desc_num = 0; 1357 darg.rbuf = (char *)rvalp; 1358 darg.rsize = rlen; 1359 if (door_call(doorfd, &darg) != 0) { 1360 (void) close(doorfd); 1361 /* 1362 * We'll get EBADF if the door has been revoked. 1363 */ 1364 if (errno != EBADF) { 1365 zperror(gettext("door_call failed"), B_FALSE); 1366 break; 1367 } 1368 continue; /* take another lap */ 1369 } 1370 (void) close(doorfd); 1371 1372 if (darg.data_size == 0) { 1373 /* Door server is going away; kick it again. */ 1374 continue; 1375 } 1376 1377 errbuf = rvalp->errbuf; 1378 while (*errbuf != '\0') { 1379 /* 1380 * Remove any newlines since zerror() 1381 * will append one automatically. 1382 */ 1383 cp = strchr(errbuf, '\n'); 1384 if (cp != NULL) 1385 *cp = '\0'; 1386 zerror("%s", errbuf); 1387 if (cp == NULL) 1388 break; 1389 errbuf = cp + 1; 1390 } 1391 result = rvalp->rval == 0 ? 0 : -1; 1392 free(rvalp); 1393 return (result); 1394 } 1395 1396 free(rvalp); 1397 return (-1); 1398 } 1399 1400 static int 1401 invoke_brand_handler(int cmd_num, char *argv[]) 1402 { 1403 zone_dochandle_t handle; 1404 int err; 1405 1406 if ((handle = zonecfg_init_handle()) == NULL) { 1407 zperror(cmd_to_str(cmd_num), B_TRUE); 1408 return (Z_ERR); 1409 } 1410 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 1411 errno = err; 1412 zperror(cmd_to_str(cmd_num), B_TRUE); 1413 zonecfg_fini_handle(handle); 1414 return (Z_ERR); 1415 } 1416 if (verify_brand(handle, cmd_num, argv) != Z_OK) { 1417 zonecfg_fini_handle(handle); 1418 return (Z_ERR); 1419 } 1420 zonecfg_fini_handle(handle); 1421 return (Z_OK); 1422 } 1423 1424 static int 1425 ready_func(int argc, char *argv[]) 1426 { 1427 zone_cmd_arg_t zarg; 1428 int arg; 1429 1430 if (zonecfg_in_alt_root()) { 1431 zerror(gettext("cannot ready zone in alternate root")); 1432 return (Z_ERR); 1433 } 1434 1435 optind = 0; 1436 if ((arg = getopt(argc, argv, "?")) != EOF) { 1437 switch (arg) { 1438 case '?': 1439 sub_usage(SHELP_READY, CMD_READY); 1440 return (optopt == '?' ? Z_OK : Z_USAGE); 1441 default: 1442 sub_usage(SHELP_READY, CMD_READY); 1443 return (Z_USAGE); 1444 } 1445 } 1446 if (argc > optind) { 1447 sub_usage(SHELP_READY, CMD_READY); 1448 return (Z_USAGE); 1449 } 1450 if (sanity_check(target_zone, CMD_READY, B_FALSE, B_FALSE, B_FALSE) 1451 != Z_OK) 1452 return (Z_ERR); 1453 if (verify_details(CMD_READY, argv) != Z_OK) 1454 return (Z_ERR); 1455 1456 zarg.cmd = Z_READY; 1457 if (call_zoneadmd(target_zone, &zarg) != 0) { 1458 zerror(gettext("call to %s failed"), "zoneadmd"); 1459 return (Z_ERR); 1460 } 1461 return (Z_OK); 1462 } 1463 1464 static int 1465 boot_func(int argc, char *argv[]) 1466 { 1467 zone_cmd_arg_t zarg; 1468 boolean_t force = B_FALSE; 1469 int arg; 1470 1471 if (zonecfg_in_alt_root()) { 1472 zerror(gettext("cannot boot zone in alternate root")); 1473 return (Z_ERR); 1474 } 1475 1476 zarg.bootbuf[0] = '\0'; 1477 1478 /* 1479 * The following getopt processes arguments to zone boot; that 1480 * is to say, the [here] portion of the argument string: 1481 * 1482 * zoneadm -z myzone boot [here] -- -v -m verbose 1483 * 1484 * Where [here] can either be nothing, -? (in which case we bail 1485 * and print usage), -f (a private option to indicate that the 1486 * boot operation should be 'forced'), or -s. Support for -s is 1487 * vestigal and obsolete, but is retained because it was a 1488 * documented interface and there are known consumers including 1489 * admin/install; the proper way to specify boot arguments like -s 1490 * is: 1491 * 1492 * zoneadm -z myzone boot -- -s -v -m verbose. 1493 */ 1494 optind = 0; 1495 while ((arg = getopt(argc, argv, "?fs")) != EOF) { 1496 switch (arg) { 1497 case '?': 1498 sub_usage(SHELP_BOOT, CMD_BOOT); 1499 return (optopt == '?' ? Z_OK : Z_USAGE); 1500 case 's': 1501 (void) strlcpy(zarg.bootbuf, "-s", 1502 sizeof (zarg.bootbuf)); 1503 break; 1504 case 'f': 1505 force = B_TRUE; 1506 break; 1507 default: 1508 sub_usage(SHELP_BOOT, CMD_BOOT); 1509 return (Z_USAGE); 1510 } 1511 } 1512 1513 for (; optind < argc; optind++) { 1514 if (strlcat(zarg.bootbuf, argv[optind], 1515 sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) { 1516 zerror(gettext("Boot argument list too long")); 1517 return (Z_ERR); 1518 } 1519 if (optind < argc - 1) 1520 if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >= 1521 sizeof (zarg.bootbuf)) { 1522 zerror(gettext("Boot argument list too long")); 1523 return (Z_ERR); 1524 } 1525 } 1526 if (sanity_check(target_zone, CMD_BOOT, B_FALSE, B_FALSE, force) 1527 != Z_OK) 1528 return (Z_ERR); 1529 if (verify_details(CMD_BOOT, argv) != Z_OK) 1530 return (Z_ERR); 1531 zarg.cmd = force ? Z_FORCEBOOT : Z_BOOT; 1532 if (call_zoneadmd(target_zone, &zarg) != 0) { 1533 zerror(gettext("call to %s failed"), "zoneadmd"); 1534 return (Z_ERR); 1535 } 1536 1537 return (Z_OK); 1538 } 1539 1540 static void 1541 fake_up_local_zone(zoneid_t zid, zone_entry_t *zeptr) 1542 { 1543 ssize_t result; 1544 uuid_t uuid; 1545 FILE *fp; 1546 1547 (void) memset(zeptr, 0, sizeof (*zeptr)); 1548 1549 zeptr->zid = zid; 1550 1551 /* 1552 * Since we're looking up our own (non-global) zone name, 1553 * we can be assured that it will succeed. 1554 */ 1555 result = getzonenamebyid(zid, zeptr->zname, sizeof (zeptr->zname)); 1556 assert(result >= 0); 1557 if (zonecfg_is_scratch(zeptr->zname) && 1558 (fp = zonecfg_open_scratch("", B_FALSE)) != NULL) { 1559 (void) zonecfg_reverse_scratch(fp, zeptr->zname, zeptr->zname, 1560 sizeof (zeptr->zname), NULL, 0); 1561 zonecfg_close_scratch(fp); 1562 } 1563 1564 if (is_system_labeled()) { 1565 (void) zone_getattr(zid, ZONE_ATTR_ROOT, zeptr->zroot, 1566 sizeof (zeptr->zroot)); 1567 (void) strlcpy(zeptr->zbrand, NATIVE_BRAND_NAME, 1568 sizeof (zeptr->zbrand)); 1569 } else { 1570 (void) strlcpy(zeptr->zroot, "/", sizeof (zeptr->zroot)); 1571 (void) zone_getattr(zid, ZONE_ATTR_BRAND, zeptr->zbrand, 1572 sizeof (zeptr->zbrand)); 1573 } 1574 1575 zeptr->zstate_str = "running"; 1576 if (zonecfg_get_uuid(zeptr->zname, uuid) == Z_OK && 1577 !uuid_is_null(uuid)) 1578 uuid_unparse(uuid, zeptr->zuuid); 1579 } 1580 1581 static int 1582 list_func(int argc, char *argv[]) 1583 { 1584 zone_entry_t *zentp, zent; 1585 int arg, retv; 1586 boolean_t output = B_FALSE, verbose = B_FALSE, parsable = B_FALSE; 1587 zone_state_t min_state = ZONE_STATE_RUNNING; 1588 zoneid_t zone_id = getzoneid(); 1589 1590 if (target_zone == NULL) { 1591 /* all zones: default view to running but allow override */ 1592 optind = 0; 1593 while ((arg = getopt(argc, argv, "?cipv")) != EOF) { 1594 switch (arg) { 1595 case '?': 1596 sub_usage(SHELP_LIST, CMD_LIST); 1597 return (optopt == '?' ? Z_OK : Z_USAGE); 1598 /* 1599 * The 'i' and 'c' options are not mutually 1600 * exclusive so if 'c' is given, then min_state 1601 * is set to 0 (ZONE_STATE_CONFIGURED) which is 1602 * the lowest possible state. If 'i' is given, 1603 * then min_state is set to be the lowest state 1604 * so far. 1605 */ 1606 case 'c': 1607 min_state = ZONE_STATE_CONFIGURED; 1608 break; 1609 case 'i': 1610 min_state = min(ZONE_STATE_INSTALLED, 1611 min_state); 1612 1613 break; 1614 case 'p': 1615 parsable = B_TRUE; 1616 break; 1617 case 'v': 1618 verbose = B_TRUE; 1619 break; 1620 default: 1621 sub_usage(SHELP_LIST, CMD_LIST); 1622 return (Z_USAGE); 1623 } 1624 } 1625 if (parsable && verbose) { 1626 zerror(gettext("%s -p and -v are mutually exclusive."), 1627 cmd_to_str(CMD_LIST)); 1628 return (Z_ERR); 1629 } 1630 if (zone_id == GLOBAL_ZONEID || is_system_labeled()) { 1631 retv = zone_print_list(min_state, verbose, parsable); 1632 } else { 1633 fake_up_local_zone(zone_id, &zent); 1634 retv = Z_OK; 1635 zone_print(&zent, verbose, parsable); 1636 } 1637 return (retv); 1638 } 1639 1640 /* 1641 * Specific target zone: disallow -i/-c suboptions. 1642 */ 1643 optind = 0; 1644 while ((arg = getopt(argc, argv, "?pv")) != EOF) { 1645 switch (arg) { 1646 case '?': 1647 sub_usage(SHELP_LIST, CMD_LIST); 1648 return (optopt == '?' ? Z_OK : Z_USAGE); 1649 case 'p': 1650 parsable = B_TRUE; 1651 break; 1652 case 'v': 1653 verbose = B_TRUE; 1654 break; 1655 default: 1656 sub_usage(SHELP_LIST, CMD_LIST); 1657 return (Z_USAGE); 1658 } 1659 } 1660 if (parsable && verbose) { 1661 zerror(gettext("%s -p and -v are mutually exclusive."), 1662 cmd_to_str(CMD_LIST)); 1663 return (Z_ERR); 1664 } 1665 if (argc > optind) { 1666 sub_usage(SHELP_LIST, CMD_LIST); 1667 return (Z_USAGE); 1668 } 1669 if (zone_id != GLOBAL_ZONEID) { 1670 fake_up_local_zone(zone_id, &zent); 1671 /* 1672 * main() will issue a Z_NO_ZONE error if it cannot get an 1673 * id for target_zone, which in a non-global zone should 1674 * happen for any zone name except `zonename`. Thus we 1675 * assert() that here but don't otherwise check. 1676 */ 1677 assert(strcmp(zent.zname, target_zone) == 0); 1678 zone_print(&zent, verbose, parsable); 1679 output = B_TRUE; 1680 } else if ((zentp = lookup_running_zone(target_zone)) != NULL) { 1681 zone_print(zentp, verbose, parsable); 1682 output = B_TRUE; 1683 } else if (lookup_zone_info(target_zone, ZONE_ID_UNDEFINED, 1684 &zent) == Z_OK) { 1685 zone_print(&zent, verbose, parsable); 1686 output = B_TRUE; 1687 } 1688 1689 /* 1690 * Invoke brand-specific handler. Note that we do this 1691 * only if we're in the global zone, and target_zone is specified. 1692 */ 1693 if (zone_id == GLOBAL_ZONEID && target_zone != NULL) 1694 if (invoke_brand_handler(CMD_LIST, argv) != Z_OK) 1695 return (Z_ERR); 1696 1697 return (output ? Z_OK : Z_ERR); 1698 } 1699 1700 static void 1701 sigterm(int sig) 1702 { 1703 /* 1704 * Ignore SIG{INT,TERM}, so we don't end up in an infinite loop, 1705 * then propagate the signal to our process group. 1706 */ 1707 assert(sig == SIGINT || sig == SIGTERM); 1708 (void) sigset(SIGINT, SIG_IGN); 1709 (void) sigset(SIGTERM, SIG_IGN); 1710 (void) kill(0, sig); 1711 child_killed = B_TRUE; 1712 } 1713 1714 static int 1715 do_subproc(char *cmdbuf) 1716 { 1717 char inbuf[1024]; /* arbitrary large amount */ 1718 FILE *file; 1719 1720 do_subproc_cnt++; 1721 child_killed = B_FALSE; 1722 /* 1723 * We use popen(3c) to launch child processes for [un]install; 1724 * this library call does not return a PID, so we have to kill 1725 * the whole process group. To avoid killing our parent, we 1726 * become a process group leader here. But doing so can wreak 1727 * havoc with reading from stdin when launched by a non-job-control 1728 * shell, so we close stdin and reopen it as /dev/null first. 1729 */ 1730 (void) close(STDIN_FILENO); 1731 (void) openat(STDIN_FILENO, "/dev/null", O_RDONLY); 1732 if (!zoneadm_is_nested) 1733 (void) setpgid(0, 0); 1734 (void) sigset(SIGINT, sigterm); 1735 (void) sigset(SIGTERM, sigterm); 1736 file = popen(cmdbuf, "r"); 1737 for (;;) { 1738 if (child_killed || fgets(inbuf, sizeof (inbuf), file) == NULL) 1739 break; 1740 (void) fputs(inbuf, stdout); 1741 } 1742 (void) sigset(SIGINT, SIG_DFL); 1743 (void) sigset(SIGTERM, SIG_DFL); 1744 return (pclose(file)); 1745 } 1746 1747 static int 1748 do_subproc_interactive(char *cmdbuf) 1749 { 1750 void (*saveint)(int); 1751 void (*saveterm)(int); 1752 void (*savequit)(int); 1753 void (*savehup)(int); 1754 int pid, child, status; 1755 1756 /* 1757 * do_subproc() links stdin to /dev/null, which would break any 1758 * interactive subprocess we try to launch here. Similarly, we 1759 * can't have been launched as a subprocess ourselves. 1760 */ 1761 assert(do_subproc_cnt == 0 && !zoneadm_is_nested); 1762 1763 if ((child = vfork()) == 0) { 1764 (void) execl("/bin/sh", "sh", "-c", cmdbuf, (char *)NULL); 1765 } 1766 1767 if (child == -1) 1768 return (-1); 1769 1770 saveint = sigset(SIGINT, SIG_IGN); 1771 saveterm = sigset(SIGTERM, SIG_IGN); 1772 savequit = sigset(SIGQUIT, SIG_IGN); 1773 savehup = sigset(SIGHUP, SIG_IGN); 1774 1775 while ((pid = waitpid(child, &status, 0)) != child && pid != -1) 1776 ; 1777 1778 (void) sigset(SIGINT, saveint); 1779 (void) sigset(SIGTERM, saveterm); 1780 (void) sigset(SIGQUIT, savequit); 1781 (void) sigset(SIGHUP, savehup); 1782 1783 return (pid == -1 ? -1 : status); 1784 } 1785 1786 static int 1787 subproc_status(const char *cmd, int status, boolean_t verbose_failure) 1788 { 1789 if (WIFEXITED(status)) { 1790 int exit_code = WEXITSTATUS(status); 1791 1792 if ((verbose_failure) && (exit_code != ZONE_SUBPROC_OK)) 1793 zerror(gettext("'%s' failed with exit code %d."), cmd, 1794 exit_code); 1795 1796 return (exit_code); 1797 } else if (WIFSIGNALED(status)) { 1798 int signal = WTERMSIG(status); 1799 char sigstr[SIG2STR_MAX]; 1800 1801 if (sig2str(signal, sigstr) == 0) { 1802 zerror(gettext("'%s' terminated by signal SIG%s."), cmd, 1803 sigstr); 1804 } else { 1805 zerror(gettext("'%s' terminated by an unknown signal."), 1806 cmd); 1807 } 1808 } else { 1809 zerror(gettext("'%s' failed for unknown reasons."), cmd); 1810 } 1811 1812 /* 1813 * Assume a subprocess that died due to a signal or an unknown error 1814 * should be considered an exit code of ZONE_SUBPROC_FATAL, as the 1815 * user will likely need to do some manual cleanup. 1816 */ 1817 return (ZONE_SUBPROC_FATAL); 1818 } 1819 1820 /* 1821 * Various sanity checks; make sure: 1822 * 1. We're in the global zone. 1823 * 2. The calling user has sufficient privilege. 1824 * 3. The target zone is neither the global zone nor anything starting with 1825 * "SUNW". 1826 * 4a. If we're looking for a 'not running' (i.e., configured or installed) 1827 * zone, the name service knows about it. 1828 * 4b. For some operations which expect a zone not to be running, that it is 1829 * not already running (or ready). 1830 */ 1831 static int 1832 sanity_check(char *zone, int cmd_num, boolean_t running, 1833 boolean_t unsafe_when_running, boolean_t force) 1834 { 1835 zone_entry_t *zent; 1836 priv_set_t *privset; 1837 zone_state_t state, min_state; 1838 char kernzone[ZONENAME_MAX]; 1839 FILE *fp; 1840 1841 if (getzoneid() != GLOBAL_ZONEID) { 1842 switch (cmd_num) { 1843 case CMD_HALT: 1844 zerror(gettext("use %s to %s this zone."), "halt(1M)", 1845 cmd_to_str(cmd_num)); 1846 break; 1847 case CMD_REBOOT: 1848 zerror(gettext("use %s to %s this zone."), 1849 "reboot(1M)", cmd_to_str(cmd_num)); 1850 break; 1851 default: 1852 zerror(gettext("must be in the global zone to %s a " 1853 "zone."), cmd_to_str(cmd_num)); 1854 break; 1855 } 1856 return (Z_ERR); 1857 } 1858 1859 if ((privset = priv_allocset()) == NULL) { 1860 zerror(gettext("%s failed"), "priv_allocset"); 1861 return (Z_ERR); 1862 } 1863 1864 if (getppriv(PRIV_EFFECTIVE, privset) != 0) { 1865 zerror(gettext("%s failed"), "getppriv"); 1866 priv_freeset(privset); 1867 return (Z_ERR); 1868 } 1869 1870 if (priv_isfullset(privset) == B_FALSE) { 1871 zerror(gettext("only a privileged user may %s a zone."), 1872 cmd_to_str(cmd_num)); 1873 priv_freeset(privset); 1874 return (Z_ERR); 1875 } 1876 priv_freeset(privset); 1877 1878 if (zone == NULL) { 1879 zerror(gettext("no zone specified")); 1880 return (Z_ERR); 1881 } 1882 1883 if (strcmp(zone, GLOBAL_ZONENAME) == 0) { 1884 zerror(gettext("%s operation is invalid for the global zone."), 1885 cmd_to_str(cmd_num)); 1886 return (Z_ERR); 1887 } 1888 1889 if (strncmp(zone, "SUNW", 4) == 0) { 1890 zerror(gettext("%s operation is invalid for zones starting " 1891 "with SUNW."), cmd_to_str(cmd_num)); 1892 return (Z_ERR); 1893 } 1894 1895 if (!is_native_zone && cmd_num == CMD_MOUNT) { 1896 zerror(gettext("%s operation is invalid for branded zones."), 1897 cmd_to_str(cmd_num)); 1898 return (Z_ERR); 1899 } 1900 1901 if (!zonecfg_in_alt_root()) { 1902 zent = lookup_running_zone(zone); 1903 } else if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) { 1904 zent = NULL; 1905 } else { 1906 if (zonecfg_find_scratch(fp, zone, zonecfg_get_root(), 1907 kernzone, sizeof (kernzone)) == 0) 1908 zent = lookup_running_zone(kernzone); 1909 else 1910 zent = NULL; 1911 zonecfg_close_scratch(fp); 1912 } 1913 1914 /* 1915 * Look up from the kernel for 'running' zones. 1916 */ 1917 if (running && !force) { 1918 if (zent == NULL) { 1919 zerror(gettext("not running")); 1920 return (Z_ERR); 1921 } 1922 } else { 1923 int err; 1924 1925 if (unsafe_when_running && zent != NULL) { 1926 /* check whether the zone is ready or running */ 1927 if ((err = zone_get_state(zent->zname, 1928 &zent->zstate_num)) != Z_OK) { 1929 errno = err; 1930 zperror2(zent->zname, 1931 gettext("could not get state")); 1932 /* can't tell, so hedge */ 1933 zent->zstate_str = "ready/running"; 1934 } else { 1935 zent->zstate_str = 1936 zone_state_str(zent->zstate_num); 1937 } 1938 zerror(gettext("%s operation is invalid for %s zones."), 1939 cmd_to_str(cmd_num), zent->zstate_str); 1940 return (Z_ERR); 1941 } 1942 if ((err = zone_get_state(zone, &state)) != Z_OK) { 1943 errno = err; 1944 zperror2(zone, gettext("could not get state")); 1945 return (Z_ERR); 1946 } 1947 switch (cmd_num) { 1948 case CMD_UNINSTALL: 1949 if (state == ZONE_STATE_CONFIGURED) { 1950 zerror(gettext("is already in state '%s'."), 1951 zone_state_str(ZONE_STATE_CONFIGURED)); 1952 return (Z_ERR); 1953 } 1954 break; 1955 case CMD_ATTACH: 1956 case CMD_CLONE: 1957 case CMD_INSTALL: 1958 if (state == ZONE_STATE_INSTALLED) { 1959 zerror(gettext("is already %s."), 1960 zone_state_str(ZONE_STATE_INSTALLED)); 1961 return (Z_ERR); 1962 } else if (state == ZONE_STATE_INCOMPLETE) { 1963 zerror(gettext("zone is %s; %s required."), 1964 zone_state_str(ZONE_STATE_INCOMPLETE), 1965 cmd_to_str(CMD_UNINSTALL)); 1966 return (Z_ERR); 1967 } 1968 break; 1969 case CMD_DETACH: 1970 case CMD_MOVE: 1971 case CMD_READY: 1972 case CMD_BOOT: 1973 case CMD_MOUNT: 1974 case CMD_MARK: 1975 if ((cmd_num == CMD_BOOT || cmd_num == CMD_MOUNT) && 1976 force) 1977 min_state = ZONE_STATE_INCOMPLETE; 1978 else 1979 min_state = ZONE_STATE_INSTALLED; 1980 1981 if (force && cmd_num == CMD_BOOT && is_native_zone) { 1982 zerror(gettext("Only branded zones may be " 1983 "force-booted.")); 1984 return (Z_ERR); 1985 } 1986 1987 if (state < min_state) { 1988 zerror(gettext("must be %s before %s."), 1989 zone_state_str(min_state), 1990 cmd_to_str(cmd_num)); 1991 return (Z_ERR); 1992 } 1993 break; 1994 case CMD_VERIFY: 1995 if (state == ZONE_STATE_INCOMPLETE) { 1996 zerror(gettext("zone is %s; %s required."), 1997 zone_state_str(ZONE_STATE_INCOMPLETE), 1998 cmd_to_str(CMD_UNINSTALL)); 1999 return (Z_ERR); 2000 } 2001 break; 2002 case CMD_UNMOUNT: 2003 if (state != ZONE_STATE_MOUNTED) { 2004 zerror(gettext("must be %s before %s."), 2005 zone_state_str(ZONE_STATE_MOUNTED), 2006 cmd_to_str(cmd_num)); 2007 return (Z_ERR); 2008 } 2009 break; 2010 } 2011 } 2012 return (Z_OK); 2013 } 2014 2015 static int 2016 halt_func(int argc, char *argv[]) 2017 { 2018 zone_cmd_arg_t zarg; 2019 int arg; 2020 2021 if (zonecfg_in_alt_root()) { 2022 zerror(gettext("cannot halt zone in alternate root")); 2023 return (Z_ERR); 2024 } 2025 2026 optind = 0; 2027 if ((arg = getopt(argc, argv, "?")) != EOF) { 2028 switch (arg) { 2029 case '?': 2030 sub_usage(SHELP_HALT, CMD_HALT); 2031 return (optopt == '?' ? Z_OK : Z_USAGE); 2032 default: 2033 sub_usage(SHELP_HALT, CMD_HALT); 2034 return (Z_USAGE); 2035 } 2036 } 2037 if (argc > optind) { 2038 sub_usage(SHELP_HALT, CMD_HALT); 2039 return (Z_USAGE); 2040 } 2041 /* 2042 * zoneadmd should be the one to decide whether or not to proceed, 2043 * so even though it seems that the fourth parameter below should 2044 * perhaps be B_TRUE, it really shouldn't be. 2045 */ 2046 if (sanity_check(target_zone, CMD_HALT, B_FALSE, B_FALSE, B_FALSE) 2047 != Z_OK) 2048 return (Z_ERR); 2049 2050 /* 2051 * Invoke brand-specific handler. 2052 */ 2053 if (invoke_brand_handler(CMD_HALT, argv) != Z_OK) 2054 return (Z_ERR); 2055 2056 zarg.cmd = Z_HALT; 2057 return ((call_zoneadmd(target_zone, &zarg) == 0) ? Z_OK : Z_ERR); 2058 } 2059 2060 static int 2061 reboot_func(int argc, char *argv[]) 2062 { 2063 zone_cmd_arg_t zarg; 2064 int arg; 2065 2066 if (zonecfg_in_alt_root()) { 2067 zerror(gettext("cannot reboot zone in alternate root")); 2068 return (Z_ERR); 2069 } 2070 2071 optind = 0; 2072 if ((arg = getopt(argc, argv, "?")) != EOF) { 2073 switch (arg) { 2074 case '?': 2075 sub_usage(SHELP_REBOOT, CMD_REBOOT); 2076 return (optopt == '?' ? Z_OK : Z_USAGE); 2077 default: 2078 sub_usage(SHELP_REBOOT, CMD_REBOOT); 2079 return (Z_USAGE); 2080 } 2081 } 2082 2083 zarg.bootbuf[0] = '\0'; 2084 for (; optind < argc; optind++) { 2085 if (strlcat(zarg.bootbuf, argv[optind], 2086 sizeof (zarg.bootbuf)) >= sizeof (zarg.bootbuf)) { 2087 zerror(gettext("Boot argument list too long")); 2088 return (Z_ERR); 2089 } 2090 if (optind < argc - 1) 2091 if (strlcat(zarg.bootbuf, " ", sizeof (zarg.bootbuf)) >= 2092 sizeof (zarg.bootbuf)) { 2093 zerror(gettext("Boot argument list too long")); 2094 return (Z_ERR); 2095 } 2096 } 2097 2098 2099 /* 2100 * zoneadmd should be the one to decide whether or not to proceed, 2101 * so even though it seems that the fourth parameter below should 2102 * perhaps be B_TRUE, it really shouldn't be. 2103 */ 2104 if (sanity_check(target_zone, CMD_REBOOT, B_TRUE, B_FALSE, B_FALSE) 2105 != Z_OK) 2106 return (Z_ERR); 2107 if (verify_details(CMD_REBOOT, argv) != Z_OK) 2108 return (Z_ERR); 2109 2110 zarg.cmd = Z_REBOOT; 2111 return ((call_zoneadmd(target_zone, &zarg) == 0) ? Z_OK : Z_ERR); 2112 } 2113 2114 static int 2115 verify_brand(zone_dochandle_t handle, int cmd_num, char *argv[]) 2116 { 2117 char cmdbuf[MAXPATHLEN]; 2118 int err; 2119 char zonepath[MAXPATHLEN]; 2120 brand_handle_t bh = NULL; 2121 int status, i; 2122 2123 /* 2124 * Fetch the verify command from the brand configuration. 2125 * "exec" the command so that the returned status is that of 2126 * the command and not the shell. 2127 */ 2128 if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) != 2129 Z_OK) { 2130 errno = err; 2131 zperror(cmd_to_str(cmd_num), B_TRUE); 2132 return (Z_ERR); 2133 } 2134 if ((bh = brand_open(target_brand)) == NULL) { 2135 zerror(gettext("missing or invalid brand")); 2136 return (Z_ERR); 2137 } 2138 2139 /* 2140 * If the brand has its own verification routine, execute it now. 2141 * The verification routine validates the intended zoneadm 2142 * operation for the specific brand. The zoneadm subcommand and 2143 * all its arguments are passed to the routine. 2144 */ 2145 (void) strcpy(cmdbuf, EXEC_PREFIX); 2146 err = brand_get_verify_adm(bh, target_zone, zonepath, 2147 cmdbuf + EXEC_LEN, sizeof (cmdbuf) - EXEC_LEN, 0, NULL); 2148 brand_close(bh); 2149 if (err != 0) 2150 return (Z_BRAND_ERROR); 2151 if (strlen(cmdbuf) <= EXEC_LEN) 2152 return (Z_OK); 2153 2154 if (strlcat(cmdbuf, cmd_to_str(cmd_num), 2155 sizeof (cmdbuf)) >= sizeof (cmdbuf)) 2156 return (Z_ERR); 2157 2158 /* Build the argv string */ 2159 i = 0; 2160 while (argv[i] != NULL) { 2161 if ((strlcat(cmdbuf, " ", 2162 sizeof (cmdbuf)) >= sizeof (cmdbuf)) || 2163 (strlcat(cmdbuf, argv[i++], 2164 sizeof (cmdbuf)) >= sizeof (cmdbuf))) 2165 return (Z_ERR); 2166 } 2167 2168 status = do_subproc_interactive(cmdbuf); 2169 err = subproc_status(gettext("brand-specific verification"), 2170 status, B_FALSE); 2171 2172 return ((err == ZONE_SUBPROC_OK) ? Z_OK : Z_BRAND_ERROR); 2173 } 2174 2175 static int 2176 verify_rctls(zone_dochandle_t handle) 2177 { 2178 struct zone_rctltab rctltab; 2179 size_t rbs = rctlblk_size(); 2180 rctlblk_t *rctlblk; 2181 int error = Z_INVAL; 2182 2183 if ((rctlblk = malloc(rbs)) == NULL) { 2184 zerror(gettext("failed to allocate %lu bytes: %s"), rbs, 2185 strerror(errno)); 2186 return (Z_NOMEM); 2187 } 2188 2189 if (zonecfg_setrctlent(handle) != Z_OK) { 2190 zerror(gettext("zonecfg_setrctlent failed")); 2191 free(rctlblk); 2192 return (error); 2193 } 2194 2195 rctltab.zone_rctl_valptr = NULL; 2196 while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) { 2197 struct zone_rctlvaltab *rctlval; 2198 const char *name = rctltab.zone_rctl_name; 2199 2200 if (!zonecfg_is_rctl(name)) { 2201 zerror(gettext("WARNING: Ignoring unrecognized rctl " 2202 "'%s'."), name); 2203 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 2204 rctltab.zone_rctl_valptr = NULL; 2205 continue; 2206 } 2207 2208 for (rctlval = rctltab.zone_rctl_valptr; rctlval != NULL; 2209 rctlval = rctlval->zone_rctlval_next) { 2210 if (zonecfg_construct_rctlblk(rctlval, rctlblk) 2211 != Z_OK) { 2212 zerror(gettext("invalid rctl value: " 2213 "(priv=%s,limit=%s,action%s)"), 2214 rctlval->zone_rctlval_priv, 2215 rctlval->zone_rctlval_limit, 2216 rctlval->zone_rctlval_action); 2217 goto out; 2218 } 2219 if (!zonecfg_valid_rctl(name, rctlblk)) { 2220 zerror(gettext("(priv=%s,limit=%s,action=%s) " 2221 "is not a valid value for rctl '%s'"), 2222 rctlval->zone_rctlval_priv, 2223 rctlval->zone_rctlval_limit, 2224 rctlval->zone_rctlval_action, 2225 name); 2226 goto out; 2227 } 2228 } 2229 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 2230 } 2231 rctltab.zone_rctl_valptr = NULL; 2232 error = Z_OK; 2233 out: 2234 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 2235 (void) zonecfg_endrctlent(handle); 2236 free(rctlblk); 2237 return (error); 2238 } 2239 2240 static int 2241 verify_pool(zone_dochandle_t handle) 2242 { 2243 char poolname[MAXPATHLEN]; 2244 pool_conf_t *poolconf; 2245 pool_t *pool; 2246 int status; 2247 int error; 2248 2249 /* 2250 * This ends up being very similar to the check done in zoneadmd. 2251 */ 2252 error = zonecfg_get_pool(handle, poolname, sizeof (poolname)); 2253 if (error == Z_NO_ENTRY || (error == Z_OK && strlen(poolname) == 0)) { 2254 /* 2255 * No pool specified. 2256 */ 2257 return (0); 2258 } 2259 if (error != Z_OK) { 2260 zperror(gettext("Unable to retrieve pool name from " 2261 "configuration"), B_TRUE); 2262 return (error); 2263 } 2264 /* 2265 * Don't do anything if pools aren't enabled. 2266 */ 2267 if (pool_get_status(&status) != PO_SUCCESS || status != POOL_ENABLED) { 2268 zerror(gettext("WARNING: pools facility not active; " 2269 "zone will not be bound to pool '%s'."), poolname); 2270 return (Z_OK); 2271 } 2272 /* 2273 * Try to provide a sane error message if the requested pool doesn't 2274 * exist. It isn't clear that pools-related failures should 2275 * necessarily translate to a failure to verify the zone configuration, 2276 * hence they are not considered errors. 2277 */ 2278 if ((poolconf = pool_conf_alloc()) == NULL) { 2279 zerror(gettext("WARNING: pool_conf_alloc failed; " 2280 "using default pool")); 2281 return (Z_OK); 2282 } 2283 if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) != 2284 PO_SUCCESS) { 2285 zerror(gettext("WARNING: pool_conf_open failed; " 2286 "using default pool")); 2287 pool_conf_free(poolconf); 2288 return (Z_OK); 2289 } 2290 pool = pool_get_pool(poolconf, poolname); 2291 (void) pool_conf_close(poolconf); 2292 pool_conf_free(poolconf); 2293 if (pool == NULL) { 2294 zerror(gettext("WARNING: pool '%s' not found. " 2295 "using default pool"), poolname); 2296 } 2297 2298 return (Z_OK); 2299 } 2300 2301 static int 2302 verify_ipd(zone_dochandle_t handle) 2303 { 2304 int return_code = Z_OK; 2305 struct zone_fstab fstab; 2306 struct stat st; 2307 char specdir[MAXPATHLEN]; 2308 2309 if (zonecfg_setipdent(handle) != Z_OK) { 2310 /* 2311 * TRANSLATION_NOTE 2312 * inherit-pkg-dirs is a literal that should not be translated. 2313 */ 2314 (void) fprintf(stderr, gettext("could not verify " 2315 "inherit-pkg-dirs: unable to enumerate mounts\n")); 2316 return (Z_ERR); 2317 } 2318 while (zonecfg_getipdent(handle, &fstab) == Z_OK) { 2319 /* 2320 * Verify fs_dir exists. 2321 */ 2322 (void) snprintf(specdir, sizeof (specdir), "%s%s", 2323 zonecfg_get_root(), fstab.zone_fs_dir); 2324 if (stat(specdir, &st) != 0) { 2325 /* 2326 * TRANSLATION_NOTE 2327 * inherit-pkg-dir is a literal that should not be 2328 * translated. 2329 */ 2330 (void) fprintf(stderr, gettext("could not verify " 2331 "inherit-pkg-dir %s: %s\n"), 2332 fstab.zone_fs_dir, strerror(errno)); 2333 return_code = Z_ERR; 2334 } 2335 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) { 2336 /* 2337 * TRANSLATION_NOTE 2338 * inherit-pkg-dir and NFS are literals that should 2339 * not be translated. 2340 */ 2341 (void) fprintf(stderr, gettext("cannot verify " 2342 "inherit-pkg-dir %s: NFS mounted file system.\n" 2343 "\tA local file system must be used.\n"), 2344 fstab.zone_fs_dir); 2345 return_code = Z_ERR; 2346 } 2347 } 2348 (void) zonecfg_endipdent(handle); 2349 2350 return (return_code); 2351 } 2352 2353 /* 2354 * Verify that the special device/file system exists and is valid. 2355 */ 2356 static int 2357 verify_fs_special(struct zone_fstab *fstab) 2358 { 2359 struct stat st; 2360 2361 /* 2362 * This validation is really intended for standard zone administration. 2363 * If we are in a mini-root or some other upgrade situation where 2364 * we are using the scratch zone, just by-pass this. 2365 */ 2366 if (zonecfg_in_alt_root()) 2367 return (Z_OK); 2368 2369 if (strcmp(fstab->zone_fs_type, MNTTYPE_ZFS) == 0) 2370 return (verify_fs_zfs(fstab)); 2371 2372 if (stat(fstab->zone_fs_special, &st) != 0) { 2373 (void) fprintf(stderr, gettext("could not verify fs " 2374 "%s: could not access %s: %s\n"), fstab->zone_fs_dir, 2375 fstab->zone_fs_special, strerror(errno)); 2376 return (Z_ERR); 2377 } 2378 2379 if (strcmp(st.st_fstype, MNTTYPE_NFS) == 0) { 2380 /* 2381 * TRANSLATION_NOTE 2382 * fs and NFS are literals that should 2383 * not be translated. 2384 */ 2385 (void) fprintf(stderr, gettext("cannot verify " 2386 "fs %s: NFS mounted file system.\n" 2387 "\tA local file system must be used.\n"), 2388 fstab->zone_fs_special); 2389 return (Z_ERR); 2390 } 2391 2392 return (Z_OK); 2393 } 2394 2395 static int 2396 verify_filesystems(zone_dochandle_t handle) 2397 { 2398 int return_code = Z_OK; 2399 struct zone_fstab fstab; 2400 char cmdbuf[MAXPATHLEN]; 2401 struct stat st; 2402 2403 /* 2404 * No need to verify inherit-pkg-dir fs types, as their type is 2405 * implicitly lofs, which is known. Therefore, the types are only 2406 * verified for regular file systems below. 2407 * 2408 * Since the actual mount point is not known until the dependent mounts 2409 * are performed, we don't attempt any path validation here: that will 2410 * happen later when zoneadmd actually does the mounts. 2411 */ 2412 if (zonecfg_setfsent(handle) != Z_OK) { 2413 (void) fprintf(stderr, gettext("could not verify file systems: " 2414 "unable to enumerate mounts\n")); 2415 return (Z_ERR); 2416 } 2417 while (zonecfg_getfsent(handle, &fstab) == Z_OK) { 2418 if (!zonecfg_valid_fs_type(fstab.zone_fs_type)) { 2419 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2420 "type %s is not allowed.\n"), fstab.zone_fs_dir, 2421 fstab.zone_fs_type); 2422 return_code = Z_ERR; 2423 goto next_fs; 2424 } 2425 /* 2426 * Verify /usr/lib/fs/<fstype>/mount exists. 2427 */ 2428 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/mount", 2429 fstab.zone_fs_type) > sizeof (cmdbuf)) { 2430 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2431 "type %s is too long.\n"), fstab.zone_fs_dir, 2432 fstab.zone_fs_type); 2433 return_code = Z_ERR; 2434 goto next_fs; 2435 } 2436 if (stat(cmdbuf, &st) != 0) { 2437 (void) fprintf(stderr, gettext("could not verify fs " 2438 "%s: could not access %s: %s\n"), fstab.zone_fs_dir, 2439 cmdbuf, strerror(errno)); 2440 return_code = Z_ERR; 2441 goto next_fs; 2442 } 2443 if (!S_ISREG(st.st_mode)) { 2444 (void) fprintf(stderr, gettext("could not verify fs " 2445 "%s: %s is not a regular file\n"), 2446 fstab.zone_fs_dir, cmdbuf); 2447 return_code = Z_ERR; 2448 goto next_fs; 2449 } 2450 /* 2451 * Verify /usr/lib/fs/<fstype>/fsck exists iff zone_fs_raw is 2452 * set. 2453 */ 2454 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/fsck", 2455 fstab.zone_fs_type) > sizeof (cmdbuf)) { 2456 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2457 "type %s is too long.\n"), fstab.zone_fs_dir, 2458 fstab.zone_fs_type); 2459 return_code = Z_ERR; 2460 goto next_fs; 2461 } 2462 if (fstab.zone_fs_raw[0] == '\0' && stat(cmdbuf, &st) == 0) { 2463 (void) fprintf(stderr, gettext("could not verify fs " 2464 "%s: must specify 'raw' device for %s " 2465 "file systems\n"), 2466 fstab.zone_fs_dir, fstab.zone_fs_type); 2467 return_code = Z_ERR; 2468 goto next_fs; 2469 } 2470 if (fstab.zone_fs_raw[0] != '\0' && 2471 (stat(cmdbuf, &st) != 0 || !S_ISREG(st.st_mode))) { 2472 (void) fprintf(stderr, gettext("cannot verify fs %s: " 2473 "'raw' device specified but " 2474 "no fsck executable exists for %s\n"), 2475 fstab.zone_fs_dir, fstab.zone_fs_type); 2476 return_code = Z_ERR; 2477 goto next_fs; 2478 } 2479 2480 /* Verify fs_special. */ 2481 if ((return_code = verify_fs_special(&fstab)) != Z_OK) 2482 goto next_fs; 2483 2484 /* Verify fs_raw. */ 2485 if (fstab.zone_fs_raw[0] != '\0' && 2486 stat(fstab.zone_fs_raw, &st) != 0) { 2487 /* 2488 * TRANSLATION_NOTE 2489 * fs is a literal that should not be translated. 2490 */ 2491 (void) fprintf(stderr, gettext("could not verify fs " 2492 "%s: could not access %s: %s\n"), fstab.zone_fs_dir, 2493 fstab.zone_fs_raw, strerror(errno)); 2494 return_code = Z_ERR; 2495 goto next_fs; 2496 } 2497 next_fs: 2498 zonecfg_free_fs_option_list(fstab.zone_fs_options); 2499 } 2500 (void) zonecfg_endfsent(handle); 2501 2502 return (return_code); 2503 } 2504 2505 static int 2506 verify_limitpriv(zone_dochandle_t handle) 2507 { 2508 char *privname = NULL; 2509 int err; 2510 priv_set_t *privs; 2511 2512 if ((privs = priv_allocset()) == NULL) { 2513 zperror(gettext("failed to allocate privilege set"), B_FALSE); 2514 return (Z_NOMEM); 2515 } 2516 err = zonecfg_get_privset(handle, privs, &privname); 2517 switch (err) { 2518 case Z_OK: 2519 break; 2520 case Z_PRIV_PROHIBITED: 2521 (void) fprintf(stderr, gettext("privilege \"%s\" is not " 2522 "permitted within the zone's privilege set\n"), privname); 2523 break; 2524 case Z_PRIV_REQUIRED: 2525 (void) fprintf(stderr, gettext("required privilege \"%s\" is " 2526 "missing from the zone's privilege set\n"), privname); 2527 break; 2528 case Z_PRIV_UNKNOWN: 2529 (void) fprintf(stderr, gettext("unknown privilege \"%s\" " 2530 "specified in the zone's privilege set\n"), privname); 2531 break; 2532 default: 2533 zperror( 2534 gettext("failed to determine the zone's privilege set"), 2535 B_TRUE); 2536 break; 2537 } 2538 free(privname); 2539 priv_freeset(privs); 2540 return (err); 2541 } 2542 2543 static void 2544 free_local_netifs(int if_cnt, struct net_if **if_list) 2545 { 2546 int i; 2547 2548 for (i = 0; i < if_cnt; i++) { 2549 free(if_list[i]->name); 2550 free(if_list[i]); 2551 } 2552 free(if_list); 2553 } 2554 2555 /* 2556 * Get a list of the network interfaces, along with their address families, 2557 * that are plumbed in the global zone. See if_tcp(7p) for a description 2558 * of the ioctls used here. 2559 */ 2560 static int 2561 get_local_netifs(int *if_cnt, struct net_if ***if_list) 2562 { 2563 int s; 2564 int i; 2565 int res = Z_OK; 2566 int space_needed; 2567 int cnt = 0; 2568 struct lifnum if_num; 2569 struct lifconf if_conf; 2570 struct lifreq *if_reqp; 2571 char *if_buf; 2572 struct net_if **local_ifs = NULL; 2573 2574 *if_cnt = 0; 2575 *if_list = NULL; 2576 2577 if ((s = socket(SOCKET_AF(AF_INET), SOCK_DGRAM, 0)) < 0) 2578 return (Z_ERR); 2579 2580 /* 2581 * Come back here in the unlikely event that the number of interfaces 2582 * increases between the time we get the count and the time we do the 2583 * SIOCGLIFCONF ioctl. 2584 */ 2585 retry: 2586 /* Get the number of interfaces. */ 2587 if_num.lifn_family = AF_UNSPEC; 2588 if_num.lifn_flags = LIFC_NOXMIT; 2589 if (ioctl(s, SIOCGLIFNUM, &if_num) < 0) { 2590 (void) close(s); 2591 return (Z_ERR); 2592 } 2593 2594 /* Get the interface configuration list. */ 2595 space_needed = if_num.lifn_count * sizeof (struct lifreq); 2596 if ((if_buf = malloc(space_needed)) == NULL) { 2597 (void) close(s); 2598 return (Z_ERR); 2599 } 2600 if_conf.lifc_family = AF_UNSPEC; 2601 if_conf.lifc_flags = LIFC_NOXMIT; 2602 if_conf.lifc_len = space_needed; 2603 if_conf.lifc_buf = if_buf; 2604 if (ioctl(s, SIOCGLIFCONF, &if_conf) < 0) { 2605 free(if_buf); 2606 /* 2607 * SIOCGLIFCONF returns EINVAL if the buffer we passed in is 2608 * too small. In this case go back and get the new if cnt. 2609 */ 2610 if (errno == EINVAL) 2611 goto retry; 2612 2613 (void) close(s); 2614 return (Z_ERR); 2615 } 2616 (void) close(s); 2617 2618 /* Get the name and address family for each interface. */ 2619 if_reqp = if_conf.lifc_req; 2620 for (i = 0; i < (if_conf.lifc_len / sizeof (struct lifreq)); i++) { 2621 struct net_if **p; 2622 struct lifreq req; 2623 2624 if (strcmp(LOOPBACK_IF, if_reqp->lifr_name) == 0) { 2625 if_reqp++; 2626 continue; 2627 } 2628 2629 if ((s = socket(SOCKET_AF(if_reqp->lifr_addr.ss_family), 2630 SOCK_DGRAM, 0)) == -1) { 2631 res = Z_ERR; 2632 break; 2633 } 2634 2635 (void) strncpy(req.lifr_name, if_reqp->lifr_name, 2636 sizeof (req.lifr_name)); 2637 if (ioctl(s, SIOCGLIFADDR, &req) < 0) { 2638 (void) close(s); 2639 if_reqp++; 2640 continue; 2641 } 2642 2643 if ((p = (struct net_if **)realloc(local_ifs, 2644 sizeof (struct net_if *) * (cnt + 1))) == NULL) { 2645 res = Z_ERR; 2646 break; 2647 } 2648 local_ifs = p; 2649 2650 if ((local_ifs[cnt] = malloc(sizeof (struct net_if))) == NULL) { 2651 res = Z_ERR; 2652 break; 2653 } 2654 2655 if ((local_ifs[cnt]->name = strdup(if_reqp->lifr_name)) 2656 == NULL) { 2657 free(local_ifs[cnt]); 2658 res = Z_ERR; 2659 break; 2660 } 2661 local_ifs[cnt]->af = req.lifr_addr.ss_family; 2662 cnt++; 2663 2664 (void) close(s); 2665 if_reqp++; 2666 } 2667 2668 free(if_buf); 2669 2670 if (res != Z_OK) { 2671 free_local_netifs(cnt, local_ifs); 2672 } else { 2673 *if_cnt = cnt; 2674 *if_list = local_ifs; 2675 } 2676 2677 return (res); 2678 } 2679 2680 static char * 2681 af2str(int af) 2682 { 2683 switch (af) { 2684 case AF_INET: 2685 return ("IPv4"); 2686 case AF_INET6: 2687 return ("IPv6"); 2688 default: 2689 return ("Unknown"); 2690 } 2691 } 2692 2693 /* 2694 * Cross check the network interface name and address family with the 2695 * interfaces that are set up in the global zone so that we can print the 2696 * appropriate error message. 2697 */ 2698 static void 2699 print_net_err(char *phys, char *addr, int af, char *msg) 2700 { 2701 int i; 2702 int local_if_cnt = 0; 2703 struct net_if **local_ifs = NULL; 2704 boolean_t found_if = B_FALSE; 2705 boolean_t found_af = B_FALSE; 2706 2707 if (get_local_netifs(&local_if_cnt, &local_ifs) != Z_OK) { 2708 (void) fprintf(stderr, 2709 gettext("could not verify %s %s=%s %s=%s\n\t%s\n"), 2710 "net", "address", addr, "physical", phys, msg); 2711 return; 2712 } 2713 2714 for (i = 0; i < local_if_cnt; i++) { 2715 if (strcmp(phys, local_ifs[i]->name) == 0) { 2716 found_if = B_TRUE; 2717 if (af == local_ifs[i]->af) { 2718 found_af = B_TRUE; 2719 break; 2720 } 2721 } 2722 } 2723 2724 free_local_netifs(local_if_cnt, local_ifs); 2725 2726 if (!found_if) { 2727 (void) fprintf(stderr, 2728 gettext("could not verify %s %s=%s\n\t" 2729 "network interface %s is not plumbed in the global zone\n"), 2730 "net", "physical", phys, phys); 2731 return; 2732 } 2733 2734 /* 2735 * Print this error if we were unable to find the address family 2736 * for this interface. If the af variable is not initialized to 2737 * to something meaningful by the caller (not AF_UNSPEC) then we 2738 * also skip this message since it wouldn't be informative. 2739 */ 2740 if (!found_af && af != AF_UNSPEC) { 2741 (void) fprintf(stderr, 2742 gettext("could not verify %s %s=%s %s=%s\n\tthe %s address " 2743 "family is not configured on this interface in the\n\t" 2744 "global zone\n"), 2745 "net", "address", addr, "physical", phys, af2str(af)); 2746 return; 2747 } 2748 2749 (void) fprintf(stderr, 2750 gettext("could not verify %s %s=%s %s=%s\n\t%s\n"), 2751 "net", "address", addr, "physical", phys, msg); 2752 } 2753 2754 static int 2755 verify_handle(int cmd_num, zone_dochandle_t handle, char *argv[]) 2756 { 2757 struct zone_nwiftab nwiftab; 2758 int return_code = Z_OK; 2759 int err; 2760 boolean_t in_alt_root; 2761 2762 in_alt_root = zonecfg_in_alt_root(); 2763 if (in_alt_root) 2764 goto no_net; 2765 2766 if ((err = zonecfg_setnwifent(handle)) != Z_OK) { 2767 errno = err; 2768 zperror(cmd_to_str(cmd_num), B_TRUE); 2769 zonecfg_fini_handle(handle); 2770 return (Z_ERR); 2771 } 2772 while (zonecfg_getnwifent(handle, &nwiftab) == Z_OK) { 2773 struct lifreq lifr; 2774 sa_family_t af = AF_UNSPEC; 2775 int so, res; 2776 2777 /* skip any loopback interfaces */ 2778 if (strcmp(nwiftab.zone_nwif_physical, "lo0") == 0) 2779 continue; 2780 if ((res = zonecfg_valid_net_address(nwiftab.zone_nwif_address, 2781 &lifr)) != Z_OK) { 2782 print_net_err(nwiftab.zone_nwif_physical, 2783 nwiftab.zone_nwif_address, af, 2784 zonecfg_strerror(res)); 2785 return_code = Z_ERR; 2786 continue; 2787 } 2788 af = lifr.lifr_addr.ss_family; 2789 (void) memset(&lifr, 0, sizeof (lifr)); 2790 (void) strlcpy(lifr.lifr_name, nwiftab.zone_nwif_physical, 2791 sizeof (lifr.lifr_name)); 2792 lifr.lifr_addr.ss_family = af; 2793 if ((so = socket(af, SOCK_DGRAM, 0)) < 0) { 2794 (void) fprintf(stderr, gettext("could not verify %s " 2795 "%s=%s %s=%s: could not get socket: %s\n"), "net", 2796 "address", nwiftab.zone_nwif_address, "physical", 2797 nwiftab.zone_nwif_physical, strerror(errno)); 2798 return_code = Z_ERR; 2799 continue; 2800 } 2801 if (ioctl(so, SIOCGLIFFLAGS, &lifr) < 0) { 2802 /* 2803 * The interface failed to come up. We continue on 2804 * anyway for the sake of consistency: a zone is not 2805 * shut down if the interface fails any time after 2806 * boot, nor does the global zone fail to boot if an 2807 * interface fails. 2808 */ 2809 (void) fprintf(stderr, 2810 gettext("WARNING: skipping interface '%s' which " 2811 "may not be present/plumbed in the global zone.\n"), 2812 nwiftab.zone_nwif_physical); 2813 2814 } 2815 (void) close(so); 2816 } 2817 (void) zonecfg_endnwifent(handle); 2818 no_net: 2819 2820 /* verify that lofs has not been excluded from the kernel */ 2821 if (!(cmd_num == CMD_DETACH || cmd_num == CMD_ATTACH || 2822 cmd_num == CMD_MOVE || cmd_num == CMD_CLONE) && 2823 modctl(MODLOAD, 1, "fs/lofs", NULL) != 0) { 2824 if (errno == ENXIO) 2825 (void) fprintf(stderr, gettext("could not verify " 2826 "lofs(7FS): possibly excluded in /etc/system\n")); 2827 else 2828 (void) fprintf(stderr, gettext("could not verify " 2829 "lofs(7FS): %s\n"), strerror(errno)); 2830 return_code = Z_ERR; 2831 } 2832 2833 if (verify_filesystems(handle) != Z_OK) 2834 return_code = Z_ERR; 2835 if (verify_ipd(handle) != Z_OK) 2836 return_code = Z_ERR; 2837 if (!in_alt_root && verify_rctls(handle) != Z_OK) 2838 return_code = Z_ERR; 2839 if (!in_alt_root && verify_pool(handle) != Z_OK) 2840 return_code = Z_ERR; 2841 if (!in_alt_root && verify_brand(handle, cmd_num, argv) != Z_OK) 2842 return_code = Z_ERR; 2843 if (!in_alt_root && verify_datasets(handle) != Z_OK) 2844 return_code = Z_ERR; 2845 2846 /* 2847 * As the "mount" command is used for patching/upgrading of zones 2848 * or other maintenance processes, the zone's privilege set is not 2849 * checked in this case. Instead, the default, safe set of 2850 * privileges will be used when this zone is created in the 2851 * kernel. 2852 */ 2853 if (!in_alt_root && cmd_num != CMD_MOUNT && 2854 verify_limitpriv(handle) != Z_OK) 2855 return_code = Z_ERR; 2856 2857 return (return_code); 2858 } 2859 2860 static int 2861 verify_details(int cmd_num, char *argv[]) 2862 { 2863 zone_dochandle_t handle; 2864 char zonepath[MAXPATHLEN], checkpath[MAXPATHLEN]; 2865 int return_code = Z_OK; 2866 int err; 2867 2868 if ((handle = zonecfg_init_handle()) == NULL) { 2869 zperror(cmd_to_str(cmd_num), B_TRUE); 2870 return (Z_ERR); 2871 } 2872 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 2873 errno = err; 2874 zperror(cmd_to_str(cmd_num), B_TRUE); 2875 zonecfg_fini_handle(handle); 2876 return (Z_ERR); 2877 } 2878 if ((err = zonecfg_get_zonepath(handle, zonepath, sizeof (zonepath))) != 2879 Z_OK) { 2880 errno = err; 2881 zperror(cmd_to_str(cmd_num), B_TRUE); 2882 zonecfg_fini_handle(handle); 2883 return (Z_ERR); 2884 } 2885 /* 2886 * zonecfg_get_zonepath() gets its data from the XML repository. 2887 * Verify this against the index file, which is checked first by 2888 * zone_get_zonepath(). If they don't match, bail out. 2889 */ 2890 if ((err = zone_get_zonepath(target_zone, checkpath, 2891 sizeof (checkpath))) != Z_OK) { 2892 errno = err; 2893 zperror2(target_zone, gettext("could not get zone path")); 2894 return (Z_ERR); 2895 } 2896 if (strcmp(zonepath, checkpath) != 0) { 2897 /* 2898 * TRANSLATION_NOTE 2899 * XML and zonepath are literals that should not be translated. 2900 */ 2901 (void) fprintf(stderr, gettext("The XML repository has " 2902 "zonepath '%s',\nbut the index file has zonepath '%s'.\n" 2903 "These must match, so fix the incorrect entry.\n"), 2904 zonepath, checkpath); 2905 return (Z_ERR); 2906 } 2907 if (validate_zonepath(zonepath, cmd_num) != Z_OK) { 2908 (void) fprintf(stderr, gettext("could not verify zonepath %s " 2909 "because of the above errors.\n"), zonepath); 2910 return_code = Z_ERR; 2911 } 2912 2913 if (verify_handle(cmd_num, handle, argv) != Z_OK) 2914 return_code = Z_ERR; 2915 2916 zonecfg_fini_handle(handle); 2917 if (return_code == Z_ERR) 2918 (void) fprintf(stderr, 2919 gettext("%s: zone %s failed to verify\n"), 2920 execname, target_zone); 2921 return (return_code); 2922 } 2923 2924 static int 2925 verify_func(int argc, char *argv[]) 2926 { 2927 int arg; 2928 2929 optind = 0; 2930 if ((arg = getopt(argc, argv, "?")) != EOF) { 2931 switch (arg) { 2932 case '?': 2933 sub_usage(SHELP_VERIFY, CMD_VERIFY); 2934 return (optopt == '?' ? Z_OK : Z_USAGE); 2935 default: 2936 sub_usage(SHELP_VERIFY, CMD_VERIFY); 2937 return (Z_USAGE); 2938 } 2939 } 2940 if (argc > optind) { 2941 sub_usage(SHELP_VERIFY, CMD_VERIFY); 2942 return (Z_USAGE); 2943 } 2944 if (sanity_check(target_zone, CMD_VERIFY, B_FALSE, B_FALSE, B_FALSE) 2945 != Z_OK) 2946 return (Z_ERR); 2947 return (verify_details(CMD_VERIFY, argv)); 2948 } 2949 2950 static int 2951 addopt(char *buf, int opt, char *optarg, size_t bufsize) 2952 { 2953 char optstring[4]; 2954 2955 if (opt > 0) 2956 (void) sprintf(optstring, " -%c", opt); 2957 else 2958 (void) strcpy(optstring, " "); 2959 2960 if ((strlcat(buf, optstring, bufsize) > bufsize)) 2961 return (Z_ERR); 2962 if ((optarg != NULL) && (strlcat(buf, optarg, bufsize) > bufsize)) 2963 return (Z_ERR); 2964 return (Z_OK); 2965 } 2966 2967 static int 2968 install_func(int argc, char *argv[]) 2969 { 2970 char cmdbuf[MAXPATHLEN]; 2971 int lockfd; 2972 int arg, err, subproc_err; 2973 char zonepath[MAXPATHLEN]; 2974 brand_handle_t bh = NULL; 2975 int status; 2976 boolean_t nodataset = B_FALSE; 2977 char opts[128]; 2978 2979 if (target_zone == NULL) { 2980 sub_usage(SHELP_INSTALL, CMD_INSTALL); 2981 return (Z_USAGE); 2982 } 2983 2984 if (zonecfg_in_alt_root()) { 2985 zerror(gettext("cannot install zone in alternate root")); 2986 return (Z_ERR); 2987 } 2988 2989 if ((err = zone_get_zonepath(target_zone, zonepath, 2990 sizeof (zonepath))) != Z_OK) { 2991 errno = err; 2992 zperror2(target_zone, gettext("could not get zone path")); 2993 return (Z_ERR); 2994 } 2995 2996 /* Fetch the install command from the brand configuration. */ 2997 if ((bh = brand_open(target_brand)) == NULL) { 2998 zerror(gettext("missing or invalid brand")); 2999 return (Z_ERR); 3000 } 3001 3002 (void) strcpy(cmdbuf, EXEC_PREFIX); 3003 if (brand_get_install(bh, target_zone, zonepath, cmdbuf + EXEC_LEN, 3004 sizeof (cmdbuf) - EXEC_LEN, 0, NULL) != 0) { 3005 zerror("invalid brand configuration: missing install resource"); 3006 brand_close(bh); 3007 return (Z_ERR); 3008 } 3009 3010 (void) strcpy(opts, "?x:"); 3011 if (!is_native_zone) { 3012 /* 3013 * Fetch the list of recognized command-line options from 3014 * the brand configuration file. 3015 */ 3016 if (brand_get_installopts(bh, opts + strlen(opts), 3017 sizeof (opts) - strlen(opts)) != 0) { 3018 zerror("invalid brand configuration: missing " 3019 "install options resource"); 3020 brand_close(bh); 3021 return (Z_ERR); 3022 } 3023 } 3024 brand_close(bh); 3025 3026 optind = 0; 3027 while ((arg = getopt(argc, argv, opts)) != EOF) { 3028 switch (arg) { 3029 case '?': 3030 sub_usage(SHELP_INSTALL, CMD_INSTALL); 3031 return (optopt == '?' ? Z_OK : Z_USAGE); 3032 case 'x': 3033 if (strcmp(optarg, "nodataset") != 0) { 3034 sub_usage(SHELP_INSTALL, CMD_INSTALL); 3035 return (Z_USAGE); 3036 } 3037 nodataset = B_TRUE; 3038 break; 3039 default: 3040 if (is_native_zone) { 3041 sub_usage(SHELP_INSTALL, CMD_INSTALL); 3042 return (Z_USAGE); 3043 } 3044 3045 /* 3046 * This option isn't for zoneadm, so append it to 3047 * the command line passed to the brand-specific 3048 * install routine. 3049 */ 3050 if (addopt(cmdbuf, optopt, optarg, 3051 sizeof (cmdbuf)) != Z_OK) { 3052 zerror("Install command line too long"); 3053 return (Z_ERR); 3054 } 3055 break; 3056 } 3057 } 3058 3059 if (!is_native_zone) { 3060 for (; optind < argc; optind++) { 3061 if (addopt(cmdbuf, 0, argv[optind], 3062 sizeof (cmdbuf)) != Z_OK) { 3063 zerror("Install command line too long"); 3064 return (Z_ERR); 3065 } 3066 } 3067 } 3068 3069 if (sanity_check(target_zone, CMD_INSTALL, B_FALSE, B_TRUE, B_FALSE) 3070 != Z_OK) 3071 return (Z_ERR); 3072 if (verify_details(CMD_INSTALL, argv) != Z_OK) 3073 return (Z_ERR); 3074 3075 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 3076 zerror(gettext("another %s may have an operation in progress."), 3077 "zoneadm"); 3078 return (Z_ERR); 3079 } 3080 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 3081 if (err != Z_OK) { 3082 errno = err; 3083 zperror2(target_zone, gettext("could not set state")); 3084 goto done; 3085 } 3086 3087 if (!nodataset) 3088 create_zfs_zonepath(zonepath); 3089 3090 /* 3091 * According to the Application Packaging Developer's Guide, a 3092 * "checkinstall" script when included in a package is executed as 3093 * the user "install", if such a user exists, or by the user 3094 * "nobody". In order to support this dubious behavior, the path 3095 * to the zone being constructed is opened up during the life of 3096 * the command laying down the zone's root file system. Once this 3097 * has completed, regardless of whether it was successful, the 3098 * path to the zone is again restricted. 3099 */ 3100 if (chmod(zonepath, DEFAULT_DIR_MODE) != 0) { 3101 zperror(zonepath, B_FALSE); 3102 err = Z_ERR; 3103 goto done; 3104 } 3105 3106 if (is_native_zone) 3107 status = do_subproc(cmdbuf); 3108 else 3109 status = do_subproc_interactive(cmdbuf); 3110 3111 if (chmod(zonepath, S_IRWXU) != 0) { 3112 zperror(zonepath, B_FALSE); 3113 err = Z_ERR; 3114 goto done; 3115 } 3116 if ((subproc_err = 3117 subproc_status(gettext("brand-specific installation"), status, 3118 B_FALSE)) != ZONE_SUBPROC_OK) { 3119 err = Z_ERR; 3120 goto done; 3121 } 3122 3123 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 3124 errno = err; 3125 zperror2(target_zone, gettext("could not set state")); 3126 goto done; 3127 } 3128 3129 done: 3130 /* 3131 * If the install script exited with ZONE_SUBPROC_USAGE or 3132 * ZONE_SUBPROC_NOTCOMPLETE, try to clean up the zone and leave the 3133 * zone in the CONFIGURED state so that another install can be 3134 * attempted without requiring an uninstall first. 3135 */ 3136 if ((subproc_err == ZONE_SUBPROC_USAGE) || 3137 (subproc_err == ZONE_SUBPROC_NOTCOMPLETE)) { 3138 if ((err = cleanup_zonepath(zonepath, B_FALSE)) != Z_OK) { 3139 errno = err; 3140 zperror2(target_zone, 3141 gettext("cleaning up zonepath failed")); 3142 } else if ((err = zone_set_state(target_zone, 3143 ZONE_STATE_CONFIGURED)) != Z_OK) { 3144 errno = err; 3145 zperror2(target_zone, gettext("could not set state")); 3146 } 3147 } 3148 3149 release_lock_file(lockfd); 3150 return ((err == Z_OK) ? Z_OK : Z_ERR); 3151 } 3152 3153 /* 3154 * Check that the inherited pkg dirs are the same for the clone and its source. 3155 * The easiest way to do that is check that the list of ipds is the same 3156 * by matching each one against the other. This algorithm should be fine since 3157 * the list of ipds should not be that long. 3158 */ 3159 static int 3160 valid_ipd_clone(zone_dochandle_t s_handle, char *source_zone, 3161 zone_dochandle_t t_handle, char *target_zone) 3162 { 3163 int err; 3164 int res = Z_OK; 3165 int s_cnt = 0; 3166 int t_cnt = 0; 3167 struct zone_fstab s_fstab; 3168 struct zone_fstab t_fstab; 3169 3170 /* 3171 * First check the source of the clone against the target. 3172 */ 3173 if ((err = zonecfg_setipdent(s_handle)) != Z_OK) { 3174 errno = err; 3175 zperror2(source_zone, gettext("could not enumerate " 3176 "inherit-pkg-dirs")); 3177 return (Z_ERR); 3178 } 3179 3180 while (zonecfg_getipdent(s_handle, &s_fstab) == Z_OK) { 3181 boolean_t match = B_FALSE; 3182 3183 s_cnt++; 3184 3185 if ((err = zonecfg_setipdent(t_handle)) != Z_OK) { 3186 errno = err; 3187 zperror2(target_zone, gettext("could not enumerate " 3188 "inherit-pkg-dirs")); 3189 (void) zonecfg_endipdent(s_handle); 3190 return (Z_ERR); 3191 } 3192 3193 while (zonecfg_getipdent(t_handle, &t_fstab) == Z_OK) { 3194 if (strcmp(s_fstab.zone_fs_dir, t_fstab.zone_fs_dir) 3195 == 0) { 3196 match = B_TRUE; 3197 break; 3198 } 3199 } 3200 (void) zonecfg_endipdent(t_handle); 3201 3202 if (!match) { 3203 (void) fprintf(stderr, gettext("inherit-pkg-dir " 3204 "'%s' is not configured in zone %s.\n"), 3205 s_fstab.zone_fs_dir, target_zone); 3206 res = Z_ERR; 3207 } 3208 } 3209 3210 (void) zonecfg_endipdent(s_handle); 3211 3212 /* skip the next check if we already have errors */ 3213 if (res == Z_ERR) 3214 return (res); 3215 3216 /* 3217 * Now check the number of ipds in the target so we can verify 3218 * that the source is not a subset of the target. 3219 */ 3220 if ((err = zonecfg_setipdent(t_handle)) != Z_OK) { 3221 errno = err; 3222 zperror2(target_zone, gettext("could not enumerate " 3223 "inherit-pkg-dirs")); 3224 return (Z_ERR); 3225 } 3226 3227 while (zonecfg_getipdent(t_handle, &t_fstab) == Z_OK) 3228 t_cnt++; 3229 3230 (void) zonecfg_endipdent(t_handle); 3231 3232 if (t_cnt != s_cnt) { 3233 (void) fprintf(stderr, gettext("Zone %s is configured " 3234 "with inherit-pkg-dirs that are not configured in zone " 3235 "%s.\n"), target_zone, source_zone); 3236 res = Z_ERR; 3237 } 3238 3239 return (res); 3240 } 3241 3242 static void 3243 warn_dev_match(zone_dochandle_t s_handle, char *source_zone, 3244 zone_dochandle_t t_handle, char *target_zone) 3245 { 3246 int err; 3247 struct zone_devtab s_devtab; 3248 struct zone_devtab t_devtab; 3249 3250 if ((err = zonecfg_setdevent(t_handle)) != Z_OK) { 3251 errno = err; 3252 zperror2(target_zone, gettext("could not enumerate devices")); 3253 return; 3254 } 3255 3256 while (zonecfg_getdevent(t_handle, &t_devtab) == Z_OK) { 3257 if ((err = zonecfg_setdevent(s_handle)) != Z_OK) { 3258 errno = err; 3259 zperror2(source_zone, 3260 gettext("could not enumerate devices")); 3261 (void) zonecfg_enddevent(t_handle); 3262 return; 3263 } 3264 3265 while (zonecfg_getdevent(s_handle, &s_devtab) == Z_OK) { 3266 /* 3267 * Use fnmatch to catch the case where wildcards 3268 * were used in one zone and the other has an 3269 * explicit entry (e.g. /dev/dsk/c0t0d0s6 vs. 3270 * /dev/\*dsk/c0t0d0s6). 3271 */ 3272 if (fnmatch(t_devtab.zone_dev_match, 3273 s_devtab.zone_dev_match, FNM_PATHNAME) == 0 || 3274 fnmatch(s_devtab.zone_dev_match, 3275 t_devtab.zone_dev_match, FNM_PATHNAME) == 0) { 3276 (void) fprintf(stderr, 3277 gettext("WARNING: device '%s' " 3278 "is configured in both zones.\n"), 3279 t_devtab.zone_dev_match); 3280 break; 3281 } 3282 } 3283 (void) zonecfg_enddevent(s_handle); 3284 } 3285 3286 (void) zonecfg_enddevent(t_handle); 3287 } 3288 3289 /* 3290 * Check if the specified mount option (opt) is contained within the 3291 * options string. 3292 */ 3293 static boolean_t 3294 opt_match(char *opt, char *options) 3295 { 3296 char *p; 3297 char *lastp; 3298 3299 if ((p = strtok_r(options, ",", &lastp)) != NULL) { 3300 if (strcmp(p, opt) == 0) 3301 return (B_TRUE); 3302 while ((p = strtok_r(NULL, ",", &lastp)) != NULL) { 3303 if (strcmp(p, opt) == 0) 3304 return (B_TRUE); 3305 } 3306 } 3307 3308 return (B_FALSE); 3309 } 3310 3311 #define RW_LOFS "WARNING: read-write lofs file system on '%s' is configured " \ 3312 "in both zones.\n" 3313 3314 static void 3315 print_fs_warnings(struct zone_fstab *s_fstab, struct zone_fstab *t_fstab) 3316 { 3317 /* 3318 * It is ok to have shared lofs mounted fs but we want to warn if 3319 * either is rw since this will effect the other zone. 3320 */ 3321 if (strcmp(t_fstab->zone_fs_type, "lofs") == 0) { 3322 zone_fsopt_t *optp; 3323 3324 /* The default is rw so no options means rw */ 3325 if (t_fstab->zone_fs_options == NULL || 3326 s_fstab->zone_fs_options == NULL) { 3327 (void) fprintf(stderr, gettext(RW_LOFS), 3328 t_fstab->zone_fs_special); 3329 return; 3330 } 3331 3332 for (optp = s_fstab->zone_fs_options; optp != NULL; 3333 optp = optp->zone_fsopt_next) { 3334 if (opt_match("rw", optp->zone_fsopt_opt)) { 3335 (void) fprintf(stderr, gettext(RW_LOFS), 3336 s_fstab->zone_fs_special); 3337 return; 3338 } 3339 } 3340 3341 for (optp = t_fstab->zone_fs_options; optp != NULL; 3342 optp = optp->zone_fsopt_next) { 3343 if (opt_match("rw", optp->zone_fsopt_opt)) { 3344 (void) fprintf(stderr, gettext(RW_LOFS), 3345 t_fstab->zone_fs_special); 3346 return; 3347 } 3348 } 3349 3350 return; 3351 } 3352 3353 /* 3354 * TRANSLATION_NOTE 3355 * The first variable is the file system type and the second is 3356 * the file system special device. For example, 3357 * WARNING: ufs file system on '/dev/dsk/c0t0d0s0' ... 3358 */ 3359 (void) fprintf(stderr, gettext("WARNING: %s file system on '%s' " 3360 "is configured in both zones.\n"), t_fstab->zone_fs_type, 3361 t_fstab->zone_fs_special); 3362 } 3363 3364 static void 3365 warn_fs_match(zone_dochandle_t s_handle, char *source_zone, 3366 zone_dochandle_t t_handle, char *target_zone) 3367 { 3368 int err; 3369 struct zone_fstab s_fstab; 3370 struct zone_fstab t_fstab; 3371 3372 if ((err = zonecfg_setfsent(t_handle)) != Z_OK) { 3373 errno = err; 3374 zperror2(target_zone, 3375 gettext("could not enumerate file systems")); 3376 return; 3377 } 3378 3379 while (zonecfg_getfsent(t_handle, &t_fstab) == Z_OK) { 3380 if ((err = zonecfg_setfsent(s_handle)) != Z_OK) { 3381 errno = err; 3382 zperror2(source_zone, 3383 gettext("could not enumerate file systems")); 3384 (void) zonecfg_endfsent(t_handle); 3385 return; 3386 } 3387 3388 while (zonecfg_getfsent(s_handle, &s_fstab) == Z_OK) { 3389 if (strcmp(t_fstab.zone_fs_special, 3390 s_fstab.zone_fs_special) == 0) { 3391 print_fs_warnings(&s_fstab, &t_fstab); 3392 break; 3393 } 3394 } 3395 (void) zonecfg_endfsent(s_handle); 3396 } 3397 3398 (void) zonecfg_endfsent(t_handle); 3399 } 3400 3401 /* 3402 * We don't catch the case where you used the same IP address but 3403 * it is not an exact string match. For example, 192.9.0.128 vs. 192.09.0.128. 3404 * However, we're not going to worry about that but we will check for 3405 * a possible netmask on one of the addresses (e.g. 10.0.0.1 and 10.0.0.1/24) 3406 * and handle that case as a match. 3407 */ 3408 static void 3409 warn_ip_match(zone_dochandle_t s_handle, char *source_zone, 3410 zone_dochandle_t t_handle, char *target_zone) 3411 { 3412 int err; 3413 struct zone_nwiftab s_nwiftab; 3414 struct zone_nwiftab t_nwiftab; 3415 3416 if ((err = zonecfg_setnwifent(t_handle)) != Z_OK) { 3417 errno = err; 3418 zperror2(target_zone, 3419 gettext("could not enumerate network interfaces")); 3420 return; 3421 } 3422 3423 while (zonecfg_getnwifent(t_handle, &t_nwiftab) == Z_OK) { 3424 char *p; 3425 3426 /* remove an (optional) netmask from the address */ 3427 if ((p = strchr(t_nwiftab.zone_nwif_address, '/')) != NULL) 3428 *p = '\0'; 3429 3430 if ((err = zonecfg_setnwifent(s_handle)) != Z_OK) { 3431 errno = err; 3432 zperror2(source_zone, 3433 gettext("could not enumerate network interfaces")); 3434 (void) zonecfg_endnwifent(t_handle); 3435 return; 3436 } 3437 3438 while (zonecfg_getnwifent(s_handle, &s_nwiftab) == Z_OK) { 3439 /* remove an (optional) netmask from the address */ 3440 if ((p = strchr(s_nwiftab.zone_nwif_address, '/')) 3441 != NULL) 3442 *p = '\0'; 3443 3444 if (strcmp(t_nwiftab.zone_nwif_address, 3445 s_nwiftab.zone_nwif_address) == 0) { 3446 (void) fprintf(stderr, 3447 gettext("WARNING: network address '%s' " 3448 "is configured in both zones.\n"), 3449 t_nwiftab.zone_nwif_address); 3450 break; 3451 } 3452 } 3453 (void) zonecfg_endnwifent(s_handle); 3454 } 3455 3456 (void) zonecfg_endnwifent(t_handle); 3457 } 3458 3459 static void 3460 warn_dataset_match(zone_dochandle_t s_handle, char *source, 3461 zone_dochandle_t t_handle, char *target) 3462 { 3463 int err; 3464 struct zone_dstab s_dstab; 3465 struct zone_dstab t_dstab; 3466 3467 if ((err = zonecfg_setdsent(t_handle)) != Z_OK) { 3468 errno = err; 3469 zperror2(target, gettext("could not enumerate datasets")); 3470 return; 3471 } 3472 3473 while (zonecfg_getdsent(t_handle, &t_dstab) == Z_OK) { 3474 if ((err = zonecfg_setdsent(s_handle)) != Z_OK) { 3475 errno = err; 3476 zperror2(source, 3477 gettext("could not enumerate datasets")); 3478 (void) zonecfg_enddsent(t_handle); 3479 return; 3480 } 3481 3482 while (zonecfg_getdsent(s_handle, &s_dstab) == Z_OK) { 3483 if (strcmp(t_dstab.zone_dataset_name, 3484 s_dstab.zone_dataset_name) == 0) { 3485 target_zone = source; 3486 zerror(gettext("WARNING: dataset '%s' " 3487 "is configured in both zones.\n"), 3488 t_dstab.zone_dataset_name); 3489 break; 3490 } 3491 } 3492 (void) zonecfg_enddsent(s_handle); 3493 } 3494 3495 (void) zonecfg_enddsent(t_handle); 3496 } 3497 3498 /* 3499 * Check that the clone and its source have the same brand type. 3500 */ 3501 static int 3502 valid_brand_clone(char *source_zone, char *target_zone) 3503 { 3504 brand_handle_t bh; 3505 char source_brand[MAXNAMELEN]; 3506 3507 if ((zone_get_brand(source_zone, source_brand, 3508 sizeof (source_brand))) != Z_OK) { 3509 (void) fprintf(stderr, "%s: zone '%s': %s\n", 3510 execname, source_zone, gettext("missing or invalid brand")); 3511 return (Z_ERR); 3512 } 3513 3514 if (strcmp(source_brand, target_brand) != NULL) { 3515 (void) fprintf(stderr, 3516 gettext("%s: Zones '%s' and '%s' have different brand " 3517 "types.\n"), execname, source_zone, target_zone); 3518 return (Z_ERR); 3519 } 3520 3521 if ((bh = brand_open(target_brand)) == NULL) { 3522 zerror(gettext("missing or invalid brand")); 3523 return (Z_ERR); 3524 } 3525 brand_close(bh); 3526 return (Z_OK); 3527 } 3528 3529 static int 3530 validate_clone(char *source_zone, char *target_zone) 3531 { 3532 int err = Z_OK; 3533 zone_dochandle_t s_handle; 3534 zone_dochandle_t t_handle; 3535 3536 if ((t_handle = zonecfg_init_handle()) == NULL) { 3537 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3538 return (Z_ERR); 3539 } 3540 if ((err = zonecfg_get_handle(target_zone, t_handle)) != Z_OK) { 3541 errno = err; 3542 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3543 zonecfg_fini_handle(t_handle); 3544 return (Z_ERR); 3545 } 3546 3547 if ((s_handle = zonecfg_init_handle()) == NULL) { 3548 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3549 zonecfg_fini_handle(t_handle); 3550 return (Z_ERR); 3551 } 3552 if ((err = zonecfg_get_handle(source_zone, s_handle)) != Z_OK) { 3553 errno = err; 3554 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 3555 goto done; 3556 } 3557 3558 /* verify new zone has same brand type */ 3559 err = valid_brand_clone(source_zone, target_zone); 3560 if (err != Z_OK) 3561 goto done; 3562 3563 /* verify new zone has same inherit-pkg-dirs */ 3564 err = valid_ipd_clone(s_handle, source_zone, t_handle, target_zone); 3565 3566 /* warn about imported fs's which are the same */ 3567 warn_fs_match(s_handle, source_zone, t_handle, target_zone); 3568 3569 /* warn about imported IP addresses which are the same */ 3570 warn_ip_match(s_handle, source_zone, t_handle, target_zone); 3571 3572 /* warn about imported devices which are the same */ 3573 warn_dev_match(s_handle, source_zone, t_handle, target_zone); 3574 3575 /* warn about imported datasets which are the same */ 3576 warn_dataset_match(s_handle, source_zone, t_handle, target_zone); 3577 3578 done: 3579 zonecfg_fini_handle(t_handle); 3580 zonecfg_fini_handle(s_handle); 3581 3582 return ((err == Z_OK) ? Z_OK : Z_ERR); 3583 } 3584 3585 static int 3586 copy_zone(char *src, char *dst) 3587 { 3588 boolean_t out_null = B_FALSE; 3589 int status; 3590 char *outfile; 3591 char cmdbuf[MAXPATHLEN * 2 + 128]; 3592 3593 if ((outfile = tempnam("/var/log", "zone")) == NULL) { 3594 outfile = "/dev/null"; 3595 out_null = B_TRUE; 3596 } 3597 3598 /* 3599 * Use find to get the list of files to copy. We need to skip 3600 * files of type "socket" since cpio can't handle those but that 3601 * should be ok since the app will recreate the socket when it runs. 3602 * We also need to filter out anything under the .zfs subdir. Since 3603 * find is running depth-first, we need the extra egrep to filter .zfs. 3604 */ 3605 (void) snprintf(cmdbuf, sizeof (cmdbuf), 3606 "cd %s && /usr/bin/find . -type s -prune -o -depth -print | " 3607 "/usr/bin/egrep -v '^\\./\\.zfs$|^\\./\\.zfs/' | " 3608 "/usr/bin/cpio -pdmuP@ %s > %s 2>&1", 3609 src, dst, outfile); 3610 3611 status = do_subproc(cmdbuf); 3612 3613 if (subproc_status("copy", status, B_TRUE) != ZONE_SUBPROC_OK) { 3614 if (!out_null) 3615 (void) fprintf(stderr, gettext("\nThe copy failed.\n" 3616 "More information can be found in %s\n"), outfile); 3617 return (Z_ERR); 3618 } 3619 3620 if (!out_null) 3621 (void) unlink(outfile); 3622 3623 return (Z_OK); 3624 } 3625 3626 static int 3627 zone_postclone(char *zonepath) 3628 { 3629 char cmdbuf[MAXPATHLEN]; 3630 int status; 3631 brand_handle_t bh; 3632 int err = Z_OK; 3633 3634 /* 3635 * Fetch the post-clone command, if any, from the brand 3636 * configuration. 3637 */ 3638 if ((bh = brand_open(target_brand)) == NULL) { 3639 zerror(gettext("missing or invalid brand")); 3640 return (Z_ERR); 3641 } 3642 (void) strcpy(cmdbuf, EXEC_PREFIX); 3643 err = brand_get_postclone(bh, target_zone, zonepath, cmdbuf + EXEC_LEN, 3644 sizeof (cmdbuf) - EXEC_LEN, 0, NULL); 3645 brand_close(bh); 3646 3647 if (err == 0 && strlen(cmdbuf) > EXEC_LEN) { 3648 status = do_subproc(cmdbuf); 3649 if ((err = subproc_status("postclone", status, B_FALSE)) 3650 != ZONE_SUBPROC_OK) { 3651 zerror(gettext("post-clone configuration failed.")); 3652 err = Z_ERR; 3653 } 3654 } 3655 3656 return (err); 3657 } 3658 3659 /* ARGSUSED */ 3660 static int 3661 zfm_print(const char *p, void *r) { 3662 zerror(" %s\n", p); 3663 return (0); 3664 } 3665 3666 int 3667 clone_copy(char *source_zonepath, char *zonepath) 3668 { 3669 int err; 3670 3671 /* Don't clone the zone if anything is still mounted there */ 3672 if (zonecfg_find_mounts(source_zonepath, NULL, NULL)) { 3673 zerror(gettext("These file systems are mounted on " 3674 "subdirectories of %s.\n"), source_zonepath); 3675 (void) zonecfg_find_mounts(source_zonepath, zfm_print, NULL); 3676 return (Z_ERR); 3677 } 3678 3679 /* 3680 * Attempt to create a ZFS fs for the zonepath. As usual, we don't 3681 * care if this works or not since we always have the default behavior 3682 * of a simple directory for the zonepath. 3683 */ 3684 create_zfs_zonepath(zonepath); 3685 3686 (void) printf(gettext("Copying %s..."), source_zonepath); 3687 (void) fflush(stdout); 3688 3689 err = copy_zone(source_zonepath, zonepath); 3690 3691 (void) printf("\n"); 3692 3693 return (err); 3694 } 3695 3696 static int 3697 clone_func(int argc, char *argv[]) 3698 { 3699 char *source_zone = NULL; 3700 int lockfd; 3701 int err, arg; 3702 char zonepath[MAXPATHLEN]; 3703 char source_zonepath[MAXPATHLEN]; 3704 zone_state_t state; 3705 zone_entry_t *zent; 3706 char *method = NULL; 3707 char *snapshot = NULL; 3708 3709 if (zonecfg_in_alt_root()) { 3710 zerror(gettext("cannot clone zone in alternate root")); 3711 return (Z_ERR); 3712 } 3713 3714 optind = 0; 3715 if ((arg = getopt(argc, argv, "?m:s:")) != EOF) { 3716 switch (arg) { 3717 case '?': 3718 sub_usage(SHELP_CLONE, CMD_CLONE); 3719 return (optopt == '?' ? Z_OK : Z_USAGE); 3720 case 'm': 3721 method = optarg; 3722 break; 3723 case 's': 3724 snapshot = optarg; 3725 break; 3726 default: 3727 sub_usage(SHELP_CLONE, CMD_CLONE); 3728 return (Z_USAGE); 3729 } 3730 } 3731 if (argc != (optind + 1) || 3732 (method != NULL && strcmp(method, "copy") != 0)) { 3733 sub_usage(SHELP_CLONE, CMD_CLONE); 3734 return (Z_USAGE); 3735 } 3736 source_zone = argv[optind]; 3737 if (sanity_check(target_zone, CMD_CLONE, B_FALSE, B_TRUE, B_FALSE) 3738 != Z_OK) 3739 return (Z_ERR); 3740 if (verify_details(CMD_CLONE, argv) != Z_OK) 3741 return (Z_ERR); 3742 3743 /* 3744 * We also need to do some extra validation on the source zone. 3745 */ 3746 if (strcmp(source_zone, GLOBAL_ZONENAME) == 0) { 3747 zerror(gettext("%s operation is invalid for the global zone."), 3748 cmd_to_str(CMD_CLONE)); 3749 return (Z_ERR); 3750 } 3751 3752 if (strncmp(source_zone, "SUNW", 4) == 0) { 3753 zerror(gettext("%s operation is invalid for zones starting " 3754 "with SUNW."), cmd_to_str(CMD_CLONE)); 3755 return (Z_ERR); 3756 } 3757 3758 zent = lookup_running_zone(source_zone); 3759 if (zent != NULL) { 3760 /* check whether the zone is ready or running */ 3761 if ((err = zone_get_state(zent->zname, &zent->zstate_num)) 3762 != Z_OK) { 3763 errno = err; 3764 zperror2(zent->zname, gettext("could not get state")); 3765 /* can't tell, so hedge */ 3766 zent->zstate_str = "ready/running"; 3767 } else { 3768 zent->zstate_str = zone_state_str(zent->zstate_num); 3769 } 3770 zerror(gettext("%s operation is invalid for %s zones."), 3771 cmd_to_str(CMD_CLONE), zent->zstate_str); 3772 return (Z_ERR); 3773 } 3774 3775 if ((err = zone_get_state(source_zone, &state)) != Z_OK) { 3776 errno = err; 3777 zperror2(source_zone, gettext("could not get state")); 3778 return (Z_ERR); 3779 } 3780 if (state != ZONE_STATE_INSTALLED) { 3781 (void) fprintf(stderr, 3782 gettext("%s: zone %s is %s; %s is required.\n"), 3783 execname, source_zone, zone_state_str(state), 3784 zone_state_str(ZONE_STATE_INSTALLED)); 3785 return (Z_ERR); 3786 } 3787 3788 /* 3789 * The source zone checks out ok, continue with the clone. 3790 */ 3791 3792 if (validate_clone(source_zone, target_zone) != Z_OK) 3793 return (Z_ERR); 3794 3795 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 3796 zerror(gettext("another %s may have an operation in progress."), 3797 "zoneadm"); 3798 return (Z_ERR); 3799 } 3800 3801 if ((err = zone_get_zonepath(source_zone, source_zonepath, 3802 sizeof (source_zonepath))) != Z_OK) { 3803 errno = err; 3804 zperror2(source_zone, gettext("could not get zone path")); 3805 goto done; 3806 } 3807 3808 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 3809 != Z_OK) { 3810 errno = err; 3811 zperror2(target_zone, gettext("could not get zone path")); 3812 goto done; 3813 } 3814 3815 if ((err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE)) 3816 != Z_OK) { 3817 errno = err; 3818 zperror2(target_zone, gettext("could not set state")); 3819 goto done; 3820 } 3821 3822 if (snapshot != NULL) { 3823 err = clone_snapshot_zfs(snapshot, zonepath); 3824 } else { 3825 /* 3826 * We always copy the clone unless the source is ZFS and a 3827 * ZFS clone worked. We fallback to copying if the ZFS clone 3828 * fails for some reason. 3829 */ 3830 err = Z_ERR; 3831 if (method == NULL && is_zonepath_zfs(source_zonepath)) 3832 err = clone_zfs(source_zone, source_zonepath, zonepath); 3833 3834 if (err != Z_OK) 3835 err = clone_copy(source_zonepath, zonepath); 3836 } 3837 3838 /* 3839 * Trusted Extensions requires that cloned zones use the same sysid 3840 * configuration, so it is not appropriate to perform any 3841 * post-clone reconfiguration. 3842 */ 3843 if ((err == Z_OK) && !is_system_labeled()) 3844 err = zone_postclone(zonepath); 3845 3846 done: 3847 /* 3848 * If everything went well, we mark the zone as installed. 3849 */ 3850 if (err == Z_OK) { 3851 err = zone_set_state(target_zone, ZONE_STATE_INSTALLED); 3852 if (err != Z_OK) { 3853 errno = err; 3854 zperror2(target_zone, gettext("could not set state")); 3855 } 3856 } 3857 release_lock_file(lockfd); 3858 return ((err == Z_OK) ? Z_OK : Z_ERR); 3859 } 3860 3861 /* 3862 * Used when removing a zonepath after uninstalling or cleaning up after 3863 * the move subcommand. This handles a zonepath that has non-standard 3864 * contents so that we will only cleanup the stuff we know about and leave 3865 * any user data alone. 3866 * 3867 * If the "all" parameter is true then we should remove the whole zonepath 3868 * even if it has non-standard files/directories in it. This can be used when 3869 * we need to cleanup after moving the zonepath across file systems. 3870 * 3871 * We "exec" the RMCOMMAND so that the returned status is that of RMCOMMAND 3872 * and not the shell. 3873 */ 3874 static int 3875 cleanup_zonepath(char *zonepath, boolean_t all) 3876 { 3877 int status; 3878 int i; 3879 boolean_t non_std = B_FALSE; 3880 struct dirent *dp; 3881 DIR *dirp; 3882 char *std_entries[] = {"dev", "lu", "root", NULL}; 3883 /* (MAXPATHLEN * 3) is for the 3 std_entries dirs */ 3884 char cmdbuf[sizeof (RMCOMMAND) + (MAXPATHLEN * 3) + 64]; 3885 3886 /* 3887 * We shouldn't need these checks but lets be paranoid since we 3888 * could blow away the whole system here if we got the wrong zonepath. 3889 */ 3890 if (*zonepath == NULL || strcmp(zonepath, "/") == 0) { 3891 (void) fprintf(stderr, "invalid zonepath '%s'\n", zonepath); 3892 return (Z_INVAL); 3893 } 3894 3895 /* 3896 * If the dirpath is already gone (maybe it was manually removed) then 3897 * we just return Z_OK so that the cleanup is successful. 3898 */ 3899 if ((dirp = opendir(zonepath)) == NULL) 3900 return (Z_OK); 3901 3902 /* 3903 * Look through the zonepath directory to see if there are any 3904 * non-standard files/dirs. Also skip .zfs since that might be 3905 * there but we'll handle ZFS file systems as a special case. 3906 */ 3907 while ((dp = readdir(dirp)) != NULL) { 3908 if (strcmp(dp->d_name, ".") == 0 || 3909 strcmp(dp->d_name, "..") == 0 || 3910 strcmp(dp->d_name, ".zfs") == 0) 3911 continue; 3912 3913 for (i = 0; std_entries[i] != NULL; i++) 3914 if (strcmp(dp->d_name, std_entries[i]) == 0) 3915 break; 3916 3917 if (std_entries[i] == NULL) 3918 non_std = B_TRUE; 3919 } 3920 (void) closedir(dirp); 3921 3922 if (!all && non_std) { 3923 /* 3924 * There are extra, non-standard directories/files in the 3925 * zonepath so we don't want to remove the zonepath. We 3926 * just want to remove the standard directories and leave 3927 * the user data alone. 3928 */ 3929 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND); 3930 3931 for (i = 0; std_entries[i] != NULL; i++) { 3932 char tmpbuf[MAXPATHLEN]; 3933 3934 if (snprintf(tmpbuf, sizeof (tmpbuf), " %s/%s", 3935 zonepath, std_entries[i]) >= sizeof (tmpbuf) || 3936 strlcat(cmdbuf, tmpbuf, sizeof (cmdbuf)) >= 3937 sizeof (cmdbuf)) { 3938 (void) fprintf(stderr, 3939 gettext("path is too long\n")); 3940 return (Z_INVAL); 3941 } 3942 } 3943 3944 status = do_subproc(cmdbuf); 3945 3946 (void) fprintf(stderr, gettext("WARNING: Unable to completely " 3947 "remove %s\nbecause it contains additional user data. " 3948 "Only the standard directory\nentries have been " 3949 "removed.\n"), 3950 zonepath); 3951 3952 return ((subproc_status(RMCOMMAND, status, B_TRUE) == 3953 ZONE_SUBPROC_OK) ? Z_OK : Z_ERR); 3954 } 3955 3956 /* 3957 * There is nothing unexpected in the zonepath, try to get rid of the 3958 * whole zonepath directory. 3959 * 3960 * If the zonepath is its own zfs file system, try to destroy the 3961 * file system. If that fails for some reason (e.g. it has clones) 3962 * then we'll just remove the contents of the zonepath. 3963 */ 3964 if (is_zonepath_zfs(zonepath)) { 3965 if (destroy_zfs(zonepath) == Z_OK) 3966 return (Z_OK); 3967 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND 3968 " %s/*", zonepath); 3969 status = do_subproc(cmdbuf); 3970 return ((subproc_status(RMCOMMAND, status, B_TRUE) == 3971 ZONE_SUBPROC_OK) ? Z_OK : Z_ERR); 3972 } 3973 3974 (void) snprintf(cmdbuf, sizeof (cmdbuf), "exec " RMCOMMAND " %s", 3975 zonepath); 3976 status = do_subproc(cmdbuf); 3977 3978 return ((subproc_status(RMCOMMAND, status, B_TRUE) == ZONE_SUBPROC_OK) 3979 ? Z_OK : Z_ERR); 3980 } 3981 3982 static int 3983 move_func(int argc, char *argv[]) 3984 { 3985 char *new_zonepath = NULL; 3986 int lockfd; 3987 int err, arg; 3988 char zonepath[MAXPATHLEN]; 3989 zone_dochandle_t handle; 3990 boolean_t fast; 3991 boolean_t is_zfs = B_FALSE; 3992 struct dirent *dp; 3993 DIR *dirp; 3994 boolean_t empty = B_TRUE; 3995 boolean_t revert; 3996 struct stat zonepath_buf; 3997 struct stat new_zonepath_buf; 3998 3999 if (zonecfg_in_alt_root()) { 4000 zerror(gettext("cannot move zone in alternate root")); 4001 return (Z_ERR); 4002 } 4003 4004 optind = 0; 4005 if ((arg = getopt(argc, argv, "?")) != EOF) { 4006 switch (arg) { 4007 case '?': 4008 sub_usage(SHELP_MOVE, CMD_MOVE); 4009 return (optopt == '?' ? Z_OK : Z_USAGE); 4010 default: 4011 sub_usage(SHELP_MOVE, CMD_MOVE); 4012 return (Z_USAGE); 4013 } 4014 } 4015 if (argc != (optind + 1)) { 4016 sub_usage(SHELP_MOVE, CMD_MOVE); 4017 return (Z_USAGE); 4018 } 4019 new_zonepath = argv[optind]; 4020 if (sanity_check(target_zone, CMD_MOVE, B_FALSE, B_TRUE, B_FALSE) 4021 != Z_OK) 4022 return (Z_ERR); 4023 if (verify_details(CMD_MOVE, argv) != Z_OK) 4024 return (Z_ERR); 4025 4026 /* 4027 * Check out the new zonepath. This has the side effect of creating 4028 * a directory for the new zonepath. We depend on this later when we 4029 * stat to see if we are doing a cross file system move or not. 4030 */ 4031 if (validate_zonepath(new_zonepath, CMD_MOVE) != Z_OK) 4032 return (Z_ERR); 4033 4034 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 4035 != Z_OK) { 4036 errno = err; 4037 zperror2(target_zone, gettext("could not get zone path")); 4038 return (Z_ERR); 4039 } 4040 4041 if (stat(zonepath, &zonepath_buf) == -1) { 4042 zperror(gettext("could not stat zone path"), B_FALSE); 4043 return (Z_ERR); 4044 } 4045 4046 if (stat(new_zonepath, &new_zonepath_buf) == -1) { 4047 zperror(gettext("could not stat new zone path"), B_FALSE); 4048 return (Z_ERR); 4049 } 4050 4051 /* 4052 * Check if the destination directory is empty. 4053 */ 4054 if ((dirp = opendir(new_zonepath)) == NULL) { 4055 zperror(gettext("could not open new zone path"), B_FALSE); 4056 return (Z_ERR); 4057 } 4058 while ((dp = readdir(dirp)) != (struct dirent *)0) { 4059 if (strcmp(dp->d_name, ".") == 0 || 4060 strcmp(dp->d_name, "..") == 0) 4061 continue; 4062 empty = B_FALSE; 4063 break; 4064 } 4065 (void) closedir(dirp); 4066 4067 /* Error if there is anything in the destination directory. */ 4068 if (!empty) { 4069 (void) fprintf(stderr, gettext("could not move zone to %s: " 4070 "directory not empty\n"), new_zonepath); 4071 return (Z_ERR); 4072 } 4073 4074 /* Don't move the zone if anything is still mounted there */ 4075 if (zonecfg_find_mounts(zonepath, NULL, NULL)) { 4076 zerror(gettext("These file systems are mounted on " 4077 "subdirectories of %s.\n"), zonepath); 4078 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 4079 return (Z_ERR); 4080 } 4081 4082 /* 4083 * Check if we are moving in the same file system and can do a fast 4084 * move or if we are crossing file systems and have to copy the data. 4085 */ 4086 fast = (zonepath_buf.st_dev == new_zonepath_buf.st_dev); 4087 4088 if ((handle = zonecfg_init_handle()) == NULL) { 4089 zperror(cmd_to_str(CMD_MOVE), B_TRUE); 4090 return (Z_ERR); 4091 } 4092 4093 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 4094 errno = err; 4095 zperror(cmd_to_str(CMD_MOVE), B_TRUE); 4096 zonecfg_fini_handle(handle); 4097 return (Z_ERR); 4098 } 4099 4100 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 4101 zerror(gettext("another %s may have an operation in progress."), 4102 "zoneadm"); 4103 zonecfg_fini_handle(handle); 4104 return (Z_ERR); 4105 } 4106 4107 /* 4108 * We're making some file system changes now so we have to clean up 4109 * the file system before we are done. This will either clean up the 4110 * new zonepath if the zonecfg update failed or it will clean up the 4111 * old zonepath if everything is ok. 4112 */ 4113 revert = B_TRUE; 4114 4115 if (is_zonepath_zfs(zonepath) && 4116 move_zfs(zonepath, new_zonepath) != Z_ERR) { 4117 is_zfs = B_TRUE; 4118 4119 } else if (fast) { 4120 /* same file system, use rename for a quick move */ 4121 4122 /* 4123 * Remove the new_zonepath directory that got created above 4124 * during the validation. It gets in the way of the rename. 4125 */ 4126 if (rmdir(new_zonepath) != 0) { 4127 zperror(gettext("could not rmdir new zone path"), 4128 B_FALSE); 4129 zonecfg_fini_handle(handle); 4130 release_lock_file(lockfd); 4131 return (Z_ERR); 4132 } 4133 4134 if (rename(zonepath, new_zonepath) != 0) { 4135 /* 4136 * If this fails we don't need to do all of the 4137 * cleanup that happens for the rest of the code 4138 * so just return from this error. 4139 */ 4140 zperror(gettext("could not move zone"), B_FALSE); 4141 zonecfg_fini_handle(handle); 4142 release_lock_file(lockfd); 4143 return (Z_ERR); 4144 } 4145 4146 } else { 4147 /* 4148 * Attempt to create a ZFS fs for the new zonepath. As usual, 4149 * we don't care if this works or not since we always have the 4150 * default behavior of a simple directory for the zonepath. 4151 */ 4152 create_zfs_zonepath(new_zonepath); 4153 4154 (void) printf(gettext( 4155 "Moving across file systems; copying zonepath %s..."), 4156 zonepath); 4157 (void) fflush(stdout); 4158 4159 err = copy_zone(zonepath, new_zonepath); 4160 4161 (void) printf("\n"); 4162 if (err != Z_OK) 4163 goto done; 4164 } 4165 4166 if ((err = zonecfg_set_zonepath(handle, new_zonepath)) != Z_OK) { 4167 errno = err; 4168 zperror(gettext("could not set new zonepath"), B_TRUE); 4169 goto done; 4170 } 4171 4172 if ((err = zonecfg_save(handle)) != Z_OK) { 4173 errno = err; 4174 zperror(gettext("zonecfg save failed"), B_TRUE); 4175 goto done; 4176 } 4177 4178 revert = B_FALSE; 4179 4180 done: 4181 zonecfg_fini_handle(handle); 4182 release_lock_file(lockfd); 4183 4184 /* 4185 * Clean up the file system based on how things went. We either 4186 * clean up the new zonepath if the operation failed for some reason 4187 * or we clean up the old zonepath if everything is ok. 4188 */ 4189 if (revert) { 4190 /* The zonecfg update failed, cleanup the new zonepath. */ 4191 if (is_zfs) { 4192 if (move_zfs(new_zonepath, zonepath) == Z_ERR) { 4193 (void) fprintf(stderr, gettext("could not " 4194 "restore zonepath, the zfs mountpoint is " 4195 "set as:\n%s\n"), new_zonepath); 4196 /* 4197 * err is already != Z_OK since we're reverting 4198 */ 4199 } 4200 4201 } else if (fast) { 4202 if (rename(new_zonepath, zonepath) != 0) { 4203 zperror(gettext("could not restore zonepath"), 4204 B_FALSE); 4205 /* 4206 * err is already != Z_OK since we're reverting 4207 */ 4208 } 4209 } else { 4210 (void) printf(gettext("Cleaning up zonepath %s..."), 4211 new_zonepath); 4212 (void) fflush(stdout); 4213 err = cleanup_zonepath(new_zonepath, B_TRUE); 4214 (void) printf("\n"); 4215 4216 if (err != Z_OK) { 4217 errno = err; 4218 zperror(gettext("could not remove new " 4219 "zonepath"), B_TRUE); 4220 } else { 4221 /* 4222 * Because we're reverting we know the mainline 4223 * code failed but we just reused the err 4224 * variable so we reset it back to Z_ERR. 4225 */ 4226 err = Z_ERR; 4227 } 4228 } 4229 4230 } else { 4231 /* The move was successful, cleanup the old zonepath. */ 4232 if (!is_zfs && !fast) { 4233 (void) printf( 4234 gettext("Cleaning up zonepath %s..."), zonepath); 4235 (void) fflush(stdout); 4236 err = cleanup_zonepath(zonepath, B_TRUE); 4237 (void) printf("\n"); 4238 4239 if (err != Z_OK) { 4240 errno = err; 4241 zperror(gettext("could not remove zonepath"), 4242 B_TRUE); 4243 } 4244 } 4245 } 4246 4247 return ((err == Z_OK) ? Z_OK : Z_ERR); 4248 } 4249 4250 static int 4251 detach_func(int argc, char *argv[]) 4252 { 4253 int lockfd; 4254 int err, arg; 4255 char zonepath[MAXPATHLEN]; 4256 zone_dochandle_t handle; 4257 boolean_t execute = B_TRUE; 4258 4259 if (zonecfg_in_alt_root()) { 4260 zerror(gettext("cannot detach zone in alternate root")); 4261 return (Z_ERR); 4262 } 4263 4264 optind = 0; 4265 if ((arg = getopt(argc, argv, "?n")) != EOF) { 4266 switch (arg) { 4267 case '?': 4268 sub_usage(SHELP_DETACH, CMD_DETACH); 4269 return (optopt == '?' ? Z_OK : Z_USAGE); 4270 case 'n': 4271 execute = B_FALSE; 4272 break; 4273 default: 4274 sub_usage(SHELP_DETACH, CMD_DETACH); 4275 return (Z_USAGE); 4276 } 4277 } 4278 4279 if (execute) { 4280 if (sanity_check(target_zone, CMD_DETACH, B_FALSE, B_TRUE, 4281 B_FALSE) != Z_OK) 4282 return (Z_ERR); 4283 if (verify_details(CMD_DETACH, argv) != Z_OK) 4284 return (Z_ERR); 4285 } else { 4286 /* 4287 * We want a dry-run to work for a non-privileged user so we 4288 * only do minimal validation. 4289 */ 4290 if (getzoneid() != GLOBAL_ZONEID) { 4291 zerror(gettext("must be in the global zone to %s a " 4292 "zone."), cmd_to_str(CMD_DETACH)); 4293 return (Z_ERR); 4294 } 4295 4296 if (target_zone == NULL) { 4297 zerror(gettext("no zone specified")); 4298 return (Z_ERR); 4299 } 4300 4301 if (strcmp(target_zone, GLOBAL_ZONENAME) == 0) { 4302 zerror(gettext("%s operation is invalid for the " 4303 "global zone."), cmd_to_str(CMD_DETACH)); 4304 return (Z_ERR); 4305 } 4306 } 4307 4308 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 4309 != Z_OK) { 4310 errno = err; 4311 zperror2(target_zone, gettext("could not get zone path")); 4312 return (Z_ERR); 4313 } 4314 4315 /* Don't detach the zone if anything is still mounted there */ 4316 if (execute && zonecfg_find_mounts(zonepath, NULL, NULL)) { 4317 zerror(gettext("These file systems are mounted on " 4318 "subdirectories of %s.\n"), zonepath); 4319 (void) zonecfg_find_mounts(zonepath, zfm_print, NULL); 4320 return (Z_ERR); 4321 } 4322 4323 if ((handle = zonecfg_init_handle()) == NULL) { 4324 zperror(cmd_to_str(CMD_DETACH), B_TRUE); 4325 return (Z_ERR); 4326 } 4327 4328 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 4329 errno = err; 4330 zperror(cmd_to_str(CMD_DETACH), B_TRUE); 4331 zonecfg_fini_handle(handle); 4332 return (Z_ERR); 4333 } 4334 4335 if (execute && grab_lock_file(target_zone, &lockfd) != Z_OK) { 4336 zerror(gettext("another %s may have an operation in progress."), 4337 "zoneadm"); 4338 zonecfg_fini_handle(handle); 4339 return (Z_ERR); 4340 } 4341 4342 if ((err = zonecfg_get_detach_info(handle, B_TRUE)) != Z_OK) { 4343 errno = err; 4344 zperror(gettext("getting the detach information failed"), 4345 B_TRUE); 4346 goto done; 4347 } 4348 4349 if ((err = zonecfg_detach_save(handle, (execute ? 0 : ZONE_DRY_RUN))) 4350 != Z_OK) { 4351 errno = err; 4352 zperror(gettext("saving the detach manifest failed"), B_TRUE); 4353 goto done; 4354 } 4355 4356 /* 4357 * Set the zone state back to configured unless we are running with the 4358 * no-execute option. 4359 */ 4360 if (execute && (err = zone_set_state(target_zone, 4361 ZONE_STATE_CONFIGURED)) != Z_OK) { 4362 errno = err; 4363 zperror(gettext("could not reset state"), B_TRUE); 4364 } 4365 4366 done: 4367 zonecfg_fini_handle(handle); 4368 if (execute) 4369 release_lock_file(lockfd); 4370 4371 return ((err == Z_OK) ? Z_OK : Z_ERR); 4372 } 4373 4374 /* 4375 * During attach we go through and fix up the /dev entries for the zone 4376 * we are attaching. In order to regenerate /dev with the correct devices, 4377 * the old /dev will be removed, the zone readied (which generates a new 4378 * /dev) then halted, then we use the info from the manifest to update 4379 * the modes, owners, etc. on the new /dev. 4380 */ 4381 static int 4382 dev_fix(zone_dochandle_t handle) 4383 { 4384 int res; 4385 int err; 4386 int status; 4387 struct zone_devpermtab devtab; 4388 zone_cmd_arg_t zarg; 4389 char devpath[MAXPATHLEN]; 4390 /* 6: "exec " and " " */ 4391 char cmdbuf[sizeof (RMCOMMAND) + MAXPATHLEN + 6]; 4392 4393 if ((res = zonecfg_get_zonepath(handle, devpath, sizeof (devpath))) 4394 != Z_OK) 4395 return (res); 4396 4397 if (strlcat(devpath, "/dev", sizeof (devpath)) >= sizeof (devpath)) 4398 return (Z_TOO_BIG); 4399 4400 /* 4401 * "exec" the command so that the returned status is that of 4402 * RMCOMMAND and not the shell. 4403 */ 4404 (void) snprintf(cmdbuf, sizeof (cmdbuf), EXEC_PREFIX RMCOMMAND " %s", 4405 devpath); 4406 status = do_subproc(cmdbuf); 4407 if ((err = subproc_status(RMCOMMAND, status, B_TRUE)) != 4408 ZONE_SUBPROC_OK) { 4409 (void) fprintf(stderr, 4410 gettext("could not remove existing /dev\n")); 4411 return (Z_ERR); 4412 } 4413 4414 /* In order to ready the zone, it must be in the installed state */ 4415 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 4416 errno = err; 4417 zperror(gettext("could not reset state"), B_TRUE); 4418 return (Z_ERR); 4419 } 4420 4421 /* We have to ready the zone to regen the dev tree */ 4422 zarg.cmd = Z_READY; 4423 if (call_zoneadmd(target_zone, &zarg) != 0) { 4424 zerror(gettext("call to %s failed"), "zoneadmd"); 4425 /* attempt to restore zone to configured state */ 4426 (void) zone_set_state(target_zone, ZONE_STATE_CONFIGURED); 4427 return (Z_ERR); 4428 } 4429 4430 zarg.cmd = Z_HALT; 4431 if (call_zoneadmd(target_zone, &zarg) != 0) { 4432 zerror(gettext("call to %s failed"), "zoneadmd"); 4433 /* attempt to restore zone to configured state */ 4434 (void) zone_set_state(target_zone, ZONE_STATE_CONFIGURED); 4435 return (Z_ERR); 4436 } 4437 4438 /* attempt to restore zone to configured state */ 4439 (void) zone_set_state(target_zone, ZONE_STATE_CONFIGURED); 4440 4441 if (zonecfg_setdevperment(handle) != Z_OK) { 4442 (void) fprintf(stderr, 4443 gettext("unable to enumerate device entries\n")); 4444 return (Z_ERR); 4445 } 4446 4447 while (zonecfg_getdevperment(handle, &devtab) == Z_OK) { 4448 int err; 4449 4450 if ((err = zonecfg_devperms_apply(handle, 4451 devtab.zone_devperm_name, devtab.zone_devperm_uid, 4452 devtab.zone_devperm_gid, devtab.zone_devperm_mode, 4453 devtab.zone_devperm_acl)) != Z_OK && err != Z_INVAL) 4454 (void) fprintf(stderr, gettext("error updating device " 4455 "%s: %s\n"), devtab.zone_devperm_name, 4456 zonecfg_strerror(err)); 4457 4458 free(devtab.zone_devperm_acl); 4459 } 4460 4461 (void) zonecfg_enddevperment(handle); 4462 4463 return (Z_OK); 4464 } 4465 4466 /* 4467 * Validate attaching a zone but don't actually do the work. The zone 4468 * does not have to exist, so there is some complexity getting a new zone 4469 * configuration set up so that we can perform the validation. This is 4470 * handled within zonecfg_attach_manifest() which returns two handles; one 4471 * for the the full configuration to validate (rem_handle) and the other 4472 * (local_handle) containing only the zone configuration derived from the 4473 * manifest. 4474 */ 4475 static int 4476 dryrun_attach(char *manifest_path, char *argv[]) 4477 { 4478 int fd; 4479 int err; 4480 int res; 4481 zone_dochandle_t local_handle; 4482 zone_dochandle_t rem_handle = NULL; 4483 4484 if (strcmp(manifest_path, "-") == 0) { 4485 fd = 0; 4486 } else if ((fd = open(manifest_path, O_RDONLY)) < 0) { 4487 zperror(gettext("could not open manifest path"), B_FALSE); 4488 return (Z_ERR); 4489 } 4490 4491 if ((local_handle = zonecfg_init_handle()) == NULL) { 4492 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4493 res = Z_ERR; 4494 goto done; 4495 } 4496 4497 if ((rem_handle = zonecfg_init_handle()) == NULL) { 4498 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4499 res = Z_ERR; 4500 goto done; 4501 } 4502 4503 if ((err = zonecfg_attach_manifest(fd, local_handle, rem_handle)) 4504 != Z_OK) { 4505 if (err == Z_INVALID_DOCUMENT) 4506 zerror(gettext("Cannot attach to an earlier release " 4507 "of the operating system")); 4508 else 4509 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4510 res = Z_ERR; 4511 goto done; 4512 } 4513 4514 /* 4515 * Retrieve remote handle brand type and determine whether it is 4516 * native or not. 4517 */ 4518 if (zonecfg_get_brand(rem_handle, target_brand, sizeof (target_brand)) 4519 != Z_OK) { 4520 zerror(gettext("missing or invalid brand")); 4521 exit(Z_ERR); 4522 } 4523 is_native_zone = (strcmp(target_brand, NATIVE_BRAND_NAME) == 0); 4524 4525 res = verify_handle(CMD_ATTACH, local_handle, argv); 4526 4527 /* Get the detach information for the locally defined zone. */ 4528 if ((err = zonecfg_get_detach_info(local_handle, B_FALSE)) != Z_OK) { 4529 errno = err; 4530 zperror(gettext("getting the attach information failed"), 4531 B_TRUE); 4532 res = Z_ERR; 4533 } else { 4534 /* sw_cmp prints error msgs as necessary */ 4535 if (sw_cmp(local_handle, rem_handle, SW_CMP_NONE) != Z_OK) 4536 res = Z_ERR; 4537 } 4538 4539 done: 4540 if (strcmp(manifest_path, "-") != 0) 4541 (void) close(fd); 4542 4543 zonecfg_fini_handle(local_handle); 4544 zonecfg_fini_handle(rem_handle); 4545 4546 return ((res == Z_OK) ? Z_OK : Z_ERR); 4547 } 4548 4549 static int 4550 attach_func(int argc, char *argv[]) 4551 { 4552 int lockfd; 4553 int err, arg; 4554 boolean_t force = B_FALSE; 4555 zone_dochandle_t handle; 4556 zone_dochandle_t athandle = NULL; 4557 char zonepath[MAXPATHLEN]; 4558 char brand[MAXNAMELEN], atbrand[MAXNAMELEN]; 4559 boolean_t execute = B_TRUE; 4560 char *manifest_path; 4561 4562 if (zonecfg_in_alt_root()) { 4563 zerror(gettext("cannot attach zone in alternate root")); 4564 return (Z_ERR); 4565 } 4566 4567 optind = 0; 4568 if ((arg = getopt(argc, argv, "?Fn:")) != EOF) { 4569 switch (arg) { 4570 case '?': 4571 sub_usage(SHELP_ATTACH, CMD_ATTACH); 4572 return (optopt == '?' ? Z_OK : Z_USAGE); 4573 case 'F': 4574 force = B_TRUE; 4575 break; 4576 case 'n': 4577 execute = B_FALSE; 4578 manifest_path = optarg; 4579 break; 4580 default: 4581 sub_usage(SHELP_ATTACH, CMD_ATTACH); 4582 return (Z_USAGE); 4583 } 4584 } 4585 4586 /* 4587 * If the no-execute option was specified, we need to branch down 4588 * a completely different path since there is no zone required to be 4589 * configured for this option. 4590 */ 4591 if (!execute) 4592 return (dryrun_attach(manifest_path, argv)); 4593 4594 if (sanity_check(target_zone, CMD_ATTACH, B_FALSE, B_TRUE, B_FALSE) 4595 != Z_OK) 4596 return (Z_ERR); 4597 if (verify_details(CMD_ATTACH, argv) != Z_OK) 4598 return (Z_ERR); 4599 4600 if ((err = zone_get_zonepath(target_zone, zonepath, sizeof (zonepath))) 4601 != Z_OK) { 4602 errno = err; 4603 zperror2(target_zone, gettext("could not get zone path")); 4604 return (Z_ERR); 4605 } 4606 4607 if ((handle = zonecfg_init_handle()) == NULL) { 4608 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4609 return (Z_ERR); 4610 } 4611 4612 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 4613 errno = err; 4614 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4615 zonecfg_fini_handle(handle); 4616 return (Z_ERR); 4617 } 4618 4619 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 4620 zerror(gettext("another %s may have an operation in progress."), 4621 "zoneadm"); 4622 zonecfg_fini_handle(handle); 4623 return (Z_ERR); 4624 } 4625 4626 if (force) 4627 goto forced; 4628 4629 if ((athandle = zonecfg_init_handle()) == NULL) { 4630 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4631 goto done; 4632 } 4633 4634 if ((err = zonecfg_get_attach_handle(zonepath, target_zone, B_TRUE, 4635 athandle)) != Z_OK) { 4636 if (err == Z_NO_ZONE) 4637 zerror(gettext("Not a detached zone")); 4638 else if (err == Z_INVALID_DOCUMENT) 4639 zerror(gettext("Cannot attach to an earlier release " 4640 "of the operating system")); 4641 else 4642 zperror(cmd_to_str(CMD_ATTACH), B_TRUE); 4643 goto done; 4644 } 4645 4646 /* Get the detach information for the locally defined zone. */ 4647 if ((err = zonecfg_get_detach_info(handle, B_FALSE)) != Z_OK) { 4648 errno = err; 4649 zperror(gettext("getting the attach information failed"), 4650 B_TRUE); 4651 goto done; 4652 } 4653 4654 /* 4655 * Ensure that the detached and locally defined zones are both of 4656 * the same brand. 4657 */ 4658 if ((zonecfg_get_brand(handle, brand, sizeof (brand)) != 0) || 4659 (zonecfg_get_brand(athandle, atbrand, sizeof (atbrand)) != 0)) { 4660 err = Z_ERR; 4661 zerror(gettext("missing or invalid brand")); 4662 goto done; 4663 } 4664 4665 if (strcmp(atbrand, brand) != NULL) { 4666 err = Z_ERR; 4667 zerror(gettext("Trying to attach a '%s' zone to a '%s' " 4668 "configuration."), atbrand, brand); 4669 goto done; 4670 } 4671 4672 /* sw_cmp prints error msgs as necessary */ 4673 if ((err = sw_cmp(handle, athandle, SW_CMP_NONE)) != Z_OK) 4674 goto done; 4675 4676 if ((err = dev_fix(athandle)) != Z_OK) 4677 goto done; 4678 4679 forced: 4680 4681 zonecfg_rm_detached(handle, force); 4682 4683 if ((err = zone_set_state(target_zone, ZONE_STATE_INSTALLED)) != Z_OK) { 4684 errno = err; 4685 zperror(gettext("could not reset state"), B_TRUE); 4686 } 4687 4688 done: 4689 zonecfg_fini_handle(handle); 4690 release_lock_file(lockfd); 4691 if (athandle != NULL) 4692 zonecfg_fini_handle(athandle); 4693 4694 return ((err == Z_OK) ? Z_OK : Z_ERR); 4695 } 4696 4697 /* 4698 * On input, TRUE => yes, FALSE => no. 4699 * On return, TRUE => 1, FALSE => 0, could not ask => -1. 4700 */ 4701 4702 static int 4703 ask_yesno(boolean_t default_answer, const char *question) 4704 { 4705 char line[64]; /* should be large enough to answer yes or no */ 4706 4707 if (!isatty(STDIN_FILENO)) 4708 return (-1); 4709 for (;;) { 4710 (void) printf("%s (%s)? ", question, 4711 default_answer ? "[y]/n" : "y/[n]"); 4712 if (fgets(line, sizeof (line), stdin) == NULL || 4713 line[0] == '\n') 4714 return (default_answer ? 1 : 0); 4715 if (tolower(line[0]) == 'y') 4716 return (1); 4717 if (tolower(line[0]) == 'n') 4718 return (0); 4719 } 4720 } 4721 4722 static int 4723 uninstall_func(int argc, char *argv[]) 4724 { 4725 char line[ZONENAME_MAX + 128]; /* Enough for "Are you sure ..." */ 4726 char rootpath[MAXPATHLEN], zonepath[MAXPATHLEN]; 4727 boolean_t force = B_FALSE; 4728 int lockfd, answer; 4729 int err, arg; 4730 4731 if (zonecfg_in_alt_root()) { 4732 zerror(gettext("cannot uninstall zone in alternate root")); 4733 return (Z_ERR); 4734 } 4735 4736 optind = 0; 4737 while ((arg = getopt(argc, argv, "?F")) != EOF) { 4738 switch (arg) { 4739 case '?': 4740 sub_usage(SHELP_UNINSTALL, CMD_UNINSTALL); 4741 return (optopt == '?' ? Z_OK : Z_USAGE); 4742 case 'F': 4743 force = B_TRUE; 4744 break; 4745 default: 4746 sub_usage(SHELP_UNINSTALL, CMD_UNINSTALL); 4747 return (Z_USAGE); 4748 } 4749 } 4750 if (argc > optind) { 4751 sub_usage(SHELP_UNINSTALL, CMD_UNINSTALL); 4752 return (Z_USAGE); 4753 } 4754 4755 if (sanity_check(target_zone, CMD_UNINSTALL, B_FALSE, B_TRUE, B_FALSE) 4756 != Z_OK) 4757 return (Z_ERR); 4758 4759 /* 4760 * Invoke brand-specific handler. 4761 */ 4762 if (invoke_brand_handler(CMD_UNINSTALL, argv) != Z_OK) 4763 return (Z_ERR); 4764 4765 if (!force) { 4766 (void) snprintf(line, sizeof (line), 4767 gettext("Are you sure you want to %s zone %s"), 4768 cmd_to_str(CMD_UNINSTALL), target_zone); 4769 if ((answer = ask_yesno(B_FALSE, line)) == 0) { 4770 return (Z_OK); 4771 } else if (answer == -1) { 4772 zerror(gettext("Input not from terminal and -F " 4773 "not specified: %s not done."), 4774 cmd_to_str(CMD_UNINSTALL)); 4775 return (Z_ERR); 4776 } 4777 } 4778 4779 if ((err = zone_get_zonepath(target_zone, zonepath, 4780 sizeof (zonepath))) != Z_OK) { 4781 errno = err; 4782 zperror2(target_zone, gettext("could not get zone path")); 4783 return (Z_ERR); 4784 } 4785 if ((err = zone_get_rootpath(target_zone, rootpath, 4786 sizeof (rootpath))) != Z_OK) { 4787 errno = err; 4788 zperror2(target_zone, gettext("could not get root path")); 4789 return (Z_ERR); 4790 } 4791 4792 /* 4793 * If there seems to be a zoneadmd running for this zone, call it 4794 * to tell it that an uninstall is happening; if all goes well it 4795 * will then shut itself down. 4796 */ 4797 if (ping_zoneadmd(target_zone) == Z_OK) { 4798 zone_cmd_arg_t zarg; 4799 zarg.cmd = Z_NOTE_UNINSTALLING; 4800 /* we don't care too much if this fails... just plow on */ 4801 (void) call_zoneadmd(target_zone, &zarg); 4802 } 4803 4804 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 4805 zerror(gettext("another %s may have an operation in progress."), 4806 "zoneadm"); 4807 return (Z_ERR); 4808 } 4809 4810 /* Don't uninstall the zone if anything is mounted there */ 4811 err = zonecfg_find_mounts(rootpath, NULL, NULL); 4812 if (err) { 4813 zerror(gettext("These file systems are mounted on " 4814 "subdirectories of %s.\n"), rootpath); 4815 (void) zonecfg_find_mounts(rootpath, zfm_print, NULL); 4816 return (Z_ERR); 4817 } 4818 4819 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 4820 if (err != Z_OK) { 4821 errno = err; 4822 zperror2(target_zone, gettext("could not set state")); 4823 goto bad; 4824 } 4825 4826 if ((err = cleanup_zonepath(zonepath, B_FALSE)) != Z_OK) { 4827 errno = err; 4828 zperror2(target_zone, gettext("cleaning up zonepath failed")); 4829 goto bad; 4830 } 4831 4832 err = zone_set_state(target_zone, ZONE_STATE_CONFIGURED); 4833 if (err != Z_OK) { 4834 errno = err; 4835 zperror2(target_zone, gettext("could not reset state")); 4836 } 4837 bad: 4838 release_lock_file(lockfd); 4839 return (err); 4840 } 4841 4842 /* ARGSUSED */ 4843 static int 4844 mount_func(int argc, char *argv[]) 4845 { 4846 zone_cmd_arg_t zarg; 4847 boolean_t force = B_FALSE; 4848 int arg; 4849 4850 /* 4851 * The only supported subargument to the "mount" subcommand is 4852 * "-f", which forces us to mount a zone in the INCOMPLETE state. 4853 */ 4854 optind = 0; 4855 if ((arg = getopt(argc, argv, "f")) != EOF) { 4856 switch (arg) { 4857 case 'f': 4858 force = B_TRUE; 4859 break; 4860 default: 4861 return (Z_USAGE); 4862 } 4863 } 4864 if (argc > optind) 4865 return (Z_USAGE); 4866 4867 if (sanity_check(target_zone, CMD_MOUNT, B_FALSE, B_FALSE, force) 4868 != Z_OK) 4869 return (Z_ERR); 4870 if (verify_details(CMD_MOUNT, argv) != Z_OK) 4871 return (Z_ERR); 4872 4873 zarg.cmd = force ? Z_FORCEMOUNT : Z_MOUNT; 4874 if (call_zoneadmd(target_zone, &zarg) != 0) { 4875 zerror(gettext("call to %s failed"), "zoneadmd"); 4876 return (Z_ERR); 4877 } 4878 return (Z_OK); 4879 } 4880 4881 /* ARGSUSED */ 4882 static int 4883 unmount_func(int argc, char *argv[]) 4884 { 4885 zone_cmd_arg_t zarg; 4886 4887 if (argc > 0) 4888 return (Z_USAGE); 4889 if (sanity_check(target_zone, CMD_UNMOUNT, B_FALSE, B_FALSE, B_FALSE) 4890 != Z_OK) 4891 return (Z_ERR); 4892 4893 zarg.cmd = Z_UNMOUNT; 4894 if (call_zoneadmd(target_zone, &zarg) != 0) { 4895 zerror(gettext("call to %s failed"), "zoneadmd"); 4896 return (Z_ERR); 4897 } 4898 return (Z_OK); 4899 } 4900 4901 static int 4902 mark_func(int argc, char *argv[]) 4903 { 4904 int err, lockfd; 4905 4906 if (argc != 1 || strcmp(argv[0], "incomplete") != 0) 4907 return (Z_USAGE); 4908 if (sanity_check(target_zone, CMD_MARK, B_FALSE, B_FALSE, B_FALSE) 4909 != Z_OK) 4910 return (Z_ERR); 4911 4912 /* 4913 * Invoke brand-specific handler. 4914 */ 4915 if (invoke_brand_handler(CMD_MARK, argv) != Z_OK) 4916 return (Z_ERR); 4917 4918 if (grab_lock_file(target_zone, &lockfd) != Z_OK) { 4919 zerror(gettext("another %s may have an operation in progress."), 4920 "zoneadm"); 4921 return (Z_ERR); 4922 } 4923 4924 err = zone_set_state(target_zone, ZONE_STATE_INCOMPLETE); 4925 if (err != Z_OK) { 4926 errno = err; 4927 zperror2(target_zone, gettext("could not set state")); 4928 } 4929 release_lock_file(lockfd); 4930 4931 return (err); 4932 } 4933 4934 /* 4935 * Check what scheduling class we're running under and print a warning if 4936 * we're not using FSS. 4937 */ 4938 static int 4939 check_sched_fss(zone_dochandle_t handle) 4940 { 4941 char class_name[PC_CLNMSZ]; 4942 4943 if (zonecfg_get_dflt_sched_class(handle, class_name, 4944 sizeof (class_name)) != Z_OK) { 4945 zerror(gettext("WARNING: unable to determine the zone's " 4946 "scheduling class")); 4947 } else if (strcmp("FSS", class_name) != 0) { 4948 zerror(gettext("WARNING: The zone.cpu-shares rctl is set but\n" 4949 "FSS is not the default scheduling class for this zone. " 4950 "FSS will be\nused for processes in the zone but to get " 4951 "the full benefit of FSS,\nit should be the default " 4952 "scheduling class. See dispadmin(1M) for\nmore details.")); 4953 return (Z_SYSTEM); 4954 } 4955 4956 return (Z_OK); 4957 } 4958 4959 static int 4960 check_cpu_shares_sched(zone_dochandle_t handle) 4961 { 4962 int err; 4963 int res = Z_OK; 4964 struct zone_rctltab rctl; 4965 4966 if ((err = zonecfg_setrctlent(handle)) != Z_OK) { 4967 errno = err; 4968 zperror(cmd_to_str(CMD_APPLY), B_TRUE); 4969 return (err); 4970 } 4971 4972 while (zonecfg_getrctlent(handle, &rctl) == Z_OK) { 4973 if (strcmp(rctl.zone_rctl_name, "zone.cpu-shares") == 0) { 4974 if (check_sched_fss(handle) != Z_OK) 4975 res = Z_SYSTEM; 4976 break; 4977 } 4978 } 4979 4980 (void) zonecfg_endrctlent(handle); 4981 4982 return (res); 4983 } 4984 4985 /* 4986 * Check if there is a mix of processes running in different pools within the 4987 * zone. This is currently only going to be called for the global zone from 4988 * apply_func but that could be generalized in the future. 4989 */ 4990 static boolean_t 4991 mixed_pools(zoneid_t zoneid) 4992 { 4993 DIR *dirp; 4994 dirent_t *dent; 4995 boolean_t mixed = B_FALSE; 4996 boolean_t poolid_set = B_FALSE; 4997 poolid_t last_poolid = 0; 4998 4999 if ((dirp = opendir("/proc")) == NULL) { 5000 zerror(gettext("could not open /proc")); 5001 return (B_FALSE); 5002 } 5003 5004 while ((dent = readdir(dirp)) != NULL) { 5005 int procfd; 5006 psinfo_t ps; 5007 char procpath[MAXPATHLEN]; 5008 5009 if (dent->d_name[0] == '.') 5010 continue; 5011 5012 (void) snprintf(procpath, sizeof (procpath), "/proc/%s/psinfo", 5013 dent->d_name); 5014 5015 if ((procfd = open(procpath, O_RDONLY)) == -1) 5016 continue; 5017 5018 if (read(procfd, &ps, sizeof (ps)) == sizeof (psinfo_t)) { 5019 /* skip processes in other zones and system processes */ 5020 if (zoneid != ps.pr_zoneid || ps.pr_flag & SSYS) { 5021 (void) close(procfd); 5022 continue; 5023 } 5024 5025 if (poolid_set) { 5026 if (ps.pr_poolid != last_poolid) 5027 mixed = B_TRUE; 5028 } else { 5029 last_poolid = ps.pr_poolid; 5030 poolid_set = B_TRUE; 5031 } 5032 } 5033 5034 (void) close(procfd); 5035 5036 if (mixed) 5037 break; 5038 } 5039 5040 (void) closedir(dirp); 5041 5042 return (mixed); 5043 } 5044 5045 /* 5046 * Check if a persistent or temporary pool is configured for the zone. 5047 * This is currently only going to be called for the global zone from 5048 * apply_func but that could be generalized in the future. 5049 */ 5050 static boolean_t 5051 pool_configured(zone_dochandle_t handle) 5052 { 5053 int err1, err2; 5054 struct zone_psettab pset_tab; 5055 char poolname[MAXPATHLEN]; 5056 5057 err1 = zonecfg_lookup_pset(handle, &pset_tab); 5058 err2 = zonecfg_get_pool(handle, poolname, sizeof (poolname)); 5059 5060 if (err1 == Z_NO_ENTRY && 5061 (err2 == Z_NO_ENTRY || (err2 == Z_OK && strlen(poolname) == 0))) 5062 return (B_FALSE); 5063 5064 return (B_TRUE); 5065 } 5066 5067 /* 5068 * This is an undocumented interface which is currently only used to apply 5069 * the global zone resource management settings when the system boots. 5070 * This function does not yet properly handle updating a running system so 5071 * any projects running in the zone would be trashed if this function 5072 * were to run after the zone had booted. It also does not reset any 5073 * rctl settings that were removed from zonecfg. There is still work to be 5074 * done before we can properly support dynamically updating the resource 5075 * management settings for a running zone (global or non-global). Thus, this 5076 * functionality is undocumented for now. 5077 */ 5078 /* ARGSUSED */ 5079 static int 5080 apply_func(int argc, char *argv[]) 5081 { 5082 int err; 5083 int res = Z_OK; 5084 priv_set_t *privset; 5085 zoneid_t zoneid; 5086 zone_dochandle_t handle; 5087 struct zone_mcaptab mcap; 5088 char pool_err[128]; 5089 5090 zoneid = getzoneid(); 5091 5092 if (zonecfg_in_alt_root() || zoneid != GLOBAL_ZONEID || 5093 target_zone == NULL || strcmp(target_zone, GLOBAL_ZONENAME) != 0) 5094 return (usage(B_FALSE)); 5095 5096 if ((privset = priv_allocset()) == NULL) { 5097 zerror(gettext("%s failed"), "priv_allocset"); 5098 return (Z_ERR); 5099 } 5100 5101 if (getppriv(PRIV_EFFECTIVE, privset) != 0) { 5102 zerror(gettext("%s failed"), "getppriv"); 5103 priv_freeset(privset); 5104 return (Z_ERR); 5105 } 5106 5107 if (priv_isfullset(privset) == B_FALSE) { 5108 (void) usage(B_FALSE); 5109 priv_freeset(privset); 5110 return (Z_ERR); 5111 } 5112 priv_freeset(privset); 5113 5114 if ((handle = zonecfg_init_handle()) == NULL) { 5115 zperror(cmd_to_str(CMD_APPLY), B_TRUE); 5116 return (Z_ERR); 5117 } 5118 5119 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 5120 errno = err; 5121 zperror(cmd_to_str(CMD_APPLY), B_TRUE); 5122 zonecfg_fini_handle(handle); 5123 return (Z_ERR); 5124 } 5125 5126 /* specific error msgs are printed within apply_rctls */ 5127 if ((err = zonecfg_apply_rctls(target_zone, handle)) != Z_OK) { 5128 errno = err; 5129 zperror(cmd_to_str(CMD_APPLY), B_TRUE); 5130 res = Z_ERR; 5131 } 5132 5133 if ((err = check_cpu_shares_sched(handle)) != Z_OK) 5134 res = Z_ERR; 5135 5136 if (pool_configured(handle)) { 5137 if (mixed_pools(zoneid)) { 5138 zerror(gettext("Zone is using multiple resource " 5139 "pools. The pool\nconfiguration cannot be " 5140 "applied without rebooting.")); 5141 res = Z_ERR; 5142 } else { 5143 5144 /* 5145 * The next two blocks of code attempt to set up 5146 * temporary pools as well as persistent pools. In 5147 * both cases we call the functions unconditionally. 5148 * Within each funtion the code will check if the zone 5149 * is actually configured for a temporary pool or 5150 * persistent pool and just return if there is nothing 5151 * to do. 5152 */ 5153 if ((err = zonecfg_bind_tmp_pool(handle, zoneid, 5154 pool_err, sizeof (pool_err))) != Z_OK) { 5155 if (err == Z_POOL || err == Z_POOL_CREATE || 5156 err == Z_POOL_BIND) 5157 zerror("%s: %s", zonecfg_strerror(err), 5158 pool_err); 5159 else 5160 zerror(gettext("could not bind zone to " 5161 "temporary pool: %s"), 5162 zonecfg_strerror(err)); 5163 res = Z_ERR; 5164 } 5165 5166 if ((err = zonecfg_bind_pool(handle, zoneid, pool_err, 5167 sizeof (pool_err))) != Z_OK) { 5168 if (err == Z_POOL || err == Z_POOL_BIND) 5169 zerror("%s: %s", zonecfg_strerror(err), 5170 pool_err); 5171 else 5172 zerror("%s", zonecfg_strerror(err)); 5173 } 5174 } 5175 } 5176 5177 /* 5178 * If a memory cap is configured, set the cap in the kernel using 5179 * zone_setattr() and make sure the rcapd SMF service is enabled. 5180 */ 5181 if (zonecfg_getmcapent(handle, &mcap) == Z_OK) { 5182 uint64_t num; 5183 char smf_err[128]; 5184 5185 num = (uint64_t)strtoll(mcap.zone_physmem_cap, NULL, 10); 5186 if (zone_setattr(zoneid, ZONE_ATTR_PHYS_MCAP, &num, 0) == -1) { 5187 zerror(gettext("could not set zone memory cap")); 5188 res = Z_ERR; 5189 } 5190 5191 if (zonecfg_enable_rcapd(smf_err, sizeof (smf_err)) != Z_OK) { 5192 zerror(gettext("enabling system/rcap service failed: " 5193 "%s"), smf_err); 5194 res = Z_ERR; 5195 } 5196 } 5197 5198 zonecfg_fini_handle(handle); 5199 5200 return (res); 5201 } 5202 5203 static int 5204 help_func(int argc, char *argv[]) 5205 { 5206 int arg, cmd_num; 5207 5208 if (argc == 0) { 5209 (void) usage(B_TRUE); 5210 return (Z_OK); 5211 } 5212 optind = 0; 5213 if ((arg = getopt(argc, argv, "?")) != EOF) { 5214 switch (arg) { 5215 case '?': 5216 sub_usage(SHELP_HELP, CMD_HELP); 5217 return (optopt == '?' ? Z_OK : Z_USAGE); 5218 default: 5219 sub_usage(SHELP_HELP, CMD_HELP); 5220 return (Z_USAGE); 5221 } 5222 } 5223 while (optind < argc) { 5224 /* Private commands have NULL short_usage; omit them */ 5225 if ((cmd_num = cmd_match(argv[optind])) < 0 || 5226 cmdtab[cmd_num].short_usage == NULL) { 5227 sub_usage(SHELP_HELP, CMD_HELP); 5228 return (Z_USAGE); 5229 } 5230 sub_usage(cmdtab[cmd_num].short_usage, cmd_num); 5231 optind++; 5232 } 5233 return (Z_OK); 5234 } 5235 5236 /* 5237 * Returns: CMD_MIN thru CMD_MAX on success, -1 on error 5238 */ 5239 5240 static int 5241 cmd_match(char *cmd) 5242 { 5243 int i; 5244 5245 for (i = CMD_MIN; i <= CMD_MAX; i++) { 5246 /* return only if there is an exact match */ 5247 if (strcmp(cmd, cmdtab[i].cmd_name) == 0) 5248 return (cmdtab[i].cmd_num); 5249 } 5250 return (-1); 5251 } 5252 5253 static int 5254 parse_and_run(int argc, char *argv[]) 5255 { 5256 int i = cmd_match(argv[0]); 5257 5258 if (i < 0) 5259 return (usage(B_FALSE)); 5260 return (cmdtab[i].handler(argc - 1, &(argv[1]))); 5261 } 5262 5263 static char * 5264 get_execbasename(char *execfullname) 5265 { 5266 char *last_slash, *execbasename; 5267 5268 /* guard against '/' at end of command invocation */ 5269 for (;;) { 5270 last_slash = strrchr(execfullname, '/'); 5271 if (last_slash == NULL) { 5272 execbasename = execfullname; 5273 break; 5274 } else { 5275 execbasename = last_slash + 1; 5276 if (*execbasename == '\0') { 5277 *last_slash = '\0'; 5278 continue; 5279 } 5280 break; 5281 } 5282 } 5283 return (execbasename); 5284 } 5285 5286 int 5287 main(int argc, char **argv) 5288 { 5289 int arg; 5290 zoneid_t zid; 5291 struct stat st; 5292 char *zone_lock_env; 5293 int err; 5294 5295 if ((locale = setlocale(LC_ALL, "")) == NULL) 5296 locale = "C"; 5297 (void) textdomain(TEXT_DOMAIN); 5298 setbuf(stdout, NULL); 5299 (void) sigset(SIGHUP, SIG_IGN); 5300 execname = get_execbasename(argv[0]); 5301 target_zone = NULL; 5302 if (chdir("/") != 0) { 5303 zerror(gettext("could not change directory to /.")); 5304 exit(Z_ERR); 5305 } 5306 5307 if (init_zfs() != Z_OK) 5308 exit(Z_ERR); 5309 5310 while ((arg = getopt(argc, argv, "?u:z:R:")) != EOF) { 5311 switch (arg) { 5312 case '?': 5313 return (usage(B_TRUE)); 5314 case 'u': 5315 target_uuid = optarg; 5316 break; 5317 case 'z': 5318 target_zone = optarg; 5319 break; 5320 case 'R': /* private option for admin/install use */ 5321 if (*optarg != '/') { 5322 zerror(gettext("root path must be absolute.")); 5323 exit(Z_ERR); 5324 } 5325 if (stat(optarg, &st) == -1 || !S_ISDIR(st.st_mode)) { 5326 zerror( 5327 gettext("root path must be a directory.")); 5328 exit(Z_ERR); 5329 } 5330 zonecfg_set_root(optarg); 5331 break; 5332 default: 5333 return (usage(B_FALSE)); 5334 } 5335 } 5336 5337 if (optind >= argc) 5338 return (usage(B_FALSE)); 5339 5340 if (target_uuid != NULL && *target_uuid != '\0') { 5341 uuid_t uuid; 5342 static char newtarget[ZONENAME_MAX]; 5343 5344 if (uuid_parse(target_uuid, uuid) == -1) { 5345 zerror(gettext("illegal UUID value specified")); 5346 exit(Z_ERR); 5347 } 5348 if (zonecfg_get_name_by_uuid(uuid, newtarget, 5349 sizeof (newtarget)) == Z_OK) 5350 target_zone = newtarget; 5351 } 5352 5353 if (target_zone != NULL && zone_get_id(target_zone, &zid) != 0) { 5354 errno = Z_NO_ZONE; 5355 zperror(target_zone, B_TRUE); 5356 exit(Z_ERR); 5357 } 5358 5359 /* 5360 * See if we have inherited the right to manipulate this zone from 5361 * a zoneadm instance in our ancestry. If so, set zone_lock_cnt to 5362 * indicate it. If not, make that explicit in our environment. 5363 */ 5364 zone_lock_env = getenv(LOCK_ENV_VAR); 5365 if (zone_lock_env == NULL) { 5366 if (putenv(zoneadm_lock_not_held) != 0) { 5367 zperror(target_zone, B_TRUE); 5368 exit(Z_ERR); 5369 } 5370 } else { 5371 zoneadm_is_nested = B_TRUE; 5372 if (atoi(zone_lock_env) == 1) 5373 zone_lock_cnt = 1; 5374 } 5375 5376 /* 5377 * If we are going to be operating on a single zone, retrieve its 5378 * brand type and determine whether it is native or not. 5379 */ 5380 if ((target_zone != NULL) && 5381 (strcmp(target_zone, GLOBAL_ZONENAME) != NULL)) { 5382 if (zone_get_brand(target_zone, target_brand, 5383 sizeof (target_brand)) != Z_OK) { 5384 zerror(gettext("missing or invalid brand")); 5385 exit(Z_ERR); 5386 } 5387 is_native_zone = (strcmp(target_brand, NATIVE_BRAND_NAME) == 0); 5388 } 5389 5390 err = parse_and_run(argc - optind, &argv[optind]); 5391 5392 return (err); 5393 } 5394