libbe(3): Properly mount BEs with mountpoint=none

Instead of pretending to successfully mount them while not actually
mounting anything, we'll now actually mount them *and* claim we mounted them
successfully.

Reported by:	ler
MFC after:	3 days
This commit is contained in:
Kyle Evans 2019-05-02 17:44:46 +00:00
parent 9acc2a6af6
commit 011fdcbf1c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=347027

View File

@ -45,6 +45,7 @@ struct be_mount_info {
const char *mountpoint; const char *mountpoint;
int mntflags; int mntflags;
int deepmount; int deepmount;
int depth;
}; };
static int static int
@ -79,6 +80,7 @@ be_mount_iter(zfs_handle_t *zfs_hdl, void *data)
char *mountpoint; char *mountpoint;
char tmp[BE_MAXPATHLEN], zfs_mnt[BE_MAXPATHLEN]; char tmp[BE_MAXPATHLEN], zfs_mnt[BE_MAXPATHLEN];
struct be_mount_info *info; struct be_mount_info *info;
char opt;
info = (struct be_mount_info *)data; info = (struct be_mount_info *)data;
@ -94,37 +96,50 @@ be_mount_iter(zfs_handle_t *zfs_hdl, void *data)
NULL, NULL, 0, 1)) NULL, NULL, 0, 1))
return (1); return (1);
if (strcmp("none", zfs_mnt) != 0) { if (strcmp("none", zfs_mnt) == 0) {
char opt = '\0'; /*
* mountpoint=none; we'll mount it at info->mountpoint assuming
* we're at the root. If we're not at the root... that's less
* than stellar and not entirely sure what to do with that.
* For now, we won't treat it as an error condition -- we just
* won't mount it, and we'll continue on.
*/
if (info->depth > 0)
return (0);
snprintf(tmp, BE_MAXPATHLEN, "%s", info->mountpoint);
} else {
mountpoint = be_mountpoint_augmented(info->lbh, zfs_mnt); mountpoint = be_mountpoint_augmented(info->lbh, zfs_mnt);
snprintf(tmp, BE_MAXPATHLEN, "%s%s", info->mountpoint, snprintf(tmp, BE_MAXPATHLEN, "%s%s", info->mountpoint,
mountpoint); mountpoint);
}
if ((err = zmount(zfs_get_name(zfs_hdl), tmp, info->mntflags, opt = '\0';
__DECONST(char *, MNTTYPE_ZFS), NULL, 0, &opt, 1)) != 0) { if ((err = zmount(zfs_get_name(zfs_hdl), tmp, info->mntflags,
switch (errno) { __DECONST(char *, MNTTYPE_ZFS), NULL, 0, &opt, 1)) != 0) {
case ENAMETOOLONG: switch (errno) {
return (set_error(info->lbh, BE_ERR_PATHLEN)); case ENAMETOOLONG:
case ELOOP: return (set_error(info->lbh, BE_ERR_PATHLEN));
case ENOENT: case ELOOP:
case ENOTDIR: case ENOENT:
return (set_error(info->lbh, BE_ERR_BADPATH)); case ENOTDIR:
case EPERM: return (set_error(info->lbh, BE_ERR_BADPATH));
return (set_error(info->lbh, BE_ERR_PERMS)); case EPERM:
case EBUSY: return (set_error(info->lbh, BE_ERR_PERMS));
return (set_error(info->lbh, BE_ERR_PATHBUSY)); case EBUSY:
default: return (set_error(info->lbh, BE_ERR_PATHBUSY));
return (set_error(info->lbh, BE_ERR_UNKNOWN)); default:
} return (set_error(info->lbh, BE_ERR_UNKNOWN));
} }
} }
if (!info->deepmount) if (!info->deepmount)
return (0); return (0);
return (zfs_iter_filesystems(zfs_hdl, be_mount_iter, info)); ++info->depth;
err = zfs_iter_filesystems(zfs_hdl, be_mount_iter, info);
--info->depth;
return (err);
} }
@ -138,9 +153,11 @@ be_umount_iter(zfs_handle_t *zfs_hdl, void *data)
info = (struct be_mount_info *)data; info = (struct be_mount_info *)data;
++info->depth;
if((err = zfs_iter_filesystems(zfs_hdl, be_umount_iter, info)) != 0) { if((err = zfs_iter_filesystems(zfs_hdl, be_umount_iter, info)) != 0) {
return (err); return (err);
} }
--info->depth;
if (!zfs_is_mounted(zfs_hdl, &mountpoint)) { if (!zfs_is_mounted(zfs_hdl, &mountpoint)) {
return (0); return (0);
@ -248,6 +265,7 @@ be_mount(libbe_handle_t *lbh, char *bootenv, char *mountpoint, int flags,
info.mountpoint = (mountpoint == NULL) ? mnt_temp : mountpoint; info.mountpoint = (mountpoint == NULL) ? mnt_temp : mountpoint;
info.mntflags = mntflags; info.mntflags = mntflags;
info.deepmount = mntdeep; info.deepmount = mntdeep;
info.depth = 0;
if((err = be_mount_iter(zhdl, &info) != 0)) { if((err = be_mount_iter(zhdl, &info) != 0)) {
zfs_close(zhdl); zfs_close(zhdl);
@ -283,6 +301,7 @@ be_unmount(libbe_handle_t *lbh, char *bootenv, int flags)
info.be = be; info.be = be;
info.mountpoint = NULL; info.mountpoint = NULL;
info.mntflags = (flags & BE_MNT_FORCE) ? MS_FORCE : 0; info.mntflags = (flags & BE_MNT_FORCE) ? MS_FORCE : 0;
info.depth = 0;
if ((err = be_umount_iter(root_hdl, &info)) != 0) { if ((err = be_umount_iter(root_hdl, &info)) != 0) {
zfs_close(root_hdl); zfs_close(root_hdl);