vplat.c revision 12734:76969fc28795
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22/* 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26/* 27 * This module contains functions used to bring up and tear down the 28 * Virtual Platform: [un]mounting file-systems, [un]plumbing network 29 * interfaces, [un]configuring devices, establishing resource controls, 30 * and creating/destroying the zone in the kernel. These actions, on 31 * the way up, ready the zone; on the way down, they halt the zone. 32 * See the much longer block comment at the beginning of zoneadmd.c 33 * for a bigger picture of how the whole program functions. 34 * 35 * This module also has primary responsibility for the layout of "scratch 36 * zones." These are mounted, but inactive, zones that are used during 37 * operating system upgrade and potentially other administrative action. The 38 * scratch zone environment is similar to the miniroot environment. The zone's 39 * actual root is mounted read-write on /a, and the standard paths (/usr, 40 * /sbin, /lib) all lead to read-only copies of the running system's binaries. 41 * This allows the administrative tools to manipulate the zone using "-R /a" 42 * without relying on any binaries in the zone itself. 43 * 44 * If the scratch zone is on an alternate root (Live Upgrade [LU] boot 45 * environment), then we must resolve the lofs mounts used there to uncover 46 * writable (unshared) resources. Shared resources, though, are always 47 * read-only. In addition, if the "same" zone with a different root path is 48 * currently running, then "/b" inside the zone points to the running zone's 49 * root. This allows LU to synchronize configuration files during the upgrade 50 * process. 51 * 52 * To construct this environment, this module creates a tmpfs mount on 53 * $ZONEPATH/lu. Inside this scratch area, the miniroot-like environment as 54 * described above is constructed on the fly. The zone is then created using 55 * $ZONEPATH/lu as the root. 56 * 57 * Note that scratch zones are inactive. The zone's bits are not running and 58 * likely cannot be run correctly until upgrade is done. Init is not running 59 * there, nor is SMF. Because of this, the "mounted" state of a scratch zone 60 * is not a part of the usual halt/ready/boot state machine. 61 */ 62 63#include <sys/param.h> 64#include <sys/mount.h> 65#include <sys/mntent.h> 66#include <sys/socket.h> 67#include <sys/utsname.h> 68#include <sys/types.h> 69#include <sys/stat.h> 70#include <sys/sockio.h> 71#include <sys/stropts.h> 72#include <sys/conf.h> 73#include <sys/systeminfo.h> 74 75#include <libdlpi.h> 76#include <libdllink.h> 77#include <libdlvlan.h> 78 79#include <inet/tcp.h> 80#include <arpa/inet.h> 81#include <netinet/in.h> 82#include <net/route.h> 83 84#include <stdio.h> 85#include <errno.h> 86#include <fcntl.h> 87#include <unistd.h> 88#include <rctl.h> 89#include <stdlib.h> 90#include <string.h> 91#include <strings.h> 92#include <wait.h> 93#include <limits.h> 94#include <libgen.h> 95#include <libzfs.h> 96#include <libdevinfo.h> 97#include <zone.h> 98#include <assert.h> 99#include <libcontract.h> 100#include <libcontract_priv.h> 101#include <uuid/uuid.h> 102 103#include <sys/mntio.h> 104#include <sys/mnttab.h> 105#include <sys/fs/autofs.h> /* for _autofssys() */ 106#include <sys/fs/lofs_info.h> 107#include <sys/fs/zfs.h> 108 109#include <pool.h> 110#include <sys/pool.h> 111#include <sys/priocntl.h> 112 113#include <libbrand.h> 114#include <sys/brand.h> 115#include <libzonecfg.h> 116#include <synch.h> 117 118#include "zoneadmd.h" 119#include <tsol/label.h> 120#include <libtsnet.h> 121#include <sys/priv.h> 122 123#define V4_ADDR_LEN 32 124#define V6_ADDR_LEN 128 125 126#define RESOURCE_DEFAULT_OPTS \ 127 MNTOPT_RO "," MNTOPT_LOFS_NOSUB "," MNTOPT_NODEVICES 128 129#define DFSTYPES "/etc/dfs/fstypes" 130#define MAXTNZLEN 2048 131 132#define ALT_MOUNT(mount_cmd) ((mount_cmd) != Z_MNT_BOOT) 133 134/* a reasonable estimate for the number of lwps per process */ 135#define LWPS_PER_PROCESS 10 136 137/* for routing socket */ 138static int rts_seqno = 0; 139 140/* mangled zone name when mounting in an alternate root environment */ 141static char kernzone[ZONENAME_MAX]; 142 143/* array of cached mount entries for resolve_lofs */ 144static struct mnttab *resolve_lofs_mnts, *resolve_lofs_mnt_max; 145 146/* for Trusted Extensions */ 147static tsol_zcent_t *get_zone_label(zlog_t *, priv_set_t *); 148static int tsol_mounts(zlog_t *, char *, char *); 149static void tsol_unmounts(zlog_t *, char *); 150 151static m_label_t *zlabel = NULL; 152static m_label_t *zid_label = NULL; 153static priv_set_t *zprivs = NULL; 154 155/* from libsocket, not in any header file */ 156extern int getnetmaskbyaddr(struct in_addr, struct in_addr *); 157 158/* from zoneadmd */ 159extern char query_hook[]; 160 161/* 162 * An optimization for build_mnttable: reallocate (and potentially copy the 163 * data) only once every N times through the loop. 164 */ 165#define MNTTAB_HUNK 32 166 167/* 168 * Private autofs system call 169 */ 170extern int _autofssys(int, void *); 171 172static int 173autofs_cleanup(zoneid_t zoneid) 174{ 175 /* 176 * Ask autofs to unmount all trigger nodes in the given zone. 177 */ 178 return (_autofssys(AUTOFS_UNMOUNTALL, (void *)zoneid)); 179} 180 181static void 182free_mnttable(struct mnttab *mnt_array, uint_t nelem) 183{ 184 uint_t i; 185 186 if (mnt_array == NULL) 187 return; 188 for (i = 0; i < nelem; i++) { 189 free(mnt_array[i].mnt_mountp); 190 free(mnt_array[i].mnt_fstype); 191 free(mnt_array[i].mnt_special); 192 free(mnt_array[i].mnt_mntopts); 193 assert(mnt_array[i].mnt_time == NULL); 194 } 195 free(mnt_array); 196} 197 198/* 199 * Build the mount table for the zone rooted at "zroot", storing the resulting 200 * array of struct mnttabs in "mnt_arrayp" and the number of elements in the 201 * array in "nelemp". 202 */ 203static int 204build_mnttable(zlog_t *zlogp, const char *zroot, size_t zrootlen, FILE *mnttab, 205 struct mnttab **mnt_arrayp, uint_t *nelemp) 206{ 207 struct mnttab mnt; 208 struct mnttab *mnts; 209 struct mnttab *mnp; 210 uint_t nmnt; 211 212 rewind(mnttab); 213 resetmnttab(mnttab); 214 nmnt = 0; 215 mnts = NULL; 216 while (getmntent(mnttab, &mnt) == 0) { 217 struct mnttab *tmp_array; 218 219 if (strncmp(mnt.mnt_mountp, zroot, zrootlen) != 0) 220 continue; 221 if (nmnt % MNTTAB_HUNK == 0) { 222 tmp_array = realloc(mnts, 223 (nmnt + MNTTAB_HUNK) * sizeof (*mnts)); 224 if (tmp_array == NULL) { 225 free_mnttable(mnts, nmnt); 226 return (-1); 227 } 228 mnts = tmp_array; 229 } 230 mnp = &mnts[nmnt++]; 231 232 /* 233 * Zero out any fields we're not using. 234 */ 235 (void) memset(mnp, 0, sizeof (*mnp)); 236 237 if (mnt.mnt_special != NULL) 238 mnp->mnt_special = strdup(mnt.mnt_special); 239 if (mnt.mnt_mntopts != NULL) 240 mnp->mnt_mntopts = strdup(mnt.mnt_mntopts); 241 mnp->mnt_mountp = strdup(mnt.mnt_mountp); 242 mnp->mnt_fstype = strdup(mnt.mnt_fstype); 243 if ((mnt.mnt_special != NULL && mnp->mnt_special == NULL) || 244 (mnt.mnt_mntopts != NULL && mnp->mnt_mntopts == NULL) || 245 mnp->mnt_mountp == NULL || mnp->mnt_fstype == NULL) { 246 zerror(zlogp, B_TRUE, "memory allocation failed"); 247 free_mnttable(mnts, nmnt); 248 return (-1); 249 } 250 } 251 *mnt_arrayp = mnts; 252 *nelemp = nmnt; 253 return (0); 254} 255 256/* 257 * This is an optimization. The resolve_lofs function is used quite frequently 258 * to manipulate file paths, and on a machine with a large number of zones, 259 * there will be a huge number of mounted file systems. Thus, we trigger a 260 * reread of the list of mount points 261 */ 262static void 263lofs_discard_mnttab(void) 264{ 265 free_mnttable(resolve_lofs_mnts, 266 resolve_lofs_mnt_max - resolve_lofs_mnts); 267 resolve_lofs_mnts = resolve_lofs_mnt_max = NULL; 268} 269 270static int 271lofs_read_mnttab(zlog_t *zlogp) 272{ 273 FILE *mnttab; 274 uint_t nmnts; 275 276 if ((mnttab = fopen(MNTTAB, "r")) == NULL) 277 return (-1); 278 if (build_mnttable(zlogp, "", 0, mnttab, &resolve_lofs_mnts, 279 &nmnts) == -1) { 280 (void) fclose(mnttab); 281 return (-1); 282 } 283 (void) fclose(mnttab); 284 resolve_lofs_mnt_max = resolve_lofs_mnts + nmnts; 285 return (0); 286} 287 288/* 289 * This function loops over potential loopback mounts and symlinks in a given 290 * path and resolves them all down to an absolute path. 291 */ 292void 293resolve_lofs(zlog_t *zlogp, char *path, size_t pathlen) 294{ 295 int len, arlen; 296 const char *altroot; 297 char tmppath[MAXPATHLEN]; 298 boolean_t outside_altroot; 299 300 if ((len = resolvepath(path, tmppath, sizeof (tmppath))) == -1) 301 return; 302 tmppath[len] = '\0'; 303 (void) strlcpy(path, tmppath, sizeof (tmppath)); 304 305 /* This happens once per zoneadmd operation. */ 306 if (resolve_lofs_mnts == NULL && lofs_read_mnttab(zlogp) == -1) 307 return; 308 309 altroot = zonecfg_get_root(); 310 arlen = strlen(altroot); 311 outside_altroot = B_FALSE; 312 for (;;) { 313 struct mnttab *mnp; 314 315 /* Search in reverse order to find longest match */ 316 for (mnp = resolve_lofs_mnt_max - 1; mnp >= resolve_lofs_mnts; 317 mnp--) { 318 if (mnp->mnt_fstype == NULL || 319 mnp->mnt_mountp == NULL || 320 mnp->mnt_special == NULL) 321 continue; 322 len = strlen(mnp->mnt_mountp); 323 if (strncmp(mnp->mnt_mountp, path, len) == 0 && 324 (path[len] == '/' || path[len] == '\0')) 325 break; 326 } 327 if (mnp < resolve_lofs_mnts) 328 break; 329 /* If it's not a lofs then we're done */ 330 if (strcmp(mnp->mnt_fstype, MNTTYPE_LOFS) != 0) 331 break; 332 if (outside_altroot) { 333 char *cp; 334 int olen = sizeof (MNTOPT_RO) - 1; 335 336 /* 337 * If we run into a read-only mount outside of the 338 * alternate root environment, then the user doesn't 339 * want this path to be made read-write. 340 */ 341 if (mnp->mnt_mntopts != NULL && 342 (cp = strstr(mnp->mnt_mntopts, MNTOPT_RO)) != 343 NULL && 344 (cp == mnp->mnt_mntopts || cp[-1] == ',') && 345 (cp[olen] == '\0' || cp[olen] == ',')) { 346 break; 347 } 348 } else if (arlen > 0 && 349 (strncmp(mnp->mnt_special, altroot, arlen) != 0 || 350 (mnp->mnt_special[arlen] != '\0' && 351 mnp->mnt_special[arlen] != '/'))) { 352 outside_altroot = B_TRUE; 353 } 354 /* use temporary buffer because new path might be longer */ 355 (void) snprintf(tmppath, sizeof (tmppath), "%s%s", 356 mnp->mnt_special, path + len); 357 if ((len = resolvepath(tmppath, path, pathlen)) == -1) 358 break; 359 path[len] = '\0'; 360 } 361} 362 363/* 364 * For a regular mount, check if a replacement lofs mount is needed because the 365 * referenced device is already mounted somewhere. 366 */ 367static int 368check_lofs_needed(zlog_t *zlogp, struct zone_fstab *fsptr) 369{ 370 struct mnttab *mnp; 371 zone_fsopt_t *optptr, *onext; 372 373 /* This happens once per zoneadmd operation. */ 374 if (resolve_lofs_mnts == NULL && lofs_read_mnttab(zlogp) == -1) 375 return (-1); 376 377 /* 378 * If this special node isn't already in use, then it's ours alone; 379 * no need to worry about conflicting mounts. 380 */ 381 for (mnp = resolve_lofs_mnts; mnp < resolve_lofs_mnt_max; 382 mnp++) { 383 if (strcmp(mnp->mnt_special, fsptr->zone_fs_special) == 0) 384 break; 385 } 386 if (mnp >= resolve_lofs_mnt_max) 387 return (0); 388 389 /* 390 * Convert this duplicate mount into a lofs mount. 391 */ 392 (void) strlcpy(fsptr->zone_fs_special, mnp->mnt_mountp, 393 sizeof (fsptr->zone_fs_special)); 394 (void) strlcpy(fsptr->zone_fs_type, MNTTYPE_LOFS, 395 sizeof (fsptr->zone_fs_type)); 396 fsptr->zone_fs_raw[0] = '\0'; 397 398 /* 399 * Discard all but one of the original options and set that to our 400 * default set of options used for resources. 401 */ 402 optptr = fsptr->zone_fs_options; 403 if (optptr == NULL) { 404 optptr = malloc(sizeof (*optptr)); 405 if (optptr == NULL) { 406 zerror(zlogp, B_TRUE, "cannot mount %s", 407 fsptr->zone_fs_dir); 408 return (-1); 409 } 410 } else { 411 while ((onext = optptr->zone_fsopt_next) != NULL) { 412 optptr->zone_fsopt_next = onext->zone_fsopt_next; 413 free(onext); 414 } 415 } 416 (void) strcpy(optptr->zone_fsopt_opt, RESOURCE_DEFAULT_OPTS); 417 optptr->zone_fsopt_next = NULL; 418 fsptr->zone_fs_options = optptr; 419 return (0); 420} 421 422int 423make_one_dir(zlog_t *zlogp, const char *prefix, const char *subdir, mode_t mode, 424 uid_t userid, gid_t groupid) 425{ 426 char path[MAXPATHLEN]; 427 struct stat st; 428 429 if (snprintf(path, sizeof (path), "%s%s", prefix, subdir) > 430 sizeof (path)) { 431 zerror(zlogp, B_FALSE, "pathname %s%s is too long", prefix, 432 subdir); 433 return (-1); 434 } 435 436 if (lstat(path, &st) == 0) { 437 /* 438 * We don't check the file mode since presumably the zone 439 * administrator may have had good reason to change the mode, 440 * and we don't need to second guess him. 441 */ 442 if (!S_ISDIR(st.st_mode)) { 443 if (S_ISREG(st.st_mode)) { 444 /* 445 * Allow readonly mounts of /etc/ files; this 446 * is needed most by Trusted Extensions. 447 */ 448 if (strncmp(subdir, "/etc/", 449 strlen("/etc/")) != 0) { 450 zerror(zlogp, B_FALSE, 451 "%s is not in /etc", path); 452 return (-1); 453 } 454 } else { 455 zerror(zlogp, B_FALSE, 456 "%s is not a directory", path); 457 return (-1); 458 } 459 } 460 return (0); 461 } 462 463 if (mkdirp(path, mode) != 0) { 464 if (errno == EROFS) 465 zerror(zlogp, B_FALSE, "Could not mkdir %s.\nIt is on " 466 "a read-only file system in this local zone.\nMake " 467 "sure %s exists in the global zone.", path, subdir); 468 else 469 zerror(zlogp, B_TRUE, "mkdirp of %s failed", path); 470 return (-1); 471 } 472 473 (void) chown(path, userid, groupid); 474 return (0); 475} 476 477static void 478free_remote_fstypes(char **types) 479{ 480 uint_t i; 481 482 if (types == NULL) 483 return; 484 for (i = 0; types[i] != NULL; i++) 485 free(types[i]); 486 free(types); 487} 488 489static char ** 490get_remote_fstypes(zlog_t *zlogp) 491{ 492 char **types = NULL; 493 FILE *fp; 494 char buf[MAXPATHLEN]; 495 char fstype[MAXPATHLEN]; 496 uint_t lines = 0; 497 uint_t i; 498 499 if ((fp = fopen(DFSTYPES, "r")) == NULL) { 500 zerror(zlogp, B_TRUE, "failed to open %s", DFSTYPES); 501 return (NULL); 502 } 503 /* 504 * Count the number of lines 505 */ 506 while (fgets(buf, sizeof (buf), fp) != NULL) 507 lines++; 508 if (lines == 0) /* didn't read anything; empty file */ 509 goto out; 510 rewind(fp); 511 /* 512 * Allocate enough space for a NULL-terminated array. 513 */ 514 types = calloc(lines + 1, sizeof (char *)); 515 if (types == NULL) { 516 zerror(zlogp, B_TRUE, "memory allocation failed"); 517 goto out; 518 } 519 i = 0; 520 while (fgets(buf, sizeof (buf), fp) != NULL) { 521 /* LINTED - fstype is big enough to hold buf */ 522 if (sscanf(buf, "%s", fstype) == 0) { 523 zerror(zlogp, B_FALSE, "unable to parse %s", DFSTYPES); 524 free_remote_fstypes(types); 525 types = NULL; 526 goto out; 527 } 528 types[i] = strdup(fstype); 529 if (types[i] == NULL) { 530 zerror(zlogp, B_TRUE, "memory allocation failed"); 531 free_remote_fstypes(types); 532 types = NULL; 533 goto out; 534 } 535 i++; 536 } 537out: 538 (void) fclose(fp); 539 return (types); 540} 541 542static boolean_t 543is_remote_fstype(const char *fstype, char *const *remote_fstypes) 544{ 545 uint_t i; 546 547 if (remote_fstypes == NULL) 548 return (B_FALSE); 549 for (i = 0; remote_fstypes[i] != NULL; i++) { 550 if (strcmp(remote_fstypes[i], fstype) == 0) 551 return (B_TRUE); 552 } 553 return (B_FALSE); 554} 555 556/* 557 * This converts a zone root path (normally of the form .../root) to a Live 558 * Upgrade scratch zone root (of the form .../lu). 559 */ 560static void 561root_to_lu(zlog_t *zlogp, char *zroot, size_t zrootlen, boolean_t isresolved) 562{ 563 if (!isresolved && zonecfg_in_alt_root()) 564 resolve_lofs(zlogp, zroot, zrootlen); 565 (void) strcpy(strrchr(zroot, '/') + 1, "lu"); 566} 567 568/* 569 * The general strategy for unmounting filesystems is as follows: 570 * 571 * - Remote filesystems may be dead, and attempting to contact them as 572 * part of a regular unmount may hang forever; we want to always try to 573 * forcibly unmount such filesystems and only fall back to regular 574 * unmounts if the filesystem doesn't support forced unmounts. 575 * 576 * - We don't want to unnecessarily corrupt metadata on local 577 * filesystems (ie UFS), so we want to start off with graceful unmounts, 578 * and only escalate to doing forced unmounts if we get stuck. 579 * 580 * We start off walking backwards through the mount table. This doesn't 581 * give us strict ordering but ensures that we try to unmount submounts 582 * first. We thus limit the number of failed umount2(2) calls. 583 * 584 * The mechanism for determining if we're stuck is to count the number 585 * of failed unmounts each iteration through the mount table. This 586 * gives us an upper bound on the number of filesystems which remain 587 * mounted (autofs trigger nodes are dealt with separately). If at the 588 * end of one unmount+autofs_cleanup cycle we still have the same number 589 * of mounts that we started out with, we're stuck and try a forced 590 * unmount. If that fails (filesystem doesn't support forced unmounts) 591 * then we bail and are unable to teardown the zone. If it succeeds, 592 * we're no longer stuck so we continue with our policy of trying 593 * graceful mounts first. 594 * 595 * Zone must be down (ie, no processes or threads active). 596 */ 597static int 598unmount_filesystems(zlog_t *zlogp, zoneid_t zoneid, boolean_t unmount_cmd) 599{ 600 int error = 0; 601 FILE *mnttab; 602 struct mnttab *mnts; 603 uint_t nmnt; 604 char zroot[MAXPATHLEN + 1]; 605 size_t zrootlen; 606 uint_t oldcount = UINT_MAX; 607 boolean_t stuck = B_FALSE; 608 char **remote_fstypes = NULL; 609 610 if (zone_get_rootpath(zone_name, zroot, sizeof (zroot)) != Z_OK) { 611 zerror(zlogp, B_FALSE, "unable to determine zone root"); 612 return (-1); 613 } 614 if (unmount_cmd) 615 root_to_lu(zlogp, zroot, sizeof (zroot), B_FALSE); 616 617 (void) strcat(zroot, "/"); 618 zrootlen = strlen(zroot); 619 620 /* 621 * For Trusted Extensions unmount each higher level zone's mount 622 * of our zone's /export/home 623 */ 624 if (!unmount_cmd) 625 tsol_unmounts(zlogp, zone_name); 626 627 if ((mnttab = fopen(MNTTAB, "r")) == NULL) { 628 zerror(zlogp, B_TRUE, "failed to open %s", MNTTAB); 629 return (-1); 630 } 631 /* 632 * Use our hacky mntfs ioctl so we see everything, even mounts with 633 * MS_NOMNTTAB. 634 */ 635 if (ioctl(fileno(mnttab), MNTIOC_SHOWHIDDEN, NULL) < 0) { 636 zerror(zlogp, B_TRUE, "unable to configure %s", MNTTAB); 637 error++; 638 goto out; 639 } 640 641 /* 642 * Build the list of remote fstypes so we know which ones we 643 * should forcibly unmount. 644 */ 645 remote_fstypes = get_remote_fstypes(zlogp); 646 for (; /* ever */; ) { 647 uint_t newcount = 0; 648 boolean_t unmounted; 649 struct mnttab *mnp; 650 char *path; 651 uint_t i; 652 653 mnts = NULL; 654 nmnt = 0; 655 /* 656 * MNTTAB gives us a way to walk through mounted 657 * filesystems; we need to be able to walk them in 658 * reverse order, so we build a list of all mounted 659 * filesystems. 660 */ 661 if (build_mnttable(zlogp, zroot, zrootlen, mnttab, &mnts, 662 &nmnt) != 0) { 663 error++; 664 goto out; 665 } 666 for (i = 0; i < nmnt; i++) { 667 mnp = &mnts[nmnt - i - 1]; /* access in reverse order */ 668 path = mnp->mnt_mountp; 669 unmounted = B_FALSE; 670 /* 671 * Try forced unmount first for remote filesystems. 672 * 673 * Not all remote filesystems support forced unmounts, 674 * so if this fails (ENOTSUP) we'll continue on 675 * and try a regular unmount. 676 */ 677 if (is_remote_fstype(mnp->mnt_fstype, remote_fstypes)) { 678 if (umount2(path, MS_FORCE) == 0) 679 unmounted = B_TRUE; 680 } 681 /* 682 * Try forced unmount if we're stuck. 683 */ 684 if (stuck) { 685 if (umount2(path, MS_FORCE) == 0) { 686 unmounted = B_TRUE; 687 stuck = B_FALSE; 688 } else { 689 /* 690 * The first failure indicates a 691 * mount we won't be able to get 692 * rid of automatically, so we 693 * bail. 694 */ 695 error++; 696 zerror(zlogp, B_FALSE, 697 "unable to unmount '%s'", path); 698 free_mnttable(mnts, nmnt); 699 goto out; 700 } 701 } 702 /* 703 * Try regular unmounts for everything else. 704 */ 705 if (!unmounted && umount2(path, 0) != 0) 706 newcount++; 707 } 708 free_mnttable(mnts, nmnt); 709 710 if (newcount == 0) 711 break; 712 if (newcount >= oldcount) { 713 /* 714 * Last round didn't unmount anything; we're stuck and 715 * should start trying forced unmounts. 716 */ 717 stuck = B_TRUE; 718 } 719 oldcount = newcount; 720 721 /* 722 * Autofs doesn't let you unmount its trigger nodes from 723 * userland so we have to tell the kernel to cleanup for us. 724 */ 725 if (autofs_cleanup(zoneid) != 0) { 726 zerror(zlogp, B_TRUE, "unable to remove autofs nodes"); 727 error++; 728 goto out; 729 } 730 } 731 732out: 733 free_remote_fstypes(remote_fstypes); 734 (void) fclose(mnttab); 735 return (error ? -1 : 0); 736} 737 738static int 739fs_compare(const void *m1, const void *m2) 740{ 741 struct zone_fstab *i = (struct zone_fstab *)m1; 742 struct zone_fstab *j = (struct zone_fstab *)m2; 743 744 return (strcmp(i->zone_fs_dir, j->zone_fs_dir)); 745} 746 747/* 748 * Fork and exec (and wait for) the mentioned binary with the provided 749 * arguments. Returns (-1) if something went wrong with fork(2) or exec(2), 750 * returns the exit status otherwise. 751 * 752 * If we were unable to exec the provided pathname (for whatever 753 * reason), we return the special token ZEXIT_EXEC. The current value 754 * of ZEXIT_EXEC doesn't conflict with legitimate exit codes of the 755 * consumers of this function; any future consumers must make sure this 756 * remains the case. 757 */ 758static int 759forkexec(zlog_t *zlogp, const char *path, char *const argv[]) 760{ 761 pid_t child_pid; 762 int child_status = 0; 763 764 /* 765 * Do not let another thread localize a message while we are forking. 766 */ 767 (void) mutex_lock(&msglock); 768 child_pid = fork(); 769 (void) mutex_unlock(&msglock); 770 if (child_pid == -1) { 771 zerror(zlogp, B_TRUE, "could not fork for %s", argv[0]); 772 return (-1); 773 } else if (child_pid == 0) { 774 closefrom(0); 775 /* redirect stdin, stdout & stderr to /dev/null */ 776 (void) open("/dev/null", O_RDONLY); /* stdin */ 777 (void) open("/dev/null", O_WRONLY); /* stdout */ 778 (void) open("/dev/null", O_WRONLY); /* stderr */ 779 (void) execv(path, argv); 780 /* 781 * Since we are in the child, there is no point calling zerror() 782 * since there is nobody waiting to consume it. So exit with a 783 * special code that the parent will recognize and call zerror() 784 * accordingly. 785 */ 786 787 _exit(ZEXIT_EXEC); 788 } else { 789 (void) waitpid(child_pid, &child_status, 0); 790 } 791 792 if (WIFSIGNALED(child_status)) { 793 zerror(zlogp, B_FALSE, "%s unexpectedly terminated due to " 794 "signal %d", path, WTERMSIG(child_status)); 795 return (-1); 796 } 797 assert(WIFEXITED(child_status)); 798 if (WEXITSTATUS(child_status) == ZEXIT_EXEC) { 799 zerror(zlogp, B_FALSE, "failed to exec %s", path); 800 return (-1); 801 } 802 return (WEXITSTATUS(child_status)); 803} 804 805static int 806isregfile(const char *path) 807{ 808 struct stat64 st; 809 810 if (stat64(path, &st) == -1) 811 return (-1); 812 813 return (S_ISREG(st.st_mode)); 814} 815 816static int 817dofsck(zlog_t *zlogp, const char *fstype, const char *rawdev) 818{ 819 char cmdbuf[MAXPATHLEN]; 820 char *argv[5]; 821 int status; 822 823 /* 824 * We could alternatively have called /usr/sbin/fsck -F <fstype>, but 825 * that would cost us an extra fork/exec without buying us anything. 826 */ 827 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/fsck", fstype) 828 >= sizeof (cmdbuf)) { 829 zerror(zlogp, B_FALSE, "file-system type %s too long", fstype); 830 return (-1); 831 } 832 833 /* 834 * If it doesn't exist, that's OK: we verified this previously 835 * in zoneadm. 836 */ 837 if (isregfile(cmdbuf) == -1) 838 return (0); 839 840 argv[0] = "fsck"; 841 argv[1] = "-o"; 842 argv[2] = "p"; 843 argv[3] = (char *)rawdev; 844 argv[4] = NULL; 845 846 status = forkexec(zlogp, cmdbuf, argv); 847 if (status == 0 || status == -1) 848 return (status); 849 zerror(zlogp, B_FALSE, "fsck of '%s' failed with exit status %d; " 850 "run fsck manually", rawdev, status); 851 return (-1); 852} 853 854static int 855domount(zlog_t *zlogp, const char *fstype, const char *opts, 856 const char *special, const char *directory) 857{ 858 char cmdbuf[MAXPATHLEN]; 859 char *argv[6]; 860 int status; 861 862 /* 863 * We could alternatively have called /usr/sbin/mount -F <fstype>, but 864 * that would cost us an extra fork/exec without buying us anything. 865 */ 866 if (snprintf(cmdbuf, sizeof (cmdbuf), "/usr/lib/fs/%s/mount", fstype) 867 >= sizeof (cmdbuf)) { 868 zerror(zlogp, B_FALSE, "file-system type %s too long", fstype); 869 return (-1); 870 } 871 argv[0] = "mount"; 872 if (opts[0] == '\0') { 873 argv[1] = (char *)special; 874 argv[2] = (char *)directory; 875 argv[3] = NULL; 876 } else { 877 argv[1] = "-o"; 878 argv[2] = (char *)opts; 879 argv[3] = (char *)special; 880 argv[4] = (char *)directory; 881 argv[5] = NULL; 882 } 883 884 status = forkexec(zlogp, cmdbuf, argv); 885 if (status == 0 || status == -1) 886 return (status); 887 if (opts[0] == '\0') 888 zerror(zlogp, B_FALSE, "\"%s %s %s\" " 889 "failed with exit code %d", 890 cmdbuf, special, directory, status); 891 else 892 zerror(zlogp, B_FALSE, "\"%s -o %s %s %s\" " 893 "failed with exit code %d", 894 cmdbuf, opts, special, directory, status); 895 return (-1); 896} 897 898/* 899 * Check if a given mount point path exists. 900 * If it does, make sure it doesn't contain any symlinks. 901 * Note that if "leaf" is false we're checking an intermediate 902 * component of the mount point path, so it must be a directory. 903 * If "leaf" is true, then we're checking the entire mount point 904 * path, so the mount point itself can be anything aside from a 905 * symbolic link. 906 * 907 * If the path is invalid then a negative value is returned. If the 908 * path exists and is a valid mount point path then 0 is returned. 909 * If the path doesn't exist return a positive value. 910 */ 911static int 912valid_mount_point(zlog_t *zlogp, const char *path, const boolean_t leaf) 913{ 914 struct stat statbuf; 915 char respath[MAXPATHLEN]; 916 int res; 917 918 if (lstat(path, &statbuf) != 0) { 919 if (errno == ENOENT) 920 return (1); 921 zerror(zlogp, B_TRUE, "can't stat %s", path); 922 return (-1); 923 } 924 if (S_ISLNK(statbuf.st_mode)) { 925 zerror(zlogp, B_FALSE, "%s is a symlink", path); 926 return (-1); 927 } 928 if (!leaf && !S_ISDIR(statbuf.st_mode)) { 929 zerror(zlogp, B_FALSE, "%s is not a directory", path); 930 return (-1); 931 } 932 if ((res = resolvepath(path, respath, sizeof (respath))) == -1) { 933 zerror(zlogp, B_TRUE, "unable to resolve path %s", path); 934 return (-1); 935 } 936 respath[res] = '\0'; 937 if (strcmp(path, respath) != 0) { 938 /* 939 * We don't like ".."s, "."s, or "//"s throwing us off 940 */ 941 zerror(zlogp, B_FALSE, "%s is not a canonical path", path); 942 return (-1); 943 } 944 return (0); 945} 946 947/* 948 * Validate a mount point path. A valid mount point path is an 949 * absolute path that either doesn't exist, or, if it does exists it 950 * must be an absolute canonical path that doesn't have any symbolic 951 * links in it. The target of a mount point path can be any filesystem 952 * object. (Different filesystems can support different mount points, 953 * for example "lofs" and "mntfs" both support files and directories 954 * while "ufs" just supports directories.) 955 * 956 * If the path is invalid then a negative value is returned. If the 957 * path exists and is a valid mount point path then 0 is returned. 958 * If the path doesn't exist return a positive value. 959 */ 960int 961valid_mount_path(zlog_t *zlogp, const char *rootpath, const char *spec, 962 const char *dir, const char *fstype) 963{ 964 char abspath[MAXPATHLEN], *slashp, *slashp_next; 965 int rv; 966 967 /* 968 * Sanity check the target mount point path. 969 * It must be a non-null string that starts with a '/'. 970 */ 971 if (dir[0] != '/') { 972 /* Something went wrong. */ 973 zerror(zlogp, B_FALSE, "invalid mount directory, " 974 "type: \"%s\", special: \"%s\", dir: \"%s\"", 975 fstype, spec, dir); 976 return (-1); 977 } 978 979 /* 980 * Join rootpath and dir. Make sure abspath ends with '/', this 981 * is added to all paths (even non-directory paths) to allow us 982 * to detect the end of paths below. If the path already ends 983 * in a '/', then that's ok too (although we'll fail the 984 * cannonical path check in valid_mount_point()). 985 */ 986 if (snprintf(abspath, sizeof (abspath), 987 "%s%s/", rootpath, dir) >= sizeof (abspath)) { 988 zerror(zlogp, B_FALSE, "pathname %s%s is too long", 989 rootpath, dir); 990 return (-1); 991 } 992 993 /* 994 * Starting with rootpath, verify the mount path one component 995 * at a time. Continue until we've evaluated all of abspath. 996 */ 997 slashp = &abspath[strlen(rootpath)]; 998 assert(*slashp == '/'); 999 do { 1000 slashp_next = strchr(slashp + 1, '/'); 1001 *slashp = '\0'; 1002 if (slashp_next != NULL) { 1003 /* This is an intermediary mount path component. */ 1004 rv = valid_mount_point(zlogp, abspath, B_FALSE); 1005 } else { 1006 /* This is the last component of the mount path. */ 1007 rv = valid_mount_point(zlogp, abspath, B_TRUE); 1008 } 1009 if (rv < 0) 1010 return (rv); 1011 *slashp = '/'; 1012 } while ((slashp = slashp_next) != NULL); 1013 return (rv); 1014} 1015 1016static int 1017mount_one_dev_device_cb(void *arg, const char *match, const char *name) 1018{ 1019 di_prof_t prof = arg; 1020 1021 if (name == NULL) 1022 return (di_prof_add_dev(prof, match)); 1023 return (di_prof_add_map(prof, match, name)); 1024} 1025 1026static int 1027mount_one_dev_symlink_cb(void *arg, const char *source, const char *target) 1028{ 1029 di_prof_t prof = arg; 1030 1031 return (di_prof_add_symlink(prof, source, target)); 1032} 1033 1034int 1035vplat_get_iptype(zlog_t *zlogp, zone_iptype_t *iptypep) 1036{ 1037 zone_dochandle_t handle; 1038 1039 if ((handle = zonecfg_init_handle()) == NULL) { 1040 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 1041 return (-1); 1042 } 1043 if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { 1044 zerror(zlogp, B_FALSE, "invalid configuration"); 1045 zonecfg_fini_handle(handle); 1046 return (-1); 1047 } 1048 if (zonecfg_get_iptype(handle, iptypep) != Z_OK) { 1049 zerror(zlogp, B_FALSE, "invalid ip-type configuration"); 1050 zonecfg_fini_handle(handle); 1051 return (-1); 1052 } 1053 zonecfg_fini_handle(handle); 1054 return (0); 1055} 1056 1057/* 1058 * Apply the standard lists of devices/symlinks/mappings and the user-specified 1059 * list of devices (via zonecfg) to the /dev filesystem. The filesystem will 1060 * use these as a profile/filter to determine what exists in /dev. 1061 */ 1062static int 1063mount_one_dev(zlog_t *zlogp, char *devpath, zone_mnt_t mount_cmd) 1064{ 1065 char brand[MAXNAMELEN]; 1066 zone_dochandle_t handle = NULL; 1067 brand_handle_t bh = NULL; 1068 struct zone_devtab ztab; 1069 di_prof_t prof = NULL; 1070 int err; 1071 int retval = -1; 1072 zone_iptype_t iptype; 1073 const char *curr_iptype; 1074 1075 if (di_prof_init(devpath, &prof)) { 1076 zerror(zlogp, B_TRUE, "failed to initialize profile"); 1077 goto cleanup; 1078 } 1079 1080 /* 1081 * Get a handle to the brand info for this zone. 1082 * If we are mounting the zone, then we must always use the default 1083 * brand device mounts. 1084 */ 1085 if (ALT_MOUNT(mount_cmd)) { 1086 (void) strlcpy(brand, default_brand, sizeof (brand)); 1087 } else { 1088 (void) strlcpy(brand, brand_name, sizeof (brand)); 1089 } 1090 1091 if ((bh = brand_open(brand)) == NULL) { 1092 zerror(zlogp, B_FALSE, "unable to determine zone brand"); 1093 goto cleanup; 1094 } 1095 1096 if (vplat_get_iptype(zlogp, &iptype) < 0) { 1097 zerror(zlogp, B_TRUE, "unable to determine ip-type"); 1098 goto cleanup; 1099 } 1100 switch (iptype) { 1101 case ZS_SHARED: 1102 curr_iptype = "shared"; 1103 break; 1104 case ZS_EXCLUSIVE: 1105 curr_iptype = "exclusive"; 1106 break; 1107 } 1108 1109 if (brand_platform_iter_devices(bh, zone_name, 1110 mount_one_dev_device_cb, prof, curr_iptype) != 0) { 1111 zerror(zlogp, B_TRUE, "failed to add standard device"); 1112 goto cleanup; 1113 } 1114 1115 if (brand_platform_iter_link(bh, 1116 mount_one_dev_symlink_cb, prof) != 0) { 1117 zerror(zlogp, B_TRUE, "failed to add standard symlink"); 1118 goto cleanup; 1119 } 1120 1121 /* Add user-specified devices and directories */ 1122 if ((handle = zonecfg_init_handle()) == NULL) { 1123 zerror(zlogp, B_FALSE, "can't initialize zone handle"); 1124 goto cleanup; 1125 } 1126 if (err = zonecfg_get_handle(zone_name, handle)) { 1127 zerror(zlogp, B_FALSE, "can't get handle for zone " 1128 "%s: %s", zone_name, zonecfg_strerror(err)); 1129 goto cleanup; 1130 } 1131 if (err = zonecfg_setdevent(handle)) { 1132 zerror(zlogp, B_FALSE, "%s: %s", zone_name, 1133 zonecfg_strerror(err)); 1134 goto cleanup; 1135 } 1136 while (zonecfg_getdevent(handle, &ztab) == Z_OK) { 1137 if (di_prof_add_dev(prof, ztab.zone_dev_match)) { 1138 zerror(zlogp, B_TRUE, "failed to add " 1139 "user-specified device"); 1140 goto cleanup; 1141 } 1142 } 1143 (void) zonecfg_enddevent(handle); 1144 1145 /* Send profile to kernel */ 1146 if (di_prof_commit(prof)) { 1147 zerror(zlogp, B_TRUE, "failed to commit profile"); 1148 goto cleanup; 1149 } 1150 1151 retval = 0; 1152 1153cleanup: 1154 if (bh != NULL) 1155 brand_close(bh); 1156 if (handle != NULL) 1157 zonecfg_fini_handle(handle); 1158 if (prof) 1159 di_prof_fini(prof); 1160 return (retval); 1161} 1162 1163static int 1164mount_one(zlog_t *zlogp, struct zone_fstab *fsptr, const char *rootpath, 1165 zone_mnt_t mount_cmd) 1166{ 1167 char path[MAXPATHLEN]; 1168 char optstr[MAX_MNTOPT_STR]; 1169 zone_fsopt_t *optptr; 1170 int rv; 1171 1172 if ((rv = valid_mount_path(zlogp, rootpath, fsptr->zone_fs_special, 1173 fsptr->zone_fs_dir, fsptr->zone_fs_type)) < 0) { 1174 zerror(zlogp, B_FALSE, "%s%s is not a valid mount point", 1175 rootpath, fsptr->zone_fs_dir); 1176 return (-1); 1177 } else if (rv > 0) { 1178 /* The mount point path doesn't exist, create it now. */ 1179 if (make_one_dir(zlogp, rootpath, fsptr->zone_fs_dir, 1180 DEFAULT_DIR_MODE, DEFAULT_DIR_USER, 1181 DEFAULT_DIR_GROUP) != 0) { 1182 zerror(zlogp, B_FALSE, "failed to create mount point"); 1183 return (-1); 1184 } 1185 1186 /* 1187 * Now this might seem weird, but we need to invoke 1188 * valid_mount_path() again. Why? Because it checks 1189 * to make sure that the mount point path is canonical, 1190 * which it can only do if the path exists, so now that 1191 * we've created the path we have to verify it again. 1192 */ 1193 if ((rv = valid_mount_path(zlogp, rootpath, 1194 fsptr->zone_fs_special, fsptr->zone_fs_dir, 1195 fsptr->zone_fs_type)) < 0) { 1196 zerror(zlogp, B_FALSE, 1197 "%s%s is not a valid mount point", 1198 rootpath, fsptr->zone_fs_dir); 1199 return (-1); 1200 } 1201 } 1202 1203 (void) snprintf(path, sizeof (path), "%s%s", rootpath, 1204 fsptr->zone_fs_dir); 1205 1206 /* 1207 * In general the strategy here is to do just as much verification as 1208 * necessary to avoid crashing or otherwise doing something bad; if the 1209 * administrator initiated the operation via zoneadm(1m), he'll get 1210 * auto-verification which will let him know what's wrong. If he 1211 * modifies the zone configuration of a running zone and doesn't attempt 1212 * to verify that it's OK we won't crash but won't bother trying to be 1213 * too helpful either. zoneadm verify is only a couple keystrokes away. 1214 */ 1215 if (!zonecfg_valid_fs_type(fsptr->zone_fs_type)) { 1216 zerror(zlogp, B_FALSE, "cannot mount %s on %s: " 1217 "invalid file-system type %s", fsptr->zone_fs_special, 1218 fsptr->zone_fs_dir, fsptr->zone_fs_type); 1219 return (-1); 1220 } 1221 1222 /* 1223 * If we're looking at an alternate root environment, then construct 1224 * read-only loopback mounts as necessary. Note that any special 1225 * paths for lofs zone mounts in an alternate root must have 1226 * already been pre-pended with any alternate root path by the 1227 * time we get here. 1228 */ 1229 if (zonecfg_in_alt_root()) { 1230 struct stat64 st; 1231 1232 if (stat64(fsptr->zone_fs_special, &st) != -1 && 1233 S_ISBLK(st.st_mode)) { 1234 /* 1235 * If we're going to mount a block device we need 1236 * to check if that device is already mounted 1237 * somewhere else, and if so, do a lofs mount 1238 * of the device instead of a direct mount 1239 */ 1240 if (check_lofs_needed(zlogp, fsptr) == -1) 1241 return (-1); 1242 } else if (strcmp(fsptr->zone_fs_type, MNTTYPE_LOFS) == 0) { 1243 /* 1244 * For lofs mounts, the special node is inside the 1245 * alternate root. We need lofs resolution for 1246 * this case in order to get at the underlying 1247 * read-write path. 1248 */ 1249 resolve_lofs(zlogp, fsptr->zone_fs_special, 1250 sizeof (fsptr->zone_fs_special)); 1251 } 1252 } 1253 1254 /* 1255 * Run 'fsck -m' if there's a device to fsck. 1256 */ 1257 if (fsptr->zone_fs_raw[0] != '\0' && 1258 dofsck(zlogp, fsptr->zone_fs_type, fsptr->zone_fs_raw) != 0) { 1259 return (-1); 1260 } else if (isregfile(fsptr->zone_fs_special) == 1 && 1261 dofsck(zlogp, fsptr->zone_fs_type, fsptr->zone_fs_special) != 0) { 1262 return (-1); 1263 } 1264 1265 /* 1266 * Build up mount option string. 1267 */ 1268 optstr[0] = '\0'; 1269 if (fsptr->zone_fs_options != NULL) { 1270 (void) strlcpy(optstr, fsptr->zone_fs_options->zone_fsopt_opt, 1271 sizeof (optstr)); 1272 for (optptr = fsptr->zone_fs_options->zone_fsopt_next; 1273 optptr != NULL; optptr = optptr->zone_fsopt_next) { 1274 (void) strlcat(optstr, ",", sizeof (optstr)); 1275 (void) strlcat(optstr, optptr->zone_fsopt_opt, 1276 sizeof (optstr)); 1277 } 1278 } 1279 1280 if ((rv = domount(zlogp, fsptr->zone_fs_type, optstr, 1281 fsptr->zone_fs_special, path)) != 0) 1282 return (rv); 1283 1284 /* 1285 * The mount succeeded. If this was not a mount of /dev then 1286 * we're done. 1287 */ 1288 if (strcmp(fsptr->zone_fs_type, MNTTYPE_DEV) != 0) 1289 return (0); 1290 1291 /* 1292 * We just mounted an instance of a /dev filesystem, so now we 1293 * need to configure it. 1294 */ 1295 return (mount_one_dev(zlogp, path, mount_cmd)); 1296} 1297 1298static void 1299free_fs_data(struct zone_fstab *fsarray, uint_t nelem) 1300{ 1301 uint_t i; 1302 1303 if (fsarray == NULL) 1304 return; 1305 for (i = 0; i < nelem; i++) 1306 zonecfg_free_fs_option_list(fsarray[i].zone_fs_options); 1307 free(fsarray); 1308} 1309 1310/* 1311 * This function initiates the creation of a small Solaris Environment for 1312 * scratch zone. The Environment creation process is split up into two 1313 * functions(build_mounted_pre_var() and build_mounted_post_var()). It 1314 * is done this way because: 1315 * We need to have both /etc and /var in the root of the scratchzone. 1316 * We loopback mount zone's own /etc and /var into the root of the 1317 * scratch zone. Unlike /etc, /var can be a seperate filesystem. So we 1318 * need to delay the mount of /var till the zone's root gets populated. 1319 * So mounting of localdirs[](/etc and /var) have been moved to the 1320 * build_mounted_post_var() which gets called only after the zone 1321 * specific filesystems are mounted. 1322 * 1323 * Note that the scratch zone we set up for updating the zone (Z_MNT_UPDATE) 1324 * does not loopback mount the zone's own /etc and /var into the root of the 1325 * scratch zone. 1326 */ 1327static boolean_t 1328build_mounted_pre_var(zlog_t *zlogp, char *rootpath, 1329 size_t rootlen, const char *zonepath, char *luroot, size_t lurootlen) 1330{ 1331 char tmp[MAXPATHLEN], fromdir[MAXPATHLEN]; 1332 const char **cpp; 1333 static const char *mkdirs[] = { 1334 "/system", "/system/contract", "/system/object", "/proc", 1335 "/dev", "/tmp", "/a", NULL 1336 }; 1337 char *altstr; 1338 FILE *fp; 1339 uuid_t uuid; 1340 1341 resolve_lofs(zlogp, rootpath, rootlen); 1342 (void) snprintf(luroot, lurootlen, "%s/lu", zonepath); 1343 resolve_lofs(zlogp, luroot, lurootlen); 1344 (void) snprintf(tmp, sizeof (tmp), "%s/bin", luroot); 1345 (void) symlink("./usr/bin", tmp); 1346 1347 /* 1348 * These are mostly special mount points; not handled here. (See 1349 * zone_mount_early.) 1350 */ 1351 for (cpp = mkdirs; *cpp != NULL; cpp++) { 1352 (void) snprintf(tmp, sizeof (tmp), "%s%s", luroot, *cpp); 1353 if (mkdir(tmp, 0755) != 0) { 1354 zerror(zlogp, B_TRUE, "cannot create %s", tmp); 1355 return (B_FALSE); 1356 } 1357 } 1358 /* 1359 * This is here to support lucopy. If there's an instance of this same 1360 * zone on the current running system, then we mount its root up as 1361 * read-only inside the scratch zone. 1362 */ 1363 (void) zonecfg_get_uuid(zone_name, uuid); 1364 altstr = strdup(zonecfg_get_root()); 1365 if (altstr == NULL) { 1366 zerror(zlogp, B_TRUE, "memory allocation failed"); 1367 return (B_FALSE); 1368 } 1369 zonecfg_set_root(""); 1370 (void) strlcpy(tmp, zone_name, sizeof (tmp)); 1371 (void) zonecfg_get_name_by_uuid(uuid, tmp, sizeof (tmp)); 1372 if (zone_get_rootpath(tmp, fromdir, sizeof (fromdir)) == Z_OK && 1373 strcmp(fromdir, rootpath) != 0) { 1374 (void) snprintf(tmp, sizeof (tmp), "%s/b", luroot); 1375 if (mkdir(tmp, 0755) != 0) { 1376 zerror(zlogp, B_TRUE, "cannot create %s", tmp); 1377 return (B_FALSE); 1378 } 1379 if (domount(zlogp, MNTTYPE_LOFS, RESOURCE_DEFAULT_OPTS, fromdir, 1380 tmp) != 0) { 1381 zerror(zlogp, B_TRUE, "cannot mount %s on %s", tmp, 1382 fromdir); 1383 return (B_FALSE); 1384 } 1385 } 1386 zonecfg_set_root(altstr); 1387 free(altstr); 1388 1389 if ((fp = zonecfg_open_scratch(luroot, B_TRUE)) == NULL) { 1390 zerror(zlogp, B_TRUE, "cannot open zone mapfile"); 1391 return (B_FALSE); 1392 } 1393 (void) ftruncate(fileno(fp), 0); 1394 if (zonecfg_add_scratch(fp, zone_name, kernzone, "/") == -1) { 1395 zerror(zlogp, B_TRUE, "cannot add zone mapfile entry"); 1396 } 1397 zonecfg_close_scratch(fp); 1398 (void) snprintf(tmp, sizeof (tmp), "%s/a", luroot); 1399 if (domount(zlogp, MNTTYPE_LOFS, "", rootpath, tmp) != 0) 1400 return (B_FALSE); 1401 (void) strlcpy(rootpath, tmp, rootlen); 1402 return (B_TRUE); 1403} 1404 1405 1406static boolean_t 1407build_mounted_post_var(zlog_t *zlogp, zone_mnt_t mount_cmd, char *rootpath, 1408 const char *luroot) 1409{ 1410 char tmp[MAXPATHLEN], fromdir[MAXPATHLEN]; 1411 const char **cpp; 1412 const char **loopdirs; 1413 const char **tmpdirs; 1414 static const char *localdirs[] = { 1415 "/etc", "/var", NULL 1416 }; 1417 static const char *scr_loopdirs[] = { 1418 "/etc/lib", "/etc/fs", "/lib", "/sbin", "/platform", 1419 "/usr", NULL 1420 }; 1421 static const char *upd_loopdirs[] = { 1422 "/etc", "/kernel", "/lib", "/opt", "/platform", "/sbin", 1423 "/usr", "/var", NULL 1424 }; 1425 static const char *scr_tmpdirs[] = { 1426 "/tmp", "/var/run", NULL 1427 }; 1428 static const char *upd_tmpdirs[] = { 1429 "/tmp", "/var/run", "/var/tmp", NULL 1430 }; 1431 struct stat st; 1432 1433 if (mount_cmd == Z_MNT_SCRATCH) { 1434 /* 1435 * These are mounted read-write from the zone undergoing 1436 * upgrade. We must be careful not to 'leak' things from the 1437 * main system into the zone, and this accomplishes that goal. 1438 */ 1439 for (cpp = localdirs; *cpp != NULL; cpp++) { 1440 (void) snprintf(tmp, sizeof (tmp), "%s%s", luroot, 1441 *cpp); 1442 (void) snprintf(fromdir, sizeof (fromdir), "%s%s", 1443 rootpath, *cpp); 1444 if (mkdir(tmp, 0755) != 0) { 1445 zerror(zlogp, B_TRUE, "cannot create %s", tmp); 1446 return (B_FALSE); 1447 } 1448 if (domount(zlogp, MNTTYPE_LOFS, "", fromdir, tmp) 1449 != 0) { 1450 zerror(zlogp, B_TRUE, "cannot mount %s on %s", 1451 tmp, *cpp); 1452 return (B_FALSE); 1453 } 1454 } 1455 } 1456 1457 if (mount_cmd == Z_MNT_UPDATE) 1458 loopdirs = upd_loopdirs; 1459 else 1460 loopdirs = scr_loopdirs; 1461 1462 /* 1463 * These are things mounted read-only from the running system because 1464 * they contain binaries that must match system. 1465 */ 1466 for (cpp = loopdirs; *cpp != NULL; cpp++) { 1467 (void) snprintf(tmp, sizeof (tmp), "%s%s", luroot, *cpp); 1468 if (mkdir(tmp, 0755) != 0) { 1469 if (errno != EEXIST) { 1470 zerror(zlogp, B_TRUE, "cannot create %s", tmp); 1471 return (B_FALSE); 1472 } 1473 if (lstat(tmp, &st) != 0) { 1474 zerror(zlogp, B_TRUE, "cannot stat %s", tmp); 1475 return (B_FALSE); 1476 } 1477 /* 1478 * Ignore any non-directories encountered. These are 1479 * things that have been converted into symlinks 1480 * (/etc/fs and /etc/lib) and no longer need a lofs 1481 * fixup. 1482 */ 1483 if (!S_ISDIR(st.st_mode)) 1484 continue; 1485 } 1486 if (domount(zlogp, MNTTYPE_LOFS, RESOURCE_DEFAULT_OPTS, *cpp, 1487 tmp) != 0) { 1488 zerror(zlogp, B_TRUE, "cannot mount %s on %s", tmp, 1489 *cpp); 1490 return (B_FALSE); 1491 } 1492 } 1493 1494 if (mount_cmd == Z_MNT_UPDATE) 1495 tmpdirs = upd_tmpdirs; 1496 else 1497 tmpdirs = scr_tmpdirs; 1498 1499 /* 1500 * These are things with tmpfs mounted inside. 1501 */ 1502 for (cpp = tmpdirs; *cpp != NULL; cpp++) { 1503 (void) snprintf(tmp, sizeof (tmp), "%s%s", luroot, *cpp); 1504 if (mount_cmd == Z_MNT_SCRATCH && mkdir(tmp, 0755) != 0 && 1505 errno != EEXIST) { 1506 zerror(zlogp, B_TRUE, "cannot create %s", tmp); 1507 return (B_FALSE); 1508 } 1509 1510 /* 1511 * We could set the mode for /tmp when we do the mkdir but 1512 * since that can be modified by the umask we will just set 1513 * the correct mode for /tmp now. 1514 */ 1515 if (strcmp(*cpp, "/tmp") == 0 && chmod(tmp, 01777) != 0) { 1516 zerror(zlogp, B_TRUE, "cannot chmod %s", tmp); 1517 return (B_FALSE); 1518 } 1519 1520 if (domount(zlogp, MNTTYPE_TMPFS, "", "swap", tmp) != 0) { 1521 zerror(zlogp, B_TRUE, "cannot mount swap on %s", *cpp); 1522 return (B_FALSE); 1523 } 1524 } 1525 return (B_TRUE); 1526} 1527 1528typedef struct plat_gmount_cb_data { 1529 zlog_t *pgcd_zlogp; 1530 struct zone_fstab **pgcd_fs_tab; 1531 int *pgcd_num_fs; 1532} plat_gmount_cb_data_t; 1533 1534/* 1535 * plat_gmount_cb() is a callback function invoked by libbrand to iterate 1536 * through all global brand platform mounts. 1537 */ 1538int 1539plat_gmount_cb(void *data, const char *spec, const char *dir, 1540 const char *fstype, const char *opt) 1541{ 1542 plat_gmount_cb_data_t *cp = data; 1543 zlog_t *zlogp = cp->pgcd_zlogp; 1544 struct zone_fstab *fs_ptr = *cp->pgcd_fs_tab; 1545 int num_fs = *cp->pgcd_num_fs; 1546 struct zone_fstab *fsp, *tmp_ptr; 1547 1548 num_fs++; 1549 if ((tmp_ptr = realloc(fs_ptr, num_fs * sizeof (*tmp_ptr))) == NULL) { 1550 zerror(zlogp, B_TRUE, "memory allocation failed"); 1551 return (-1); 1552 } 1553 1554 fs_ptr = tmp_ptr; 1555 fsp = &fs_ptr[num_fs - 1]; 1556 1557 /* update the callback struct passed in */ 1558 *cp->pgcd_fs_tab = fs_ptr; 1559 *cp->pgcd_num_fs = num_fs; 1560 1561 fsp->zone_fs_raw[0] = '\0'; 1562 (void) strlcpy(fsp->zone_fs_special, spec, 1563 sizeof (fsp->zone_fs_special)); 1564 (void) strlcpy(fsp->zone_fs_dir, dir, sizeof (fsp->zone_fs_dir)); 1565 (void) strlcpy(fsp->zone_fs_type, fstype, sizeof (fsp->zone_fs_type)); 1566 fsp->zone_fs_options = NULL; 1567 if ((opt != NULL) && 1568 (zonecfg_add_fs_option(fsp, (char *)opt) != Z_OK)) { 1569 zerror(zlogp, B_FALSE, "error adding property"); 1570 return (-1); 1571 } 1572 1573 return (0); 1574} 1575 1576static int 1577mount_filesystems_fsent(zone_dochandle_t handle, zlog_t *zlogp, 1578 struct zone_fstab **fs_tabp, int *num_fsp, zone_mnt_t mount_cmd) 1579{ 1580 struct zone_fstab *tmp_ptr, *fs_ptr, *fsp, fstab; 1581 int num_fs; 1582 1583 num_fs = *num_fsp; 1584 fs_ptr = *fs_tabp; 1585 1586 if (zonecfg_setfsent(handle) != Z_OK) { 1587 zerror(zlogp, B_FALSE, "invalid configuration"); 1588 return (-1); 1589 } 1590 while (zonecfg_getfsent(handle, &fstab) == Z_OK) { 1591 /* 1592 * ZFS filesystems will not be accessible under an alternate 1593 * root, since the pool will not be known. Ignore them in this 1594 * case. 1595 */ 1596 if (ALT_MOUNT(mount_cmd) && 1597 strcmp(fstab.zone_fs_type, MNTTYPE_ZFS) == 0) 1598 continue; 1599 1600 num_fs++; 1601 if ((tmp_ptr = realloc(fs_ptr, 1602 num_fs * sizeof (*tmp_ptr))) == NULL) { 1603 zerror(zlogp, B_TRUE, "memory allocation failed"); 1604 (void) zonecfg_endfsent(handle); 1605 return (-1); 1606 } 1607 /* update the pointers passed in */ 1608 *fs_tabp = tmp_ptr; 1609 *num_fsp = num_fs; 1610 1611 fs_ptr = tmp_ptr; 1612 fsp = &fs_ptr[num_fs - 1]; 1613 (void) strlcpy(fsp->zone_fs_dir, 1614 fstab.zone_fs_dir, sizeof (fsp->zone_fs_dir)); 1615 (void) strlcpy(fsp->zone_fs_raw, fstab.zone_fs_raw, 1616 sizeof (fsp->zone_fs_raw)); 1617 (void) strlcpy(fsp->zone_fs_type, fstab.zone_fs_type, 1618 sizeof (fsp->zone_fs_type)); 1619 fsp->zone_fs_options = fstab.zone_fs_options; 1620 1621 /* 1622 * For all lofs mounts, make sure that the 'special' 1623 * entry points inside the alternate root. The 1624 * source path for a lofs mount in a given zone needs 1625 * to be relative to the root of the boot environment 1626 * that contains the zone. Note that we don't do this 1627 * for non-lofs mounts since they will have a device 1628 * as a backing store and device paths must always be 1629 * specified relative to the current boot environment. 1630 */ 1631 fsp->zone_fs_special[0] = '\0'; 1632 if (strcmp(fsp->zone_fs_type, MNTTYPE_LOFS) == 0) { 1633 (void) strlcat(fsp->zone_fs_special, zonecfg_get_root(), 1634 sizeof (fsp->zone_fs_special)); 1635 } 1636 (void) strlcat(fsp->zone_fs_special, fstab.zone_fs_special, 1637 sizeof (fsp->zone_fs_special)); 1638 } 1639 (void) zonecfg_endfsent(handle); 1640 return (0); 1641} 1642 1643static int 1644mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd) 1645{ 1646 char rootpath[MAXPATHLEN]; 1647 char zonepath[MAXPATHLEN]; 1648 char brand[MAXNAMELEN]; 1649 char luroot[MAXPATHLEN]; 1650 int i, num_fs = 0; 1651 struct zone_fstab *fs_ptr = NULL; 1652 zone_dochandle_t handle = NULL; 1653 zone_state_t zstate; 1654 brand_handle_t bh; 1655 plat_gmount_cb_data_t cb; 1656 1657 if (zone_get_state(zone_name, &zstate) != Z_OK || 1658 (zstate != ZONE_STATE_READY && zstate != ZONE_STATE_MOUNTED)) { 1659 zerror(zlogp, B_FALSE, 1660 "zone must be in '%s' or '%s' state to mount file-systems", 1661 zone_state_str(ZONE_STATE_READY), 1662 zone_state_str(ZONE_STATE_MOUNTED)); 1663 goto bad; 1664 } 1665 1666 if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) { 1667 zerror(zlogp, B_TRUE, "unable to determine zone path"); 1668 goto bad; 1669 } 1670 1671 if (zone_get_rootpath(zone_name, rootpath, sizeof (rootpath)) != Z_OK) { 1672 zerror(zlogp, B_TRUE, "unable to determine zone root"); 1673 goto bad; 1674 } 1675 1676 if ((handle = zonecfg_init_handle()) == NULL) { 1677 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 1678 goto bad; 1679 } 1680 if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK || 1681 zonecfg_setfsent(handle) != Z_OK) { 1682 zerror(zlogp, B_FALSE, "invalid configuration"); 1683 goto bad; 1684 } 1685 1686 /* 1687 * If we are mounting the zone, then we must always use the default 1688 * brand global mounts. 1689 */ 1690 if (ALT_MOUNT(mount_cmd)) { 1691 (void) strlcpy(brand, default_brand, sizeof (brand)); 1692 } else { 1693 (void) strlcpy(brand, brand_name, sizeof (brand)); 1694 } 1695 1696 /* Get a handle to the brand info for this zone */ 1697 if ((bh = brand_open(brand)) == NULL) { 1698 zerror(zlogp, B_FALSE, "unable to determine zone brand"); 1699 zonecfg_fini_handle(handle); 1700 return (-1); 1701 } 1702 1703 /* 1704 * Get the list of global filesystems to mount from the brand 1705 * configuration. 1706 */ 1707 cb.pgcd_zlogp = zlogp; 1708 cb.pgcd_fs_tab = &fs_ptr; 1709 cb.pgcd_num_fs = &num_fs; 1710 if (brand_platform_iter_gmounts(bh, zonepath, 1711 plat_gmount_cb, &cb) != 0) { 1712 zerror(zlogp, B_FALSE, "unable to mount filesystems"); 1713 brand_close(bh); 1714 zonecfg_fini_handle(handle); 1715 return (-1); 1716 } 1717 brand_close(bh); 1718 1719 /* 1720 * Iterate through the rest of the filesystems. Sort them all, 1721 * then mount them in sorted order. This is to make sure the 1722 * higher level directories (e.g., /usr) get mounted before 1723 * any beneath them (e.g., /usr/local). 1724 */ 1725 if (mount_filesystems_fsent(handle, zlogp, &fs_ptr, &num_fs, 1726 mount_cmd) != 0) 1727 goto bad; 1728 1729 zonecfg_fini_handle(handle); 1730 handle = NULL; 1731 1732 /* 1733 * Normally when we mount a zone all the zone filesystems 1734 * get mounted relative to rootpath, which is usually 1735 * <zonepath>/root. But when mounting a zone for administration 1736 * purposes via the zone "mount" state, build_mounted_pre_var() 1737 * updates rootpath to be <zonepath>/lu/a so we'll mount all 1738 * the zones filesystems there instead. 1739 * 1740 * build_mounted_pre_var() and build_mounted_post_var() will 1741 * also do some extra work to create directories and lofs mount 1742 * a bunch of global zone file system paths into <zonepath>/lu. 1743 * 1744 * This allows us to be able to enter the zone (now rooted at 1745 * <zonepath>/lu) and run the upgrade/patch tools that are in the 1746 * global zone and have them upgrade the to-be-modified zone's 1747 * files mounted on /a. (Which mirrors the existing standard 1748 * upgrade environment.) 1749 * 1750 * There is of course one catch. When doing the upgrade 1751 * we need <zoneroot>/lu/dev to be the /dev filesystem 1752 * for the zone and we don't want to have any /dev filesystem 1753 * mounted at <zoneroot>/lu/a/dev. Since /dev is specified 1754 * as a normal zone filesystem by default we'll try to mount 1755 * it at <zoneroot>/lu/a/dev, so we have to detect this 1756 * case and instead mount it at <zoneroot>/lu/dev. 1757 * 1758 * All this work is done in three phases: 1759 * 1) Create and populate lu directory (build_mounted_pre_var()). 1760 * 2) Mount the required filesystems as per the zone configuration. 1761 * 3) Set up the rest of the scratch zone environment 1762 * (build_mounted_post_var()). 1763 */ 1764 if (ALT_MOUNT(mount_cmd) && !build_mounted_pre_var(zlogp, 1765 rootpath, sizeof (rootpath), zonepath, luroot, sizeof (luroot))) 1766 goto bad; 1767 1768 qsort(fs_ptr, num_fs, sizeof (*fs_ptr), fs_compare); 1769 1770 for (i = 0; i < num_fs; i++) { 1771 if (ALT_MOUNT(mount_cmd) && 1772 strcmp(fs_ptr[i].zone_fs_dir, "/dev") == 0) { 1773 size_t slen = strlen(rootpath) - 2; 1774 1775 /* 1776 * By default we'll try to mount /dev as /a/dev 1777 * but /dev is special and always goes at the top 1778 * so strip the trailing '/a' from the rootpath. 1779 */ 1780 assert(strcmp(&rootpath[slen], "/a") == 0); 1781 rootpath[slen] = '\0'; 1782 if (mount_one(zlogp, &fs_ptr[i], rootpath, mount_cmd) 1783 != 0) 1784 goto bad; 1785 rootpath[slen] = '/'; 1786 continue; 1787 } 1788 if (mount_one(zlogp, &fs_ptr[i], rootpath, mount_cmd) != 0) 1789 goto bad; 1790 } 1791 if (ALT_MOUNT(mount_cmd) && 1792 !build_mounted_post_var(zlogp, mount_cmd, rootpath, luroot)) 1793 goto bad; 1794 1795 /* 1796 * For Trusted Extensions cross-mount each lower level /export/home 1797 */ 1798 if (mount_cmd == Z_MNT_BOOT && 1799 tsol_mounts(zlogp, zone_name, rootpath) != 0) 1800 goto bad; 1801 1802 free_fs_data(fs_ptr, num_fs); 1803 1804 /* 1805 * Everything looks fine. 1806 */ 1807 return (0); 1808 1809bad: 1810 if (handle != NULL) 1811 zonecfg_fini_handle(handle); 1812 free_fs_data(fs_ptr, num_fs); 1813 return (-1); 1814} 1815 1816/* caller makes sure neither parameter is NULL */ 1817static int 1818addr2netmask(char *prefixstr, int maxprefixlen, uchar_t *maskstr) 1819{ 1820 int prefixlen; 1821 1822 prefixlen = atoi(prefixstr); 1823 if (prefixlen < 0 || prefixlen > maxprefixlen) 1824 return (1); 1825 while (prefixlen > 0) { 1826 if (prefixlen >= 8) { 1827 *maskstr++ = 0xFF; 1828 prefixlen -= 8; 1829 continue; 1830 } 1831 *maskstr |= 1 << (8 - prefixlen); 1832 prefixlen--; 1833 } 1834 return (0); 1835} 1836 1837/* 1838 * Tear down all interfaces belonging to the given zone. This should 1839 * be called with the zone in a state other than "running", so that 1840 * interfaces can't be assigned to the zone after this returns. 1841 * 1842 * If anything goes wrong, log an error message and return an error. 1843 */ 1844static int 1845unconfigure_shared_network_interfaces(zlog_t *zlogp, zoneid_t zone_id) 1846{ 1847 struct lifnum lifn; 1848 struct lifconf lifc; 1849 struct lifreq *lifrp, lifrl; 1850 int64_t lifc_flags = LIFC_NOXMIT | LIFC_ALLZONES; 1851 int num_ifs, s, i, ret_code = 0; 1852 uint_t bufsize; 1853 char *buf = NULL; 1854 1855 if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 1856 zerror(zlogp, B_TRUE, "could not get socket"); 1857 ret_code = -1; 1858 goto bad; 1859 } 1860 lifn.lifn_family = AF_UNSPEC; 1861 lifn.lifn_flags = (int)lifc_flags; 1862 if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) { 1863 zerror(zlogp, B_TRUE, 1864 "could not determine number of network interfaces"); 1865 ret_code = -1; 1866 goto bad; 1867 } 1868 num_ifs = lifn.lifn_count; 1869 bufsize = num_ifs * sizeof (struct lifreq); 1870 if ((buf = malloc(bufsize)) == NULL) { 1871 zerror(zlogp, B_TRUE, "memory allocation failed"); 1872 ret_code = -1; 1873 goto bad; 1874 } 1875 lifc.lifc_family = AF_UNSPEC; 1876 lifc.lifc_flags = (int)lifc_flags; 1877 lifc.lifc_len = bufsize; 1878 lifc.lifc_buf = buf; 1879 if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) { 1880 zerror(zlogp, B_TRUE, "could not get configured network " 1881 "interfaces"); 1882 ret_code = -1; 1883 goto bad; 1884 } 1885 lifrp = lifc.lifc_req; 1886 for (i = lifc.lifc_len / sizeof (struct lifreq); i > 0; i--, lifrp++) { 1887 (void) close(s); 1888 if ((s = socket(lifrp->lifr_addr.ss_family, SOCK_DGRAM, 0)) < 1889 0) { 1890 zerror(zlogp, B_TRUE, "%s: could not get socket", 1891 lifrl.lifr_name); 1892 ret_code = -1; 1893 continue; 1894 } 1895 (void) memset(&lifrl, 0, sizeof (lifrl)); 1896 (void) strncpy(lifrl.lifr_name, lifrp->lifr_name, 1897 sizeof (lifrl.lifr_name)); 1898 if (ioctl(s, SIOCGLIFZONE, (caddr_t)&lifrl) < 0) { 1899 if (errno == ENXIO) 1900 /* 1901 * Interface may have been removed by admin or 1902 * another zone halting. 1903 */ 1904 continue; 1905 zerror(zlogp, B_TRUE, 1906 "%s: could not determine the zone to which this " 1907 "network interface is bound", lifrl.lifr_name); 1908 ret_code = -1; 1909 continue; 1910 } 1911 if (lifrl.lifr_zoneid == zone_id) { 1912 if (ioctl(s, SIOCLIFREMOVEIF, (caddr_t)&lifrl) < 0) { 1913 zerror(zlogp, B_TRUE, 1914 "%s: could not remove network interface", 1915 lifrl.lifr_name); 1916 ret_code = -1; 1917 continue; 1918 } 1919 } 1920 } 1921bad: 1922 if (s > 0) 1923 (void) close(s); 1924 if (buf) 1925 free(buf); 1926 return (ret_code); 1927} 1928 1929static union sockunion { 1930 struct sockaddr sa; 1931 struct sockaddr_in sin; 1932 struct sockaddr_dl sdl; 1933 struct sockaddr_in6 sin6; 1934} so_dst, so_ifp; 1935 1936static struct { 1937 struct rt_msghdr hdr; 1938 char space[512]; 1939} rtmsg; 1940 1941static int 1942salen(struct sockaddr *sa) 1943{ 1944 switch (sa->sa_family) { 1945 case AF_INET: 1946 return (sizeof (struct sockaddr_in)); 1947 case AF_LINK: 1948 return (sizeof (struct sockaddr_dl)); 1949 case AF_INET6: 1950 return (sizeof (struct sockaddr_in6)); 1951 default: 1952 return (sizeof (struct sockaddr)); 1953 } 1954} 1955 1956#define ROUNDUP_LONG(a) \ 1957 ((a) > 0 ? (1 + (((a) - 1) | (sizeof (long) - 1))) : sizeof (long)) 1958 1959/* 1960 * Look up which zone is using a given IP address. The address in question 1961 * is expected to have been stuffed into the structure to which lifr points 1962 * via a previous SIOCGLIFADDR ioctl(). 1963 * 1964 * This is done using black router socket magic. 1965 * 1966 * Return the name of the zone on success or NULL on failure. 1967 * 1968 * This is a lot of code for a simple task; a new ioctl request to take care 1969 * of this might be a useful RFE. 1970 */ 1971 1972static char * 1973who_is_using(zlog_t *zlogp, struct lifreq *lifr) 1974{ 1975 static char answer[ZONENAME_MAX]; 1976 pid_t pid; 1977 int s, rlen, l, i; 1978 char *cp = rtmsg.space; 1979 struct sockaddr_dl *ifp = NULL; 1980 struct sockaddr *sa; 1981 char save_if_name[LIFNAMSIZ]; 1982 1983 answer[0] = '\0'; 1984 1985 pid = getpid(); 1986 if ((s = socket(PF_ROUTE, SOCK_RAW, 0)) < 0) { 1987 zerror(zlogp, B_TRUE, "could not get routing socket"); 1988 return (NULL); 1989 } 1990 1991 if (lifr->lifr_addr.ss_family == AF_INET) { 1992 struct sockaddr_in *sin4; 1993 1994 so_dst.sa.sa_family = AF_INET; 1995 sin4 = (struct sockaddr_in *)&lifr->lifr_addr; 1996 so_dst.sin.sin_addr = sin4->sin_addr; 1997 } else { 1998 struct sockaddr_in6 *sin6; 1999 2000 so_dst.sa.sa_family = AF_INET6; 2001 sin6 = (struct sockaddr_in6 *)&lifr->lifr_addr; 2002 so_dst.sin6.sin6_addr = sin6->sin6_addr; 2003 } 2004 2005 so_ifp.sa.sa_family = AF_LINK; 2006 2007 (void) memset(&rtmsg, 0, sizeof (rtmsg)); 2008 rtmsg.hdr.rtm_type = RTM_GET; 2009 rtmsg.hdr.rtm_flags = RTF_UP | RTF_HOST; 2010 rtmsg.hdr.rtm_version = RTM_VERSION; 2011 rtmsg.hdr.rtm_seq = ++rts_seqno; 2012 rtmsg.hdr.rtm_addrs = RTA_IFP | RTA_DST; 2013 2014 l = ROUNDUP_LONG(salen(&so_dst.sa)); 2015 (void) memmove(cp, &(so_dst), l); 2016 cp += l; 2017 l = ROUNDUP_LONG(salen(&so_ifp.sa)); 2018 (void) memmove(cp, &(so_ifp), l); 2019 cp += l; 2020 2021 rtmsg.hdr.rtm_msglen = l = cp - (char *)&rtmsg; 2022 2023 if ((rlen = write(s, &rtmsg, l)) < 0) { 2024 zerror(zlogp, B_TRUE, "writing to routing socket"); 2025 return (NULL); 2026 } else if (rlen < (int)rtmsg.hdr.rtm_msglen) { 2027 zerror(zlogp, B_TRUE, 2028 "write to routing socket got only %d for len\n", rlen); 2029 return (NULL); 2030 } 2031 do { 2032 l = read(s, &rtmsg, sizeof (rtmsg)); 2033 } while (l > 0 && (rtmsg.hdr.rtm_seq != rts_seqno || 2034 rtmsg.hdr.rtm_pid != pid)); 2035 if (l < 0) { 2036 zerror(zlogp, B_TRUE, "reading from routing socket"); 2037 return (NULL); 2038 } 2039 2040 if (rtmsg.hdr.rtm_version != RTM_VERSION) { 2041 zerror(zlogp, B_FALSE, 2042 "routing message version %d not understood", 2043 rtmsg.hdr.rtm_version); 2044 return (NULL); 2045 } 2046 if (rtmsg.hdr.rtm_msglen != (ushort_t)l) { 2047 zerror(zlogp, B_FALSE, "message length mismatch, " 2048 "expected %d bytes, returned %d bytes", 2049 rtmsg.hdr.rtm_msglen, l); 2050 return (NULL); 2051 } 2052 if (rtmsg.hdr.rtm_errno != 0) { 2053 errno = rtmsg.hdr.rtm_errno; 2054 zerror(zlogp, B_TRUE, "RTM_GET routing socket message"); 2055 return (NULL); 2056 } 2057 if ((rtmsg.hdr.rtm_addrs & RTA_IFP) == 0) { 2058 zerror(zlogp, B_FALSE, "network interface not found"); 2059 return (NULL); 2060 } 2061 cp = ((char *)(&rtmsg.hdr + 1)); 2062 for (i = 1; i != 0; i <<= 1) { 2063 /* LINTED E_BAD_PTR_CAST_ALIGN */ 2064 sa = (struct sockaddr *)cp; 2065 if (i != RTA_IFP) { 2066 if ((i & rtmsg.hdr.rtm_addrs) != 0) 2067 cp += ROUNDUP_LONG(salen(sa)); 2068 continue; 2069 } 2070 if (sa->sa_family == AF_LINK && 2071 ((struct sockaddr_dl *)sa)->sdl_nlen != 0) 2072 ifp = (struct sockaddr_dl *)sa; 2073 break; 2074 } 2075 if (ifp == NULL) { 2076 zerror(zlogp, B_FALSE, "network interface could not be " 2077 "determined"); 2078 return (NULL); 2079 } 2080 2081 /* 2082 * We need to set the I/F name to what we got above, then do the 2083 * appropriate ioctl to get its zone name. But lifr->lifr_name is 2084 * used by the calling function to do a REMOVEIF, so if we leave the 2085 * "good" zone's I/F name in place, *that* I/F will be removed instead 2086 * of the bad one. So we save the old (bad) I/F name before over- 2087 * writing it and doing the ioctl, then restore it after the ioctl. 2088 */ 2089 (void) strlcpy(save_if_name, lifr->lifr_name, sizeof (save_if_name)); 2090 (void) strncpy(lifr->lifr_name, ifp->sdl_data, ifp->sdl_nlen); 2091 lifr->lifr_name[ifp->sdl_nlen] = '\0'; 2092 i = ioctl(s, SIOCGLIFZONE, lifr); 2093 (void) strlcpy(lifr->lifr_name, save_if_name, sizeof (save_if_name)); 2094 if (i < 0) { 2095 zerror(zlogp, B_TRUE, 2096 "%s: could not determine the zone network interface " 2097 "belongs to", lifr->lifr_name); 2098 return (NULL); 2099 } 2100 if (getzonenamebyid(lifr->lifr_zoneid, answer, sizeof (answer)) < 0) 2101 (void) snprintf(answer, sizeof (answer), "%d", 2102 lifr->lifr_zoneid); 2103 2104 if (strlen(answer) > 0) 2105 return (answer); 2106 return (NULL); 2107} 2108 2109/* 2110 * Configures a single interface: a new virtual interface is added, based on 2111 * the physical interface nwiftabptr->zone_nwif_physical, with the address 2112 * specified in nwiftabptr->zone_nwif_address, for zone zone_id. Note that 2113 * the "address" can be an IPv6 address (with a /prefixlength required), an 2114 * IPv4 address (with a /prefixlength optional), or a name; for the latter, 2115 * an IPv4 name-to-address resolution will be attempted. 2116 * 2117 * If anything goes wrong, we log an detailed error message, attempt to tear 2118 * down whatever we set up and return an error. 2119 */ 2120static int 2121configure_one_interface(zlog_t *zlogp, zoneid_t zone_id, 2122 struct zone_nwiftab *nwiftabptr) 2123{ 2124 struct lifreq lifr; 2125 struct sockaddr_in netmask4; 2126 struct sockaddr_in6 netmask6; 2127 struct sockaddr_storage laddr; 2128 struct in_addr in4; 2129 sa_family_t af; 2130 char *slashp = strchr(nwiftabptr->zone_nwif_address, '/'); 2131 int s; 2132 boolean_t got_netmask = B_FALSE; 2133 boolean_t is_loopback = B_FALSE; 2134 char addrstr4[INET_ADDRSTRLEN]; 2135 int res; 2136 2137 res = zonecfg_valid_net_address(nwiftabptr->zone_nwif_address, &lifr); 2138 if (res != Z_OK) { 2139 zerror(zlogp, B_FALSE, "%s: %s", zonecfg_strerror(res), 2140 nwiftabptr->zone_nwif_address); 2141 return (-1); 2142 } 2143 af = lifr.lifr_addr.ss_family; 2144 if (af == AF_INET) 2145 in4 = ((struct sockaddr_in *)(&lifr.lifr_addr))->sin_addr; 2146 if ((s = socket(af, SOCK_DGRAM, 0)) < 0) { 2147 zerror(zlogp, B_TRUE, "could not get socket"); 2148 return (-1); 2149 } 2150 2151 /* 2152 * This is a similar kind of "hack" like in addif() to get around 2153 * the problem of SIOCLIFADDIF. The problem is that this ioctl 2154 * does not include the netmask when adding a logical interface. 2155 * To get around this problem, we first add the logical interface 2156 * with a 0 address. After that, we set the netmask if provided. 2157 * Finally we set the interface address. 2158 */ 2159 laddr = lifr.lifr_addr; 2160 (void) strlcpy(lifr.lifr_name, nwiftabptr->zone_nwif_physical, 2161 sizeof (lifr.lifr_name)); 2162 (void) memset(&lifr.lifr_addr, 0, sizeof (lifr.lifr_addr)); 2163 2164 if (ioctl(s, SIOCLIFADDIF, (caddr_t)&lifr) < 0) { 2165 /* 2166 * Here, we know that the interface can't be brought up. 2167 * A similar warning message was already printed out to 2168 * the console by zoneadm(1M) so instead we log the 2169 * message to syslog and continue. 2170 */ 2171 zerror(&logsys, B_TRUE, "WARNING: skipping network interface " 2172 "'%s' which may not be present/plumbed in the " 2173 "global zone.", lifr.lifr_name); 2174 (void) close(s); 2175 return (Z_OK); 2176 } 2177 2178 /* Preserve literal IPv4 address for later potential printing. */ 2179 if (af == AF_INET) 2180 (void) inet_ntop(AF_INET, &in4, addrstr4, INET_ADDRSTRLEN); 2181 2182 lifr.lifr_zoneid = zone_id; 2183 if (ioctl(s, SIOCSLIFZONE, (caddr_t)&lifr) < 0) { 2184 zerror(zlogp, B_TRUE, "%s: could not place network interface " 2185 "into zone", lifr.lifr_name); 2186 goto bad; 2187 } 2188 2189 /* 2190 * Loopback interface will use the default netmask assigned, if no 2191 * netmask is found. 2192 */ 2193 if (strcmp(nwiftabptr->zone_nwif_physical, "lo0") == 0) { 2194 is_loopback = B_TRUE; 2195 } 2196 if (af == AF_INET) { 2197 /* 2198 * The IPv4 netmask can be determined either 2199 * directly if a prefix length was supplied with 2200 * the address or via the netmasks database. Not 2201 * being able to determine it is a common failure, 2202 * but it often is not fatal to operation of the 2203 * interface. In that case, a warning will be 2204 * printed after the rest of the interface's 2205 * parameters have been configured. 2206 */ 2207 (void) memset(&netmask4, 0, sizeof (netmask4)); 2208 if (slashp != NULL) { 2209 if (addr2netmask(slashp + 1, V4_ADDR_LEN, 2210 (uchar_t *)&netmask4.sin_addr) != 0) { 2211 *slashp = '/'; 2212 zerror(zlogp, B_FALSE, 2213 "%s: invalid prefix length in %s", 2214 lifr.lifr_name, 2215 nwiftabptr->zone_nwif_address); 2216 goto bad; 2217 } 2218 got_netmask = B_TRUE; 2219 } else if (getnetmaskbyaddr(in4, 2220 &netmask4.sin_addr) == 0) { 2221 got_netmask = B_TRUE; 2222 } 2223 if (got_netmask) { 2224 netmask4.sin_family = af; 2225 (void) memcpy(&lifr.lifr_addr, &netmask4, 2226 sizeof (netmask4)); 2227 } 2228 } else { 2229 (void) memset(&netmask6, 0, sizeof (netmask6)); 2230 if (addr2netmask(slashp + 1, V6_ADDR_LEN, 2231 (uchar_t *)&netmask6.sin6_addr) != 0) { 2232 *slashp = '/'; 2233 zerror(zlogp, B_FALSE, 2234 "%s: invalid prefix length in %s", 2235 lifr.lifr_name, 2236 nwiftabptr->zone_nwif_address); 2237 goto bad; 2238 } 2239 got_netmask = B_TRUE; 2240 netmask6.sin6_family = af; 2241 (void) memcpy(&lifr.lifr_addr, &netmask6, 2242 sizeof (netmask6)); 2243 } 2244 if (got_netmask && 2245 ioctl(s, SIOCSLIFNETMASK, (caddr_t)&lifr) < 0) { 2246 zerror(zlogp, B_TRUE, "%s: could not set netmask", 2247 lifr.lifr_name); 2248 goto bad; 2249 } 2250 2251 /* Set the interface address */ 2252 lifr.lifr_addr = laddr; 2253 if (ioctl(s, SIOCSLIFADDR, (caddr_t)&lifr) < 0) { 2254 zerror(zlogp, B_TRUE, 2255 "%s: could not set IP address to %s", 2256 lifr.lifr_name, nwiftabptr->zone_nwif_address); 2257 goto bad; 2258 } 2259 2260 if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) { 2261 zerror(zlogp, B_TRUE, "%s: could not get flags", 2262 lifr.lifr_name); 2263 goto bad; 2264 } 2265 lifr.lifr_flags |= IFF_UP; 2266 if (ioctl(s, SIOCSLIFFLAGS, (caddr_t)&lifr) < 0) { 2267 int save_errno = errno; 2268 char *zone_using; 2269 2270 /* 2271 * If we failed with something other than EADDRNOTAVAIL, 2272 * then skip to the end. Otherwise, look up our address, 2273 * then call a function to determine which zone is already 2274 * using that address. 2275 */ 2276 if (errno != EADDRNOTAVAIL) { 2277 zerror(zlogp, B_TRUE, 2278 "%s: could not bring network interface up", 2279 lifr.lifr_name); 2280 goto bad; 2281 } 2282 if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) < 0) { 2283 zerror(zlogp, B_TRUE, "%s: could not get address", 2284 lifr.lifr_name); 2285 goto bad; 2286 } 2287 zone_using = who_is_using(zlogp, &lifr); 2288 errno = save_errno; 2289 if (zone_using == NULL) 2290 zerror(zlogp, B_TRUE, 2291 "%s: could not bring network interface up", 2292 lifr.lifr_name); 2293 else 2294 zerror(zlogp, B_TRUE, "%s: could not bring network " 2295 "interface up: address in use by zone '%s'", 2296 lifr.lifr_name, zone_using); 2297 goto bad; 2298 } 2299 2300 if (!got_netmask && !is_loopback) { 2301 /* 2302 * A common, but often non-fatal problem, is that the system 2303 * cannot find the netmask for an interface address. This is 2304 * often caused by it being only in /etc/inet/netmasks, but 2305 * /etc/nsswitch.conf says to use NIS or NIS+ and it's not 2306 * in that. This doesn't show up at boot because the netmask 2307 * is obtained from /etc/inet/netmasks when no network 2308 * interfaces are up, but isn't consulted when NIS/NIS+ is 2309 * available. We warn the user here that something like this 2310 * has happened and we're just running with a default and 2311 * possible incorrect netmask. 2312 */ 2313 char buffer[INET6_ADDRSTRLEN]; 2314 void *addr; 2315 const char *nomatch = "no matching subnet found in netmasks(4)"; 2316 2317 if (af == AF_INET) 2318 addr = &((struct sockaddr_in *) 2319 (&lifr.lifr_addr))->sin_addr; 2320 else 2321 addr = &((struct sockaddr_in6 *) 2322 (&lifr.lifr_addr))->sin6_addr; 2323 2324 /* 2325 * Find out what netmask the interface is going to be using. 2326 * If we just brought up an IPMP data address on an underlying 2327 * interface above, the address will have already migrated, so 2328 * the SIOCGLIFNETMASK won't be able to find it (but we need 2329 * to bring the address up to get the actual netmask). Just 2330 * omit printing the actual netmask in this corner-case. 2331 */ 2332 if (ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifr) < 0 || 2333 inet_ntop(af, addr, buffer, sizeof (buffer)) == NULL) { 2334 zerror(zlogp, B_FALSE, "WARNING: %s; using default.", 2335 nomatch); 2336 } else { 2337 zerror(zlogp, B_FALSE, 2338 "WARNING: %s: %s: %s; using default of %s.", 2339 lifr.lifr_name, nomatch, addrstr4, buffer); 2340 } 2341 } 2342 2343 /* 2344 * If a default router was specified for this interface 2345 * set the route now. Ignore if already set. 2346 */ 2347 if (strlen(nwiftabptr->zone_nwif_defrouter) > 0) { 2348 int status; 2349 char *argv[7]; 2350 2351 argv[0] = "route"; 2352 argv[1] = "add"; 2353 argv[2] = "-ifp"; 2354 argv[3] = nwiftabptr->zone_nwif_physical; 2355 argv[4] = "default"; 2356 argv[5] = nwiftabptr->zone_nwif_defrouter; 2357 argv[6] = NULL; 2358 2359 status = forkexec(zlogp, "/usr/sbin/route", argv); 2360 if (status != 0 && status != EEXIST) 2361 zerror(zlogp, B_FALSE, "Unable to set route for " 2362 "interface %s to %s\n", 2363 nwiftabptr->zone_nwif_physical, 2364 nwiftabptr->zone_nwif_defrouter); 2365 } 2366 2367 (void) close(s); 2368 return (Z_OK); 2369bad: 2370 (void) ioctl(s, SIOCLIFREMOVEIF, (caddr_t)&lifr); 2371 (void) close(s); 2372 return (-1); 2373} 2374 2375/* 2376 * Sets up network interfaces based on information from the zone configuration. 2377 * IPv4 and IPv6 loopback interfaces are set up "for free", modeling the global 2378 * system. 2379 * 2380 * If anything goes wrong, we log a general error message, attempt to tear down 2381 * whatever we set up, and return an error. 2382 */ 2383static int 2384configure_shared_network_interfaces(zlog_t *zlogp) 2385{ 2386 zone_dochandle_t handle; 2387 struct zone_nwiftab nwiftab, loopback_iftab; 2388 zoneid_t zoneid; 2389 2390 if ((zoneid = getzoneidbyname(zone_name)) == ZONE_ID_UNDEFINED) { 2391 zerror(zlogp, B_TRUE, "unable to get zoneid"); 2392 return (-1); 2393 } 2394 2395 if ((handle = zonecfg_init_handle()) == NULL) { 2396 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 2397 return (-1); 2398 } 2399 if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { 2400 zerror(zlogp, B_FALSE, "invalid configuration"); 2401 zonecfg_fini_handle(handle); 2402 return (-1); 2403 } 2404 if (zonecfg_setnwifent(handle) == Z_OK) { 2405 for (;;) { 2406 if (zonecfg_getnwifent(handle, &nwiftab) != Z_OK) 2407 break; 2408 if (configure_one_interface(zlogp, zoneid, &nwiftab) != 2409 Z_OK) { 2410 (void) zonecfg_endnwifent(handle); 2411 zonecfg_fini_handle(handle); 2412 return (-1); 2413 } 2414 } 2415 (void) zonecfg_endnwifent(handle); 2416 } 2417 zonecfg_fini_handle(handle); 2418 if (is_system_labeled()) { 2419 /* 2420 * Labeled zones share the loopback interface 2421 * so it is not plumbed for shared stack instances. 2422 */ 2423 return (0); 2424 } 2425 (void) strlcpy(loopback_iftab.zone_nwif_physical, "lo0", 2426 sizeof (loopback_iftab.zone_nwif_physical)); 2427 (void) strlcpy(loopback_iftab.zone_nwif_address, "127.0.0.1", 2428 sizeof (loopback_iftab.zone_nwif_address)); 2429 loopback_iftab.zone_nwif_defrouter[0] = '\0'; 2430 if (configure_one_interface(zlogp, zoneid, &loopback_iftab) != Z_OK) 2431 return (-1); 2432 2433 /* Always plumb up the IPv6 loopback interface. */ 2434 (void) strlcpy(loopback_iftab.zone_nwif_address, "::1/128", 2435 sizeof (loopback_iftab.zone_nwif_address)); 2436 if (configure_one_interface(zlogp, zoneid, &loopback_iftab) != Z_OK) 2437 return (-1); 2438 return (0); 2439} 2440 2441static void 2442zdlerror(zlog_t *zlogp, dladm_status_t err, const char *dlname, const char *str) 2443{ 2444 char errmsg[DLADM_STRSIZE]; 2445 2446 (void) dladm_status2str(err, errmsg); 2447 zerror(zlogp, B_FALSE, "%s '%s': %s", str, dlname, errmsg); 2448} 2449 2450static int 2451add_datalink(zlog_t *zlogp, char *zone_name, datalink_id_t linkid, char *dlname) 2452{ 2453 dladm_status_t err; 2454 boolean_t cpuset, poolset; 2455 2456 /* First check if it's in use by global zone. */ 2457 if (zonecfg_ifname_exists(AF_INET, dlname) || 2458 zonecfg_ifname_exists(AF_INET6, dlname)) { 2459 zerror(zlogp, B_FALSE, "WARNING: skipping network interface " 2460 "'%s' which is used in the global zone", dlname); 2461 return (-1); 2462 } 2463 2464 /* Set zoneid of this link. */ 2465 err = dladm_set_linkprop(dld_handle, linkid, "zone", &zone_name, 1, 2466 DLADM_OPT_ACTIVE); 2467 if (err != DLADM_STATUS_OK) { 2468 zdlerror(zlogp, err, dlname, 2469 "WARNING: unable to add network interface"); 2470 return (-1); 2471 } 2472 2473 /* 2474 * Set the pool of this link if the zone has a pool and 2475 * neither the cpus nor the pool datalink property is 2476 * already set. 2477 */ 2478 err = dladm_linkprop_is_set(dld_handle, linkid, DLADM_PROP_VAL_CURRENT, 2479 "cpus", &cpuset); 2480 if (err != DLADM_STATUS_OK) { 2481 zdlerror(zlogp, err, dlname, 2482 "WARNING: unable to check if cpus link property is set"); 2483 } 2484 err = dladm_linkprop_is_set(dld_handle, linkid, DLADM_PROP_VAL_CURRENT, 2485 "pool", &poolset); 2486 if (err != DLADM_STATUS_OK) { 2487 zdlerror(zlogp, err, dlname, 2488 "WARNING: unable to check if pool link property is set"); 2489 } 2490 2491 if ((strlen(pool_name) != 0) && !cpuset && !poolset) { 2492 err = dladm_set_linkprop(dld_handle, linkid, "pool", 2493 &pool_name, 1, DLADM_OPT_ACTIVE); 2494 if (err != DLADM_STATUS_OK) { 2495 zerror(zlogp, B_FALSE, "WARNING: unable to set " 2496 "pool %s to datalink %s", pool_name, dlname); 2497 bzero(pool_name, MAXPATHLEN); 2498 } 2499 } else { 2500 bzero(pool_name, MAXPATHLEN); 2501 } 2502 return (0); 2503} 2504 2505/* 2506 * Add the kernel access control information for the interface names. 2507 * If anything goes wrong, we log a general error message, attempt to tear down 2508 * whatever we set up, and return an error. 2509 */ 2510static int 2511configure_exclusive_network_interfaces(zlog_t *zlogp) 2512{ 2513 zone_dochandle_t handle; 2514 struct zone_nwiftab nwiftab; 2515 char rootpath[MAXPATHLEN]; 2516 char path[MAXPATHLEN]; 2517 datalink_id_t linkid; 2518 di_prof_t prof = NULL; 2519 boolean_t added = B_FALSE; 2520 2521 if ((handle = zonecfg_init_handle()) == NULL) { 2522 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 2523 return (-1); 2524 } 2525 if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { 2526 zerror(zlogp, B_FALSE, "invalid configuration"); 2527 zonecfg_fini_handle(handle); 2528 return (-1); 2529 } 2530 2531 if (zonecfg_setnwifent(handle) != Z_OK) { 2532 zonecfg_fini_handle(handle); 2533 return (0); 2534 } 2535 2536 for (;;) { 2537 if (zonecfg_getnwifent(handle, &nwiftab) != Z_OK) 2538 break; 2539 2540 if (prof == NULL) { 2541 if (zone_get_devroot(zone_name, rootpath, 2542 sizeof (rootpath)) != Z_OK) { 2543 (void) zonecfg_endnwifent(handle); 2544 zonecfg_fini_handle(handle); 2545 zerror(zlogp, B_TRUE, 2546 "unable to determine dev root"); 2547 return (-1); 2548 } 2549 (void) snprintf(path, sizeof (path), "%s%s", rootpath, 2550 "/dev"); 2551 if (di_prof_init(path, &prof) != 0) { 2552 (void) zonecfg_endnwifent(handle); 2553 zonecfg_fini_handle(handle); 2554 zerror(zlogp, B_TRUE, 2555 "failed to initialize profile"); 2556 return (-1); 2557 } 2558 } 2559 2560 /* 2561 * Create the /dev entry for backward compatibility. 2562 * Only create the /dev entry if it's not in use. 2563 * Note that the zone still boots when the assigned 2564 * interface is inaccessible, used by others, etc. 2565 * Also, when vanity naming is used, some interface do 2566 * do not have corresponding /dev node names (for example, 2567 * vanity named aggregations). The /dev entry is not 2568 * created in that case. The /dev/net entry is always 2569 * accessible. 2570 */ 2571 if (dladm_name2info(dld_handle, nwiftab.zone_nwif_physical, 2572 &linkid, NULL, NULL, NULL) == DLADM_STATUS_OK && 2573 add_datalink(zlogp, zone_name, linkid, 2574 nwiftab.zone_nwif_physical) == 0) { 2575 added = B_TRUE; 2576 } else { 2577 (void) zonecfg_endnwifent(handle); 2578 zonecfg_fini_handle(handle); 2579 zerror(zlogp, B_TRUE, "failed to add network device"); 2580 return (-1); 2581 } 2582 } 2583 (void) zonecfg_endnwifent(handle); 2584 zonecfg_fini_handle(handle); 2585 2586 if (prof != NULL && added) { 2587 if (di_prof_commit(prof) != 0) { 2588 zerror(zlogp, B_TRUE, "failed to commit profile"); 2589 return (-1); 2590 } 2591 } 2592 if (prof != NULL) 2593 di_prof_fini(prof); 2594 2595 return (0); 2596} 2597 2598static int 2599remove_datalink_pool(zlog_t *zlogp, zoneid_t zoneid) 2600{ 2601 ushort_t flags; 2602 zone_iptype_t iptype; 2603 int i, dlnum = 0; 2604 datalink_id_t *dllink, *dllinks = NULL; 2605 dladm_status_t err; 2606 2607 if (strlen(pool_name) == 0) 2608 return (0); 2609 2610 if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 2611 sizeof (flags)) < 0) { 2612 if (vplat_get_iptype(zlogp, &iptype) < 0) { 2613 zerror(zlogp, B_TRUE, "unable to determine " 2614 "ip-type"); 2615 return (-1); 2616 } 2617 } else { 2618 if (flags & ZF_NET_EXCL) 2619 iptype = ZS_EXCLUSIVE; 2620 else 2621 iptype = ZS_SHARED; 2622 } 2623 2624 if (iptype == ZS_EXCLUSIVE) { 2625 /* 2626 * Get the datalink count and for each datalink, 2627 * attempt to clear the pool property and clear 2628 * the pool_name. 2629 */ 2630 if (zone_list_datalink(zoneid, &dlnum, NULL) != 0) { 2631 zerror(zlogp, B_TRUE, "unable to count network " 2632 "interfaces"); 2633 return (-1); 2634 } 2635 2636 if (dlnum == 0) 2637 return (0); 2638 2639 if ((dllinks = malloc(dlnum * sizeof (datalink_id_t))) 2640 == NULL) { 2641 zerror(zlogp, B_TRUE, "memory allocation failed"); 2642 return (-1); 2643 } 2644 if (zone_list_datalink(zoneid, &dlnum, dllinks) != 0) { 2645 zerror(zlogp, B_TRUE, "unable to list network " 2646 "interfaces"); 2647 return (-1); 2648 } 2649 2650 bzero(pool_name, MAXPATHLEN); 2651 for (i = 0, dllink = dllinks; i < dlnum; i++, dllink++) { 2652 err = dladm_set_linkprop(dld_handle, *dllink, "pool", 2653 NULL, 0, DLADM_OPT_ACTIVE); 2654 if (err != DLADM_STATUS_OK) { 2655 zerror(zlogp, B_TRUE, 2656 "WARNING: unable to clear pool"); 2657 } 2658 } 2659 free(dllinks); 2660 } 2661 return (0); 2662} 2663 2664static int 2665unconfigure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid) 2666{ 2667 int dlnum = 0; 2668 2669 /* 2670 * The kernel shutdown callback for the dls module should have removed 2671 * all datalinks from this zone. If any remain, then there's a 2672 * problem. 2673 */ 2674 if (zone_list_datalink(zoneid, &dlnum, NULL) != 0) { 2675 zerror(zlogp, B_TRUE, "unable to list network interfaces"); 2676 return (-1); 2677 } 2678 if (dlnum != 0) { 2679 zerror(zlogp, B_FALSE, 2680 "datalinks remain in zone after shutdown"); 2681 return (-1); 2682 } 2683 return (0); 2684} 2685 2686static int 2687tcp_abort_conn(zlog_t *zlogp, zoneid_t zoneid, 2688 const struct sockaddr_storage *local, const struct sockaddr_storage *remote) 2689{ 2690 int fd; 2691 struct strioctl ioc; 2692 tcp_ioc_abort_conn_t conn; 2693 int error; 2694 2695 conn.ac_local = *local; 2696 conn.ac_remote = *remote; 2697 conn.ac_start = TCPS_SYN_SENT; 2698 conn.ac_end = TCPS_TIME_WAIT; 2699 conn.ac_zoneid = zoneid; 2700 2701 ioc.ic_cmd = TCP_IOC_ABORT_CONN; 2702 ioc.ic_timout = -1; /* infinite timeout */ 2703 ioc.ic_len = sizeof (conn); 2704 ioc.ic_dp = (char *)&conn; 2705 2706 if ((fd = open("/dev/tcp", O_RDONLY)) < 0) { 2707 zerror(zlogp, B_TRUE, "unable to open %s", "/dev/tcp"); 2708 return (-1); 2709 } 2710 2711 error = ioctl(fd, I_STR, &ioc); 2712 (void) close(fd); 2713 if (error == 0 || errno == ENOENT) /* ENOENT is not an error */ 2714 return (0); 2715 return (-1); 2716} 2717 2718static int 2719tcp_abort_connections(zlog_t *zlogp, zoneid_t zoneid) 2720{ 2721 struct sockaddr_storage l, r; 2722 struct sockaddr_in *local, *remote; 2723 struct sockaddr_in6 *local6, *remote6; 2724 int error; 2725 2726 /* 2727 * Abort IPv4 connections. 2728 */ 2729 bzero(&l, sizeof (*local)); 2730 local = (struct sockaddr_in *)&l; 2731 local->sin_family = AF_INET; 2732 local->sin_addr.s_addr = INADDR_ANY; 2733 local->sin_port = 0; 2734 2735 bzero(&r, sizeof (*remote)); 2736 remote = (struct sockaddr_in *)&r; 2737 remote->sin_family = AF_INET; 2738 remote->sin_addr.s_addr = INADDR_ANY; 2739 remote->sin_port = 0; 2740 2741 if ((error = tcp_abort_conn(zlogp, zoneid, &l, &r)) != 0) 2742 return (error); 2743 2744 /* 2745 * Abort IPv6 connections. 2746 */ 2747 bzero(&l, sizeof (*local6)); 2748 local6 = (struct sockaddr_in6 *)&l; 2749 local6->sin6_family = AF_INET6; 2750 local6->sin6_port = 0; 2751 local6->sin6_addr = in6addr_any; 2752 2753 bzero(&r, sizeof (*remote6)); 2754 remote6 = (struct sockaddr_in6 *)&r; 2755 remote6->sin6_family = AF_INET6; 2756 remote6->sin6_port = 0; 2757 remote6->sin6_addr = in6addr_any; 2758 2759 if ((error = tcp_abort_conn(zlogp, zoneid, &l, &r)) != 0) 2760 return (error); 2761 return (0); 2762} 2763 2764static int 2765get_privset(zlog_t *zlogp, priv_set_t *privs, zone_mnt_t mount_cmd) 2766{ 2767 int error = -1; 2768 zone_dochandle_t handle; 2769 char *privname = NULL; 2770 2771 if ((handle = zonecfg_init_handle()) == NULL) { 2772 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 2773 return (-1); 2774 } 2775 if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { 2776 zerror(zlogp, B_FALSE, "invalid configuration"); 2777 zonecfg_fini_handle(handle); 2778 return (-1); 2779 } 2780 2781 if (ALT_MOUNT(mount_cmd)) { 2782 zone_iptype_t iptype; 2783 const char *curr_iptype; 2784 2785 if (zonecfg_get_iptype(handle, &iptype) != Z_OK) { 2786 zerror(zlogp, B_TRUE, "unable to determine ip-type"); 2787 zonecfg_fini_handle(handle); 2788 return (-1); 2789 } 2790 2791 switch (iptype) { 2792 case ZS_SHARED: 2793 curr_iptype = "shared"; 2794 break; 2795 case ZS_EXCLUSIVE: 2796 curr_iptype = "exclusive"; 2797 break; 2798 } 2799 2800 if (zonecfg_default_privset(privs, curr_iptype) == Z_OK) { 2801 zonecfg_fini_handle(handle); 2802 return (0); 2803 } 2804 zerror(zlogp, B_FALSE, 2805 "failed to determine the zone's default privilege set"); 2806 zonecfg_fini_handle(handle); 2807 return (-1); 2808 } 2809 2810 switch (zonecfg_get_privset(handle, privs, &privname)) { 2811 case Z_OK: 2812 error = 0; 2813 break; 2814 case Z_PRIV_PROHIBITED: 2815 zerror(zlogp, B_FALSE, "privilege \"%s\" is not permitted " 2816 "within the zone's privilege set", privname); 2817 break; 2818 case Z_PRIV_REQUIRED: 2819 zerror(zlogp, B_FALSE, "required privilege \"%s\" is missing " 2820 "from the zone's privilege set", privname); 2821 break; 2822 case Z_PRIV_UNKNOWN: 2823 zerror(zlogp, B_FALSE, "unknown privilege \"%s\" specified " 2824 "in the zone's privilege set", privname); 2825 break; 2826 default: 2827 zerror(zlogp, B_FALSE, "failed to determine the zone's " 2828 "privilege set"); 2829 break; 2830 } 2831 2832 free(privname); 2833 zonecfg_fini_handle(handle); 2834 return (error); 2835} 2836 2837static int 2838get_rctls(zlog_t *zlogp, char **bufp, size_t *bufsizep) 2839{ 2840 nvlist_t *nvl = NULL; 2841 char *nvl_packed = NULL; 2842 size_t nvl_size = 0; 2843 nvlist_t **nvlv = NULL; 2844 int rctlcount = 0; 2845 int error = -1; 2846 zone_dochandle_t handle; 2847 struct zone_rctltab rctltab; 2848 rctlblk_t *rctlblk = NULL; 2849 uint64_t maxlwps; 2850 uint64_t maxprocs; 2851 2852 *bufp = NULL; 2853 *bufsizep = 0; 2854 2855 if ((handle = zonecfg_init_handle()) == NULL) { 2856 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 2857 return (-1); 2858 } 2859 if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { 2860 zerror(zlogp, B_FALSE, "invalid configuration"); 2861 zonecfg_fini_handle(handle); 2862 return (-1); 2863 } 2864 2865 rctltab.zone_rctl_valptr = NULL; 2866 if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) { 2867 zerror(zlogp, B_TRUE, "%s failed", "nvlist_alloc"); 2868 goto out; 2869 } 2870 2871 /* 2872 * Allow the administrator to control both the maximum number of 2873 * process table slots and the maximum number of lwps with just the 2874 * max-processes property. If only the max-processes property is set, 2875 * we add a max-lwps property with a limit derived from max-processes. 2876 */ 2877 if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXPROCS, &maxprocs) 2878 == Z_OK && 2879 zonecfg_get_aliased_rctl(handle, ALIAS_MAXLWPS, &maxlwps) 2880 == Z_NO_ENTRY) { 2881 if (zonecfg_set_aliased_rctl(handle, ALIAS_MAXLWPS, 2882 maxprocs * LWPS_PER_PROCESS) != Z_OK) { 2883 zerror(zlogp, B_FALSE, "unable to set max-lwps alias"); 2884 goto out; 2885 } 2886 } 2887 2888 if (zonecfg_setrctlent(handle) != Z_OK) { 2889 zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setrctlent"); 2890 goto out; 2891 } 2892 2893 if ((rctlblk = malloc(rctlblk_size())) == NULL) { 2894 zerror(zlogp, B_TRUE, "memory allocation failed"); 2895 goto out; 2896 } 2897 while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) { 2898 struct zone_rctlvaltab *rctlval; 2899 uint_t i, count; 2900 const char *name = rctltab.zone_rctl_name; 2901 2902 /* zoneadm should have already warned about unknown rctls. */ 2903 if (!zonecfg_is_rctl(name)) { 2904 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 2905 rctltab.zone_rctl_valptr = NULL; 2906 continue; 2907 } 2908 count = 0; 2909 for (rctlval = rctltab.zone_rctl_valptr; rctlval != NULL; 2910 rctlval = rctlval->zone_rctlval_next) { 2911 count++; 2912 } 2913 if (count == 0) { /* ignore */ 2914 continue; /* Nothing to free */ 2915 } 2916 if ((nvlv = malloc(sizeof (*nvlv) * count)) == NULL) 2917 goto out; 2918 i = 0; 2919 for (rctlval = rctltab.zone_rctl_valptr; rctlval != NULL; 2920 rctlval = rctlval->zone_rctlval_next, i++) { 2921 if (nvlist_alloc(&nvlv[i], NV_UNIQUE_NAME, 0) != 0) { 2922 zerror(zlogp, B_TRUE, "%s failed", 2923 "nvlist_alloc"); 2924 goto out; 2925 } 2926 if (zonecfg_construct_rctlblk(rctlval, rctlblk) 2927 != Z_OK) { 2928 zerror(zlogp, B_FALSE, "invalid rctl value: " 2929 "(priv=%s,limit=%s,action=%s)", 2930 rctlval->zone_rctlval_priv, 2931 rctlval->zone_rctlval_limit, 2932 rctlval->zone_rctlval_action); 2933 goto out; 2934 } 2935 if (!zonecfg_valid_rctl(name, rctlblk)) { 2936 zerror(zlogp, B_FALSE, 2937 "(priv=%s,limit=%s,action=%s) is not a " 2938 "valid value for rctl '%s'", 2939 rctlval->zone_rctlval_priv, 2940 rctlval->zone_rctlval_limit, 2941 rctlval->zone_rctlval_action, 2942 name); 2943 goto out; 2944 } 2945 if (nvlist_add_uint64(nvlv[i], "privilege", 2946 rctlblk_get_privilege(rctlblk)) != 0) { 2947 zerror(zlogp, B_FALSE, "%s failed", 2948 "nvlist_add_uint64"); 2949 goto out; 2950 } 2951 if (nvlist_add_uint64(nvlv[i], "limit", 2952 rctlblk_get_value(rctlblk)) != 0) { 2953 zerror(zlogp, B_FALSE, "%s failed", 2954 "nvlist_add_uint64"); 2955 goto out; 2956 } 2957 if (nvlist_add_uint64(nvlv[i], "action", 2958 (uint_t)rctlblk_get_local_action(rctlblk, NULL)) 2959 != 0) { 2960 zerror(zlogp, B_FALSE, "%s failed", 2961 "nvlist_add_uint64"); 2962 goto out; 2963 } 2964 } 2965 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 2966 rctltab.zone_rctl_valptr = NULL; 2967 if (nvlist_add_nvlist_array(nvl, (char *)name, nvlv, count) 2968 != 0) { 2969 zerror(zlogp, B_FALSE, "%s failed", 2970 "nvlist_add_nvlist_array"); 2971 goto out; 2972 } 2973 for (i = 0; i < count; i++) 2974 nvlist_free(nvlv[i]); 2975 free(nvlv); 2976 nvlv = NULL; 2977 rctlcount++; 2978 } 2979 (void) zonecfg_endrctlent(handle); 2980 2981 if (rctlcount == 0) { 2982 error = 0; 2983 goto out; 2984 } 2985 if (nvlist_pack(nvl, &nvl_packed, &nvl_size, NV_ENCODE_NATIVE, 0) 2986 != 0) { 2987 zerror(zlogp, B_FALSE, "%s failed", "nvlist_pack"); 2988 goto out; 2989 } 2990 2991 error = 0; 2992 *bufp = nvl_packed; 2993 *bufsizep = nvl_size; 2994 2995out: 2996 free(rctlblk); 2997 zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr); 2998 if (error && nvl_packed != NULL) 2999 free(nvl_packed); 3000 if (nvl != NULL) 3001 nvlist_free(nvl); 3002 if (nvlv != NULL) 3003 free(nvlv); 3004 if (handle != NULL) 3005 zonecfg_fini_handle(handle); 3006 return (error); 3007} 3008 3009static int 3010get_implicit_datasets(zlog_t *zlogp, char **retstr) 3011{ 3012 char cmdbuf[2 * MAXPATHLEN]; 3013 3014 if (query_hook[0] == '\0') 3015 return (0); 3016 3017 if (snprintf(cmdbuf, sizeof (cmdbuf), "%s datasets", query_hook) 3018 > sizeof (cmdbuf)) 3019 return (-1); 3020 3021 if (do_subproc(zlogp, cmdbuf, retstr) != 0) 3022 return (-1); 3023 3024 return (0); 3025} 3026 3027static int 3028get_datasets(zlog_t *zlogp, char **bufp, size_t *bufsizep) 3029{ 3030 zone_dochandle_t handle; 3031 struct zone_dstab dstab; 3032 size_t total, offset, len; 3033 int error = -1; 3034 char *str = NULL; 3035 char *implicit_datasets = NULL; 3036 int implicit_len = 0; 3037 3038 *bufp = NULL; 3039 *bufsizep = 0; 3040 3041 if ((handle = zonecfg_init_handle()) == NULL) { 3042 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 3043 return (-1); 3044 } 3045 if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { 3046 zerror(zlogp, B_FALSE, "invalid configuration"); 3047 zonecfg_fini_handle(handle); 3048 return (-1); 3049 } 3050 3051 if (get_implicit_datasets(zlogp, &implicit_datasets) != 0) { 3052 zerror(zlogp, B_FALSE, "getting implicit datasets failed"); 3053 goto out; 3054 } 3055 3056 if (zonecfg_setdsent(handle) != Z_OK) { 3057 zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setdsent"); 3058 goto out; 3059 } 3060 3061 total = 0; 3062 while (zonecfg_getdsent(handle, &dstab) == Z_OK) 3063 total += strlen(dstab.zone_dataset_name) + 1; 3064 (void) zonecfg_enddsent(handle); 3065 3066 if (implicit_datasets != NULL) 3067 implicit_len = strlen(implicit_datasets); 3068 if (implicit_len > 0) 3069 total += implicit_len + 1; 3070 3071 if (total == 0) { 3072 error = 0; 3073 goto out; 3074 } 3075 3076 if ((str = malloc(total)) == NULL) { 3077 zerror(zlogp, B_TRUE, "memory allocation failed"); 3078 goto out; 3079 } 3080 3081 if (zonecfg_setdsent(handle) != Z_OK) { 3082 zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setdsent"); 3083 goto out; 3084 } 3085 offset = 0; 3086 while (zonecfg_getdsent(handle, &dstab) == Z_OK) { 3087 len = strlen(dstab.zone_dataset_name); 3088 (void) strlcpy(str + offset, dstab.zone_dataset_name, 3089 total - offset); 3090 offset += len; 3091 if (offset < total - 1) 3092 str[offset++] = ','; 3093 } 3094 (void) zonecfg_enddsent(handle); 3095 3096 if (implicit_len > 0) 3097 (void) strlcpy(str + offset, implicit_datasets, total - offset); 3098 3099 error = 0; 3100 *bufp = str; 3101 *bufsizep = total; 3102 3103out: 3104 if (error != 0 && str != NULL) 3105 free(str); 3106 if (handle != NULL) 3107 zonecfg_fini_handle(handle); 3108 if (implicit_datasets != NULL) 3109 free(implicit_datasets); 3110 3111 return (error); 3112} 3113 3114static int 3115validate_datasets(zlog_t *zlogp) 3116{ 3117 zone_dochandle_t handle; 3118 struct zone_dstab dstab; 3119 zfs_handle_t *zhp; 3120 libzfs_handle_t *hdl; 3121 3122 if ((handle = zonecfg_init_handle()) == NULL) { 3123 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 3124 return (-1); 3125 } 3126 if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) { 3127 zerror(zlogp, B_FALSE, "invalid configuration"); 3128 zonecfg_fini_handle(handle); 3129 return (-1); 3130 } 3131 3132 if (zonecfg_setdsent(handle) != Z_OK) { 3133 zerror(zlogp, B_FALSE, "invalid configuration"); 3134 zonecfg_fini_handle(handle); 3135 return (-1); 3136 } 3137 3138 if ((hdl = libzfs_init()) == NULL) { 3139 zerror(zlogp, B_FALSE, "opening ZFS library"); 3140 zonecfg_fini_handle(handle); 3141 return (-1); 3142 } 3143 3144 while (zonecfg_getdsent(handle, &dstab) == Z_OK) { 3145 3146 if ((zhp = zfs_open(hdl, dstab.zone_dataset_name, 3147 ZFS_TYPE_FILESYSTEM)) == NULL) { 3148 zerror(zlogp, B_FALSE, "cannot open ZFS dataset '%s'", 3149 dstab.zone_dataset_name); 3150 zonecfg_fini_handle(handle); 3151 libzfs_fini(hdl); 3152 return (-1); 3153 } 3154 3155 /* 3156 * Automatically set the 'zoned' property. We check the value 3157 * first because we'll get EPERM if it is already set. 3158 */ 3159 if (!zfs_prop_get_int(zhp, ZFS_PROP_ZONED) && 3160 zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_ZONED), 3161 "on") != 0) { 3162 zerror(zlogp, B_FALSE, "cannot set 'zoned' " 3163 "property for ZFS dataset '%s'\n", 3164 dstab.zone_dataset_name); 3165 zonecfg_fini_handle(handle); 3166 zfs_close(zhp); 3167 libzfs_fini(hdl); 3168 return (-1); 3169 } 3170 3171 zfs_close(zhp); 3172 } 3173 (void) zonecfg_enddsent(handle); 3174 3175 zonecfg_fini_handle(handle); 3176 libzfs_fini(hdl); 3177 3178 return (0); 3179} 3180 3181/* 3182 * Return true if the path is its own zfs file system. We determine this 3183 * by stat-ing the path to see if it is zfs and stat-ing the parent to see 3184 * if it is a different fs. 3185 */ 3186boolean_t 3187is_zonepath_zfs(char *zonepath) 3188{ 3189 int res; 3190 char *path; 3191 char *parent; 3192 struct statvfs64 buf1, buf2; 3193 3194 if (statvfs64(zonepath, &buf1) != 0) 3195 return (B_FALSE); 3196 3197 if (strcmp(buf1.f_basetype, "zfs") != 0) 3198 return (B_FALSE); 3199 3200 if ((path = strdup(zonepath)) == NULL) 3201 return (B_FALSE); 3202 3203 parent = dirname(path); 3204 res = statvfs64(parent, &buf2); 3205 free(path); 3206 3207 if (res != 0) 3208 return (B_FALSE); 3209 3210 if (buf1.f_fsid == buf2.f_fsid) 3211 return (B_FALSE); 3212 3213 return (B_TRUE); 3214} 3215 3216/* 3217 * Verify the MAC label in the root dataset for the zone. 3218 * If the label exists, it must match the label configured for the zone. 3219 * Otherwise if there's no label on the dataset, create one here. 3220 */ 3221 3222static int 3223validate_rootds_label(zlog_t *zlogp, char *rootpath, m_label_t *zone_sl) 3224{ 3225 int error = -1; 3226 zfs_handle_t *zhp; 3227 libzfs_handle_t *hdl; 3228 m_label_t ds_sl; 3229 char zonepath[MAXPATHLEN]; 3230 char ds_hexsl[MAXNAMELEN]; 3231 3232 if (!is_system_labeled()) 3233 return (0); 3234 3235 if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) { 3236 zerror(zlogp, B_TRUE, "unable to determine zone path"); 3237 return (-1); 3238 } 3239 3240 if (!is_zonepath_zfs(zonepath)) 3241 return (0); 3242 3243 if ((hdl = libzfs_init()) == NULL) { 3244 zerror(zlogp, B_FALSE, "opening ZFS library"); 3245 return (-1); 3246 } 3247 3248 if ((zhp = zfs_path_to_zhandle(hdl, rootpath, 3249 ZFS_TYPE_FILESYSTEM)) == NULL) { 3250 zerror(zlogp, B_FALSE, "cannot open ZFS dataset for path '%s'", 3251 rootpath); 3252 libzfs_fini(hdl); 3253 return (-1); 3254 } 3255 3256 /* Get the mlslabel property if it exists. */ 3257 if ((zfs_prop_get(zhp, ZFS_PROP_MLSLABEL, ds_hexsl, MAXNAMELEN, 3258 NULL, NULL, 0, B_TRUE) != 0) || 3259 (strcmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) == 0)) { 3260 char *str2 = NULL; 3261 3262 /* 3263 * No label on the dataset (or default only); create one. 3264 * (Only do this automatic labeling for the labeled brand.) 3265 */ 3266 if (strcmp(brand_name, LABELED_BRAND_NAME) != 0) { 3267 error = 0; 3268 goto out; 3269 } 3270 3271 error = l_to_str_internal(zone_sl, &str2); 3272 if (error) 3273 goto out; 3274 if (str2 == NULL) { 3275 error = -1; 3276 goto out; 3277 } 3278 if ((error = zfs_prop_set(zhp, 3279 zfs_prop_to_name(ZFS_PROP_MLSLABEL), str2)) != 0) { 3280 zerror(zlogp, B_FALSE, "cannot set 'mlslabel' " 3281 "property for root dataset at '%s'\n", rootpath); 3282 } 3283 free(str2); 3284 goto out; 3285 } 3286 3287 /* Convert the retrieved dataset label to binary form. */ 3288 error = hexstr_to_label(ds_hexsl, &ds_sl); 3289 if (error) { 3290 zerror(zlogp, B_FALSE, "invalid 'mlslabel' " 3291 "property on root dataset at '%s'\n", rootpath); 3292 goto out; /* exit with error */ 3293 } 3294 3295 /* 3296 * Perform a MAC check by comparing the zone label with the 3297 * dataset label. 3298 */ 3299 error = (!blequal(zone_sl, &ds_sl)); 3300 if (error) 3301 zerror(zlogp, B_FALSE, "Rootpath dataset has mismatched label"); 3302out: 3303 zfs_close(zhp); 3304 libzfs_fini(hdl); 3305 3306 return (error); 3307} 3308 3309/* 3310 * Mount lower level home directories into/from current zone 3311 * Share exported directories specified in dfstab for zone 3312 */ 3313static int 3314tsol_mounts(zlog_t *zlogp, char *zone_name, char *rootpath) 3315{ 3316 zoneid_t *zids = NULL; 3317 priv_set_t *zid_privs; 3318 const priv_impl_info_t *ip = NULL; 3319 uint_t nzents_saved; 3320 uint_t nzents; 3321 int i; 3322 char readonly[] = "ro"; 3323 struct zone_fstab lower_fstab; 3324 char *argv[4]; 3325 3326 if (!is_system_labeled()) 3327 return (0); 3328 3329 if (zid_label == NULL) { 3330 zid_label = m_label_alloc(MAC_LABEL); 3331 if (zid_label == NULL) 3332 return (-1); 3333 } 3334 3335 /* Make sure our zone has an /export/home dir */ 3336 (void) make_one_dir(zlogp, rootpath, "/export/home", 3337 DEFAULT_DIR_MODE, DEFAULT_DIR_USER, DEFAULT_DIR_GROUP); 3338 3339 lower_fstab.zone_fs_raw[0] = '\0'; 3340 (void) strlcpy(lower_fstab.zone_fs_type, MNTTYPE_LOFS, 3341 sizeof (lower_fstab.zone_fs_type)); 3342 lower_fstab.zone_fs_options = NULL; 3343 (void) zonecfg_add_fs_option(&lower_fstab, readonly); 3344 3345 /* 3346 * Get the list of zones from the kernel 3347 */ 3348 if (zone_list(NULL, &nzents) != 0) { 3349 zerror(zlogp, B_TRUE, "unable to list zones"); 3350 zonecfg_free_fs_option_list(lower_fstab.zone_fs_options); 3351 return (-1); 3352 } 3353again: 3354 if (nzents == 0) { 3355 zonecfg_free_fs_option_list(lower_fstab.zone_fs_options); 3356 return (-1); 3357 } 3358 3359 zids = malloc(nzents * sizeof (zoneid_t)); 3360 if (zids == NULL) { 3361 zerror(zlogp, B_TRUE, "memory allocation failed"); 3362 return (-1); 3363 } 3364 nzents_saved = nzents; 3365 3366 if (zone_list(zids, &nzents) != 0) { 3367 zerror(zlogp, B_TRUE, "unable to list zones"); 3368 zonecfg_free_fs_option_list(lower_fstab.zone_fs_options); 3369 free(zids); 3370 return (-1); 3371 } 3372 if (nzents != nzents_saved) { 3373 /* list changed, try again */ 3374 free(zids); 3375 goto again; 3376 } 3377 3378 ip = getprivimplinfo(); 3379 if ((zid_privs = priv_allocset()) == NULL) { 3380 zerror(zlogp, B_TRUE, "%s failed", "priv_allocset"); 3381 zonecfg_free_fs_option_list( 3382 lower_fstab.zone_fs_options); 3383 free(zids); 3384 return (-1); 3385 } 3386 3387 for (i = 0; i < nzents; i++) { 3388 char zid_name[ZONENAME_MAX]; 3389 zone_state_t zid_state; 3390 char zid_rpath[MAXPATHLEN]; 3391 struct stat stat_buf; 3392 3393 if (zids[i] == GLOBAL_ZONEID) 3394 continue; 3395 3396 if (getzonenamebyid(zids[i], zid_name, ZONENAME_MAX) == -1) 3397 continue; 3398 3399 /* 3400 * Do special setup for the zone we are booting 3401 */ 3402 if (strcmp(zid_name, zone_name) == 0) { 3403 struct zone_fstab autofs_fstab; 3404 char map_path[MAXPATHLEN]; 3405 int fd; 3406 3407 /* 3408 * Create auto_home_<zone> map for this zone 3409 * in the global zone. The non-global zone entry 3410 * will be created by automount when the zone 3411 * is booted. 3412 */ 3413 3414 (void) snprintf(autofs_fstab.zone_fs_special, 3415 MAXPATHLEN, "auto_home_%s", zid_name); 3416 3417 (void) snprintf(autofs_fstab.zone_fs_dir, MAXPATHLEN, 3418 "/zone/%s/home", zid_name); 3419 3420 (void) snprintf(map_path, sizeof (map_path), 3421 "/etc/%s", autofs_fstab.zone_fs_special); 3422 /* 3423 * If the map file doesn't exist create a template 3424 */ 3425 if ((fd = open(map_path, O_RDWR | O_CREAT | O_EXCL, 3426 S_IRUSR | S_IWUSR | S_IRGRP| S_IROTH)) != -1) { 3427 int len; 3428 char map_rec[MAXPATHLEN]; 3429 3430 len = snprintf(map_rec, sizeof (map_rec), 3431 "+%s\n*\t-fstype=lofs\t:%s/export/home/&\n", 3432 autofs_fstab.zone_fs_special, rootpath); 3433 (void) write(fd, map_rec, len); 3434 (void) close(fd); 3435 } 3436 3437 /* 3438 * Mount auto_home_<zone> in the global zone if absent. 3439 * If it's already of type autofs, then 3440 * don't mount it again. 3441 */ 3442 if ((stat(autofs_fstab.zone_fs_dir, &stat_buf) == -1) || 3443 strcmp(stat_buf.st_fstype, MNTTYPE_AUTOFS) != 0) { 3444 char optstr[] = "indirect,ignore,nobrowse"; 3445 3446 (void) make_one_dir(zlogp, "", 3447 autofs_fstab.zone_fs_dir, DEFAULT_DIR_MODE, 3448 DEFAULT_DIR_USER, DEFAULT_DIR_GROUP); 3449 3450 /* 3451 * Mount will fail if automounter has already 3452 * processed the auto_home_<zonename> map 3453 */ 3454 (void) domount(zlogp, MNTTYPE_AUTOFS, optstr, 3455 autofs_fstab.zone_fs_special, 3456 autofs_fstab.zone_fs_dir); 3457 } 3458 continue; 3459 } 3460 3461 3462 if (zone_get_state(zid_name, &zid_state) != Z_OK || 3463 (zid_state != ZONE_STATE_READY && 3464 zid_state != ZONE_STATE_RUNNING)) 3465 /* Skip over zones without mounted filesystems */ 3466 continue; 3467 3468 if (zone_getattr(zids[i], ZONE_ATTR_SLBL, zid_label, 3469 sizeof (m_label_t)) < 0) 3470 /* Skip over zones with unspecified label */ 3471 continue; 3472 3473 if (zone_getattr(zids[i], ZONE_ATTR_ROOT, zid_rpath, 3474 sizeof (zid_rpath)) == -1) 3475 /* Skip over zones with bad path */ 3476 continue; 3477 3478 if (zone_getattr(zids[i], ZONE_ATTR_PRIVSET, zid_privs, 3479 sizeof (priv_chunk_t) * ip->priv_setsize) == -1) 3480 /* Skip over zones with bad privs */ 3481 continue; 3482 3483 /* 3484 * Reading down is valid according to our label model 3485 * but some customers want to disable it because it 3486 * allows execute down and other possible attacks. 3487 * Therefore, we restrict this feature to zones that 3488 * have the NET_MAC_AWARE privilege which is required 3489 * for NFS read-down semantics. 3490 */ 3491 if ((bldominates(zlabel, zid_label)) && 3492 (priv_ismember(zprivs, PRIV_NET_MAC_AWARE))) { 3493 /* 3494 * Our zone dominates this one. 3495 * Create a lofs mount from lower zone's /export/home 3496 */ 3497 (void) snprintf(lower_fstab.zone_fs_dir, MAXPATHLEN, 3498 "%s/zone/%s/export/home", rootpath, zid_name); 3499 3500 /* 3501 * If the target is already an LOFS mount 3502 * then don't do it again. 3503 */ 3504 if ((stat(lower_fstab.zone_fs_dir, &stat_buf) == -1) || 3505 strcmp(stat_buf.st_fstype, MNTTYPE_LOFS) != 0) { 3506 3507 if (snprintf(lower_fstab.zone_fs_special, 3508 MAXPATHLEN, "%s/export", 3509 zid_rpath) > MAXPATHLEN) 3510 continue; 3511 3512 /* 3513 * Make sure the lower-level home exists 3514 */ 3515 if (make_one_dir(zlogp, 3516 lower_fstab.zone_fs_special, "/home", 3517 DEFAULT_DIR_MODE, DEFAULT_DIR_USER, 3518 DEFAULT_DIR_GROUP) != 0) 3519 continue; 3520 3521 (void) strlcat(lower_fstab.zone_fs_special, 3522 "/home", MAXPATHLEN); 3523 3524 /* 3525 * Mount can fail because the lower-level 3526 * zone may have already done a mount up. 3527 */ 3528 (void) mount_one(zlogp, &lower_fstab, "", 3529 Z_MNT_BOOT); 3530 } 3531 } else if ((bldominates(zid_label, zlabel)) && 3532 (priv_ismember(zid_privs, PRIV_NET_MAC_AWARE))) { 3533 /* 3534 * This zone dominates our zone. 3535 * Create a lofs mount from our zone's /export/home 3536 */ 3537 if (snprintf(lower_fstab.zone_fs_dir, MAXPATHLEN, 3538 "%s/zone/%s/export/home", zid_rpath, 3539 zone_name) > MAXPATHLEN) 3540 continue; 3541 3542 /* 3543 * If the target is already an LOFS mount 3544 * then don't do it again. 3545 */ 3546 if ((stat(lower_fstab.zone_fs_dir, &stat_buf) == -1) || 3547 strcmp(stat_buf.st_fstype, MNTTYPE_LOFS) != 0) { 3548 3549 (void) snprintf(lower_fstab.zone_fs_special, 3550 MAXPATHLEN, "%s/export/home", rootpath); 3551 3552 /* 3553 * Mount can fail because the higher-level 3554 * zone may have already done a mount down. 3555 */ 3556 (void) mount_one(zlogp, &lower_fstab, "", 3557 Z_MNT_BOOT); 3558 } 3559 } 3560 } 3561 zonecfg_free_fs_option_list(lower_fstab.zone_fs_options); 3562 priv_freeset(zid_privs); 3563 free(zids); 3564 3565 /* 3566 * Now share any exported directories from this zone. 3567 * Each zone can have its own dfstab. 3568 */ 3569 3570 argv[0] = "zoneshare"; 3571 argv[1] = "-z"; 3572 argv[2] = zone_name; 3573 argv[3] = NULL; 3574 3575 (void) forkexec(zlogp, "/usr/lib/zones/zoneshare", argv); 3576 /* Don't check for errors since they don't affect the zone */ 3577 3578 return (0); 3579} 3580 3581/* 3582 * Unmount lofs mounts from higher level zones 3583 * Unshare nfs exported directories 3584 */ 3585static void 3586tsol_unmounts(zlog_t *zlogp, char *zone_name) 3587{ 3588 zoneid_t *zids = NULL; 3589 uint_t nzents_saved; 3590 uint_t nzents; 3591 int i; 3592 char *argv[4]; 3593 char path[MAXPATHLEN]; 3594 3595 if (!is_system_labeled()) 3596 return; 3597 3598 /* 3599 * Get the list of zones from the kernel 3600 */ 3601 if (zone_list(NULL, &nzents) != 0) { 3602 return; 3603 } 3604 3605 if (zid_label == NULL) { 3606 zid_label = m_label_alloc(MAC_LABEL); 3607 if (zid_label == NULL) 3608 return; 3609 } 3610 3611again: 3612 if (nzents == 0) 3613 return; 3614 3615 zids = malloc(nzents * sizeof (zoneid_t)); 3616 if (zids == NULL) { 3617 zerror(zlogp, B_TRUE, "memory allocation failed"); 3618 return; 3619 } 3620 nzents_saved = nzents; 3621 3622 if (zone_list(zids, &nzents) != 0) { 3623 free(zids); 3624 return; 3625 } 3626 if (nzents != nzents_saved) { 3627 /* list changed, try again */ 3628 free(zids); 3629 goto again; 3630 } 3631 3632 for (i = 0; i < nzents; i++) { 3633 char zid_name[ZONENAME_MAX]; 3634 zone_state_t zid_state; 3635 char zid_rpath[MAXPATHLEN]; 3636 3637 if (zids[i] == GLOBAL_ZONEID) 3638 continue; 3639 3640 if (getzonenamebyid(zids[i], zid_name, ZONENAME_MAX) == -1) 3641 continue; 3642 3643 /* 3644 * Skip the zone we are halting 3645 */ 3646 if (strcmp(zid_name, zone_name) == 0) 3647 continue; 3648 3649 if ((zone_getattr(zids[i], ZONE_ATTR_STATUS, &zid_state, 3650 sizeof (zid_state)) < 0) || 3651 (zid_state < ZONE_IS_READY)) 3652 /* Skip over zones without mounted filesystems */ 3653 continue; 3654 3655 if (zone_getattr(zids[i], ZONE_ATTR_SLBL, zid_label, 3656 sizeof (m_label_t)) < 0) 3657 /* Skip over zones with unspecified label */ 3658 continue; 3659 3660 if (zone_getattr(zids[i], ZONE_ATTR_ROOT, zid_rpath, 3661 sizeof (zid_rpath)) == -1) 3662 /* Skip over zones with bad path */ 3663 continue; 3664 3665 if (zlabel != NULL && bldominates(zid_label, zlabel)) { 3666 /* 3667 * This zone dominates our zone. 3668 * Unmount the lofs mount of our zone's /export/home 3669 */ 3670 3671 if (snprintf(path, MAXPATHLEN, 3672 "%s/zone/%s/export/home", zid_rpath, 3673 zone_name) > MAXPATHLEN) 3674 continue; 3675 3676 /* Skip over mount failures */ 3677 (void) umount(path); 3678 } 3679 } 3680 free(zids); 3681 3682 /* 3683 * Unmount global zone autofs trigger for this zone 3684 */ 3685 (void) snprintf(path, MAXPATHLEN, "/zone/%s/home", zone_name); 3686 /* Skip over mount failures */ 3687 (void) umount(path); 3688 3689 /* 3690 * Next unshare any exported directories from this zone. 3691 */ 3692 3693 argv[0] = "zoneunshare"; 3694 argv[1] = "-z"; 3695 argv[2] = zone_name; 3696 argv[3] = NULL; 3697 3698 (void) forkexec(zlogp, "/usr/lib/zones/zoneunshare", argv); 3699 /* Don't check for errors since they don't affect the zone */ 3700 3701 /* 3702 * Finally, deallocate any devices in the zone. 3703 */ 3704 3705 argv[0] = "deallocate"; 3706 argv[1] = "-Isz"; 3707 argv[2] = zone_name; 3708 argv[3] = NULL; 3709 3710 (void) forkexec(zlogp, "/usr/sbin/deallocate", argv); 3711 /* Don't check for errors since they don't affect the zone */ 3712} 3713 3714/* 3715 * Fetch the Trusted Extensions label and multi-level ports (MLPs) for 3716 * this zone. 3717 */ 3718static tsol_zcent_t * 3719get_zone_label(zlog_t *zlogp, priv_set_t *privs) 3720{ 3721 FILE *fp; 3722 tsol_zcent_t *zcent = NULL; 3723 char line[MAXTNZLEN]; 3724 3725 if ((fp = fopen(TNZONECFG_PATH, "r")) == NULL) { 3726 zerror(zlogp, B_TRUE, "%s", TNZONECFG_PATH); 3727 return (NULL); 3728 } 3729 3730 while (fgets(line, sizeof (line), fp) != NULL) { 3731 /* 3732 * Check for malformed database 3733 */ 3734 if (strlen(line) == MAXTNZLEN - 1) 3735 break; 3736 if ((zcent = tsol_sgetzcent(line, NULL, NULL)) == NULL) 3737 continue; 3738 if (strcmp(zcent->zc_name, zone_name) == 0) 3739 break; 3740 tsol_freezcent(zcent); 3741 zcent = NULL; 3742 } 3743 (void) fclose(fp); 3744 3745 if (zcent == NULL) { 3746 zerror(zlogp, B_FALSE, "zone requires a label assignment. " 3747 "See tnzonecfg(4)"); 3748 } else { 3749 if (zlabel == NULL) 3750 zlabel = m_label_alloc(MAC_LABEL); 3751 /* 3752 * Save this zone's privileges for later read-down processing 3753 */ 3754 if ((zprivs = priv_allocset()) == NULL) { 3755 zerror(zlogp, B_TRUE, "%s failed", "priv_allocset"); 3756 return (NULL); 3757 } else { 3758 priv_copyset(privs, zprivs); 3759 } 3760 } 3761 return (zcent); 3762} 3763 3764/* 3765 * Add the Trusted Extensions multi-level ports for this zone. 3766 */ 3767static void 3768set_mlps(zlog_t *zlogp, zoneid_t zoneid, tsol_zcent_t *zcent) 3769{ 3770 tsol_mlp_t *mlp; 3771 tsol_mlpent_t tsme; 3772 3773 if (!is_system_labeled()) 3774 return; 3775 3776 tsme.tsme_zoneid = zoneid; 3777 tsme.tsme_flags = 0; 3778 for (mlp = zcent->zc_private_mlp; !TSOL_MLP_END(mlp); mlp++) { 3779 tsme.tsme_mlp = *mlp; 3780 if (tnmlp(TNDB_LOAD, &tsme) != 0) { 3781 zerror(zlogp, B_TRUE, "cannot set zone-specific MLP " 3782 "on %d-%d/%d", mlp->mlp_port, 3783 mlp->mlp_port_upper, mlp->mlp_ipp); 3784 } 3785 } 3786 3787 tsme.tsme_flags = TSOL_MEF_SHARED; 3788 for (mlp = zcent->zc_shared_mlp; !TSOL_MLP_END(mlp); mlp++) { 3789 tsme.tsme_mlp = *mlp; 3790 if (tnmlp(TNDB_LOAD, &tsme) != 0) { 3791 zerror(zlogp, B_TRUE, "cannot set shared MLP " 3792 "on %d-%d/%d", mlp->mlp_port, 3793 mlp->mlp_port_upper, mlp->mlp_ipp); 3794 } 3795 } 3796} 3797 3798static void 3799remove_mlps(zlog_t *zlogp, zoneid_t zoneid) 3800{ 3801 tsol_mlpent_t tsme; 3802 3803 if (!is_system_labeled()) 3804 return; 3805 3806 (void) memset(&tsme, 0, sizeof (tsme)); 3807 tsme.tsme_zoneid = zoneid; 3808 if (tnmlp(TNDB_FLUSH, &tsme) != 0) 3809 zerror(zlogp, B_TRUE, "cannot flush MLPs"); 3810} 3811 3812int 3813prtmount(const struct mnttab *fs, void *x) { 3814 zerror((zlog_t *)x, B_FALSE, " %s", fs->mnt_mountp); 3815 return (0); 3816} 3817 3818/* 3819 * Look for zones running on the main system that are using this root (or any 3820 * subdirectory of it). Return B_TRUE and print an error if a conflicting zone 3821 * is found or if we can't tell. 3822 */ 3823static boolean_t 3824duplicate_zone_root(zlog_t *zlogp, const char *rootpath) 3825{ 3826 zoneid_t *zids = NULL; 3827 uint_t nzids = 0; 3828 boolean_t retv; 3829 int rlen, zlen; 3830 char zroot[MAXPATHLEN]; 3831 char zonename[ZONENAME_MAX]; 3832 3833 for (;;) { 3834 nzids += 10; 3835 zids = malloc(nzids * sizeof (*zids)); 3836 if (zids == NULL) { 3837 zerror(zlogp, B_TRUE, "memory allocation failed"); 3838 return (B_TRUE); 3839 } 3840 if (zone_list(zids, &nzids) == 0) 3841 break; 3842 free(zids); 3843 } 3844 retv = B_FALSE; 3845 rlen = strlen(rootpath); 3846 while (nzids > 0) { 3847 /* 3848 * Ignore errors; they just mean that the zone has disappeared 3849 * while we were busy. 3850 */ 3851 if (zone_getattr(zids[--nzids], ZONE_ATTR_ROOT, zroot, 3852 sizeof (zroot)) == -1) 3853 continue; 3854 zlen = strlen(zroot); 3855 if (zlen > rlen) 3856 zlen = rlen; 3857 if (strncmp(rootpath, zroot, zlen) == 0 && 3858 (zroot[zlen] == '\0' || zroot[zlen] == '/') && 3859 (rootpath[zlen] == '\0' || rootpath[zlen] == '/')) { 3860 if (getzonenamebyid(zids[nzids], zonename, 3861 sizeof (zonename)) == -1) 3862 (void) snprintf(zonename, sizeof (zonename), 3863 "id %d", (int)zids[nzids]); 3864 zerror(zlogp, B_FALSE, 3865 "zone root %s already in use by zone %s", 3866 rootpath, zonename); 3867 retv = B_TRUE; 3868 break; 3869 } 3870 } 3871 free(zids); 3872 return (retv); 3873} 3874 3875/* 3876 * Search for loopback mounts that use this same source node (same device and 3877 * inode). Return B_TRUE if there is one or if we can't tell. 3878 */ 3879static boolean_t 3880duplicate_reachable_path(zlog_t *zlogp, const char *rootpath) 3881{ 3882 struct stat64 rst, zst; 3883 struct mnttab *mnp; 3884 3885 if (stat64(rootpath, &rst) == -1) { 3886 zerror(zlogp, B_TRUE, "can't stat %s", rootpath); 3887 return (B_TRUE); 3888 } 3889 if (resolve_lofs_mnts == NULL && lofs_read_mnttab(zlogp) == -1) 3890 return (B_TRUE); 3891 for (mnp = resolve_lofs_mnts; mnp < resolve_lofs_mnt_max; mnp++) { 3892 if (mnp->mnt_fstype == NULL || 3893 strcmp(MNTTYPE_LOFS, mnp->mnt_fstype) != 0) 3894 continue; 3895 /* We're looking at a loopback mount. Stat it. */ 3896 if (mnp->mnt_special != NULL && 3897 stat64(mnp->mnt_special, &zst) != -1 && 3898 rst.st_dev == zst.st_dev && rst.st_ino == zst.st_ino) { 3899 zerror(zlogp, B_FALSE, 3900 "zone root %s is reachable through %s", 3901 rootpath, mnp->mnt_mountp); 3902 return (B_TRUE); 3903 } 3904 } 3905 return (B_FALSE); 3906} 3907 3908/* 3909 * Set memory cap and pool info for the zone's resource management 3910 * configuration. 3911 */ 3912static int 3913setup_zone_rm(zlog_t *zlogp, char *zone_name, zoneid_t zoneid) 3914{ 3915 int res; 3916 uint64_t tmp; 3917 struct zone_mcaptab mcap; 3918 char sched[MAXNAMELEN]; 3919 zone_dochandle_t handle = NULL; 3920 char pool_err[128]; 3921 3922 if ((handle = zonecfg_init_handle()) == NULL) { 3923 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 3924 return (Z_BAD_HANDLE); 3925 } 3926 3927 if ((res = zonecfg_get_snapshot_handle(zone_name, handle)) != Z_OK) { 3928 zerror(zlogp, B_FALSE, "invalid configuration"); 3929 zonecfg_fini_handle(handle); 3930 return (res); 3931 } 3932 3933 /* 3934 * If a memory cap is configured, set the cap in the kernel using 3935 * zone_setattr() and make sure the rcapd SMF service is enabled. 3936 */ 3937 if (zonecfg_getmcapent(handle, &mcap) == Z_OK) { 3938 uint64_t num; 3939 char smf_err[128]; 3940 3941 num = (uint64_t)strtoull(mcap.zone_physmem_cap, NULL, 10); 3942 if (zone_setattr(zoneid, ZONE_ATTR_PHYS_MCAP, &num, 0) == -1) { 3943 zerror(zlogp, B_TRUE, "could not set zone memory cap"); 3944 zonecfg_fini_handle(handle); 3945 return (Z_INVAL); 3946 } 3947 3948 if (zonecfg_enable_rcapd(smf_err, sizeof (smf_err)) != Z_OK) { 3949 zerror(zlogp, B_FALSE, "enabling system/rcap service " 3950 "failed: %s", smf_err); 3951 zonecfg_fini_handle(handle); 3952 return (Z_INVAL); 3953 } 3954 } 3955 3956 /* Get the scheduling class set in the zone configuration. */ 3957 if (zonecfg_get_sched_class(handle, sched, sizeof (sched)) == Z_OK && 3958 strlen(sched) > 0) { 3959 if (zone_setattr(zoneid, ZONE_ATTR_SCHED_CLASS, sched, 3960 strlen(sched)) == -1) 3961 zerror(zlogp, B_TRUE, "WARNING: unable to set the " 3962 "default scheduling class"); 3963 3964 } else if (zonecfg_get_aliased_rctl(handle, ALIAS_SHARES, &tmp) 3965 == Z_OK) { 3966 /* 3967 * If the zone has the zone.cpu-shares rctl set then we want to 3968 * use the Fair Share Scheduler (FSS) for processes in the 3969 * zone. Check what scheduling class the zone would be running 3970 * in by default so we can print a warning and modify the class 3971 * if we wouldn't be using FSS. 3972 */ 3973 char class_name[PC_CLNMSZ]; 3974 3975 if (zonecfg_get_dflt_sched_class(handle, class_name, 3976 sizeof (class_name)) != Z_OK) { 3977 zerror(zlogp, B_FALSE, "WARNING: unable to determine " 3978 "the zone's scheduling class"); 3979 3980 } else if (strcmp("FSS", class_name) != 0) { 3981 zerror(zlogp, B_FALSE, "WARNING: The zone.cpu-shares " 3982 "rctl is set but\nFSS is not the default " 3983 "scheduling class for\nthis zone. FSS will be " 3984 "used for processes\nin the zone but to get the " 3985 "full benefit of FSS,\nit should be the default " 3986 "scheduling class.\nSee dispadmin(1M) for more " 3987 "details."); 3988 3989 if (zone_setattr(zoneid, ZONE_ATTR_SCHED_CLASS, "FSS", 3990 strlen("FSS")) == -1) 3991 zerror(zlogp, B_TRUE, "WARNING: unable to set " 3992 "zone scheduling class to FSS"); 3993 } 3994 } 3995 3996 /* 3997 * The next few blocks of code attempt to set up temporary pools as 3998 * well as persistent pools. In all cases we call the functions 3999 * unconditionally. Within each funtion the code will check if the 4000 * zone is actually configured for a temporary pool or persistent pool 4001 * and just return if there is nothing to do. 4002 * 4003 * If we are rebooting we want to attempt to reuse any temporary pool 4004 * that was previously set up. zonecfg_bind_tmp_pool() will do the 4005 * right thing in all cases (reuse or create) based on the current 4006 * zonecfg. 4007 */ 4008 if ((res = zonecfg_bind_tmp_pool(handle, zoneid, pool_err, 4009 sizeof (pool_err))) != Z_OK) { 4010 if (res == Z_POOL || res == Z_POOL_CREATE || res == Z_POOL_BIND) 4011 zerror(zlogp, B_FALSE, "%s: %s\ndedicated-cpu setting " 4012 "cannot be instantiated", zonecfg_strerror(res), 4013 pool_err); 4014 else 4015 zerror(zlogp, B_FALSE, "could not bind zone to " 4016 "temporary pool: %s", zonecfg_strerror(res)); 4017 zonecfg_fini_handle(handle); 4018 return (Z_POOL_BIND); 4019 } 4020 4021 /* 4022 * Check if we need to warn about poold not being enabled. 4023 */ 4024 if (zonecfg_warn_poold(handle)) { 4025 zerror(zlogp, B_FALSE, "WARNING: A range of dedicated-cpus has " 4026 "been specified\nbut the dynamic pool service is not " 4027 "enabled.\nThe system will not dynamically adjust the\n" 4028 "processor allocation within the specified range\n" 4029 "until svc:/system/pools/dynamic is enabled.\n" 4030 "See poold(1M)."); 4031 } 4032 4033 /* The following is a warning, not an error. */ 4034 if ((res = zonecfg_bind_pool(handle, zoneid, pool_err, 4035 sizeof (pool_err))) != Z_OK) { 4036 if (res == Z_POOL_BIND) 4037 zerror(zlogp, B_FALSE, "WARNING: unable to bind to " 4038 "pool '%s'; using default pool.", pool_err); 4039 else if (res == Z_POOL) 4040 zerror(zlogp, B_FALSE, "WARNING: %s: %s", 4041 zonecfg_strerror(res), pool_err); 4042 else 4043 zerror(zlogp, B_FALSE, "WARNING: %s", 4044 zonecfg_strerror(res)); 4045 } 4046 (void) zonecfg_get_poolname(handle, zone_name, pool_name, MAXPATHLEN); 4047 4048 zonecfg_fini_handle(handle); 4049 return (Z_OK); 4050} 4051 4052static void 4053report_prop_err(zlog_t *zlogp, const char *name, const char *value, int res) 4054{ 4055 switch (res) { 4056 case Z_TOO_BIG: 4057 zerror(zlogp, B_FALSE, "%s property value is too large.", name); 4058 break; 4059 4060 case Z_INVALID_PROPERTY: 4061 zerror(zlogp, B_FALSE, "%s property value \"%s\" is not valid", 4062 name, value); 4063 break; 4064 4065 default: 4066 zerror(zlogp, B_TRUE, "fetching property %s: %d", name, res); 4067 break; 4068 } 4069} 4070 4071/* 4072 * Sets the hostid of the new zone based on its configured value. The zone's 4073 * zone_t structure must already exist in kernel memory. 'zlogp' refers to the 4074 * log used to report errors and warnings and must be non-NULL. 'zone_namep' 4075 * is the name of the new zone and must be non-NULL. 'zoneid' is the numeric 4076 * ID of the new zone. 4077 * 4078 * This function returns zero on success and a nonzero error code on failure. 4079 */ 4080static int 4081setup_zone_hostid(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid) 4082{ 4083 int res; 4084 char hostidp[HW_HOSTID_LEN]; 4085 unsigned int hostid; 4086 4087 res = zonecfg_get_hostid(handle, hostidp, sizeof (hostidp)); 4088 4089 if (res == Z_BAD_PROPERTY) { 4090 return (Z_OK); 4091 } else if (res != Z_OK) { 4092 report_prop_err(zlogp, "hostid", hostidp, res); 4093 return (res); 4094 } 4095 4096 hostid = (unsigned int)strtoul(hostidp, NULL, 16); 4097 if ((res = zone_setattr(zoneid, ZONE_ATTR_HOSTID, &hostid, 4098 sizeof (hostid))) != 0) { 4099 zerror(zlogp, B_TRUE, 4100 "zone hostid is not valid: %s: %d", hostidp, res); 4101 return (Z_SYSTEM); 4102 } 4103 4104 return (res); 4105} 4106 4107static int 4108setup_zone_fs_allowed(zone_dochandle_t handle, zlog_t *zlogp, zoneid_t zoneid) 4109{ 4110 char fsallowedp[ZONE_FS_ALLOWED_MAX]; 4111 int res; 4112 4113 res = zonecfg_get_fs_allowed(handle, fsallowedp, sizeof (fsallowedp)); 4114 4115 if (res == Z_BAD_PROPERTY) { 4116 return (Z_OK); 4117 } else if (res != Z_OK) { 4118 report_prop_err(zlogp, "fs-allowed", fsallowedp, res); 4119 return (res); 4120 } 4121 4122 if (zone_setattr(zoneid, ZONE_ATTR_FS_ALLOWED, &fsallowedp, 4123 sizeof (fsallowedp)) != 0) { 4124 zerror(zlogp, B_TRUE, 4125 "fs-allowed couldn't be set: %s: %d", fsallowedp, res); 4126 return (Z_SYSTEM); 4127 } 4128 4129 return (res); 4130} 4131 4132static int 4133setup_zone_attrs(zlog_t *zlogp, char *zone_namep, zoneid_t zoneid) 4134{ 4135 zone_dochandle_t handle; 4136 int res = Z_OK; 4137 4138 if ((handle = zonecfg_init_handle()) == NULL) { 4139 zerror(zlogp, B_TRUE, "getting zone configuration handle"); 4140 return (Z_BAD_HANDLE); 4141 } 4142 if ((res = zonecfg_get_snapshot_handle(zone_namep, handle)) != Z_OK) { 4143 zerror(zlogp, B_FALSE, "invalid configuration"); 4144 goto out; 4145 } 4146 4147 if ((res = setup_zone_hostid(handle, zlogp, zoneid)) != Z_OK) 4148 goto out; 4149 4150 if ((res = setup_zone_fs_allowed(handle, zlogp, zoneid)) != Z_OK) 4151 goto out; 4152 4153out: 4154 zonecfg_fini_handle(handle); 4155 return (res); 4156} 4157 4158zoneid_t 4159vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd) 4160{ 4161 zoneid_t rval = -1; 4162 priv_set_t *privs; 4163 char rootpath[MAXPATHLEN]; 4164 char *rctlbuf = NULL; 4165 size_t rctlbufsz = 0; 4166 char *zfsbuf = NULL; 4167 size_t zfsbufsz = 0; 4168 zoneid_t zoneid = -1; 4169 int xerr; 4170 char *kzone; 4171 FILE *fp = NULL; 4172 tsol_zcent_t *zcent = NULL; 4173 int match = 0; 4174 int doi = 0; 4175 int flags; 4176 zone_iptype_t iptype; 4177 4178 if (zone_get_rootpath(zone_name, rootpath, sizeof (rootpath)) != Z_OK) { 4179 zerror(zlogp, B_TRUE, "unable to determine zone root"); 4180 return (-1); 4181 } 4182 if (zonecfg_in_alt_root()) 4183 resolve_lofs(zlogp, rootpath, sizeof (rootpath)); 4184 4185 if (vplat_get_iptype(zlogp, &iptype) < 0) { 4186 zerror(zlogp, B_TRUE, "unable to determine ip-type"); 4187 return (-1); 4188 } 4189 switch (iptype) { 4190 case ZS_SHARED: 4191 flags = 0; 4192 break; 4193 case ZS_EXCLUSIVE: 4194 flags = ZCF_NET_EXCL; 4195 break; 4196 } 4197 4198 if ((privs = priv_allocset()) == NULL) { 4199 zerror(zlogp, B_TRUE, "%s failed", "priv_allocset"); 4200 return (-1); 4201 } 4202 priv_emptyset(privs); 4203 if (get_privset(zlogp, privs, mount_cmd) != 0) 4204 goto error; 4205 4206 if (mount_cmd == Z_MNT_BOOT && 4207 get_rctls(zlogp, &rctlbuf, &rctlbufsz) != 0) { 4208 zerror(zlogp, B_FALSE, "Unable to get list of rctls"); 4209 goto error; 4210 } 4211 4212 if (get_datasets(zlogp, &zfsbuf, &zfsbufsz) != 0) { 4213 zerror(zlogp, B_FALSE, "Unable to get list of ZFS datasets"); 4214 goto error; 4215 } 4216 4217 if (mount_cmd == Z_MNT_BOOT && is_system_labeled()) { 4218 zcent = get_zone_label(zlogp, privs); 4219 if (zcent != NULL) { 4220 match = zcent->zc_match; 4221 doi = zcent->zc_doi; 4222 *zlabel = zcent->zc_label; 4223 } else { 4224 goto error; 4225 } 4226 if (validate_rootds_label(zlogp, rootpath, zlabel) != 0) 4227 goto error; 4228 } 4229 4230 kzone = zone_name; 4231 4232 /* 4233 * We must do this scan twice. First, we look for zones running on the 4234 * main system that are using this root (or any subdirectory of it). 4235 * Next, we reduce to the shortest path and search for loopback mounts 4236 * that use this same source node (same device and inode). 4237 */ 4238 if (duplicate_zone_root(zlogp, rootpath)) 4239 goto error; 4240 if (duplicate_reachable_path(zlogp, rootpath)) 4241 goto error; 4242 4243 if (ALT_MOUNT(mount_cmd)) { 4244 root_to_lu(zlogp, rootpath, sizeof (rootpath), B_TRUE); 4245 4246 /* 4247 * Forge up a special root for this zone. When a zone is 4248 * mounted, we can't let the zone have its own root because the 4249 * tools that will be used in this "scratch zone" need access 4250 * to both the zone's resources and the running machine's 4251 * executables. 4252 * 4253 * Note that the mkdir here also catches read-only filesystems. 4254 */ 4255 if (mkdir(rootpath, 0755) != 0 && errno != EEXIST) { 4256 zerror(zlogp, B_TRUE, "cannot create %s", rootpath); 4257 goto error; 4258 } 4259 if (domount(zlogp, "tmpfs", "", "swap", rootpath) != 0) 4260 goto error; 4261 } 4262 4263 if (zonecfg_in_alt_root()) { 4264 /* 4265 * If we are mounting up a zone in an alternate root partition, 4266 * then we have some additional work to do before starting the 4267 * zone. First, resolve the root path down so that we're not 4268 * fooled by duplicates. Then forge up an internal name for 4269 * the zone. 4270 */ 4271 if ((fp = zonecfg_open_scratch("", B_TRUE)) == NULL) { 4272 zerror(zlogp, B_TRUE, "cannot open mapfile"); 4273 goto error; 4274 } 4275 if (zonecfg_lock_scratch(fp) != 0) { 4276 zerror(zlogp, B_TRUE, "cannot lock mapfile"); 4277 goto error; 4278 } 4279 if (zonecfg_find_scratch(fp, zone_name, zonecfg_get_root(), 4280 NULL, 0) == 0) { 4281 zerror(zlogp, B_FALSE, "scratch zone already running"); 4282 goto error; 4283 } 4284 /* This is the preferred name */ 4285 (void) snprintf(kernzone, sizeof (kernzone), "SUNWlu-%s", 4286 zone_name); 4287 srandom(getpid()); 4288 while (zonecfg_reverse_scratch(fp, kernzone, NULL, 0, NULL, 4289 0) == 0) { 4290 /* This is just an arbitrary name; note "." usage */ 4291 (void) snprintf(kernzone, sizeof (kernzone), 4292 "SUNWlu.%08lX%08lX", random(), random()); 4293 } 4294 kzone = kernzone; 4295 } 4296 4297 xerr = 0; 4298 if ((zoneid = zone_create(kzone, rootpath, privs, rctlbuf, 4299 rctlbufsz, zfsbuf, zfsbufsz, &xerr, match, doi, zlabel, 4300 flags)) == -1) { 4301 if (xerr == ZE_AREMOUNTS) { 4302 if (zonecfg_find_mounts(rootpath, NULL, NULL) < 1) { 4303 zerror(zlogp, B_FALSE, 4304 "An unknown file-system is mounted on " 4305 "a subdirectory of %s", rootpath); 4306 } else { 4307 4308 zerror(zlogp, B_FALSE, 4309 "These file-systems are mounted on " 4310 "subdirectories of %s:", rootpath); 4311 (void) zonecfg_find_mounts(rootpath, 4312 prtmount, zlogp); 4313 } 4314 } else if (xerr == ZE_CHROOTED) { 4315 zerror(zlogp, B_FALSE, "%s: " 4316 "cannot create a zone from a chrooted " 4317 "environment", "zone_create"); 4318 } else if (xerr == ZE_LABELINUSE) { 4319 char zonename[ZONENAME_MAX]; 4320 (void) getzonenamebyid(getzoneidbylabel(zlabel), 4321 zonename, ZONENAME_MAX); 4322 zerror(zlogp, B_FALSE, "The zone label is already " 4323 "used by the zone '%s'.", zonename); 4324 } else { 4325 zerror(zlogp, B_TRUE, "%s failed", "zone_create"); 4326 } 4327 goto error; 4328 } 4329 4330 if (zonecfg_in_alt_root() && 4331 zonecfg_add_scratch(fp, zone_name, kernzone, 4332 zonecfg_get_root()) == -1) { 4333 zerror(zlogp, B_TRUE, "cannot add mapfile entry"); 4334 goto error; 4335 } 4336 4337 if ((pool_name = malloc(MAXPATHLEN)) == NULL) { 4338 zerror(zlogp, B_TRUE, "memory allocation failed"); 4339 return (Z_NOMEM); 4340 } 4341 bzero(pool_name, MAXPATHLEN); 4342 4343 /* 4344 * The following actions are not performed when merely mounting a zone 4345 * for administrative use. 4346 */ 4347 if (mount_cmd == Z_MNT_BOOT) { 4348 brand_handle_t bh; 4349 struct brand_attr attr; 4350 char modname[MAXPATHLEN]; 4351 4352 if (setup_zone_attrs(zlogp, zone_name, zoneid) != Z_OK) 4353 goto error; 4354 4355 if ((bh = brand_open(brand_name)) == NULL) { 4356 zerror(zlogp, B_FALSE, 4357 "unable to determine brand name"); 4358 goto error; 4359 } 4360 4361 if (!is_system_labeled() && 4362 (strcmp(brand_name, LABELED_BRAND_NAME) == 0)) { 4363 brand_close(bh); 4364 zerror(zlogp, B_FALSE, 4365 "cannot boot labeled zone on unlabeled system"); 4366 goto error; 4367 } 4368 4369 /* 4370 * If this brand requires any kernel support, now is the time to 4371 * get it loaded and initialized. 4372 */ 4373 if (brand_get_modname(bh, modname, MAXPATHLEN) < 0) { 4374 brand_close(bh); 4375 zerror(zlogp, B_FALSE, 4376 "unable to determine brand kernel module"); 4377 goto error; 4378 } 4379 brand_close(bh); 4380 4381 if (strlen(modname) > 0) { 4382 (void) strlcpy(attr.ba_brandname, brand_name, 4383 sizeof (attr.ba_brandname)); 4384 (void) strlcpy(attr.ba_modname, modname, 4385 sizeof (attr.ba_modname)); 4386 if (zone_setattr(zoneid, ZONE_ATTR_BRAND, &attr, 4387 sizeof (attr) != 0)) { 4388 zerror(zlogp, B_TRUE, 4389 "could not set zone brand attribute."); 4390 goto error; 4391 } 4392 } 4393 4394 if (setup_zone_rm(zlogp, zone_name, zoneid) != Z_OK) 4395 goto error; 4396 4397 set_mlps(zlogp, zoneid, zcent); 4398 } 4399 4400 rval = zoneid; 4401 zoneid = -1; 4402 4403error: 4404 if (zoneid != -1) { 4405 (void) zone_shutdown(zoneid); 4406 (void) zone_destroy(zoneid); 4407 } 4408 if (rctlbuf != NULL) 4409 free(rctlbuf); 4410 priv_freeset(privs); 4411 if (fp != NULL) 4412 zonecfg_close_scratch(fp); 4413 lofs_discard_mnttab(); 4414 if (zcent != NULL) 4415 tsol_freezcent(zcent); 4416 return (rval); 4417} 4418 4419/* 4420 * Enter the zone and write a /etc/zones/index file there. This allows 4421 * libzonecfg (and thus zoneadm) to report the UUID and potentially other zone 4422 * details from inside the zone. 4423 */ 4424static void 4425write_index_file(zoneid_t zoneid) 4426{ 4427 FILE *zef; 4428 FILE *zet; 4429 struct zoneent *zep; 4430 pid_t child; 4431 int tmpl_fd; 4432 ctid_t ct; 4433 int fd; 4434 char uuidstr[UUID_PRINTABLE_STRING_LENGTH]; 4435 4436 /* Locate the zone entry in the global zone's index file */ 4437 if ((zef = setzoneent()) == NULL) 4438 return; 4439 while ((zep = getzoneent_private(zef)) != NULL) { 4440 if (strcmp(zep->zone_name, zone_name) == 0) 4441 break; 4442 free(zep); 4443 } 4444 endzoneent(zef); 4445 if (zep == NULL) 4446 return; 4447 4448 if ((tmpl_fd = init_template()) == -1) { 4449 free(zep); 4450 return; 4451 } 4452 4453 if ((child = fork()) == -1) { 4454 (void) ct_tmpl_clear(tmpl_fd); 4455 (void) close(tmpl_fd); 4456 free(zep); 4457 return; 4458 } 4459 4460 /* parent waits for child to finish */ 4461 if (child != 0) { 4462 free(zep); 4463 if (contract_latest(&ct) == -1) 4464 ct = -1; 4465 (void) ct_tmpl_clear(tmpl_fd); 4466 (void) close(tmpl_fd); 4467 (void) waitpid(child, NULL, 0); 4468 (void) contract_abandon_id(ct); 4469 return; 4470 } 4471 4472 /* child enters zone and sets up index file */ 4473 (void) ct_tmpl_clear(tmpl_fd); 4474 if (zone_enter(zoneid) != -1) { 4475 (void) mkdir(ZONE_CONFIG_ROOT, ZONE_CONFIG_MODE); 4476 (void) chown(ZONE_CONFIG_ROOT, ZONE_CONFIG_UID, 4477 ZONE_CONFIG_GID); 4478 fd = open(ZONE_INDEX_FILE, O_WRONLY|O_CREAT|O_TRUNC, 4479 ZONE_INDEX_MODE); 4480 if (fd != -1 && (zet = fdopen(fd, "w")) != NULL) { 4481 (void) fchown(fd, ZONE_INDEX_UID, ZONE_INDEX_GID); 4482 if (uuid_is_null(zep->zone_uuid)) 4483 uuidstr[0] = '\0'; 4484 else 4485 uuid_unparse(zep->zone_uuid, uuidstr); 4486 (void) fprintf(zet, "%s:%s:/:%s\n", zep->zone_name, 4487 zone_state_str(zep->zone_state), 4488 uuidstr); 4489 (void) fclose(zet); 4490 } 4491 } 4492 _exit(0); 4493} 4494 4495int 4496vplat_bringup(zlog_t *zlogp, zone_mnt_t mount_cmd, zoneid_t zoneid) 4497{ 4498 char zonepath[MAXPATHLEN]; 4499 4500 if (mount_cmd == Z_MNT_BOOT && validate_datasets(zlogp) != 0) { 4501 lofs_discard_mnttab(); 4502 return (-1); 4503 } 4504 4505 /* 4506 * Before we try to mount filesystems we need to create the 4507 * attribute backing store for /dev 4508 */ 4509 if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) { 4510 lofs_discard_mnttab(); 4511 return (-1); 4512 } 4513 resolve_lofs(zlogp, zonepath, sizeof (zonepath)); 4514 4515 /* Make /dev directory owned by root, grouped sys */ 4516 if (make_one_dir(zlogp, zonepath, "/dev", DEFAULT_DIR_MODE, 4517 0, 3) != 0) { 4518 lofs_discard_mnttab(); 4519 return (-1); 4520 } 4521 4522 if (mount_filesystems(zlogp, mount_cmd) != 0) { 4523 lofs_discard_mnttab(); 4524 return (-1); 4525 } 4526 4527 if (mount_cmd == Z_MNT_BOOT) { 4528 zone_iptype_t iptype; 4529 4530 if (vplat_get_iptype(zlogp, &iptype) < 0) { 4531 zerror(zlogp, B_TRUE, "unable to determine ip-type"); 4532 lofs_discard_mnttab(); 4533 return (-1); 4534 } 4535 4536 switch (iptype) { 4537 case ZS_SHARED: 4538 /* Always do this to make lo0 get configured */ 4539 if (configure_shared_network_interfaces(zlogp) != 0) { 4540 lofs_discard_mnttab(); 4541 return (-1); 4542 } 4543 break; 4544 case ZS_EXCLUSIVE: 4545 if (configure_exclusive_network_interfaces(zlogp) != 4546 0) { 4547 lofs_discard_mnttab(); 4548 return (-1); 4549 } 4550 break; 4551 } 4552 } 4553 4554 write_index_file(zoneid); 4555 4556 lofs_discard_mnttab(); 4557 return (0); 4558} 4559 4560static int 4561lu_root_teardown(zlog_t *zlogp) 4562{ 4563 char zroot[MAXPATHLEN]; 4564 4565 if (zone_get_rootpath(zone_name, zroot, sizeof (zroot)) != Z_OK) { 4566 zerror(zlogp, B_FALSE, "unable to determine zone root"); 4567 return (-1); 4568 } 4569 root_to_lu(zlogp, zroot, sizeof (zroot), B_FALSE); 4570 4571 /* 4572 * At this point, the processes are gone, the filesystems (save the 4573 * root) are unmounted, and the zone is on death row. But there may 4574 * still be creds floating about in the system that reference the 4575 * zone_t, and which pin down zone_rootvp causing this call to fail 4576 * with EBUSY. Thus, we try for a little while before just giving up. 4577 * (How I wish this were not true, and umount2 just did the right 4578 * thing, or tmpfs supported MS_FORCE This is a gross hack.) 4579 */ 4580 if (umount2(zroot, MS_FORCE) != 0) { 4581 if (errno == ENOTSUP && umount2(zroot, 0) == 0) 4582 goto unmounted; 4583 if (errno == EBUSY) { 4584 int tries = 10; 4585 4586 while (--tries >= 0) { 4587 (void) sleep(1); 4588 if (umount2(zroot, 0) == 0) 4589 goto unmounted; 4590 if (errno != EBUSY) 4591 break; 4592 } 4593 } 4594 zerror(zlogp, B_TRUE, "unable to unmount '%s'", zroot); 4595 return (-1); 4596 } 4597unmounted: 4598 4599 /* 4600 * Only zones in an alternate root environment have scratch zone 4601 * entries. 4602 */ 4603 if (zonecfg_in_alt_root()) { 4604 FILE *fp; 4605 int retv; 4606 4607 if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) { 4608 zerror(zlogp, B_TRUE, "cannot open mapfile"); 4609 return (-1); 4610 } 4611 retv = -1; 4612 if (zonecfg_lock_scratch(fp) != 0) 4613 zerror(zlogp, B_TRUE, "cannot lock mapfile"); 4614 else if (zonecfg_delete_scratch(fp, kernzone) != 0) 4615 zerror(zlogp, B_TRUE, "cannot delete map entry"); 4616 else 4617 retv = 0; 4618 zonecfg_close_scratch(fp); 4619 return (retv); 4620 } else { 4621 return (0); 4622 } 4623} 4624 4625int 4626vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting) 4627{ 4628 char *kzone; 4629 zoneid_t zoneid; 4630 int res; 4631 char pool_err[128]; 4632 char zpath[MAXPATHLEN]; 4633 char cmdbuf[MAXPATHLEN]; 4634 brand_handle_t bh = NULL; 4635 dladm_status_t status; 4636 char errmsg[DLADM_STRSIZE]; 4637 ushort_t flags; 4638 4639 kzone = zone_name; 4640 if (zonecfg_in_alt_root()) { 4641 FILE *fp; 4642 4643 if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL) { 4644 zerror(zlogp, B_TRUE, "unable to open map file"); 4645 goto error; 4646 } 4647 if (zonecfg_find_scratch(fp, zone_name, zonecfg_get_root(), 4648 kernzone, sizeof (kernzone)) != 0) { 4649 zerror(zlogp, B_FALSE, "unable to find scratch zone"); 4650 zonecfg_close_scratch(fp); 4651 goto error; 4652 } 4653 zonecfg_close_scratch(fp); 4654 kzone = kernzone; 4655 } 4656 4657 if ((zoneid = getzoneidbyname(kzone)) == ZONE_ID_UNDEFINED) { 4658 if (!bringup_failure_recovery) 4659 zerror(zlogp, B_TRUE, "unable to get zoneid"); 4660 if (unmount_cmd) 4661 (void) lu_root_teardown(zlogp); 4662 goto error; 4663 } 4664 4665 if (remove_datalink_pool(zlogp, zoneid) != 0) { 4666 zerror(zlogp, B_FALSE, "unable clear datalink pool property"); 4667 goto error; 4668 } 4669 4670 if (zone_shutdown(zoneid) != 0) { 4671 zerror(zlogp, B_TRUE, "unable to shutdown zone"); 4672 goto error; 4673 } 4674 4675 /* Get the zonepath of this zone */ 4676 if (zone_get_zonepath(zone_name, zpath, sizeof (zpath)) != Z_OK) { 4677 zerror(zlogp, B_FALSE, "unable to determine zone path"); 4678 goto error; 4679 } 4680 4681 /* Get a handle to the brand info for this zone */ 4682 if ((bh = brand_open(brand_name)) == NULL) { 4683 zerror(zlogp, B_FALSE, "unable to determine zone brand"); 4684 return (-1); 4685 } 4686 /* 4687 * If there is a brand 'halt' callback, execute it now to give the 4688 * brand a chance to cleanup any custom configuration. 4689 */ 4690 (void) strcpy(cmdbuf, EXEC_PREFIX); 4691 if (brand_get_halt(bh, zone_name, zpath, cmdbuf + EXEC_LEN, 4692 sizeof (cmdbuf) - EXEC_LEN) < 0) { 4693 brand_close(bh); 4694 zerror(zlogp, B_FALSE, "unable to determine branded zone's " 4695 "halt callback."); 4696 goto error; 4697 } 4698 brand_close(bh); 4699 4700 if ((strlen(cmdbuf) > EXEC_LEN) && 4701 (do_subproc(zlogp, cmdbuf, NULL) != Z_OK)) { 4702 zerror(zlogp, B_FALSE, "%s failed", cmdbuf); 4703 goto error; 4704 } 4705 4706 if (!unmount_cmd) { 4707 zone_iptype_t iptype; 4708 4709 if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags, 4710 sizeof (flags)) < 0) { 4711 if (vplat_get_iptype(zlogp, &iptype) < 0) { 4712 zerror(zlogp, B_TRUE, "unable to determine " 4713 "ip-type"); 4714 goto error; 4715 } 4716 } else { 4717 if (flags & ZF_NET_EXCL) 4718 iptype = ZS_EXCLUSIVE; 4719 else 4720 iptype = ZS_SHARED; 4721 } 4722 4723 switch (iptype) { 4724 case ZS_SHARED: 4725 if (unconfigure_shared_network_interfaces(zlogp, 4726 zoneid) != 0) { 4727 zerror(zlogp, B_FALSE, "unable to unconfigure " 4728 "network interfaces in zone"); 4729 goto error; 4730 } 4731 break; 4732 case ZS_EXCLUSIVE: 4733 if (unconfigure_exclusive_network_interfaces(zlogp, 4734 zoneid) != 0) { 4735 zerror(zlogp, B_FALSE, "unable to unconfigure " 4736 "network interfaces in zone"); 4737 goto error; 4738 } 4739 status = dladm_zone_halt(dld_handle, zoneid); 4740 if (status != DLADM_STATUS_OK) { 4741 zerror(zlogp, B_FALSE, "unable to notify " 4742 "dlmgmtd of zone halt: %s", 4743 dladm_status2str(status, errmsg)); 4744 } 4745 break; 4746 } 4747 } 4748 4749 if (!unmount_cmd && tcp_abort_connections(zlogp, zoneid) != 0) { 4750 zerror(zlogp, B_TRUE, "unable to abort TCP connections"); 4751 goto error; 4752 } 4753 4754 if (unmount_filesystems(zlogp, zoneid, unmount_cmd) != 0) { 4755 zerror(zlogp, B_FALSE, 4756 "unable to unmount file systems in zone"); 4757 goto error; 4758 } 4759 4760 /* 4761 * If we are rebooting then we normally don't want to destroy an 4762 * existing temporary pool at this point so that we can just reuse it 4763 * when the zone boots back up. However, it is also possible we were 4764 * running with a temporary pool and the zone configuration has been 4765 * modified to no longer use a temporary pool. In that case we need 4766 * to destroy the temporary pool now. This case looks like the case 4767 * where we never had a temporary pool configured but 4768 * zonecfg_destroy_tmp_pool will do the right thing either way. 4769 */ 4770 if (!unmount_cmd) { 4771 boolean_t destroy_tmp_pool = B_TRUE; 4772 4773 if (rebooting) { 4774 struct zone_psettab pset_tab; 4775 zone_dochandle_t handle; 4776 4777 if ((handle = zonecfg_init_handle()) != NULL && 4778 zonecfg_get_handle(zone_name, handle) == Z_OK && 4779 zonecfg_lookup_pset(handle, &pset_tab) == Z_OK) 4780 destroy_tmp_pool = B_FALSE; 4781 4782 zonecfg_fini_handle(handle); 4783 } 4784 4785 if (destroy_tmp_pool) { 4786 if ((res = zonecfg_destroy_tmp_pool(zone_name, pool_err, 4787 sizeof (pool_err))) != Z_OK) { 4788 if (res == Z_POOL) 4789 zerror(zlogp, B_FALSE, pool_err); 4790 } 4791 } 4792 } 4793 4794 free(pool_name); 4795 4796 remove_mlps(zlogp, zoneid); 4797 4798 if (zone_destroy(zoneid) != 0) { 4799 zerror(zlogp, B_TRUE, "unable to destroy zone"); 4800 goto error; 4801 } 4802 4803 /* 4804 * Special teardown for alternate boot environments: remove the tmpfs 4805 * root for the zone and then remove it from the map file. 4806 */ 4807 if (unmount_cmd && lu_root_teardown(zlogp) != 0) 4808 goto error; 4809 4810 lofs_discard_mnttab(); 4811 return (0); 4812 4813error: 4814 lofs_discard_mnttab(); 4815 return (-1); 4816} 4817