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