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

@@ -51,10 +51,11 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <deflt.h>
 #include <wait.h>
 #include <libdevinfo.h>
+#include <libgen.h>
 
 #include <libbe.h>
 #include <libbe_priv.h>
 
 /* Private function prototypes */

@@ -228,17 +229,34 @@
 be_make_root_ds(const char *zpool, const char *be_name, char *be_root_ds,
     int be_root_ds_size)
 {
         struct be_defaults be_defaults;
         be_get_defaults(&be_defaults);
+        char    *root_ds = NULL;
 
-        if (be_defaults.be_deflt_rpool_container)
-                (void) snprintf(be_root_ds, be_root_ds_size, "%s/%s", zpool,
-                    be_name);
-        else
-                (void) snprintf(be_root_ds, be_root_ds_size, "%s/%s/%s", zpool,
-                    BE_CONTAINER_DS_NAME, be_name);
+        if (getzoneid() == GLOBAL_ZONEID) {
+                if (be_defaults.be_deflt_rpool_container) {
+                        (void) snprintf(be_root_ds, be_root_ds_size,
+                            "%s/%s", zpool, be_name);
+                } else {
+                        (void) snprintf(be_root_ds, be_root_ds_size,
+                            "%s/%s/%s", zpool, BE_CONTAINER_DS_NAME, be_name);
+                }
+        } else {
+                /*
+                 * In non-global zone we can use path from mounted root dataset
+                 * to generate BE's root dataset string.
+                 */
+                if ((root_ds = be_get_ds_from_dir("/")) != NULL) {
+                        (void) snprintf(be_root_ds, be_root_ds_size, "%s/%s",
+                            dirname(root_ds), be_name);
+                } else {
+                        be_print_err(gettext("be_make_root_ds: zone root "
+                            "dataset is not mounted\n"));
+                        return;
+                }
+        }
 }
 
 /*
  * Function:    be_make_container_ds
  * Description: Generate string for the BE container dataset given a pool name.

@@ -256,16 +274,30 @@
 be_make_container_ds(const char *zpool,  char *container_ds,
     int container_ds_size)
 {
         struct be_defaults be_defaults;
         be_get_defaults(&be_defaults);
+        char    *root_ds = NULL;
 
-        if (be_defaults.be_deflt_rpool_container)
-                (void) snprintf(container_ds, container_ds_size, "%s", zpool);
-        else
-                (void) snprintf(container_ds, container_ds_size, "%s/%s", zpool,
-                    BE_CONTAINER_DS_NAME);
+        if (getzoneid() == GLOBAL_ZONEID) {
+                if (be_defaults.be_deflt_rpool_container) {
+                        (void) snprintf(container_ds, container_ds_size,
+                            "%s", zpool);
+                } else {
+                        (void) snprintf(container_ds, container_ds_size,
+                            "%s/%s", zpool, BE_CONTAINER_DS_NAME);
+                }
+        } else {
+                if ((root_ds = be_get_ds_from_dir("/")) != NULL) {
+                        (void) strlcpy(container_ds, dirname(root_ds),
+                            container_ds_size);
+                } else {
+                        be_print_err(gettext("be_make_container_ds: zone root "
+                            "dataset is not mounted\n"));
+                        return;
+                }
+        }
 }
 
 /*
  * Function:    be_make_name_from_ds
  * Description: This function takes a dataset name and strips off the

@@ -2434,15 +2466,29 @@
 {
         be_transaction_data_t   *bt = data;
         zfs_handle_t            *zhp = NULL;
         const char              *zpool =  zpool_get_name(zlp);
         char                    be_container_ds[MAXPATHLEN];
+        char                    *zpath = NULL;
 
         /*
          * Generate string for BE container dataset
          */
-        be_make_container_ds(zpool, be_container_ds, sizeof (be_container_ds));
+        if (getzoneid() != GLOBAL_ZONEID) {
+                if ((zpath = be_get_ds_from_dir("/")) != NULL) {
+                        (void) strlcpy(be_container_ds, dirname(zpath),
+                            sizeof (be_container_ds));
+                } else {
+                        be_print_err(gettext(
+                            "be_zpool_find_current_be_callback: "
+                            "zone root dataset is not mounted\n"));
+                        return (0);
+                }
+        } else {
+                be_make_container_ds(zpool, be_container_ds,
+                    sizeof (be_container_ds));
+        }
 
         /*
          * Check if a BE container dataset exists in this pool.
          */
         if (!zfs_dataset_exists(g_zfs, be_container_ds, ZFS_TYPE_FILESYSTEM)) {