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 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * This file contains the functions used to support the ZFS integration 31 * with zones. This includes validation (e.g. zonecfg dataset), cloning, 32 * file system creation and destruction. 33 */ 34 35 #include <stdio.h> 36 #include <errno.h> 37 #include <unistd.h> 38 #include <string.h> 39 #include <locale.h> 40 #include <libintl.h> 41 #include <sys/stat.h> 42 #include <sys/statvfs.h> 43 #include <libgen.h> 44 #include <libzonecfg.h> 45 #include <sys/mnttab.h> 46 #include <libzfs.h> 47 #include <sys/mntent.h> 48 49 #include "zoneadm.h" 50 51 libzfs_handle_t *g_zfs; 52 53 typedef struct zfs_mount_data { 54 char *match_name; 55 zfs_handle_t *match_handle; 56 } zfs_mount_data_t; 57 58 typedef struct zfs_snapshot_data { 59 char *match_name; 60 int len; 61 int max; 62 } zfs_snapshot_data_t; 63 64 /* 65 * A ZFS file system iterator call-back function which is used to validate 66 * datasets imported into the zone. 67 */ 68 /* ARGSUSED */ 69 static int 70 check_zvol(zfs_handle_t *zhp, void *unused) 71 { 72 int ret; 73 74 if (zfs_get_type(zhp) == ZFS_TYPE_VOLUME) { 75 /* 76 * TRANSLATION_NOTE 77 * zfs and dataset are literals that should not be translated. 78 */ 79 (void) fprintf(stderr, gettext("cannot verify zfs dataset %s: " 80 "volumes cannot be specified as a zone dataset resource\n"), 81 zfs_get_name(zhp)); 82 ret = -1; 83 } else { 84 ret = zfs_iter_children(zhp, check_zvol, NULL); 85 } 86 87 zfs_close(zhp); 88 89 return (ret); 90 } 91 92 /* 93 * A ZFS file system iterator call-back function which returns the 94 * zfs_handle_t for a ZFS file system on the specified mount point. 95 */ 96 static int 97 match_mountpoint(zfs_handle_t *zhp, void *data) 98 { 99 int res; 100 zfs_mount_data_t *cbp; 101 char mp[ZFS_MAXPROPLEN]; 102 103 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) { 104 zfs_close(zhp); 105 return (0); 106 } 107 108 /* First check if the dataset is mounted. */ 109 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTED, mp, sizeof (mp), NULL, NULL, 110 0, B_FALSE) != 0 || strcmp(mp, "no") == 0) { 111 zfs_close(zhp); 112 return (0); 113 } 114 115 /* Now check mount point. */ 116 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mp, sizeof (mp), NULL, NULL, 117 0, B_FALSE) != 0) { 118 zfs_close(zhp); 119 return (0); 120 } 121 122 cbp = (zfs_mount_data_t *)data; 123 124 if (strcmp(mp, "legacy") == 0) { 125 /* If legacy, must look in mnttab for mountpoint. */ 126 FILE *fp; 127 struct mnttab entry; 128 const char *nm; 129 130 nm = zfs_get_name(zhp); 131 if ((fp = fopen(MNTTAB, "r")) == NULL) { 132 zfs_close(zhp); 133 return (0); 134 } 135 136 while (getmntent(fp, &entry) == 0) { 137 if (strcmp(nm, entry.mnt_special) == 0) { 138 if (strcmp(entry.mnt_mountp, cbp->match_name) 139 == 0) { 140 (void) fclose(fp); 141 cbp->match_handle = zhp; 142 return (1); 143 } 144 break; 145 } 146 } 147 (void) fclose(fp); 148 149 } else if (strcmp(mp, cbp->match_name) == 0) { 150 cbp->match_handle = zhp; 151 return (1); 152 } 153 154 /* Iterate over any nested datasets. */ 155 res = zfs_iter_filesystems(zhp, match_mountpoint, data); 156 zfs_close(zhp); 157 return (res); 158 } 159 160 /* 161 * Get ZFS handle for the specified mount point. 162 */ 163 static zfs_handle_t * 164 mount2zhandle(char *mountpoint) 165 { 166 zfs_mount_data_t cb; 167 168 cb.match_name = mountpoint; 169 cb.match_handle = NULL; 170 (void) zfs_iter_root(g_zfs, match_mountpoint, &cb); 171 return (cb.match_handle); 172 } 173 174 /* 175 * Check if there is already a file system (zfs or any other type) mounted on 176 * path. 177 */ 178 static boolean_t 179 is_mountpnt(char *path) 180 { 181 FILE *fp; 182 struct mnttab entry; 183 184 if ((fp = fopen(MNTTAB, "r")) == NULL) 185 return (B_FALSE); 186 187 while (getmntent(fp, &entry) == 0) { 188 if (strcmp(path, entry.mnt_mountp) == 0) { 189 (void) fclose(fp); 190 return (B_TRUE); 191 } 192 } 193 194 (void) fclose(fp); 195 return (B_FALSE); 196 } 197 198 /* 199 * Run the brand's pre-snapshot hook before we take a ZFS snapshot of the zone. 200 */ 201 static int 202 pre_snapshot(char *presnapbuf) 203 { 204 int status; 205 206 /* No brand-specific handler */ 207 if (presnapbuf[0] == '\0') 208 return (Z_OK); 209 210 /* Run the hook */ 211 status = do_subproc_interactive(presnapbuf); 212 if ((status = subproc_status(gettext("brand-specific presnapshot"), 213 status, B_FALSE)) != ZONE_SUBPROC_OK) 214 return (Z_ERR); 215 216 return (Z_OK); 217 } 218 219 /* 220 * Run the brand's post-snapshot hook after we take a ZFS snapshot of the zone. 221 */ 222 static int 223 post_snapshot(char *postsnapbuf) 224 { 225 int status; 226 227 /* No brand-specific handler */ 228 if (postsnapbuf[0] == '\0') 229 return (Z_OK); 230 231 /* Run the hook */ 232 status = do_subproc_interactive(postsnapbuf); 233 if ((status = subproc_status(gettext("brand-specific postsnapshot"), 234 status, B_FALSE)) != ZONE_SUBPROC_OK) 235 return (Z_ERR); 236 237 return (Z_OK); 238 } 239 240 /* 241 * This is a ZFS snapshot iterator call-back function which returns the 242 * highest number of SUNWzone snapshots that have been taken. 243 */ 244 static int 245 get_snap_max(zfs_handle_t *zhp, void *data) 246 { 247 int res; 248 zfs_snapshot_data_t *cbp; 249 250 if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) { 251 zfs_close(zhp); 252 return (0); 253 } 254 255 cbp = (zfs_snapshot_data_t *)data; 256 257 if (strncmp(zfs_get_name(zhp), cbp->match_name, cbp->len) == 0) { 258 char *nump; 259 int num; 260 261 nump = (char *)(zfs_get_name(zhp) + cbp->len); 262 num = atoi(nump); 263 if (num > cbp->max) 264 cbp->max = num; 265 } 266 267 res = zfs_iter_snapshots(zhp, get_snap_max, data); 268 zfs_close(zhp); 269 return (res); 270 } 271 272 /* 273 * Take a ZFS snapshot to be used for cloning the zone. 274 */ 275 static int 276 take_snapshot(zfs_handle_t *zhp, char *snapshot_name, int snap_size, 277 char *presnapbuf, char *postsnapbuf) 278 { 279 int res; 280 char template[ZFS_MAXNAMELEN]; 281 zfs_snapshot_data_t cb; 282 283 /* 284 * First we need to figure out the next available name for the 285 * zone snapshot. Look through the list of zones snapshots for 286 * this file system to determine the maximum snapshot name. 287 */ 288 if (snprintf(template, sizeof (template), "%s@SUNWzone", 289 zfs_get_name(zhp)) >= sizeof (template)) 290 return (Z_ERR); 291 292 cb.match_name = template; 293 cb.len = strlen(template); 294 cb.max = 0; 295 296 if (zfs_iter_snapshots(zhp, get_snap_max, &cb) != 0) 297 return (Z_ERR); 298 299 cb.max++; 300 301 if (snprintf(snapshot_name, snap_size, "%s@SUNWzone%d", 302 zfs_get_name(zhp), cb.max) >= snap_size) 303 return (Z_ERR); 304 305 if (pre_snapshot(presnapbuf) != Z_OK) 306 return (Z_ERR); 307 res = zfs_snapshot(g_zfs, snapshot_name, B_FALSE, NULL); 308 if (post_snapshot(postsnapbuf) != Z_OK) 309 return (Z_ERR); 310 311 if (res != 0) 312 return (Z_ERR); 313 return (Z_OK); 314 } 315 316 /* 317 * We are using an explicit snapshot from some earlier point in time so 318 * we need to validate it. Run the brand specific hook. 319 */ 320 static int 321 validate_snapshot(char *snapshot_name, char *snap_path, char *validsnapbuf) 322 { 323 int status; 324 char cmdbuf[MAXPATHLEN]; 325 326 /* No brand-specific handler */ 327 if (validsnapbuf[0] == '\0') 328 return (Z_OK); 329 330 /* pass args - snapshot_name & snap_path */ 331 if (snprintf(cmdbuf, sizeof (cmdbuf), "%s %s %s", validsnapbuf, 332 snapshot_name, snap_path) >= sizeof (cmdbuf)) { 333 zerror("Command line too long"); 334 return (Z_ERR); 335 } 336 337 /* Run the hook */ 338 status = do_subproc_interactive(cmdbuf); 339 if ((status = subproc_status(gettext("brand-specific validatesnapshot"), 340 status, B_FALSE)) != ZONE_SUBPROC_OK) 341 return (Z_ERR); 342 343 return (Z_OK); 344 } 345 346 /* 347 * Remove the sw inventory file from inside this zonepath that we picked up out 348 * of the snapshot. 349 */ 350 static int 351 clean_out_clone() 352 { 353 int err; 354 zone_dochandle_t handle; 355 356 if ((handle = zonecfg_init_handle()) == NULL) { 357 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 358 return (Z_ERR); 359 } 360 361 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 362 errno = err; 363 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 364 zonecfg_fini_handle(handle); 365 return (Z_ERR); 366 } 367 368 zonecfg_rm_detached(handle, B_FALSE); 369 zonecfg_fini_handle(handle); 370 371 return (Z_OK); 372 } 373 374 /* 375 * Make a ZFS clone on zonepath from snapshot_name. 376 */ 377 static int 378 clone_snap(char *snapshot_name, char *zonepath) 379 { 380 int res = Z_OK; 381 int err; 382 zfs_handle_t *zhp; 383 zfs_handle_t *clone; 384 nvlist_t *props = NULL; 385 386 if ((zhp = zfs_open(g_zfs, snapshot_name, ZFS_TYPE_SNAPSHOT)) == NULL) 387 return (Z_NO_ENTRY); 388 389 (void) printf(gettext("Cloning snapshot %s\n"), snapshot_name); 390 391 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0 || 392 nvlist_add_string(props, zfs_prop_to_name(ZFS_PROP_SHARENFS), 393 "off") != 0) { 394 if (props != NULL) 395 nvlist_free(props); 396 (void) fprintf(stderr, gettext("could not create ZFS clone " 397 "%s: out of memory\n"), zonepath); 398 return (Z_ERR); 399 } 400 401 err = zfs_clone(zhp, zonepath, props); 402 zfs_close(zhp); 403 404 nvlist_free(props); 405 406 if (err != 0) 407 return (Z_ERR); 408 409 /* create the mountpoint if necessary */ 410 if ((clone = zfs_open(g_zfs, zonepath, ZFS_TYPE_DATASET)) == NULL) 411 return (Z_ERR); 412 413 /* 414 * The clone has been created so we need to print a diagnostic 415 * message if one of the following steps fails for some reason. 416 */ 417 if (zfs_mount(clone, NULL, 0) != 0) { 418 (void) fprintf(stderr, gettext("could not mount ZFS clone " 419 "%s\n"), zfs_get_name(clone)); 420 res = Z_ERR; 421 422 } else if (clean_out_clone() != Z_OK) { 423 (void) fprintf(stderr, gettext("could not remove the " 424 "software inventory from ZFS clone %s\n"), 425 zfs_get_name(clone)); 426 res = Z_ERR; 427 } 428 429 zfs_close(clone); 430 return (res); 431 } 432 433 /* 434 * This function takes a zonepath and attempts to determine what the ZFS 435 * file system name (not mountpoint) should be for that path. We do not 436 * assume that zonepath is an existing directory or ZFS fs since we use 437 * this function as part of the process of creating a new ZFS fs or clone. 438 * 439 * The way this works is that we look at the parent directory of the zonepath 440 * to see if it is a ZFS fs. If it is, we get the name of that ZFS fs and 441 * append the last component of the zonepath to generate the ZFS name for the 442 * zonepath. This matches the algorithm that ZFS uses for automatically 443 * mounting a new fs after it is created. 444 * 445 * Although a ZFS fs can be mounted anywhere, we don't worry about handling 446 * all of the complexity that a user could possibly configure with arbitrary 447 * mounts since there is no way to generate a ZFS name from a random path in 448 * the file system. We only try to handle the automatic mounts that ZFS does 449 * for each file system. ZFS restricts this so that a new fs must be created 450 * in an existing parent ZFS fs. It then automatically mounts the new fs 451 * directly under the mountpoint for the parent fs using the last component 452 * of the name as the mountpoint directory. 453 * 454 * For example: 455 * Name Mountpoint 456 * space/eng/dev/test/zone1 /project1/eng/dev/test/zone1 457 * 458 * Return Z_OK if the path mapped to a ZFS file system name, otherwise return 459 * Z_ERR. 460 */ 461 static int 462 path2name(char *zonepath, char *zfs_name, int len) 463 { 464 int res; 465 char *bnm, *dnm, *dname, *bname; 466 zfs_handle_t *zhp; 467 struct stat stbuf; 468 469 /* 470 * We need two tmp strings to handle paths directly in / (e.g. /foo) 471 * since dirname will overwrite the first char after "/" in this case. 472 */ 473 if ((bnm = strdup(zonepath)) == NULL) 474 return (Z_ERR); 475 476 if ((dnm = strdup(zonepath)) == NULL) { 477 free(bnm); 478 return (Z_ERR); 479 } 480 481 bname = basename(bnm); 482 dname = dirname(dnm); 483 484 /* 485 * This is a quick test to save iterating over all of the zfs datasets 486 * on the system (which can be a lot). If the parent dir is not in a 487 * ZFS fs, then we're done. 488 */ 489 if (stat(dname, &stbuf) != 0 || !S_ISDIR(stbuf.st_mode) || 490 strcmp(stbuf.st_fstype, MNTTYPE_ZFS) != 0) { 491 free(bnm); 492 free(dnm); 493 return (Z_ERR); 494 } 495 496 /* See if the parent directory is its own ZFS dataset. */ 497 if ((zhp = mount2zhandle(dname)) == NULL) { 498 /* 499 * The parent is not a ZFS dataset so we can't automatically 500 * create a dataset on the given path. 501 */ 502 free(bnm); 503 free(dnm); 504 return (Z_ERR); 505 } 506 507 res = snprintf(zfs_name, len, "%s/%s", zfs_get_name(zhp), bname); 508 509 free(bnm); 510 free(dnm); 511 zfs_close(zhp); 512 if (res >= len) 513 return (Z_ERR); 514 515 return (Z_OK); 516 } 517 518 /* 519 * A ZFS file system iterator call-back function used to determine if the 520 * file system has dependents (snapshots & clones). 521 */ 522 /* ARGSUSED */ 523 static int 524 has_dependent(zfs_handle_t *zhp, void *data) 525 { 526 zfs_close(zhp); 527 return (1); 528 } 529 530 /* 531 * Given a snapshot name, get the file system path where the snapshot lives. 532 * A snapshot name is of the form fs_name@snap_name. For example, snapshot 533 * pl/zones/z1@SUNWzone1 would have a path of 534 * /pl/zones/z1/.zfs/snapshot/SUNWzone1. 535 */ 536 static int 537 snap2path(char *snap_name, char *path, int len) 538 { 539 char *p; 540 zfs_handle_t *zhp; 541 char mp[ZFS_MAXPROPLEN]; 542 543 if ((p = strrchr(snap_name, '@')) == NULL) 544 return (Z_ERR); 545 546 /* Get the file system name from the snap_name. */ 547 *p = '\0'; 548 zhp = zfs_open(g_zfs, snap_name, ZFS_TYPE_DATASET); 549 *p = '@'; 550 if (zhp == NULL) 551 return (Z_ERR); 552 553 /* Get the file system mount point. */ 554 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mp, sizeof (mp), NULL, NULL, 555 0, B_FALSE) != 0) { 556 zfs_close(zhp); 557 return (Z_ERR); 558 } 559 zfs_close(zhp); 560 561 p++; 562 if (snprintf(path, len, "%s/.zfs/snapshot/%s", mp, p) >= len) 563 return (Z_ERR); 564 565 return (Z_OK); 566 } 567 568 /* 569 * Clone a pre-existing ZFS snapshot, either by making a direct ZFS clone, if 570 * possible, or by copying the data from the snapshot to the zonepath. 571 */ 572 int 573 clone_snapshot_zfs(char *snap_name, char *zonepath, char *validatesnap) 574 { 575 int err = Z_OK; 576 char clone_name[MAXPATHLEN]; 577 char snap_path[MAXPATHLEN]; 578 579 if (snap2path(snap_name, snap_path, sizeof (snap_path)) != Z_OK) { 580 (void) fprintf(stderr, gettext("unable to find path for %s.\n"), 581 snap_name); 582 return (Z_ERR); 583 } 584 585 if (validate_snapshot(snap_name, snap_path, validatesnap) != Z_OK) 586 return (Z_NO_ENTRY); 587 588 /* 589 * The zonepath cannot be ZFS cloned, try to copy the data from 590 * within the snapshot to the zonepath. 591 */ 592 if (path2name(zonepath, clone_name, sizeof (clone_name)) != Z_OK) { 593 if ((err = clone_copy(snap_path, zonepath)) == Z_OK) 594 if (clean_out_clone() != Z_OK) 595 (void) fprintf(stderr, 596 gettext("could not remove the " 597 "software inventory from %s\n"), zonepath); 598 599 return (err); 600 } 601 602 if ((err = clone_snap(snap_name, clone_name)) != Z_OK) { 603 if (err != Z_NO_ENTRY) { 604 /* 605 * Cloning the snapshot failed. Fall back to trying 606 * to install the zone by copying from the snapshot. 607 */ 608 if ((err = clone_copy(snap_path, zonepath)) == Z_OK) 609 if (clean_out_clone() != Z_OK) 610 (void) fprintf(stderr, 611 gettext("could not remove the " 612 "software inventory from %s\n"), 613 zonepath); 614 } else { 615 /* 616 * The snapshot is unusable for some reason so restore 617 * the zone state to configured since we were unable to 618 * actually do anything about getting the zone 619 * installed. 620 */ 621 int tmp; 622 623 if ((tmp = zone_set_state(target_zone, 624 ZONE_STATE_CONFIGURED)) != Z_OK) { 625 errno = tmp; 626 zperror2(target_zone, 627 gettext("could not set state")); 628 } 629 } 630 } 631 632 return (err); 633 } 634 635 /* 636 * Attempt to clone a source_zone to a target zonepath by using a ZFS clone. 637 */ 638 int 639 clone_zfs(char *source_zonepath, char *zonepath, char *presnapbuf, 640 char *postsnapbuf) 641 { 642 zfs_handle_t *zhp; 643 char clone_name[MAXPATHLEN]; 644 char snap_name[MAXPATHLEN]; 645 646 /* 647 * Try to get a zfs handle for the source_zonepath. If this fails 648 * the source_zonepath is not ZFS so return an error. 649 */ 650 if ((zhp = mount2zhandle(source_zonepath)) == NULL) 651 return (Z_ERR); 652 653 /* 654 * Check if there is a file system already mounted on zonepath. If so, 655 * we can't clone to the path so we should fall back to copying. 656 */ 657 if (is_mountpnt(zonepath)) { 658 zfs_close(zhp); 659 (void) fprintf(stderr, 660 gettext("A file system is already mounted on %s,\n" 661 "preventing use of a ZFS clone.\n"), zonepath); 662 return (Z_ERR); 663 } 664 665 /* 666 * Instead of using path2name to get the clone name from the zonepath, 667 * we could generate a name from the source zone ZFS name. However, 668 * this would mean we would create the clone under the ZFS fs of the 669 * source instead of what the zonepath says. For example, 670 * 671 * source_zonepath zonepath 672 * /pl/zones/dev/z1 /pl/zones/deploy/z2 673 * 674 * We don't want the clone to be under "dev", we want it under 675 * "deploy", so that we can leverage the normal attribute inheritance 676 * that ZFS provides in the fs hierarchy. 677 */ 678 if (path2name(zonepath, clone_name, sizeof (clone_name)) != Z_OK) { 679 zfs_close(zhp); 680 return (Z_ERR); 681 } 682 683 if (take_snapshot(zhp, snap_name, sizeof (snap_name), presnapbuf, 684 postsnapbuf) != Z_OK) { 685 zfs_close(zhp); 686 return (Z_ERR); 687 } 688 zfs_close(zhp); 689 690 if (clone_snap(snap_name, clone_name) != Z_OK) { 691 /* Clean up the snapshot we just took. */ 692 if ((zhp = zfs_open(g_zfs, snap_name, ZFS_TYPE_SNAPSHOT)) 693 != NULL) { 694 if (zfs_unmount(zhp, NULL, 0) == 0) 695 (void) zfs_destroy(zhp); 696 zfs_close(zhp); 697 } 698 699 return (Z_ERR); 700 } 701 702 (void) printf(gettext("Instead of copying, a ZFS clone has been " 703 "created for this zone.\n")); 704 705 return (Z_OK); 706 } 707 708 /* 709 * Attempt to create a ZFS file system for the specified zonepath. 710 * We either will successfully create a ZFS file system and get it mounted 711 * on the zonepath or we don't. The caller doesn't care since a regular 712 * directory is used for the zonepath if no ZFS file system is mounted there. 713 */ 714 void 715 create_zfs_zonepath(char *zonepath) 716 { 717 zfs_handle_t *zhp; 718 char zfs_name[MAXPATHLEN]; 719 nvlist_t *props = NULL; 720 721 if (path2name(zonepath, zfs_name, sizeof (zfs_name)) != Z_OK) 722 return; 723 724 if (nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0 || 725 nvlist_add_string(props, zfs_prop_to_name(ZFS_PROP_SHARENFS), 726 "off") != 0) { 727 if (props != NULL) 728 nvlist_free(props); 729 (void) fprintf(stderr, gettext("cannot create ZFS dataset %s: " 730 "out of memory\n"), zfs_name); 731 } 732 733 if (zfs_create(g_zfs, zfs_name, ZFS_TYPE_FILESYSTEM, props) != 0 || 734 (zhp = zfs_open(g_zfs, zfs_name, ZFS_TYPE_DATASET)) == NULL) { 735 (void) fprintf(stderr, gettext("cannot create ZFS dataset %s: " 736 "%s\n"), zfs_name, libzfs_error_description(g_zfs)); 737 nvlist_free(props); 738 return; 739 } 740 741 nvlist_free(props); 742 743 if (zfs_mount(zhp, NULL, 0) != 0) { 744 (void) fprintf(stderr, gettext("cannot mount ZFS dataset %s: " 745 "%s\n"), zfs_name, libzfs_error_description(g_zfs)); 746 (void) zfs_destroy(zhp); 747 } else { 748 if (chmod(zonepath, S_IRWXU) != 0) { 749 (void) fprintf(stderr, gettext("file system %s " 750 "successfully created, but chmod %o failed: %s\n"), 751 zfs_name, S_IRWXU, strerror(errno)); 752 (void) destroy_zfs(zonepath); 753 } else { 754 (void) printf(gettext("A ZFS file system has been " 755 "created for this zone.\n")); 756 } 757 } 758 759 zfs_close(zhp); 760 } 761 762 /* 763 * If the zonepath is a ZFS file system, attempt to destroy it. We return Z_OK 764 * if we were able to zfs_destroy the zonepath, otherwise we return Z_ERR 765 * which means the caller should clean up the zonepath in the traditional 766 * way. 767 */ 768 int 769 destroy_zfs(char *zonepath) 770 { 771 zfs_handle_t *zhp; 772 boolean_t is_clone = B_FALSE; 773 char origin[ZFS_MAXPROPLEN]; 774 775 if ((zhp = mount2zhandle(zonepath)) == NULL) 776 return (Z_ERR); 777 778 /* 779 * We can't destroy the file system if it has dependents. 780 */ 781 if (zfs_iter_dependents(zhp, B_TRUE, has_dependent, NULL) != 0 || 782 zfs_unmount(zhp, NULL, 0) != 0) { 783 zfs_close(zhp); 784 return (Z_ERR); 785 } 786 787 /* 788 * This might be a clone. Try to get the snapshot so we can attempt 789 * to destroy that as well. 790 */ 791 if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, origin, sizeof (origin), NULL, 792 NULL, 0, B_FALSE) == 0) 793 is_clone = B_TRUE; 794 795 if (zfs_destroy(zhp) != 0) { 796 /* 797 * If the destroy fails for some reason, try to remount 798 * the file system so that we can use "rm -rf" to clean up 799 * instead. 800 */ 801 (void) zfs_mount(zhp, NULL, 0); 802 zfs_close(zhp); 803 return (Z_ERR); 804 } 805 806 /* 807 * If the zone has ever been moved then the mountpoint dir will not be 808 * cleaned up by the zfs_destroy(). To handle this case try to clean 809 * it up now but don't worry if it fails, that will be normal. 810 */ 811 (void) rmdir(zonepath); 812 813 (void) printf(gettext("The ZFS file system for this zone has been " 814 "destroyed.\n")); 815 816 if (is_clone) { 817 zfs_handle_t *ohp; 818 819 /* 820 * Try to clean up the snapshot that the clone was taken from. 821 */ 822 if ((ohp = zfs_open(g_zfs, origin, 823 ZFS_TYPE_SNAPSHOT)) != NULL) { 824 if (zfs_iter_dependents(ohp, B_TRUE, has_dependent, 825 NULL) == 0 && zfs_unmount(ohp, NULL, 0) == 0) 826 (void) zfs_destroy(ohp); 827 zfs_close(ohp); 828 } 829 } 830 831 zfs_close(zhp); 832 return (Z_OK); 833 } 834 835 /* 836 * Return true if the path is its own zfs file system. We determine this 837 * by stat-ing the path to see if it is zfs and stat-ing the parent to see 838 * if it is a different fs. 839 */ 840 boolean_t 841 is_zonepath_zfs(char *zonepath) 842 { 843 int res; 844 char *path; 845 char *parent; 846 struct statvfs64 buf1, buf2; 847 848 if (statvfs64(zonepath, &buf1) != 0) 849 return (B_FALSE); 850 851 if (strcmp(buf1.f_basetype, "zfs") != 0) 852 return (B_FALSE); 853 854 if ((path = strdup(zonepath)) == NULL) 855 return (B_FALSE); 856 857 parent = dirname(path); 858 res = statvfs64(parent, &buf2); 859 free(path); 860 861 if (res != 0) 862 return (B_FALSE); 863 864 if (buf1.f_fsid == buf2.f_fsid) 865 return (B_FALSE); 866 867 return (B_TRUE); 868 } 869 870 /* 871 * Implement the fast move of a ZFS file system by simply updating the 872 * mountpoint. Since it is file system already, we don't have the 873 * issue of cross-file system copying. 874 */ 875 int 876 move_zfs(char *zonepath, char *new_zonepath) 877 { 878 int ret = Z_ERR; 879 zfs_handle_t *zhp; 880 881 if ((zhp = mount2zhandle(zonepath)) == NULL) 882 return (Z_ERR); 883 884 if (zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 885 new_zonepath) == 0) { 886 /* 887 * Clean up the old mount point. We ignore any failure since 888 * the zone is already successfully mounted on the new path. 889 */ 890 (void) rmdir(zonepath); 891 ret = Z_OK; 892 } 893 894 zfs_close(zhp); 895 896 return (ret); 897 } 898 899 /* 900 * Validate that the given dataset exists on the system, and that neither it nor 901 * its children are zvols. 902 * 903 * Note that we don't do anything with the 'zoned' property here. All 904 * management is done in zoneadmd when the zone is actually rebooted. This 905 * allows us to automatically set the zoned property even when a zone is 906 * rebooted by the administrator. 907 */ 908 int 909 verify_datasets(zone_dochandle_t handle) 910 { 911 int return_code = Z_OK; 912 struct zone_dstab dstab; 913 zfs_handle_t *zhp; 914 char propbuf[ZFS_MAXPROPLEN]; 915 char source[ZFS_MAXNAMELEN]; 916 zprop_source_t srctype; 917 918 if (zonecfg_setdsent(handle) != Z_OK) { 919 /* 920 * TRANSLATION_NOTE 921 * zfs and dataset are literals that should not be translated. 922 */ 923 (void) fprintf(stderr, gettext("could not verify zfs datasets: " 924 "unable to enumerate datasets\n")); 925 return (Z_ERR); 926 } 927 928 while (zonecfg_getdsent(handle, &dstab) == Z_OK) { 929 930 if ((zhp = zfs_open(g_zfs, dstab.zone_dataset_name, 931 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) { 932 (void) fprintf(stderr, gettext("could not verify zfs " 933 "dataset %s: %s\n"), dstab.zone_dataset_name, 934 libzfs_error_description(g_zfs)); 935 return_code = Z_ERR; 936 continue; 937 } 938 939 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, propbuf, 940 sizeof (propbuf), &srctype, source, 941 sizeof (source), 0) == 0 && 942 (srctype == ZPROP_SRC_INHERITED)) { 943 (void) fprintf(stderr, gettext("could not verify zfs " 944 "dataset %s: mountpoint cannot be inherited\n"), 945 dstab.zone_dataset_name); 946 return_code = Z_ERR; 947 zfs_close(zhp); 948 continue; 949 } 950 951 if (zfs_get_type(zhp) == ZFS_TYPE_VOLUME) { 952 (void) fprintf(stderr, gettext("cannot verify zfs " 953 "dataset %s: volumes cannot be specified as a " 954 "zone dataset resource\n"), 955 dstab.zone_dataset_name); 956 return_code = Z_ERR; 957 } 958 959 if (zfs_iter_children(zhp, check_zvol, NULL) != 0) 960 return_code = Z_ERR; 961 962 zfs_close(zhp); 963 } 964 (void) zonecfg_enddsent(handle); 965 966 return (return_code); 967 } 968 969 /* 970 * Verify that the ZFS dataset exists, and its mountpoint 971 * property is set to "legacy". 972 */ 973 int 974 verify_fs_zfs(struct zone_fstab *fstab) 975 { 976 zfs_handle_t *zhp; 977 char propbuf[ZFS_MAXPROPLEN]; 978 979 if ((zhp = zfs_open(g_zfs, fstab->zone_fs_special, 980 ZFS_TYPE_DATASET)) == NULL) { 981 (void) fprintf(stderr, gettext("could not verify fs %s: " 982 "could not access zfs dataset '%s'\n"), 983 fstab->zone_fs_dir, fstab->zone_fs_special); 984 return (Z_ERR); 985 } 986 987 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) { 988 (void) fprintf(stderr, gettext("cannot verify fs %s: " 989 "'%s' is not a file system\n"), 990 fstab->zone_fs_dir, fstab->zone_fs_special); 991 zfs_close(zhp); 992 return (Z_ERR); 993 } 994 995 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, propbuf, sizeof (propbuf), 996 NULL, NULL, 0, 0) != 0 || strcmp(propbuf, "legacy") != 0) { 997 (void) fprintf(stderr, gettext("could not verify fs %s: " 998 "zfs '%s' mountpoint is not \"legacy\"\n"), 999 fstab->zone_fs_dir, fstab->zone_fs_special); 1000 zfs_close(zhp); 1001 return (Z_ERR); 1002 } 1003 1004 zfs_close(zhp); 1005 return (Z_OK); 1006 } 1007 1008 int 1009 init_zfs(void) 1010 { 1011 if ((g_zfs = libzfs_init()) == NULL) { 1012 (void) fprintf(stderr, gettext("failed to initialize ZFS " 1013 "library\n")); 1014 return (Z_ERR); 1015 } 1016 1017 return (Z_OK); 1018 } 1019