mirror of https://github.com/openzfs/zfs.git
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 <behlendorf1@llnl.gov> Reviewed-by: Ryan Moeller <ryan@ixsystems.com> Signed-off-by: Kyle Evans <kevans@FreeBSD.org> Closes #9833
This commit is contained in:
parent
e458fcca75
commit
68a192e4b7
|
@ -788,6 +788,7 @@ extern boolean_t zfs_bookmark_exists(const char *path);
|
|||
extern boolean_t is_mounted(libzfs_handle_t *, const char *special, char **);
|
||||
extern boolean_t zfs_is_mounted(zfs_handle_t *, char **);
|
||||
extern int zfs_mount(zfs_handle_t *, const char *, int);
|
||||
extern int zfs_mount_at(zfs_handle_t *, const char *, int, const char *);
|
||||
extern int zfs_unmount(zfs_handle_t *, const char *, int);
|
||||
extern int zfs_unmountall(zfs_handle_t *, int);
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
*
|
||||
* zfs_is_mounted()
|
||||
* zfs_mount()
|
||||
* zfs_mount_at()
|
||||
* zfs_unmount()
|
||||
* zfs_unmountall()
|
||||
*
|
||||
|
@ -239,6 +240,23 @@ zfs_is_mounted(zfs_handle_t *zhp, char **where)
|
|||
return (is_mounted(zhp->zfs_hdl, zfs_get_name(zhp), 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
|
||||
|
|
Loading…
Reference in New Issue