aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libbe/be.c21
-rw-r--r--lib/libbe/be_access.c22
-rw-r--r--lib/libbe/be_impl.h9
3 files changed, 38 insertions, 14 deletions
diff --git a/lib/libbe/be.c b/lib/libbe/be.c
index 24a0e0ae1b78..8640af11a5df 100644
--- a/lib/libbe/be.c
+++ b/lib/libbe/be.c
@@ -90,6 +90,7 @@ be_locate_rootfs(libbe_handle_t *lbh)
libbe_handle_t *
libbe_init(const char *root)
{
+ char altroot[MAXPATHLEN];
libbe_handle_t *lbh;
char *poolname, *pos;
int pnamelen;
@@ -140,6 +141,11 @@ libbe_init(const char *root)
sizeof(lbh->bootfs), NULL, true) != 0)
goto err;
+ if (zpool_get_prop(lbh->active_phandle, ZPOOL_PROP_ALTROOT,
+ altroot, sizeof(altroot), NULL, true) == 0 &&
+ strcmp(altroot, "-") != 0)
+ lbh->altroot_len = strlen(altroot);
+
return (lbh);
err:
if (lbh != NULL) {
@@ -314,7 +320,6 @@ be_create(libbe_handle_t *lbh, const char *name)
return (set_error(lbh, err));
}
-
static int
be_deep_clone_prop(int prop, void *cb)
{
@@ -345,12 +350,9 @@ be_deep_clone_prop(int prop, void *cb)
/* Augment mountpoint with altroot, if needed */
val = pval;
- if (prop == ZFS_PROP_MOUNTPOINT && *dccb->altroot != '\0') {
- if (pval[strlen(dccb->altroot)] == '\0')
- strlcpy(pval, "/", sizeof(pval));
- else
- val = pval + strlen(dccb->altroot);
- }
+ if (prop == ZFS_PROP_MOUNTPOINT)
+ val = be_mountpoint_augmented(dccb->lbh, val);
+
nvlist_add_string(dccb->props, zfs_prop_to_name(prop), val);
return (ZPROP_CONT);
@@ -392,12 +394,9 @@ be_deep_clone(zfs_handle_t *ds, void *data)
nvlist_alloc(&props, NV_UNIQUE_NAME, KM_SLEEP);
nvlist_add_string(props, "canmount", "noauto");
+ dccb.lbh = isdc->lbh;
dccb.zhp = ds;
dccb.props = props;
- if (zpool_get_prop(isdc->lbh->active_phandle, ZPOOL_PROP_ALTROOT,
- dccb.altroot, sizeof(dccb.altroot), NULL, true) != 0 ||
- strcmp(dccb.altroot, "-") == 0)
- *dccb.altroot = '\0';
if (zprop_iter(be_deep_clone_prop, &dccb, B_FALSE, B_FALSE,
ZFS_TYPE_FILESYSTEM) == ZPROP_INVAL)
return (-1);
diff --git a/lib/libbe/be_access.c b/lib/libbe/be_access.c
index a129e55a0303..e0d71a60b87f 100644
--- a/lib/libbe/be_access.c
+++ b/lib/libbe/be_access.c
@@ -195,3 +195,25 @@ be_unmount(libbe_handle_t *lbh, char *bootenv, int flags)
return (BE_ERR_SUCCESS);
}
+
+/*
+ * This function will blow away the input buffer as needed if we're discovered
+ * to be looking at a root-mount. If the mountpoint is naturally beyond the
+ * root, however, the buffer may be left intact and a pointer to the section
+ * past altroot will be returned instead for the caller's perusal.
+ */
+char *
+be_mountpoint_augmented(libbe_handle_t *lbh, char *mountpoint)
+{
+
+ if (lbh->altroot_len == 0)
+ return (mountpoint);
+ if (mountpoint == NULL || *mountpoint == '\0')
+ return (mountpoint);
+
+ if (mountpoint[lbh->altroot_len] == '\0') {
+ *(mountpoint + 1) = '\0';
+ return (mountpoint);
+ } else
+ return (mountpoint + lbh->altroot_len);
+}
diff --git a/lib/libbe/be_impl.h b/lib/libbe/be_impl.h
index 093b3c01e17e..e3a6baea5959 100644
--- a/lib/libbe/be_impl.h
+++ b/lib/libbe/be_impl.h
@@ -36,11 +36,12 @@
#include "be.h"
struct libbe_handle {
- libzfs_handle_t *lzh;
- zpool_handle_t *active_phandle;
char root[BE_MAXPATHLEN];
char rootfs[BE_MAXPATHLEN];
char bootfs[BE_MAXPATHLEN];
+ size_t altroot_len;
+ zpool_handle_t *active_phandle;
+ libzfs_handle_t *lzh;
be_error_t error;
bool print_on_err;
};
@@ -53,9 +54,9 @@ struct libbe_deep_clone {
};
struct libbe_dccb {
+ libbe_handle_t *lbh;
zfs_handle_t *zhp;
nvlist_t *props;
- char altroot[MAXPATHLEN];
};
typedef struct prop_data {
@@ -67,6 +68,8 @@ typedef struct prop_data {
int prop_list_builder_cb(zfs_handle_t *, void *);
int be_proplist_update(prop_data_t *);
+char *be_mountpoint_augmented(libbe_handle_t *lbh, char *mountpoint);
+
/* Clobbers any previous errors */
int set_error(libbe_handle_t *, be_error_t);