Print this page
*** NO COMMENTS ***


   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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
  27  */
  28 
  29 /*
  30  * System includes
  31  */
  32 #include <assert.h>
  33 #include <errno.h>

  34 #include <libintl.h>
  35 #include <libnvpair.h>
  36 #include <libzfs.h>
  37 #include <stdio.h>
  38 #include <stdlib.h>
  39 #include <string.h>
  40 #include <sys/mntent.h>
  41 #include <sys/mnttab.h>
  42 #include <sys/mount.h>
  43 #include <sys/stat.h>
  44 #include <sys/types.h>
  45 #include <sys/vfstab.h>
  46 #include <sys/zone.h>
  47 #include <sys/mkdev.h>
  48 #include <unistd.h>
  49 
  50 #include <libbe.h>
  51 #include <libbe_priv.h>
  52 
  53 #define BE_TMP_MNTPNT           "/tmp/.be.XXXXXX"


 309                 return (ret);
 310         }
 311 
 312         /*
 313          * If altroot not provided, create a temporary alternate root
 314          * to mount on
 315          */
 316         if (*altroot == NULL) {
 317                 if ((ret = be_make_tmp_mountpoint(&tmp_altroot))
 318                     != BE_SUCCESS) {
 319                         be_print_err(gettext("be_mount: failed to "
 320                             "make temporary mountpoint\n"));
 321                         ZFS_CLOSE(zhp);
 322                         return (ret);
 323                 }
 324                 gen_tmp_altroot = B_TRUE;
 325         } else {
 326                 tmp_altroot = *altroot;
 327         }
 328 




 329         /* Mount the BE's root file system */

 330         if ((ret = be_mount_root(zhp, tmp_altroot)) != BE_SUCCESS) {
 331                 be_print_err(gettext("be_mount: failed to "
 332                     "mount BE root file system\n"));
 333                 if (gen_tmp_altroot)
 334                         free(tmp_altroot);
 335                 ZFS_CLOSE(zhp);
 336                 return (ret);
 337         }










 338 
 339         /* Iterate through BE's children filesystems */
 340         if ((err = zfs_iter_filesystems(zhp, be_mount_callback,
 341             tmp_altroot)) != 0) {
 342                 be_print_err(gettext("be_mount: failed to "
 343                     "mount BE (%s) on %s\n"), bt.obe_name, tmp_altroot);
 344                 if (gen_tmp_altroot)
 345                         free(tmp_altroot);
 346                 ZFS_CLOSE(zhp);
 347                 return (err);
 348         }
 349 
 350         md.altroot = tmp_altroot;
 351         md.shared_fs = flags & BE_MOUNT_FLAG_SHARED_FS;
 352         md.shared_rw = flags & BE_MOUNT_FLAG_SHARED_RW;
 353 
 354         /*
 355          * Mount shared file systems if mount flag says so.
 356          */
 357         if (md.shared_fs) {
 358                 /*
 359                  * Mount all ZFS file systems not under the BE's root dataset
 360                  */
 361                 (void) zpool_iter(g_zfs, zpool_shared_fs_callback, &md);
 362 
 363                 /* TODO: Mount all non-ZFS file systems - Not supported yet */
 364         }
 365 
 366         /*
 367          * If we're in the global zone and the global zone has a valid uuid,
 368          * mount all supported non-global zones.
 369          */
 370         if (getzoneid() == GLOBAL_ZONEID &&
 371             !(flags & BE_MOUNT_FLAG_NO_ZONES) &&
 372             be_get_uuid(bt.obe_root_ds, &uu) == BE_SUCCESS) {
 373                 if ((ret = be_mount_zones(zhp, &md)) != BE_SUCCESS) {


 511         /* TODO: Unmount all non-ZFS file systems - Not supported yet */
 512 
 513         /* Unmount all ZFS file systems not under the BE root dataset */
 514         if ((ret = unmount_shared_fs(&ud)) != BE_SUCCESS) {
 515                 be_print_err(gettext("be_unmount: failed to "
 516                     "unmount shared file systems\n"));
 517                 ZFS_CLOSE(zhp);
 518                 return (ret);
 519         }
 520 
 521         /* Unmount all children datasets under the BE's root dataset */
 522         if ((zret = zfs_iter_filesystems(zhp, be_unmount_callback,
 523             &ud)) != 0) {
 524                 be_print_err(gettext("be_unmount: failed to "
 525                     "unmount BE (%s)\n"), bt.obe_name);
 526                 ZFS_CLOSE(zhp);
 527                 return (zret);
 528         }
 529 
 530         /* Unmount this BE's root filesystem */

 531         if ((ret = be_unmount_root(zhp, &ud)) != BE_SUCCESS) {
 532                 ZFS_CLOSE(zhp);
 533                 return (ret);
 534         }






 535 
 536         ZFS_CLOSE(zhp);
 537 
 538         return (BE_SUCCESS);
 539 }
 540 
 541 /*
 542  * Function:    be_mount_zone_root
 543  * Description: Mounts the zone root dataset for a zone.
 544  * Parameters:
 545  *              zfs - zfs_handle_t pointer to zone root dataset
 546  *              md - be_mount_data_t pointer to data for zone to be mounted
 547  * Returns:
 548  *              BE_SUCCESS - Success
 549  *              be_errno_t - Failure
 550  * Scope:
 551  *              Semi-private (library wide use only)
 552  */
 553 int
 554 be_mount_zone_root(zfs_handle_t *zhp, be_mount_data_t *md)
 555 {

 556         char    mountpoint[MAXPATHLEN];
 557         int     err = 0;
 558 
 559         /* Get mountpoint property of dataset */
 560         if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
 561             sizeof (mountpoint), NULL, NULL, 0, B_FALSE) != 0) {
 562                 be_print_err(gettext("be_mount_zone_root: failed to "
 563                     "get mountpoint property for %s: %s\n"), zfs_get_name(zhp),
 564                     libzfs_error_description(g_zfs));
 565                 return (zfs_err_to_be_err(g_zfs));
 566         }
 567 
 568         /*
 569          * Make sure zone's root dataset is set to 'legacy'.  This is
 570          * currently a requirement in this implementation of zones
 571          * support.
 572          */
 573         if (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0) {
 574                 be_print_err(gettext("be_mount_zone_root: "
 575                     "zone root dataset mountpoint is not 'legacy'\n"));
 576                 return (BE_ERR_ZONE_ROOT_NOT_LEGACY);
 577         }
 578 










 579         /*
 580          * Legacy mount the zone root dataset.
 581          *
 582          * As a workaround for 6176743, we mount the zone's root with the
 583          * MS_OVERLAY option in case an alternate BE is mounted, and we're
 584          * mounting the root for the zone from the current BE here.  When an
 585          * alternate BE is mounted, it ties up the zone's zoneroot directory
 586          * for the current BE since the zone's zonepath is loopback mounted
 587          * from the current BE.
 588          *
 589          * TODO: The MS_OVERLAY option needs to be removed when 6176743
 590          * is fixed.
 591          */
 592         if (mount(zfs_get_name(zhp), md->altroot, MS_OVERLAY, MNTTYPE_ZFS,
 593             NULL, 0, NULL, 0) != 0) {
 594                 err = errno;
 595                 be_print_err(gettext("be_mount_zone_root: failed to "
 596                     "legacy mount zone root dataset (%s) at %s\n"),
 597                     zfs_get_name(zhp), md->altroot);
 598                 return (errno_to_be_err(err));




   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) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 /*
  26  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  27  */
  28 
  29 /*
  30  * System includes
  31  */
  32 #include <assert.h>
  33 #include <errno.h>
  34 #include <libgen.h>
  35 #include <libintl.h>
  36 #include <libnvpair.h>
  37 #include <libzfs.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <string.h>
  41 #include <sys/mntent.h>
  42 #include <sys/mnttab.h>
  43 #include <sys/mount.h>
  44 #include <sys/stat.h>
  45 #include <sys/types.h>
  46 #include <sys/vfstab.h>
  47 #include <sys/zone.h>
  48 #include <sys/mkdev.h>
  49 #include <unistd.h>
  50 
  51 #include <libbe.h>
  52 #include <libbe_priv.h>
  53 
  54 #define BE_TMP_MNTPNT           "/tmp/.be.XXXXXX"


 310                 return (ret);
 311         }
 312 
 313         /*
 314          * If altroot not provided, create a temporary alternate root
 315          * to mount on
 316          */
 317         if (*altroot == NULL) {
 318                 if ((ret = be_make_tmp_mountpoint(&tmp_altroot))
 319                     != BE_SUCCESS) {
 320                         be_print_err(gettext("be_mount: failed to "
 321                             "make temporary mountpoint\n"));
 322                         ZFS_CLOSE(zhp);
 323                         return (ret);
 324                 }
 325                 gen_tmp_altroot = B_TRUE;
 326         } else {
 327                 tmp_altroot = *altroot;
 328         }
 329 
 330         md.altroot = tmp_altroot;
 331         md.shared_fs = flags & BE_MOUNT_FLAG_SHARED_FS;
 332         md.shared_rw = flags & BE_MOUNT_FLAG_SHARED_RW;
 333 
 334         /* Mount the BE's root file system */
 335         if (getzoneid() == GLOBAL_ZONEID) {
 336                 if ((ret = be_mount_root(zhp, tmp_altroot)) != BE_SUCCESS) {
 337                         be_print_err(gettext("be_mount: failed to "
 338                             "mount BE root file system\n"));
 339                         if (gen_tmp_altroot)
 340                                 free(tmp_altroot);
 341                         ZFS_CLOSE(zhp);
 342                         return (ret);
 343                 }
 344         } else {
 345                 /* Legacy mount the zone root dataset */
 346                 if ((ret = be_mount_zone_root(zhp, &md)) != BE_SUCCESS) {
 347                         be_print_err(gettext("be_mount: failed to "
 348                             "mount BE zone root file system\n"));
 349                         free(md.altroot);
 350                         ZFS_CLOSE(zhp);
 351                         return (ret);
 352                 }
 353         }
 354 
 355         /* Iterate through BE's children filesystems */
 356         if ((err = zfs_iter_filesystems(zhp, be_mount_callback,
 357             tmp_altroot)) != 0) {
 358                 be_print_err(gettext("be_mount: failed to "
 359                     "mount BE (%s) on %s\n"), bt.obe_name, tmp_altroot);
 360                 if (gen_tmp_altroot)
 361                         free(tmp_altroot);
 362                 ZFS_CLOSE(zhp);
 363                 return (err);
 364         }
 365 




 366         /*
 367          * Mount shared file systems if mount flag says so.
 368          */
 369         if (md.shared_fs) {
 370                 /*
 371                  * Mount all ZFS file systems not under the BE's root dataset
 372                  */
 373                 (void) zpool_iter(g_zfs, zpool_shared_fs_callback, &md);
 374 
 375                 /* TODO: Mount all non-ZFS file systems - Not supported yet */
 376         }
 377 
 378         /*
 379          * If we're in the global zone and the global zone has a valid uuid,
 380          * mount all supported non-global zones.
 381          */
 382         if (getzoneid() == GLOBAL_ZONEID &&
 383             !(flags & BE_MOUNT_FLAG_NO_ZONES) &&
 384             be_get_uuid(bt.obe_root_ds, &uu) == BE_SUCCESS) {
 385                 if ((ret = be_mount_zones(zhp, &md)) != BE_SUCCESS) {


 523         /* TODO: Unmount all non-ZFS file systems - Not supported yet */
 524 
 525         /* Unmount all ZFS file systems not under the BE root dataset */
 526         if ((ret = unmount_shared_fs(&ud)) != BE_SUCCESS) {
 527                 be_print_err(gettext("be_unmount: failed to "
 528                     "unmount shared file systems\n"));
 529                 ZFS_CLOSE(zhp);
 530                 return (ret);
 531         }
 532 
 533         /* Unmount all children datasets under the BE's root dataset */
 534         if ((zret = zfs_iter_filesystems(zhp, be_unmount_callback,
 535             &ud)) != 0) {
 536                 be_print_err(gettext("be_unmount: failed to "
 537                     "unmount BE (%s)\n"), bt.obe_name);
 538                 ZFS_CLOSE(zhp);
 539                 return (zret);
 540         }
 541 
 542         /* Unmount this BE's root filesystem */
 543         if (getzoneid() == GLOBAL_ZONEID) {
 544                 if ((ret = be_unmount_root(zhp, &ud)) != BE_SUCCESS) {
 545                         ZFS_CLOSE(zhp);
 546                         return (ret);
 547                 }
 548         } else {
 549                 if ((ret = be_unmount_zone_root(zhp, &ud)) != BE_SUCCESS) {
 550                         ZFS_CLOSE(zhp);
 551                         return (ret);
 552                 }
 553         }
 554 
 555         ZFS_CLOSE(zhp);
 556 
 557         return (BE_SUCCESS);
 558 }
 559 
 560 /*
 561  * Function:    be_mount_zone_root
 562  * Description: Mounts the zone root dataset for a zone.
 563  * Parameters:
 564  *              zfs - zfs_handle_t pointer to zone root dataset
 565  *              md - be_mount_data_t pointer to data for zone to be mounted
 566  * Returns:
 567  *              BE_SUCCESS - Success
 568  *              be_errno_t - Failure
 569  * Scope:
 570  *              Semi-private (library wide use only)
 571  */
 572 int
 573 be_mount_zone_root(zfs_handle_t *zhp, be_mount_data_t *md)
 574 {
 575         struct stat buf;
 576         char    mountpoint[MAXPATHLEN];
 577         int     err = 0;
 578 
 579         /* Get mountpoint property of dataset */
 580         if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, mountpoint,
 581             sizeof (mountpoint), NULL, NULL, 0, B_FALSE) != 0) {
 582                 be_print_err(gettext("be_mount_zone_root: failed to "
 583                     "get mountpoint property for %s: %s\n"), zfs_get_name(zhp),
 584                     libzfs_error_description(g_zfs));
 585                 return (zfs_err_to_be_err(g_zfs));
 586         }
 587 
 588         /*
 589          * Make sure zone's root dataset is set to 'legacy'.  This is
 590          * currently a requirement in this implementation of zones
 591          * support.
 592          */
 593         if (strcmp(mountpoint, ZFS_MOUNTPOINT_LEGACY) != 0) {
 594                 be_print_err(gettext("be_mount_zone_root: "
 595                     "zone root dataset mountpoint is not 'legacy'\n"));
 596                 return (BE_ERR_ZONE_ROOT_NOT_LEGACY);
 597         }
 598 
 599         /* Create the mountpoint if it doesn't exist */
 600         if (lstat(md->altroot, &buf) != 0) {
 601                 if (mkdirp(md->altroot, 0755) != 0) {
 602                         err = errno;
 603                         be_print_err(gettext("be_mount_zone_root: failed "
 604                             "to create mountpoint %s\n"), md->altroot);
 605                         return (errno_to_be_err(err));
 606                 }
 607         }
 608 
 609         /*
 610          * Legacy mount the zone root dataset.
 611          *
 612          * As a workaround for 6176743, we mount the zone's root with the
 613          * MS_OVERLAY option in case an alternate BE is mounted, and we're
 614          * mounting the root for the zone from the current BE here.  When an
 615          * alternate BE is mounted, it ties up the zone's zoneroot directory
 616          * for the current BE since the zone's zonepath is loopback mounted
 617          * from the current BE.
 618          *
 619          * TODO: The MS_OVERLAY option needs to be removed when 6176743
 620          * is fixed.
 621          */
 622         if (mount(zfs_get_name(zhp), md->altroot, MS_OVERLAY, MNTTYPE_ZFS,
 623             NULL, 0, NULL, 0) != 0) {
 624                 err = errno;
 625                 be_print_err(gettext("be_mount_zone_root: failed to "
 626                     "legacy mount zone root dataset (%s) at %s\n"),
 627                     zfs_get_name(zhp), md->altroot);
 628                 return (errno_to_be_err(err));