Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148448678
D18796.id52709.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D18796.id52709.diff
View Options
Index: lib/libbe/be_access.c
===================================================================
--- lib/libbe/be_access.c
+++ lib/libbe/be_access.c
@@ -38,6 +38,14 @@
char *name;
};
+struct be_mount_info {
+ libbe_handle_t *lbh;
+ const char *mountpoint;
+ const char *be;
+ int mntflags;
+ int deepmount;
+};
+
static int
be_mountcheck_cb(zfs_handle_t *zfs_hdl, void *data)
{
@@ -58,6 +66,103 @@
return (0);
}
+/*
+ * called from be_mount, uses the given zfs_handle and attempts to
+ * mount it at the passed mountpoint. If the deepmount flag is set, continue
+ * calling the function for each child dataset.
+ */
+static int
+be_mount_iter(zfs_handle_t *zfs_hdl, void *data)
+{
+ int err;
+ char *mountpoint;
+ char zfs_mnt[BE_MAXPATHLEN], tmp[BE_MAXPATHLEN];
+ struct be_mount_info *info;
+
+ info = (struct be_mount_info *)data;
+
+ if (zfs_is_mounted(zfs_hdl, &mountpoint)){
+ free(mountpoint);
+ return (0);
+ }
+
+ if (zfs_prop_get_int(zfs_hdl, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_OFF)
+ return (0);
+
+ if (zfs_prop_get(zfs_hdl, ZFS_PROP_MOUNTPOINT, zfs_mnt, BE_MAXPATHLEN,
+ NULL, NULL, 0, 1))
+ return (1);
+
+ if ( strcmp("none", zfs_mnt) != 0 ) {
+ char opt = '\0';
+
+ snprintf(tmp, BE_MAXPATHLEN, "%s%s", info->mountpoint, zfs_mnt);
+
+ if ((err = zmount(zfs_get_name(zfs_hdl), tmp, info->mntflags,
+ __DECONST(char *, MNTTYPE_ZFS), NULL, 0, &opt, 1)) != 0) {
+ switch (errno) {
+ case ENAMETOOLONG:
+ return (set_error(info->lbh, BE_ERR_PATHLEN));
+ case ELOOP:
+ case ENOENT:
+ case ENOTDIR:
+ return (set_error(info->lbh, BE_ERR_BADPATH));
+ case EPERM:
+ return (set_error(info->lbh, BE_ERR_PERMS));
+ case EBUSY:
+ return (set_error(info->lbh, BE_ERR_PATHBUSY));
+ default:
+ return (set_error(info->lbh, BE_ERR_UNKNOWN));
+ }
+ }
+ }
+
+ if(!info->deepmount)
+ return 0;
+
+ err = zfs_iter_filesystems(zfs_hdl, be_mount_iter, info);
+ return err;
+}
+
+
+static int
+be_umount_iter(zfs_handle_t *zfs_hdl, void *data)
+{
+
+ int err;
+ char *mountpoint;
+ struct be_mount_info *info;
+
+ info = (struct be_mount_info *)data;
+
+ if((err = zfs_iter_filesystems(zfs_hdl, be_umount_iter, info)) != 0){
+ return err;
+ }
+
+ if (!zfs_is_mounted(zfs_hdl, &mountpoint)){
+ return (0);
+ }
+ free(mountpoint);
+
+ if (zfs_unmount(zfs_hdl, NULL, info->mntflags) != 0) {
+ switch (errno) {
+ case ENAMETOOLONG:
+ return (set_error(info->lbh, BE_ERR_PATHLEN));
+ case ELOOP:
+ case ENOENT:
+ case ENOTDIR:
+ return (set_error(info->lbh, BE_ERR_BADPATH));
+ case EPERM:
+ return (set_error(info->lbh, BE_ERR_PERMS));
+ case EBUSY:
+ return (set_error(info->lbh, BE_ERR_PATHBUSY));
+ default:
+ return (set_error(info->lbh, BE_ERR_UNKNOWN));
+ }
+ }
+ return (0);
+}
+
/*
* usage
*/
@@ -108,8 +213,10 @@
{
char be[BE_MAXPATHLEN];
char mnt_temp[BE_MAXPATHLEN];
- int mntflags;
+ int mntflags, mntdeep;
int err;
+ struct be_mount_info info;
+ zfs_handle_t *zhdl;
if ((err = be_root_concat(lbh, bootenv, be)) != 0)
return (set_error(lbh, err));
@@ -120,6 +227,7 @@
if (is_mounted(lbh->lzh, be, NULL))
return (set_error(lbh, BE_ERR_MOUNTED));
+ mntdeep = (flags & BE_MNT_DEEP) ? 1 : 0;
mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0;
/* Create mountpoint if it is not specified */
@@ -129,24 +237,21 @@
return (set_error(lbh, BE_ERR_IO));
}
- char opt = '\0';
- if ((err = zmount(be, (mountpoint == NULL) ? mnt_temp : mountpoint,
- mntflags, __DECONST(char *, MNTTYPE_ZFS), NULL, 0, &opt, 1)) != 0) {
- switch (errno) {
- case ENAMETOOLONG:
- return (set_error(lbh, BE_ERR_PATHLEN));
- case ELOOP:
- case ENOENT:
- case ENOTDIR:
- return (set_error(lbh, BE_ERR_BADPATH));
- case EPERM:
- return (set_error(lbh, BE_ERR_PERMS));
- case EBUSY:
- return (set_error(lbh, BE_ERR_PATHBUSY));
- default:
- return (set_error(lbh, BE_ERR_UNKNOWN));
- }
+ if ((zhdl = zfs_open(lbh->lzh, be,
+ ZFS_TYPE_FILESYSTEM)) == NULL)
+ return (BE_ERR_ZFSOPEN);
+
+ info.lbh = lbh;
+ info.be = be;
+ info.mountpoint = (mountpoint == NULL) ? mnt_temp : mountpoint;
+ info.mntflags = mntflags;
+ info.deepmount = mntdeep;
+
+ if((err = be_mount_iter(zhdl, &info) != 0)) {
+ zfs_close(zhdl);
+ return err;
}
+ zfs_close(zhdl);
if (result_loc != NULL)
strlcpy(result_loc, mountpoint == NULL ? mnt_temp : mountpoint,
@@ -155,16 +260,16 @@
return (BE_ERR_SUCCESS);
}
-
/*
* usage
*/
int
be_unmount(libbe_handle_t *lbh, char *bootenv, int flags)
{
- int err, mntflags;
+ int err;
char be[BE_MAXPATHLEN];
zfs_handle_t *root_hdl;
+ struct be_mount_info info;
if ((err = be_root_concat(lbh, bootenv, be)) != 0)
return (set_error(lbh, err));
@@ -172,26 +277,16 @@
if ((root_hdl = zfs_open(lbh->lzh, be, ZFS_TYPE_FILESYSTEM)) == NULL)
return (set_error(lbh, BE_ERR_ZFSOPEN));
- mntflags = (flags & BE_MNT_FORCE) ? MS_FORCE : 0;
+ info.lbh = lbh;
+ info.be = be;
+ info.mountpoint = NULL;
+ info.mntflags = (flags & BE_MNT_FORCE) ? MS_FORCE : 0;
- if (zfs_unmount(root_hdl, NULL, mntflags) != 0) {
+ if ((err = be_umount_iter(root_hdl, &info)) != 0) {
zfs_close(root_hdl);
- switch (errno) {
- case ENAMETOOLONG:
- return (set_error(lbh, BE_ERR_PATHLEN));
- case ELOOP:
- case ENOENT:
- case ENOTDIR:
- return (set_error(lbh, BE_ERR_BADPATH));
- case EPERM:
- return (set_error(lbh, BE_ERR_PERMS));
- case EBUSY:
- return (set_error(lbh, BE_ERR_PATHBUSY));
- default:
- return (set_error(lbh, BE_ERR_UNKNOWN));
- }
+ return err;
}
+
zfs_close(root_hdl);
-
return (BE_ERR_SUCCESS);
}
Index: sbin/bectl/bectl_jail.c
===================================================================
--- sbin/bectl/bectl_jail.c
+++ sbin/bectl/bectl_jail.c
@@ -180,10 +180,11 @@
bectl_cmd_jail(int argc, char *argv[])
{
char *bootenv, *mountpoint;
- int jid, opt, ret;
+ int jid, opt, ret, mntflags;
bool default_hostname, interactive, unjail;
pid_t pid;
+ mntflags = BE_MNT_DEEP;
default_hostname = interactive = unjail = true;
jpcnt = INIT_PARAMCOUNT;
jp = malloc(jpcnt * sizeof(*jp));
@@ -250,7 +251,7 @@
mountpoint = NULL;
else
mountpoint = mnt_loc;
- if (be_mount(be, bootenv, mountpoint, 0, mnt_loc) != BE_ERR_SUCCESS) {
+ if (be_mount(be, bootenv, mountpoint, mntflags, mnt_loc) != BE_ERR_SUCCESS) {
fprintf(stderr, "could not mount bootenv\n");
return (1);
}
@@ -301,7 +302,7 @@
if (unjail) {
jail_remove(jid);
- unmount(mnt_loc, 0);
+ be_unmount(be, bootenv, 0);
}
return (0);
@@ -415,7 +416,7 @@
}
jail_remove(jid);
- unmount(path, 0);
+ be_unmount(be, target, 0);
return (0);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 18, 11:24 PM (18 h, 52 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29931854
Default Alt Text
D18796.id52709.diff (6 KB)
Attached To
Mode
D18796: Change be_mount to mount/unmount child datasets
Attached
Detach File
Event Timeline
Log In to Comment