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) 2006, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright (c) 2012 by Delphix. All rights reserved. 25 */ 26 27 /* 28 * This file contains the functions used to support the ZFS integration 29 * with zones. This includes validation (e.g. zonecfg dataset), cloning, 30 * file system creation and destruction. 31 */ 32 33 #include <stdio.h> 34 #include <errno.h> 35 #include <unistd.h> 36 #include <string.h> 37 #include <locale.h> 38 #include <libintl.h> 39 #include <sys/stat.h> 40 #include <sys/statvfs.h> 41 #include <libgen.h> 42 #include <libzonecfg.h> 43 #include <sys/mnttab.h> 44 #include <libzfs.h> 45 #include <sys/mntent.h> 46 #include <values.h> 47 #include <strings.h> 48 #include <assert.h> 49 50 #include "zoneadm.h" 51 52 libzfs_handle_t *g_zfs; 53 54 typedef struct zfs_mount_data { 55 char *match_name; 56 zfs_handle_t *match_handle; 57 } zfs_mount_data_t; 58 59 typedef struct zfs_snapshot_data { 60 char *match_name; /* zonename@SUNWzone */ 61 int len; /* strlen of match_name */ 62 int max; /* highest digit appended to snap name */ 63 int num; /* number of snapshots to rename */ 64 int cntr; /* counter for renaming snapshots */ 65 } zfs_snapshot_data_t; 66 67 typedef struct clone_data { 68 zfs_handle_t *clone_zhp; /* clone dataset to promote */ 69 time_t origin_creation; /* snapshot creation time of clone */ 70 const char *snapshot; /* snapshot of dataset being demoted */ 71 } clone_data_t; 72 73 /* 74 * A ZFS file system iterator call-back function which is used to validate 75 * datasets imported into the zone. 76 */ 77 /* ARGSUSED */ 78 static int 79 check_zvol(zfs_handle_t *zhp, void *unused) 80 { 81 int ret; 82 83 if (zfs_get_type(zhp) == ZFS_TYPE_VOLUME) { 84 /* 85 * TRANSLATION_NOTE 86 * zfs and dataset are literals that should not be translated. 87 */ 88 (void) fprintf(stderr, gettext("cannot verify zfs dataset %s: " 89 "volumes cannot be specified as a zone dataset resource\n"), 90 zfs_get_name(zhp)); 91 ret = -1; 92 } else { 93 ret = zfs_iter_children(zhp, check_zvol, NULL); 94 } 95 96 zfs_close(zhp); 97 98 return (ret); 99 } 100 101 /* 102 * A ZFS file system iterator call-back function which returns the 103 * zfs_handle_t for a ZFS file system on the specified mount point. 104 */ 105 static int 106 match_mountpoint(zfs_handle_t *zhp, void *data) 107 { 108 int res; 109 zfs_mount_data_t *cbp; 110 char mp[ZFS_MAXPROPLEN]; 111 112 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) { 113 zfs_close(zhp); 114 return (0); 115 } 116 117 /* First check if the dataset is mounted. */ 118 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTED, mp, sizeof (mp), NULL, NULL, 119 0, B_FALSE) != 0 || strcmp(mp, "no") == 0) { 120 zfs_close(zhp); 121 return (0); 122 } 123 124 /* Now check mount point. */ 125 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mp, sizeof (mp), NULL, NULL, 126 0, B_FALSE) != 0) { 127 zfs_close(zhp); 128 return (0); 129 } 130 131 cbp = (zfs_mount_data_t *)data; 132 133 if (strcmp(mp, "legacy") == 0) { 134 /* If legacy, must look in mnttab for mountpoint. */ 135 FILE *fp; 136 struct mnttab entry; 137 const char *nm; 138 139 nm = zfs_get_name(zhp); 140 if ((fp = fopen(MNTTAB, "r")) == NULL) { 141 zfs_close(zhp); 142 return (0); 143 } 144 145 while (getmntent(fp, &entry) == 0) { 146 if (strcmp(nm, entry.mnt_special) == 0) { 147 if (strcmp(entry.mnt_mountp, cbp->match_name) 148 == 0) { 149 (void) fclose(fp); 150 cbp->match_handle = zhp; 151 return (1); 152 } 153 break; 154 } 155 } 156 (void) fclose(fp); 157 158 } else if (strcmp(mp, cbp->match_name) == 0) { 159 cbp->match_handle = zhp; 160 return (1); 161 } 162 163 /* Iterate over any nested datasets. */ 164 res = zfs_iter_filesystems(zhp, match_mountpoint, data); 165 zfs_close(zhp); 166 return (res); 167 } 168 169 /* 170 * Get ZFS handle for the specified mount point. 171 */ 172 static zfs_handle_t * 173 mount2zhandle(char *mountpoint) 174 { 175 zfs_mount_data_t cb; 176 177 cb.match_name = mountpoint; 178 cb.match_handle = NULL; 179 (void) zfs_iter_root(g_zfs, match_mountpoint, &cb); 180 return (cb.match_handle); 181 } 182 183 /* 184 * Check if there is already a file system (zfs or any other type) mounted on 185 * path. 186 */ 187 static boolean_t 188 is_mountpnt(char *path) 189 { 190 FILE *fp; 191 struct mnttab entry; 192 193 if ((fp = fopen(MNTTAB, "r")) == NULL) 194 return (B_FALSE); 195 196 while (getmntent(fp, &entry) == 0) { 197 if (strcmp(path, entry.mnt_mountp) == 0) { 198 (void) fclose(fp); 199 return (B_TRUE); 200 } 201 } 202 203 (void) fclose(fp); 204 return (B_FALSE); 205 } 206 207 /* 208 * Run the brand's pre-snapshot hook before we take a ZFS snapshot of the zone. 209 */ 210 static int 211 pre_snapshot(char *presnapbuf) 212 { 213 int status; 214 215 /* No brand-specific handler */ 216 if (presnapbuf[0] == '\0') 217 return (Z_OK); 218 219 /* Run the hook */ 220 status = do_subproc(presnapbuf); 221 if ((status = subproc_status(gettext("brand-specific presnapshot"), 222 status, B_FALSE)) != ZONE_SUBPROC_OK) 223 return (Z_ERR); 224 225 return (Z_OK); 226 } 227 228 /* 229 * Run the brand's post-snapshot hook after we take a ZFS snapshot of the zone. 230 */ 231 static int 232 post_snapshot(char *postsnapbuf) 233 { 234 int status; 235 236 /* No brand-specific handler */ 237 if (postsnapbuf[0] == '\0') 238 return (Z_OK); 239 240 /* Run the hook */ 241 status = do_subproc(postsnapbuf); 242 if ((status = subproc_status(gettext("brand-specific postsnapshot"), 243 status, B_FALSE)) != ZONE_SUBPROC_OK) 244 return (Z_ERR); 245 246 return (Z_OK); 247 } 248 249 /* 250 * This is a ZFS snapshot iterator call-back function which returns the 251 * highest number of SUNWzone snapshots that have been taken. 252 */ 253 static int 254 get_snap_max(zfs_handle_t *zhp, void *data) 255 { 256 int res; 257 zfs_snapshot_data_t *cbp; 258 259 if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) { 260 zfs_close(zhp); 261 return (0); 262 } 263 264 cbp = (zfs_snapshot_data_t *)data; 265 266 if (strncmp(zfs_get_name(zhp), cbp->match_name, cbp->len) == 0) { 267 char *nump; 268 int num; 269 270 cbp->num++; 271 nump = (char *)(zfs_get_name(zhp) + cbp->len); 272 num = atoi(nump); 273 if (num > cbp->max) 274 cbp->max = num; 275 } 276 277 res = zfs_iter_snapshots(zhp, get_snap_max, data); 278 zfs_close(zhp); 279 return (res); 280 } 281 282 /* 283 * Take a ZFS snapshot to be used for cloning the zone. 284 */ 285 static int 286 take_snapshot(zfs_handle_t *zhp, char *snapshot_name, int snap_size, 287 char *presnapbuf, char *postsnapbuf) 288 { 289 int res; 290 char template[ZFS_MAXNAMELEN]; 291 zfs_snapshot_data_t cb; 292 293 /* 294 * First we need to figure out the next available name for the 295 * zone snapshot. Look through the list of zones snapshots for 296 * this file system to determine the maximum snapshot name. 297 */ 298 if (snprintf(template, sizeof (template), "%s@SUNWzone", 299 zfs_get_name(zhp)) >= sizeof (template)) 300 return (Z_ERR); 301 302 cb.match_name = template; 303 cb.len = strlen(template); 304 cb.max = 0; 305 306 if (zfs_iter_snapshots(zhp, get_snap_max, &cb) != 0) 307 return (Z_ERR); 308 309 cb.max++; 310 311 if (snprintf(snapshot_name, snap_size, "%s@SUNWzone%d", 312 zfs_get_name(zhp), cb.max) >= snap_size) 313 return (Z_ERR); 314 315 if (pre_snapshot(presnapbuf) != Z_OK) 316 return (Z_ERR); 317 res = zfs_snapshot(g_zfs, snapshot_name, B_FALSE, NULL); 318 if (post_snapshot(postsnapbuf) != Z_OK) 319 return (Z_ERR); 320 321 if (res != 0) 322 return (Z_ERR); 323 return (Z_OK); 324 } 325 326 /* 327 * We are using an explicit snapshot from some earlier point in time so 328 * we need to validate it. Run the brand specific hook. 329 */ 330 static int 331 validate_snapshot(char *snapshot_name, char *snap_path, char *validsnapbuf) 332 { 333 int status; 334 char cmdbuf[MAXPATHLEN]; 335 336 /* No brand-specific handler */ 337 if (validsnapbuf[0] == '\0') 338 return (Z_OK); 339 340 /* pass args - snapshot_name & snap_path */ 341 if (snprintf(cmdbuf, sizeof (cmdbuf), "%s %s %s", validsnapbuf, 342 snapshot_name, snap_path) >= sizeof (cmdbuf)) { 343 zerror("Command line too long"); 344 return (Z_ERR); 345 } 346 347 /* Run the hook */ 348 status = do_subproc(cmdbuf); 349 if ((status = subproc_status(gettext("brand-specific validatesnapshot"), 350 status, B_FALSE)) != ZONE_SUBPROC_OK) 351 return (Z_ERR); 352 353 return (Z_OK); 354 } 355 356 /* 357 * Remove the sw inventory file from inside this zonepath that we picked up out 358 * of the snapshot. 359 */ 360 static int 361 clean_out_clone() 362 { 363 int err; 364 zone_dochandle_t handle; 365 366 if ((handle = zonecfg_init_handle()) == NULL) { 367 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 368 return (Z_ERR); 369 } 370 371 if ((err = zonecfg_get_handle(target_zone, handle)) != Z_OK) { 372 errno = err; 373 zperror(cmd_to_str(CMD_CLONE), B_TRUE); 374 zonecfg_fini_handle(handle); 375 return (Z_ERR); 376 } 377 378 zonecfg_rm_detached(handle, B_FALSE); 379 zonecfg_fini_handle(handle); 380 381 return (Z_OK); 382 } 383 384 /* 385 * Make a ZFS clone on zonepath from snapshot_name. 386 */ 387 static int 388 clone_snap(char *snapshot_name, char *zonepath) 389 { 390 int res = Z_OK; 391 int err; 392 zfs_handle_t *zhp; 393 zfs_handle_t *clone; 394 nvlist_t *props = NULL; 395 396 if ((zhp = zfs_open(g_zfs, snapshot_name, ZFS_TYPE_SNAPSHOT)) == NULL) 397 return (Z_NO_ENTRY); 398 399 (void) printf(gettext("Cloning snapshot %s\n"), snapshot_name); 400 401 /* 402 * We turn off zfs SHARENFS and SHARESMB properties on the 403 * zoneroot dataset in order to prevent the GZ from sharing 404 * NGZ data by accident. 405 */ 406 if ((nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) || 407 (nvlist_add_string(props, zfs_prop_to_name(ZFS_PROP_SHARENFS), 408 "off") != 0) || 409 (nvlist_add_string(props, zfs_prop_to_name(ZFS_PROP_SHARESMB), 410 "off") != 0)) { 411 if (props != NULL) 412 nvlist_free(props); 413 (void) fprintf(stderr, gettext("could not create ZFS clone " 414 "%s: out of memory\n"), zonepath); 415 return (Z_ERR); 416 } 417 418 err = zfs_clone(zhp, zonepath, props); 419 zfs_close(zhp); 420 421 nvlist_free(props); 422 423 if (err != 0) 424 return (Z_ERR); 425 426 /* create the mountpoint if necessary */ 427 if ((clone = zfs_open(g_zfs, zonepath, ZFS_TYPE_DATASET)) == NULL) 428 return (Z_ERR); 429 430 /* 431 * The clone has been created so we need to print a diagnostic 432 * message if one of the following steps fails for some reason. 433 */ 434 if (zfs_mount(clone, NULL, 0) != 0) { 435 (void) fprintf(stderr, gettext("could not mount ZFS clone " 436 "%s\n"), zfs_get_name(clone)); 437 res = Z_ERR; 438 439 } else if (clean_out_clone() != Z_OK) { 440 (void) fprintf(stderr, gettext("could not remove the " 441 "software inventory from ZFS clone %s\n"), 442 zfs_get_name(clone)); 443 res = Z_ERR; 444 } 445 446 zfs_close(clone); 447 return (res); 448 } 449 450 /* 451 * This function takes a zonepath and attempts to determine what the ZFS 452 * file system name (not mountpoint) should be for that path. We do not 453 * assume that zonepath is an existing directory or ZFS fs since we use 454 * this function as part of the process of creating a new ZFS fs or clone. 455 * 456 * The way this works is that we look at the parent directory of the zonepath 457 * to see if it is a ZFS fs. If it is, we get the name of that ZFS fs and 458 * append the last component of the zonepath to generate the ZFS name for the 459 * zonepath. This matches the algorithm that ZFS uses for automatically 460 * mounting a new fs after it is created. 461 * 462 * Although a ZFS fs can be mounted anywhere, we don't worry about handling 463 * all of the complexity that a user could possibly configure with arbitrary 464 * mounts since there is no way to generate a ZFS name from a random path in 465 * the file system. We only try to handle the automatic mounts that ZFS does 466 * for each file system. ZFS restricts this so that a new fs must be created 467 * in an existing parent ZFS fs. It then automatically mounts the new fs 468 * directly under the mountpoint for the parent fs using the last component 469 * of the name as the mountpoint directory. 470 * 471 * For example: 472 * Name Mountpoint 473 * space/eng/dev/test/zone1 /project1/eng/dev/test/zone1 474 * 475 * Return Z_OK if the path mapped to a ZFS file system name, otherwise return 476 * Z_ERR. 477 */ 478 static int 479 path2name(char *zonepath, char *zfs_name, int len) 480 { 481 int res; 482 char *bnm, *dnm, *dname, *bname; 483 zfs_handle_t *zhp; 484 struct stat stbuf; 485 486 /* 487 * We need two tmp strings to handle paths directly in / (e.g. /foo) 488 * since dirname will overwrite the first char after "/" in this case. 489 */ 490 if ((bnm = strdup(zonepath)) == NULL) 491 return (Z_ERR); 492 493 if ((dnm = strdup(zonepath)) == NULL) { 494 free(bnm); 495 return (Z_ERR); 496 } 497 498 bname = basename(bnm); 499 dname = dirname(dnm); 500 501 /* 502 * This is a quick test to save iterating over all of the zfs datasets 503 * on the system (which can be a lot). If the parent dir is not in a 504 * ZFS fs, then we're done. 505 */ 506 if (stat(dname, &stbuf) != 0 || !S_ISDIR(stbuf.st_mode) || 507 strcmp(stbuf.st_fstype, MNTTYPE_ZFS) != 0) { 508 free(bnm); 509 free(dnm); 510 return (Z_ERR); 511 } 512 513 /* See if the parent directory is its own ZFS dataset. */ 514 if ((zhp = mount2zhandle(dname)) == NULL) { 515 /* 516 * The parent is not a ZFS dataset so we can't automatically 517 * create a dataset on the given path. 518 */ 519 free(bnm); 520 free(dnm); 521 return (Z_ERR); 522 } 523 524 res = snprintf(zfs_name, len, "%s/%s", zfs_get_name(zhp), bname); 525 526 free(bnm); 527 free(dnm); 528 zfs_close(zhp); 529 if (res >= len) 530 return (Z_ERR); 531 532 return (Z_OK); 533 } 534 535 /* 536 * A ZFS file system iterator call-back function used to determine if the 537 * file system has dependents (snapshots & clones). 538 */ 539 /* ARGSUSED */ 540 static int 541 has_dependent(zfs_handle_t *zhp, void *data) 542 { 543 zfs_close(zhp); 544 return (1); 545 } 546 547 /* 548 * Given a snapshot name, get the file system path where the snapshot lives. 549 * A snapshot name is of the form fs_name@snap_name. For example, snapshot 550 * pl/zones/z1@SUNWzone1 would have a path of 551 * /pl/zones/z1/.zfs/snapshot/SUNWzone1. 552 */ 553 static int 554 snap2path(char *snap_name, char *path, int len) 555 { 556 char *p; 557 zfs_handle_t *zhp; 558 char mp[ZFS_MAXPROPLEN]; 559 560 if ((p = strrchr(snap_name, '@')) == NULL) 561 return (Z_ERR); 562 563 /* Get the file system name from the snap_name. */ 564 *p = '\0'; 565 zhp = zfs_open(g_zfs, snap_name, ZFS_TYPE_DATASET); 566 *p = '@'; 567 if (zhp == NULL) 568 return (Z_ERR); 569 570 /* Get the file system mount point. */ 571 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mp, sizeof (mp), NULL, NULL, 572 0, B_FALSE) != 0) { 573 zfs_close(zhp); 574 return (Z_ERR); 575 } 576 zfs_close(zhp); 577 578 p++; 579 if (snprintf(path, len, "%s/.zfs/snapshot/%s", mp, p) >= len) 580 return (Z_ERR); 581 582 return (Z_OK); 583 } 584 585 /* 586 * This callback function is used to iterate through a snapshot's dependencies 587 * to find a filesystem that is a direct clone of the snapshot being iterated. 588 */ 589 static int 590 get_direct_clone(zfs_handle_t *zhp, void *data) 591 { 592 clone_data_t *cd = data; 593 char origin[ZFS_MAXNAMELEN]; 594 char ds_path[ZFS_MAXNAMELEN]; 595 596 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) { 597 zfs_close(zhp); 598 return (0); 599 } 600 601 (void) strlcpy(ds_path, zfs_get_name(zhp), sizeof (ds_path)); 602 603 /* Make sure this is a direct clone of the snapshot we're iterating. */ 604 if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, origin, sizeof (origin), NULL, 605 NULL, 0, B_FALSE) != 0 || strcmp(origin, cd->snapshot) != 0) { 606 zfs_close(zhp); 607 return (0); 608 } 609 610 if (cd->clone_zhp != NULL) 611 zfs_close(cd->clone_zhp); 612 613 cd->clone_zhp = zhp; 614 return (1); 615 } 616 617 /* 618 * A ZFS file system iterator call-back function used to determine the clone 619 * to promote. This function finds the youngest (i.e. last one taken) snapshot 620 * that has a clone. If found, it returns a reference to that clone in the 621 * callback data. 622 */ 623 static int 624 find_clone(zfs_handle_t *zhp, void *data) 625 { 626 clone_data_t *cd = data; 627 time_t snap_creation; 628 int zret = 0; 629 630 /* If snapshot has no clones, skip it */ 631 if (zfs_prop_get_int(zhp, ZFS_PROP_NUMCLONES) == 0) { 632 zfs_close(zhp); 633 return (0); 634 } 635 636 cd->snapshot = zfs_get_name(zhp); 637 638 /* Get the creation time of this snapshot */ 639 snap_creation = (time_t)zfs_prop_get_int(zhp, ZFS_PROP_CREATION); 640 641 /* 642 * If this snapshot's creation time is greater than (i.e. younger than) 643 * the current youngest snapshot found, iterate this snapshot to 644 * get the right clone. 645 */ 646 if (snap_creation >= cd->origin_creation) { 647 /* 648 * Iterate the dependents of this snapshot to find a clone 649 * that's a direct dependent. 650 */ 651 if ((zret = zfs_iter_dependents(zhp, B_FALSE, get_direct_clone, 652 cd)) == -1) { 653 zfs_close(zhp); 654 return (1); 655 } else if (zret == 1) { 656 /* 657 * Found a clone, update the origin_creation time 658 * in the callback data. 659 */ 660 cd->origin_creation = snap_creation; 661 } 662 } 663 664 zfs_close(zhp); 665 return (0); 666 } 667 668 /* 669 * A ZFS file system iterator call-back function used to remove standalone 670 * snapshots. 671 */ 672 /* ARGSUSED */ 673 static int 674 rm_snap(zfs_handle_t *zhp, void *data) 675 { 676 /* If snapshot has clones, something is wrong */ 677 if (zfs_prop_get_int(zhp, ZFS_PROP_NUMCLONES) != 0) { 678 zfs_close(zhp); 679 return (1); 680 } 681 682 if (zfs_unmount(zhp, NULL, 0) == 0) { 683 (void) zfs_destroy(zhp, B_FALSE); 684 } 685 686 zfs_close(zhp); 687 return (0); 688 } 689 690 /* 691 * A ZFS snapshot iterator call-back function which renames snapshots. 692 */ 693 static int 694 rename_snap(zfs_handle_t *zhp, void *data) 695 { 696 int res; 697 zfs_snapshot_data_t *cbp; 698 char template[ZFS_MAXNAMELEN]; 699 700 cbp = (zfs_snapshot_data_t *)data; 701 702 /* 703 * When renaming snapshots with the iterator, the iterator can see 704 * the same snapshot after we've renamed up in the namespace. To 705 * prevent this we check the count for the number of snapshots we have 706 * to rename and stop at that point. 707 */ 708 if (cbp->cntr >= cbp->num) { 709 zfs_close(zhp); 710 return (0); 711 } 712 713 if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) { 714 zfs_close(zhp); 715 return (0); 716 } 717 718 /* Only rename the snapshots we automatically generate when we clone. */ 719 if (strncmp(zfs_get_name(zhp), cbp->match_name, cbp->len) != 0) { 720 zfs_close(zhp); 721 return (0); 722 } 723 724 (void) snprintf(template, sizeof (template), "%s%d", cbp->match_name, 725 cbp->max++); 726 727 res = (zfs_rename(zhp, template, B_FALSE, B_FALSE) != 0); 728 if (res != 0) 729 (void) fprintf(stderr, gettext("failed to rename snapshot %s " 730 "to %s: %s\n"), zfs_get_name(zhp), template, 731 libzfs_error_description(g_zfs)); 732 733 cbp->cntr++; 734 735 zfs_close(zhp); 736 return (res); 737 } 738 739 /* 740 * Rename the source dataset's snapshots that are automatically generated when 741 * we clone a zone so that there won't be a name collision when we promote the 742 * cloned dataset. Once the snapshots have been renamed, then promote the 743 * clone. 744 * 745 * The snapshot rename process gets the highest number on the snapshot names 746 * (the format is zonename@SUNWzoneXX where XX are digits) on both the source 747 * and clone datasets, then renames the source dataset snapshots starting at 748 * the next number. 749 */ 750 static int 751 promote_clone(zfs_handle_t *src_zhp, zfs_handle_t *cln_zhp) 752 { 753 zfs_snapshot_data_t sd; 754 char nm[ZFS_MAXNAMELEN]; 755 char template[ZFS_MAXNAMELEN]; 756 757 (void) strlcpy(nm, zfs_get_name(cln_zhp), sizeof (nm)); 758 /* 759 * Start by getting the clone's snapshot max which we use 760 * during the rename of the original dataset's snapshots. 761 */ 762 (void) snprintf(template, sizeof (template), "%s@SUNWzone", nm); 763 sd.match_name = template; 764 sd.len = strlen(template); 765 sd.max = 0; 766 767 if (zfs_iter_snapshots(cln_zhp, get_snap_max, &sd) != 0) 768 return (Z_ERR); 769 770 /* 771 * Now make sure the source's snapshot max is at least as high as 772 * the clone's snapshot max. 773 */ 774 (void) snprintf(template, sizeof (template), "%s@SUNWzone", 775 zfs_get_name(src_zhp)); 776 sd.match_name = template; 777 sd.len = strlen(template); 778 sd.num = 0; 779 780 if (zfs_iter_snapshots(src_zhp, get_snap_max, &sd) != 0) 781 return (Z_ERR); 782 783 /* 784 * Now rename the source dataset's snapshots so there's no 785 * conflict when we promote the clone. 786 */ 787 sd.max++; 788 sd.cntr = 0; 789 if (zfs_iter_snapshots(src_zhp, rename_snap, &sd) != 0) 790 return (Z_ERR); 791 792 /* close and reopen the clone dataset to get the latest info */ 793 zfs_close(cln_zhp); 794 if ((cln_zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM)) == NULL) 795 return (Z_ERR); 796 797 if (zfs_promote(cln_zhp) != 0) { 798 (void) fprintf(stderr, gettext("failed to promote %s: %s\n"), 799 nm, libzfs_error_description(g_zfs)); 800 return (Z_ERR); 801 } 802 803 zfs_close(cln_zhp); 804 return (Z_OK); 805 } 806 807 /* 808 * Promote the youngest clone. That clone will then become the origin of all 809 * of the other clones that were hanging off of the source dataset. 810 */ 811 int 812 promote_all_clones(zfs_handle_t *zhp) 813 { 814 clone_data_t cd; 815 char nm[ZFS_MAXNAMELEN]; 816 817 cd.clone_zhp = NULL; 818 cd.origin_creation = 0; 819 cd.snapshot = NULL; 820 821 if (zfs_iter_snapshots(zhp, find_clone, &cd) != 0) { 822 zfs_close(zhp); 823 return (Z_ERR); 824 } 825 826 /* Nothing to promote. */ 827 if (cd.clone_zhp == NULL) 828 return (Z_OK); 829 830 /* Found the youngest clone to promote. Promote it. */ 831 if (promote_clone(zhp, cd.clone_zhp) != 0) { 832 zfs_close(cd.clone_zhp); 833 zfs_close(zhp); 834 return (Z_ERR); 835 } 836 837 /* close and reopen the main dataset to get the latest info */ 838 (void) strlcpy(nm, zfs_get_name(zhp), sizeof (nm)); 839 zfs_close(zhp); 840 if ((zhp = zfs_open(g_zfs, nm, ZFS_TYPE_FILESYSTEM)) == NULL) 841 return (Z_ERR); 842 843 return (Z_OK); 844 } 845 846 /* 847 * Clone a pre-existing ZFS snapshot, either by making a direct ZFS clone, if 848 * possible, or by copying the data from the snapshot to the zonepath. 849 */ 850 int 851 clone_snapshot_zfs(char *snap_name, char *zonepath, char *validatesnap) 852 { 853 int err = Z_OK; 854 char clone_name[MAXPATHLEN]; 855 char snap_path[MAXPATHLEN]; 856 857 if (snap2path(snap_name, snap_path, sizeof (snap_path)) != Z_OK) { 858 (void) fprintf(stderr, gettext("unable to find path for %s.\n"), 859 snap_name); 860 return (Z_ERR); 861 } 862 863 if (validate_snapshot(snap_name, snap_path, validatesnap) != Z_OK) 864 return (Z_NO_ENTRY); 865 866 /* 867 * The zonepath cannot be ZFS cloned, try to copy the data from 868 * within the snapshot to the zonepath. 869 */ 870 if (path2name(zonepath, clone_name, sizeof (clone_name)) != Z_OK) { 871 if ((err = clone_copy(snap_path, zonepath)) == Z_OK) 872 if (clean_out_clone() != Z_OK) 873 (void) fprintf(stderr, 874 gettext("could not remove the " 875 "software inventory from %s\n"), zonepath); 876 877 return (err); 878 } 879 880 if ((err = clone_snap(snap_name, clone_name)) != Z_OK) { 881 if (err != Z_NO_ENTRY) { 882 /* 883 * Cloning the snapshot failed. Fall back to trying 884 * to install the zone by copying from the snapshot. 885 */ 886 if ((err = clone_copy(snap_path, zonepath)) == Z_OK) 887 if (clean_out_clone() != Z_OK) 888 (void) fprintf(stderr, 889 gettext("could not remove the " 890 "software inventory from %s\n"), 891 zonepath); 892 } else { 893 /* 894 * The snapshot is unusable for some reason so restore 895 * the zone state to configured since we were unable to 896 * actually do anything about getting the zone 897 * installed. 898 */ 899 int tmp; 900 901 if ((tmp = zone_set_state(target_zone, 902 ZONE_STATE_CONFIGURED)) != Z_OK) { 903 errno = tmp; 904 zperror2(target_zone, 905 gettext("could not set state")); 906 } 907 } 908 } 909 910 return (err); 911 } 912 913 /* 914 * Attempt to clone a source_zone to a target zonepath by using a ZFS clone. 915 */ 916 int 917 clone_zfs(char *source_zonepath, char *zonepath, char *presnapbuf, 918 char *postsnapbuf) 919 { 920 zfs_handle_t *zhp; 921 char clone_name[MAXPATHLEN]; 922 char snap_name[MAXPATHLEN]; 923 924 /* 925 * Try to get a zfs handle for the source_zonepath. If this fails 926 * the source_zonepath is not ZFS so return an error. 927 */ 928 if ((zhp = mount2zhandle(source_zonepath)) == NULL) 929 return (Z_ERR); 930 931 /* 932 * Check if there is a file system already mounted on zonepath. If so, 933 * we can't clone to the path so we should fall back to copying. 934 */ 935 if (is_mountpnt(zonepath)) { 936 zfs_close(zhp); 937 (void) fprintf(stderr, 938 gettext("A file system is already mounted on %s,\n" 939 "preventing use of a ZFS clone.\n"), zonepath); 940 return (Z_ERR); 941 } 942 943 /* 944 * Instead of using path2name to get the clone name from the zonepath, 945 * we could generate a name from the source zone ZFS name. However, 946 * this would mean we would create the clone under the ZFS fs of the 947 * source instead of what the zonepath says. For example, 948 * 949 * source_zonepath zonepath 950 * /pl/zones/dev/z1 /pl/zones/deploy/z2 951 * 952 * We don't want the clone to be under "dev", we want it under 953 * "deploy", so that we can leverage the normal attribute inheritance 954 * that ZFS provides in the fs hierarchy. 955 */ 956 if (path2name(zonepath, clone_name, sizeof (clone_name)) != Z_OK) { 957 zfs_close(zhp); 958 return (Z_ERR); 959 } 960 961 if (take_snapshot(zhp, snap_name, sizeof (snap_name), presnapbuf, 962 postsnapbuf) != Z_OK) { 963 zfs_close(zhp); 964 return (Z_ERR); 965 } 966 zfs_close(zhp); 967 968 if (clone_snap(snap_name, clone_name) != Z_OK) { 969 /* Clean up the snapshot we just took. */ 970 if ((zhp = zfs_open(g_zfs, snap_name, ZFS_TYPE_SNAPSHOT)) 971 != NULL) { 972 if (zfs_unmount(zhp, NULL, 0) == 0) 973 (void) zfs_destroy(zhp, B_FALSE); 974 zfs_close(zhp); 975 } 976 977 return (Z_ERR); 978 } 979 980 (void) printf(gettext("Instead of copying, a ZFS clone has been " 981 "created for this zone.\n")); 982 983 return (Z_OK); 984 } 985 986 /* 987 * Attempt to create a ZFS file system for the specified zonepath. 988 * We either will successfully create a ZFS file system and get it mounted 989 * on the zonepath or we don't. The caller doesn't care since a regular 990 * directory is used for the zonepath if no ZFS file system is mounted there. 991 */ 992 void 993 create_zfs_zonepath(char *zonepath) 994 { 995 zfs_handle_t *zhp; 996 char zfs_name[MAXPATHLEN]; 997 nvlist_t *props = NULL; 998 999 if (path2name(zonepath, zfs_name, sizeof (zfs_name)) != Z_OK) 1000 return; 1001 1002 /* Check if the dataset already exists. */ 1003 if ((zhp = zfs_open(g_zfs, zfs_name, ZFS_TYPE_DATASET)) != NULL) { 1004 zfs_close(zhp); 1005 return; 1006 } 1007 1008 /* 1009 * We turn off zfs SHARENFS and SHARESMB properties on the 1010 * zoneroot dataset in order to prevent the GZ from sharing 1011 * NGZ data by accident. 1012 */ 1013 if ((nvlist_alloc(&props, NV_UNIQUE_NAME, 0) != 0) || 1014 (nvlist_add_string(props, zfs_prop_to_name(ZFS_PROP_SHARENFS), 1015 "off") != 0) || 1016 (nvlist_add_string(props, zfs_prop_to_name(ZFS_PROP_SHARESMB), 1017 "off") != 0)) { 1018 if (props != NULL) 1019 nvlist_free(props); 1020 (void) fprintf(stderr, gettext("cannot create ZFS dataset %s: " 1021 "out of memory\n"), zfs_name); 1022 } 1023 1024 if (zfs_create(g_zfs, zfs_name, ZFS_TYPE_FILESYSTEM, props) != 0 || 1025 (zhp = zfs_open(g_zfs, zfs_name, ZFS_TYPE_DATASET)) == NULL) { 1026 (void) fprintf(stderr, gettext("cannot create ZFS dataset %s: " 1027 "%s\n"), zfs_name, libzfs_error_description(g_zfs)); 1028 nvlist_free(props); 1029 return; 1030 } 1031 1032 nvlist_free(props); 1033 1034 if (zfs_mount(zhp, NULL, 0) != 0) { 1035 (void) fprintf(stderr, gettext("cannot mount ZFS dataset %s: " 1036 "%s\n"), zfs_name, libzfs_error_description(g_zfs)); 1037 (void) zfs_destroy(zhp, B_FALSE); 1038 } else { 1039 if (chmod(zonepath, S_IRWXU) != 0) { 1040 (void) fprintf(stderr, gettext("file system %s " 1041 "successfully created, but chmod %o failed: %s\n"), 1042 zfs_name, S_IRWXU, strerror(errno)); 1043 (void) destroy_zfs(zonepath); 1044 } else { 1045 (void) printf(gettext("A ZFS file system has been " 1046 "created for this zone.\n")); 1047 } 1048 } 1049 1050 zfs_close(zhp); 1051 } 1052 1053 /* 1054 * If the zonepath is a ZFS file system, attempt to destroy it. We return Z_OK 1055 * if we were able to zfs_destroy the zonepath, otherwise we return Z_ERR 1056 * which means the caller should clean up the zonepath in the traditional 1057 * way. 1058 */ 1059 int 1060 destroy_zfs(char *zonepath) 1061 { 1062 zfs_handle_t *zhp; 1063 boolean_t is_clone = B_FALSE; 1064 char origin[ZFS_MAXPROPLEN]; 1065 1066 if ((zhp = mount2zhandle(zonepath)) == NULL) 1067 return (Z_ERR); 1068 1069 if (promote_all_clones(zhp) != 0) 1070 return (Z_ERR); 1071 1072 /* Now cleanup any snapshots remaining. */ 1073 if (zfs_iter_snapshots(zhp, rm_snap, NULL) != 0) { 1074 zfs_close(zhp); 1075 return (Z_ERR); 1076 } 1077 1078 /* 1079 * We can't destroy the file system if it has still has dependents. 1080 * There shouldn't be any at this point, but we'll double check. 1081 */ 1082 if (zfs_iter_dependents(zhp, B_TRUE, has_dependent, NULL) != 0) { 1083 (void) fprintf(stderr, gettext("zfs destroy %s failed: the " 1084 "dataset still has dependents\n"), zfs_get_name(zhp)); 1085 zfs_close(zhp); 1086 return (Z_ERR); 1087 } 1088 1089 /* 1090 * This might be a clone. Try to get the snapshot so we can attempt 1091 * to destroy that as well. 1092 */ 1093 if (zfs_prop_get(zhp, ZFS_PROP_ORIGIN, origin, sizeof (origin), NULL, 1094 NULL, 0, B_FALSE) == 0) 1095 is_clone = B_TRUE; 1096 1097 if (zfs_unmount(zhp, NULL, 0) != 0) { 1098 (void) fprintf(stderr, gettext("zfs unmount %s failed: %s\n"), 1099 zfs_get_name(zhp), libzfs_error_description(g_zfs)); 1100 zfs_close(zhp); 1101 return (Z_ERR); 1102 } 1103 1104 if (zfs_destroy(zhp, B_FALSE) != 0) { 1105 /* 1106 * If the destroy fails for some reason, try to remount 1107 * the file system so that we can use "rm -rf" to clean up 1108 * instead. 1109 */ 1110 (void) fprintf(stderr, gettext("zfs destroy %s failed: %s\n"), 1111 zfs_get_name(zhp), libzfs_error_description(g_zfs)); 1112 (void) zfs_mount(zhp, NULL, 0); 1113 zfs_close(zhp); 1114 return (Z_ERR); 1115 } 1116 1117 /* 1118 * If the zone has ever been moved then the mountpoint dir will not be 1119 * cleaned up by the zfs_destroy(). To handle this case try to clean 1120 * it up now but don't worry if it fails, that will be normal. 1121 */ 1122 (void) rmdir(zonepath); 1123 1124 (void) printf(gettext("The ZFS file system for this zone has been " 1125 "destroyed.\n")); 1126 1127 if (is_clone) { 1128 zfs_handle_t *ohp; 1129 1130 /* 1131 * Try to clean up the snapshot that the clone was taken from. 1132 */ 1133 if ((ohp = zfs_open(g_zfs, origin, 1134 ZFS_TYPE_SNAPSHOT)) != NULL) { 1135 if (zfs_iter_dependents(ohp, B_TRUE, has_dependent, 1136 NULL) == 0 && zfs_unmount(ohp, NULL, 0) == 0) 1137 (void) zfs_destroy(ohp, B_FALSE); 1138 zfs_close(ohp); 1139 } 1140 } 1141 1142 zfs_close(zhp); 1143 return (Z_OK); 1144 } 1145 1146 /* 1147 * Return true if the path is its own zfs file system. We determine this 1148 * by stat-ing the path to see if it is zfs and stat-ing the parent to see 1149 * if it is a different fs. 1150 */ 1151 boolean_t 1152 is_zonepath_zfs(char *zonepath) 1153 { 1154 int res; 1155 char *path; 1156 char *parent; 1157 struct statvfs64 buf1, buf2; 1158 1159 if (statvfs64(zonepath, &buf1) != 0) 1160 return (B_FALSE); 1161 1162 if (strcmp(buf1.f_basetype, "zfs") != 0) 1163 return (B_FALSE); 1164 1165 if ((path = strdup(zonepath)) == NULL) 1166 return (B_FALSE); 1167 1168 parent = dirname(path); 1169 res = statvfs64(parent, &buf2); 1170 free(path); 1171 1172 if (res != 0) 1173 return (B_FALSE); 1174 1175 if (buf1.f_fsid == buf2.f_fsid) 1176 return (B_FALSE); 1177 1178 return (B_TRUE); 1179 } 1180 1181 /* 1182 * Implement the fast move of a ZFS file system by simply updating the 1183 * mountpoint. Since it is file system already, we don't have the 1184 * issue of cross-file system copying. 1185 */ 1186 int 1187 move_zfs(char *zonepath, char *new_zonepath) 1188 { 1189 int ret = Z_ERR; 1190 zfs_handle_t *zhp; 1191 1192 if ((zhp = mount2zhandle(zonepath)) == NULL) 1193 return (Z_ERR); 1194 1195 if (zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 1196 new_zonepath) == 0) { 1197 /* 1198 * Clean up the old mount point. We ignore any failure since 1199 * the zone is already successfully mounted on the new path. 1200 */ 1201 (void) rmdir(zonepath); 1202 ret = Z_OK; 1203 } 1204 1205 zfs_close(zhp); 1206 1207 return (ret); 1208 } 1209 1210 /* 1211 * Validate that the given dataset exists on the system, and that neither it nor 1212 * its children are zvols. 1213 * 1214 * Note that we don't do anything with the 'zoned' property here. All 1215 * management is done in zoneadmd when the zone is actually rebooted. This 1216 * allows us to automatically set the zoned property even when a zone is 1217 * rebooted by the administrator. 1218 */ 1219 int 1220 verify_datasets(zone_dochandle_t handle) 1221 { 1222 int return_code = Z_OK; 1223 struct zone_dstab dstab; 1224 zfs_handle_t *zhp; 1225 char propbuf[ZFS_MAXPROPLEN]; 1226 char source[ZFS_MAXNAMELEN]; 1227 zprop_source_t srctype; 1228 1229 if (zonecfg_setdsent(handle) != Z_OK) { 1230 /* 1231 * TRANSLATION_NOTE 1232 * zfs and dataset are literals that should not be translated. 1233 */ 1234 (void) fprintf(stderr, gettext("could not verify zfs datasets: " 1235 "unable to enumerate datasets\n")); 1236 return (Z_ERR); 1237 } 1238 1239 while (zonecfg_getdsent(handle, &dstab) == Z_OK) { 1240 1241 if ((zhp = zfs_open(g_zfs, dstab.zone_dataset_name, 1242 ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME)) == NULL) { 1243 (void) fprintf(stderr, gettext("could not verify zfs " 1244 "dataset %s: %s\n"), dstab.zone_dataset_name, 1245 libzfs_error_description(g_zfs)); 1246 return_code = Z_ERR; 1247 continue; 1248 } 1249 1250 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, propbuf, 1251 sizeof (propbuf), &srctype, source, 1252 sizeof (source), 0) == 0 && 1253 (srctype == ZPROP_SRC_INHERITED)) { 1254 (void) fprintf(stderr, gettext("could not verify zfs " 1255 "dataset %s: mountpoint cannot be inherited\n"), 1256 dstab.zone_dataset_name); 1257 return_code = Z_ERR; 1258 zfs_close(zhp); 1259 continue; 1260 } 1261 1262 if (zfs_get_type(zhp) == ZFS_TYPE_VOLUME) { 1263 (void) fprintf(stderr, gettext("cannot verify zfs " 1264 "dataset %s: volumes cannot be specified as a " 1265 "zone dataset resource\n"), 1266 dstab.zone_dataset_name); 1267 return_code = Z_ERR; 1268 } 1269 1270 if (zfs_iter_children(zhp, check_zvol, NULL) != 0) 1271 return_code = Z_ERR; 1272 1273 zfs_close(zhp); 1274 } 1275 (void) zonecfg_enddsent(handle); 1276 1277 return (return_code); 1278 } 1279 1280 /* 1281 * Verify that the ZFS dataset exists, and its mountpoint 1282 * property is set to "legacy". 1283 */ 1284 int 1285 verify_fs_zfs(struct zone_fstab *fstab) 1286 { 1287 zfs_handle_t *zhp; 1288 char propbuf[ZFS_MAXPROPLEN]; 1289 1290 if ((zhp = zfs_open(g_zfs, fstab->zone_fs_special, 1291 ZFS_TYPE_DATASET)) == NULL) { 1292 (void) fprintf(stderr, gettext("could not verify fs %s: " 1293 "could not access zfs dataset '%s'\n"), 1294 fstab->zone_fs_dir, fstab->zone_fs_special); 1295 return (Z_ERR); 1296 } 1297 1298 if (zfs_get_type(zhp) != ZFS_TYPE_FILESYSTEM) { 1299 (void) fprintf(stderr, gettext("cannot verify fs %s: " 1300 "'%s' is not a file system\n"), 1301 fstab->zone_fs_dir, fstab->zone_fs_special); 1302 zfs_close(zhp); 1303 return (Z_ERR); 1304 } 1305 1306 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, propbuf, sizeof (propbuf), 1307 NULL, NULL, 0, 0) != 0 || strcmp(propbuf, "legacy") != 0) { 1308 (void) fprintf(stderr, gettext("could not verify fs %s: " 1309 "zfs '%s' mountpoint is not \"legacy\"\n"), 1310 fstab->zone_fs_dir, fstab->zone_fs_special); 1311 zfs_close(zhp); 1312 return (Z_ERR); 1313 } 1314 1315 zfs_close(zhp); 1316 return (Z_OK); 1317 } 1318 1319 /* 1320 * Destroy the specified mnttab structure that was created by mnttab_dup(). 1321 * NOTE: The structure's mnt_time field isn't freed. 1322 */ 1323 static void 1324 mnttab_destroy(struct mnttab *tabp) 1325 { 1326 assert(tabp != NULL); 1327 1328 free(tabp->mnt_mountp); 1329 free(tabp->mnt_special); 1330 free(tabp->mnt_fstype); 1331 free(tabp->mnt_mntopts); 1332 free(tabp); 1333 } 1334 1335 /* 1336 * Duplicate the specified mnttab structure. The mnt_mountp and mnt_time 1337 * fields aren't duplicated. This function returns a pointer to the new mnttab 1338 * structure or NULL if an error occurred. If an error occurs, then this 1339 * function sets errno to reflect the error. mnttab structures created by 1340 * this function should be destroyed via mnttab_destroy(). 1341 */ 1342 static struct mnttab * 1343 mnttab_dup(const struct mnttab *srcp) 1344 { 1345 struct mnttab *retval; 1346 1347 assert(srcp != NULL); 1348 1349 retval = (struct mnttab *)calloc(1, sizeof (*retval)); 1350 if (retval == NULL) { 1351 errno = ENOMEM; 1352 return (NULL); 1353 } 1354 if (srcp->mnt_special != NULL) { 1355 retval->mnt_special = strdup(srcp->mnt_special); 1356 if (retval->mnt_special == NULL) 1357 goto err; 1358 } 1359 if (srcp->mnt_fstype != NULL) { 1360 retval->mnt_fstype = strdup(srcp->mnt_fstype); 1361 if (retval->mnt_fstype == NULL) 1362 goto err; 1363 } 1364 retval->mnt_mntopts = (char *)malloc(MAX_MNTOPT_STR * sizeof (char)); 1365 if (retval->mnt_mntopts == NULL) 1366 goto err; 1367 if (srcp->mnt_mntopts != NULL) { 1368 if (strlcpy(retval->mnt_mntopts, srcp->mnt_mntopts, 1369 MAX_MNTOPT_STR * sizeof (char)) >= MAX_MNTOPT_STR * 1370 sizeof (char)) { 1371 mnttab_destroy(retval); 1372 errno = EOVERFLOW; /* similar to mount(2) behavior */ 1373 return (NULL); 1374 } 1375 } else { 1376 retval->mnt_mntopts[0] = '\0'; 1377 } 1378 return (retval); 1379 1380 err: 1381 mnttab_destroy(retval); 1382 errno = ENOMEM; 1383 return (NULL); 1384 } 1385 1386 /* 1387 * Determine whether the specified ZFS dataset's mountpoint property is set 1388 * to "legacy". If the specified dataset does not have a legacy mountpoint, 1389 * then the string pointer to which the mountpoint argument points is assigned 1390 * a dynamically-allocated string containing the dataset's mountpoint 1391 * property. If the dataset's mountpoint property is "legacy" or a libzfs 1392 * error occurs, then the string pointer to which the mountpoint argument 1393 * points isn't modified. 1394 * 1395 * This function returns B_TRUE if it doesn't encounter any fatal errors. 1396 * It returns B_FALSE if it encounters a fatal error and sets errno to the 1397 * appropriate error code. 1398 */ 1399 static boolean_t 1400 get_zfs_non_legacy_mountpoint(const char *dataset_name, char **mountpoint) 1401 { 1402 zfs_handle_t *zhp; 1403 char propbuf[ZFS_MAXPROPLEN]; 1404 1405 assert(dataset_name != NULL); 1406 assert(mountpoint != NULL); 1407 1408 if ((zhp = zfs_open(g_zfs, dataset_name, ZFS_TYPE_DATASET)) == NULL) { 1409 errno = EINVAL; 1410 return (B_FALSE); 1411 } 1412 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, propbuf, sizeof (propbuf), 1413 NULL, NULL, 0, 0) != 0) { 1414 zfs_close(zhp); 1415 errno = EINVAL; 1416 return (B_FALSE); 1417 } 1418 zfs_close(zhp); 1419 if (strcmp(propbuf, "legacy") != 0) { 1420 if ((*mountpoint = strdup(propbuf)) == NULL) { 1421 errno = ENOMEM; 1422 return (B_FALSE); 1423 } 1424 } 1425 return (B_TRUE); 1426 } 1427 1428 1429 /* 1430 * This zonecfg_find_mounts() callback records information about mounts of 1431 * interest in a zonepath. It also tallies the number of zone 1432 * root overlay mounts and the number of unexpected mounts found. 1433 * This function outputs errors using zerror() if it finds unexpected 1434 * mounts. cookiep should point to an initialized zone_mounts_t structure. 1435 * 1436 * This function returns zero on success and a nonzero value on failure. 1437 */ 1438 static int 1439 zone_mounts_cb(const struct mnttab *mountp, void *cookiep) 1440 { 1441 zone_mounts_t *mounts; 1442 const char *zone_mount_dir; 1443 1444 assert(mountp != NULL); 1445 assert(cookiep != NULL); 1446 1447 mounts = (zone_mounts_t *)cookiep; 1448 zone_mount_dir = mountp->mnt_mountp + mounts->zonepath_len; 1449 if (strcmp(zone_mount_dir, "/root") == 0) { 1450 /* 1451 * Check for an overlay mount. If we already detected a /root 1452 * mount, then the current mount must be an overlay mount. 1453 */ 1454 if (mounts->root_mnttab != NULL) { 1455 mounts->num_root_overlay_mounts++; 1456 return (0); 1457 } 1458 1459 /* 1460 * Store the root mount's mnttab information in the 1461 * zone_mounts_t structure for future use. 1462 */ 1463 if ((mounts->root_mnttab = mnttab_dup(mountp)) == NULL) { 1464 zperror(cmd_to_str(CMD_MOVE), B_FALSE); 1465 return (-1); 1466 } 1467 1468 /* 1469 * Determine if the filesystem is a ZFS filesystem with a 1470 * non-legacy mountpoint. If it is, then set the root 1471 * filesystem's mnttab's mnt_mountp field to a non-NULL 1472 * value, which will serve as a flag to indicate this special 1473 * condition. 1474 */ 1475 if (strcmp(mountp->mnt_fstype, MNTTYPE_ZFS) == 0 && 1476 get_zfs_non_legacy_mountpoint(mountp->mnt_special, 1477 &mounts->root_mnttab->mnt_mountp) != B_TRUE) { 1478 zperror(cmd_to_str(CMD_MOVE), B_FALSE); 1479 return (-1); 1480 } 1481 } else { 1482 /* 1483 * An unexpected mount was found. Notify the user. 1484 */ 1485 if (mounts->num_unexpected_mounts == 0) 1486 zerror(gettext("These file systems are mounted on " 1487 "subdirectories of %s.\n"), mounts->zonepath); 1488 mounts->num_unexpected_mounts++; 1489 (void) zfm_print(mountp, NULL); 1490 } 1491 return (0); 1492 } 1493 1494 /* 1495 * Initialize the specified zone_mounts_t structure for the given zonepath. 1496 * If this function succeeds, it returns zero and the specified zone_mounts_t 1497 * structure contains information about mounts in the specified zonepath. 1498 * The function returns a nonzero value if it fails. The zone_mounts_t 1499 * structure doesn't need be destroyed via zone_mounts_destroy() if this 1500 * function fails. 1501 */ 1502 int 1503 zone_mounts_init(zone_mounts_t *mounts, const char *zonepath) 1504 { 1505 assert(mounts != NULL); 1506 assert(zonepath != NULL); 1507 1508 bzero(mounts, sizeof (*mounts)); 1509 if ((mounts->zonepath = strdup(zonepath)) == NULL) { 1510 zerror(gettext("the process ran out of memory while checking " 1511 "for mounts in zonepath %s."), zonepath); 1512 return (-1); 1513 } 1514 mounts->zonepath_len = strlen(zonepath); 1515 if (zonecfg_find_mounts((char *)zonepath, zone_mounts_cb, mounts) == 1516 -1) { 1517 zerror(gettext("an error occurred while checking for mounts " 1518 "in zonepath %s."), zonepath); 1519 zone_mounts_destroy(mounts); 1520 return (-1); 1521 } 1522 return (0); 1523 } 1524 1525 /* 1526 * Destroy the memory used by the specified zone_mounts_t structure's fields. 1527 * This function doesn't free the memory occupied by the structure itself 1528 * (i.e., it doesn't free the parameter). 1529 */ 1530 void 1531 zone_mounts_destroy(zone_mounts_t *mounts) 1532 { 1533 assert(mounts != NULL); 1534 1535 free(mounts->zonepath); 1536 if (mounts->root_mnttab != NULL) 1537 mnttab_destroy(mounts->root_mnttab); 1538 } 1539 1540 /* 1541 * Mount a moving zone's root filesystem (if it had a root filesystem mount 1542 * prior to the move) using the specified zonepath. mounts should refer to 1543 * the zone_mounts_t structure describing the zone's mount information. 1544 * 1545 * This function returns zero if the mount succeeds and a nonzero value 1546 * if it doesn't. 1547 */ 1548 int 1549 zone_mount_rootfs(zone_mounts_t *mounts, const char *zonepath) 1550 { 1551 char zoneroot[MAXPATHLEN]; 1552 struct mnttab *mtab; 1553 int flags; 1554 1555 assert(mounts != NULL); 1556 assert(zonepath != NULL); 1557 1558 /* 1559 * If there isn't a root filesystem, then don't do anything. 1560 */ 1561 mtab = mounts->root_mnttab; 1562 if (mtab == NULL) 1563 return (0); 1564 1565 /* 1566 * Determine the root filesystem's new mountpoint. 1567 */ 1568 if (snprintf(zoneroot, sizeof (zoneroot), "%s/root", zonepath) >= 1569 sizeof (zoneroot)) { 1570 zerror(gettext("Zonepath %s is too long.\n"), zonepath); 1571 return (-1); 1572 } 1573 1574 /* 1575 * If the root filesystem is a non-legacy ZFS filesystem (i.e., if it's 1576 * mnt_mountp field is non-NULL), then make the filesystem's new 1577 * mount point its mountpoint property and mount the filesystem. 1578 */ 1579 if (mtab->mnt_mountp != NULL) { 1580 zfs_handle_t *zhp; 1581 1582 if ((zhp = zfs_open(g_zfs, mtab->mnt_special, 1583 ZFS_TYPE_DATASET)) == NULL) { 1584 zerror(gettext("could not get ZFS handle for the zone's" 1585 " root filesystem")); 1586 return (-1); 1587 } 1588 if (zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 1589 zoneroot) != 0) { 1590 zerror(gettext("could not modify zone's root " 1591 "filesystem's mountpoint property")); 1592 zfs_close(zhp); 1593 return (-1); 1594 } 1595 if (zfs_mount(zhp, mtab->mnt_mntopts, 0) != 0) { 1596 zerror(gettext("unable to mount zone root %s: %s"), 1597 zoneroot, libzfs_error_description(g_zfs)); 1598 if (zfs_prop_set(zhp, 1599 zfs_prop_to_name(ZFS_PROP_MOUNTPOINT), 1600 mtab->mnt_mountp) != 0) 1601 zerror(gettext("unable to restore zone's root " 1602 "filesystem's mountpoint property")); 1603 zfs_close(zhp); 1604 return (-1); 1605 } 1606 zfs_close(zhp); 1607 return (0); 1608 } 1609 1610 /* 1611 * The root filesystem is either a legacy-mounted ZFS filesystem or 1612 * a non-ZFS filesystem. Use mount(2) to mount the root filesystem. 1613 */ 1614 if (mtab->mnt_mntopts != NULL) 1615 flags = MS_OPTIONSTR; 1616 else 1617 flags = 0; 1618 if (mount(mtab->mnt_special, zoneroot, flags, mtab->mnt_fstype, NULL, 0, 1619 mtab->mnt_mntopts, MAX_MNTOPT_STR * sizeof (char)) != 0) { 1620 flags = errno; 1621 zerror(gettext("unable to mount zone root %s: %s"), zoneroot, 1622 strerror(flags)); 1623 return (-1); 1624 } 1625 return (0); 1626 } 1627 1628 /* 1629 * Unmount a moving zone's root filesystem (if such a mount exists) using the 1630 * specified zonepath. mounts should refer to the zone_mounts_t structure 1631 * describing the zone's mount information. If force is B_TRUE, then if the 1632 * unmount fails, then the function will try to forcibly unmount the zone's root 1633 * filesystem. 1634 * 1635 * This function returns zero if the unmount (forced or otherwise) succeeds; 1636 * otherwise, it returns a nonzero value. 1637 */ 1638 int 1639 zone_unmount_rootfs(zone_mounts_t *mounts, const char *zonepath, 1640 boolean_t force) 1641 { 1642 char zoneroot[MAXPATHLEN]; 1643 struct mnttab *mtab; 1644 int err; 1645 1646 assert(mounts != NULL); 1647 assert(zonepath != NULL); 1648 1649 /* 1650 * If there isn't a root filesystem, then don't do anything. 1651 */ 1652 mtab = mounts->root_mnttab; 1653 if (mtab == NULL) 1654 return (0); 1655 1656 /* 1657 * Determine the root filesystem's mountpoint. 1658 */ 1659 if (snprintf(zoneroot, sizeof (zoneroot), "%s/root", zonepath) >= 1660 sizeof (zoneroot)) { 1661 zerror(gettext("Zonepath %s is too long.\n"), zonepath); 1662 return (-1); 1663 } 1664 1665 /* 1666 * If the root filesystem is a non-legacy ZFS fileystem, then unmount 1667 * the filesystem via libzfs. 1668 */ 1669 if (mtab->mnt_mountp != NULL) { 1670 zfs_handle_t *zhp; 1671 1672 if ((zhp = zfs_open(g_zfs, mtab->mnt_special, 1673 ZFS_TYPE_DATASET)) == NULL) { 1674 zerror(gettext("could not get ZFS handle for the zone's" 1675 " root filesystem")); 1676 return (-1); 1677 } 1678 if (zfs_unmount(zhp, zoneroot, 0) != 0) { 1679 if (force && zfs_unmount(zhp, zoneroot, MS_FORCE) == 1680 0) { 1681 zfs_close(zhp); 1682 return (0); 1683 } 1684 zerror(gettext("unable to unmount zone root %s: %s"), 1685 zoneroot, libzfs_error_description(g_zfs)); 1686 zfs_close(zhp); 1687 return (-1); 1688 } 1689 zfs_close(zhp); 1690 return (0); 1691 } 1692 1693 /* 1694 * Use umount(2) to unmount the root filesystem. If this fails, then 1695 * forcibly unmount it if the force flag is set. 1696 */ 1697 if (umount(zoneroot) != 0) { 1698 if (force && umount2(zoneroot, MS_FORCE) == 0) 1699 return (0); 1700 err = errno; 1701 zerror(gettext("unable to unmount zone root %s: %s"), zoneroot, 1702 strerror(err)); 1703 return (-1); 1704 } 1705 return (0); 1706 } 1707 1708 int 1709 init_zfs(void) 1710 { 1711 if ((g_zfs = libzfs_init()) == NULL) { 1712 (void) fprintf(stderr, gettext("failed to initialize ZFS " 1713 "library\n")); 1714 return (Z_ERR); 1715 } 1716 1717 return (Z_OK); 1718 } 1719