Print this page
*** NO COMMENTS ***

@@ -22,11 +22,11 @@
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
- * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  */
 
 /*
  * System includes
  */

@@ -448,10 +448,21 @@
         /* Generate string for obe_name's root dataset */
         be_make_root_ds(bt.obe_zpool, bt.obe_name, obe_root_ds,
             sizeof (obe_root_ds));
         bt.obe_root_ds = obe_root_ds;
 
+        if (getzoneid() != GLOBAL_ZONEID) {
+                if (!be_zone_compare_uuids(bt.obe_root_ds)) {
+                        if (be_is_active_on_boot(bt.obe_name)) {
+                                be_print_err(gettext("be_destroy: destroying "
+                                    "active zone root dataset from non-active "
+                                    "global BE is not supported\n"));
+                                return (BE_ERR_NOTSUP);
+                        }
+                }
+        }
+
         /*
          * Detect if the BE to destroy has the 'active on boot' property set.
          * If so, set the 'active on boot' property on the the 'active' BE.
          */
         if (be_is_active_on_boot(bt.obe_name)) {

@@ -480,14 +491,17 @@
                 ZFS_CLOSE(zhp);
                 return (BE_ERR_SS_EXISTS);
         }
 
         /* Get the UUID of the global BE */
-        if (be_get_uuid(zfs_get_name(zhp), &dd.gz_be_uuid) != BE_SUCCESS) {
-                be_print_err(gettext("be_destroy: BE has no UUID (%s)\n"),
-                    zfs_get_name(zhp));
+        if (getzoneid() == GLOBAL_ZONEID) {
+                if (be_get_uuid(zfs_get_name(zhp),
+                    &dd.gz_be_uuid) != BE_SUCCESS) {
+                        be_print_err(gettext("be_destroy: BE has no "
+                        "UUID (%s)\n"), zfs_get_name(zhp));
         }
+        }
 
         /*
          * If the global BE is mounted, make sure we've been given the
          * flag to forcibly unmount it.
          */

@@ -593,10 +607,11 @@
         be_fs_list_data_t       fld = { 0 };
         zfs_handle_t    *zhp = NULL;
         zpool_handle_t  *zphp = NULL;
         nvlist_t        *zfs_props = NULL;
         uuid_t          uu = { 0 };
+        uuid_t          parent_uu = { 0 };
         char            obe_root_ds[MAXPATHLEN];
         char            nbe_root_ds[MAXPATHLEN];
         char            ss[MAXPATHLEN];
         char            *new_mp = NULL;
         char            *obe_name = NULL;

@@ -751,23 +766,36 @@
                         ret = BE_ERR_INVAL;
                         goto done;
                 }
 
                 /* Verify it doesn't already exist */
-                if ((zret = zpool_iter(g_zfs, be_exists_callback, bt.nbe_name))
-                    > 0) {
+                if (getzoneid() == GLOBAL_ZONEID) {
+                        if ((zret = zpool_iter(g_zfs, be_exists_callback,
+                            bt.nbe_name)) > 0) {
                         be_print_err(gettext("be_copy: BE (%s) already "
                             "exists\n"), bt.nbe_name);
                         ret = BE_ERR_BE_EXISTS;
                         goto done;
                 } else if (zret < 0) {
-                        be_print_err(gettext("be_copy: zpool_iter failed: "
-                            "%s\n"), libzfs_error_description(g_zfs));
+                                be_print_err(gettext("be_copy: zpool_iter "
+                                    "failed: %s\n"),
+                                    libzfs_error_description(g_zfs));
                         ret = zfs_err_to_be_err(g_zfs);
                         goto done;
                 }
         } else {
+                        be_make_root_ds(bt.nbe_zpool, bt.nbe_name, nbe_root_ds,
+                            sizeof (nbe_root_ds));
+                        if (zfs_dataset_exists(g_zfs, nbe_root_ds,
+                            ZFS_TYPE_FILESYSTEM)) {
+                                be_print_err(gettext("be_copy: BE (%s) already "
+                                    "exists\n"), bt.nbe_name);
+                                ret = BE_ERR_BE_EXISTS;
+                                goto done;
+                        }
+                }
+        } else {
                 /*
                  * If an auto named BE is desired, it must be in the same
                  * pool is the original BE.
                  */
                 if (bt.nbe_zpool != NULL) {

@@ -1014,14 +1042,29 @@
                 (void) _be_unmount(bt.nbe_name, 0);
                 goto done;
         }
 
         /* Set UUID for new BE */
+        if (getzoneid() == GLOBAL_ZONEID) {
         if (be_set_uuid(bt.nbe_root_ds) != BE_SUCCESS) {
                 be_print_err(gettext("be_copy: failed to "
                     "set uuid for new BE\n"));
         }
+        } else {
+                if ((ret = be_zone_get_parent_uuid(bt.obe_root_ds,
+                    &parent_uu)) != BE_SUCCESS) {
+                        be_print_err(gettext("be_copy: failed to get "
+                            "parentbe uuid from orig BE\n"));
+                        ret = BE_ERR_ZONE_NO_PARENTBE;
+                        goto done;
+                } else if ((ret = be_zone_set_parent_uuid(bt.nbe_root_ds,
+                    parent_uu)) != BE_SUCCESS) {
+                        be_print_err(gettext("be_copy: failed to set "
+                            "parentbe uuid for newly created BE\n"));
+                        goto done;
+                }
+        }
 
         /*
          * Process zones outside of the private BE namespace.
          * This has to be done here because we need the uuid set in the
          * root dataset of the new BE. The uuid is use to set the parentbe