diff options
author | Kyle Evans <[email protected]> | 2020-01-14 10:49:54 -0600 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2020-01-14 08:49:54 -0800 |
commit | 68a192e4b7627f8f00d412ba68c291fcc90d3de9 (patch) | |
tree | 054fb7431ef982e15d01c53c9ab1a73afe54e590 /lib/libzfs | |
parent | e458fcca7516a0ceac7aaecc4aacfef1114eb216 (diff) |
libzfs: add zfs_mount_at() function
zfs_mount_at() mounts a dataset at an arbitrary mountpoint rather than
at the configured mountpoint. This may be used by consumers that wish to
temporarily expose a dataset at another mountpoint without altering
dataset/pool properties.
This will be used by FreeBSD's libbe be_mount(), which mounts a boot
environment at an arbitrary mountpoint.
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Signed-off-by: Kyle Evans <[email protected]>
Closes #9833
Diffstat (limited to 'lib/libzfs')
-rw-r--r-- | lib/libzfs/libzfs_mount.c | 45 |
1 files changed, 37 insertions, 8 deletions
diff --git a/lib/libzfs/libzfs_mount.c b/lib/libzfs/libzfs_mount.c index c2955ccfa..c3fe97d55 100644 --- a/lib/libzfs/libzfs_mount.c +++ b/lib/libzfs/libzfs_mount.c @@ -37,6 +37,7 @@ * * zfs_is_mounted() * zfs_mount() + * zfs_mount_at() * zfs_unmount() * zfs_unmountall() * @@ -240,6 +241,23 @@ zfs_is_mounted(zfs_handle_t *zhp, char **where) } /* + * Checks any higher order concerns about whether the given dataset is + * mountable, false otherwise. zfs_is_mountable_internal specifically assumes + * that the caller has verified the sanity of mounting the dataset at + * mountpoint to the extent the caller wants. + */ +static boolean_t +zfs_is_mountable_internal(zfs_handle_t *zhp, const char *mountpoint) +{ + + if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) && + getzoneid() == GLOBAL_ZONEID) + return (B_FALSE); + + return (B_TRUE); +} + +/* * Returns true if the given dataset is mountable, false otherwise. Returns the * mountpoint in 'buf'. */ @@ -264,8 +282,7 @@ zfs_is_mountable(zfs_handle_t *zhp, char *buf, size_t buflen, if (zfs_prop_get_int(zhp, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_OFF) return (B_FALSE); - if (zfs_prop_get_int(zhp, ZFS_PROP_ZONED) && - getzoneid() == GLOBAL_ZONEID) + if (!zfs_is_mountable_internal(zhp, buf)) return (B_FALSE); if (zfs_prop_get_int(zhp, ZFS_PROP_REDACTED) && !(flags & MS_FORCE)) @@ -346,14 +363,26 @@ zfs_add_options(zfs_handle_t *zhp, char *options, int len) return (error); } +int +zfs_mount(zfs_handle_t *zhp, const char *options, int flags) +{ + char mountpoint[ZFS_MAXPROPLEN]; + + if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL, + flags)) + return (0); + + return (zfs_mount_at(zhp, options, flags, mountpoint)); +} + /* * Mount the given filesystem. */ int -zfs_mount(zfs_handle_t *zhp, const char *options, int flags) +zfs_mount_at(zfs_handle_t *zhp, const char *options, int flags, + const char *mountpoint) { struct stat buf; - char mountpoint[ZFS_MAXPROPLEN]; char mntopts[MNT_LINE_MAX]; char overlay[ZFS_MAXPROPLEN]; libzfs_handle_t *hdl = zhp->zfs_hdl; @@ -369,16 +398,16 @@ zfs_mount(zfs_handle_t *zhp, const char *options, int flags) if (strstr(mntopts, MNTOPT_REMOUNT) != NULL) remount = 1; + /* Potentially duplicates some checks if invoked by zfs_mount(). */ + if (!zfs_is_mountable_internal(zhp, mountpoint)) + return (0); + /* * If the pool is imported read-only then all mounts must be read-only */ if (zpool_get_prop_int(zhp->zpool_hdl, ZPOOL_PROP_READONLY, NULL)) (void) strlcat(mntopts, "," MNTOPT_RO, sizeof (mntopts)); - if (!zfs_is_mountable(zhp, mountpoint, sizeof (mountpoint), NULL, - flags)) - return (0); - /* * Append default mount options which apply to the mount point. * This is done because under Linux (unlike Solaris) multiple mount |