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