libbe(3): Rewrite be_unmount to stop mucking with getmntinfo(2)

Go through the ZFS layer instead; given a BE, we can derive the dataset,
zfs_open it, then zfs_unmount. ZFS takes care of the dirty details and
likely gets it more correct than we did for more interesting setups.

MFC after:	3 days
This commit is contained in:
Kyle Evans 2018-11-17 19:19:37 +00:00
parent 51aecc893a
commit efd6500d03

View File

@ -164,37 +164,18 @@ be_unmount(libbe_handle_t *lbh, char *bootenv, int flags)
{ {
int err, mntflags; int err, mntflags;
char be[BE_MAXPATHLEN]; char be[BE_MAXPATHLEN];
struct statfs *mntbuf; zfs_handle_t *root_hdl;
int mntsize;
char *mntpath;
if ((err = be_root_concat(lbh, bootenv, be)) != 0) if ((err = be_root_concat(lbh, bootenv, be)) != 0)
return (set_error(lbh, err)); return (set_error(lbh, err));
if ((mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) { if ((root_hdl = zfs_open(lbh->lzh, be, ZFS_TYPE_FILESYSTEM)) == NULL)
if (errno == EIO) return (set_error(lbh, BE_ERR_ZFSOPEN));
return (set_error(lbh, BE_ERR_IO));
return (set_error(lbh, BE_ERR_NOMOUNT));
}
mntpath = NULL; mntflags = (flags & BE_MNT_FORCE) ? MS_FORCE : 0;
for (int i = 0; i < mntsize; ++i) {
/* 0x000000de is the type number of zfs */
if (mntbuf[i].f_type != 0x000000de)
continue;
if (strcmp(mntbuf[i].f_mntfromname, be) == 0) { if (zfs_unmount(root_hdl, NULL, mntflags) != 0) {
mntpath = mntbuf[i].f_mntonname; zfs_close(root_hdl);
break;
}
}
if (mntpath == NULL)
return (set_error(lbh, BE_ERR_NOMOUNT));
mntflags = (flags & BE_MNT_FORCE) ? MNT_FORCE : 0;
if ((err = unmount(mntpath, mntflags)) != 0) {
switch (errno) { switch (errno) {
case ENAMETOOLONG: case ENAMETOOLONG:
return (set_error(lbh, BE_ERR_PATHLEN)); return (set_error(lbh, BE_ERR_PATHLEN));
@ -210,6 +191,7 @@ be_unmount(libbe_handle_t *lbh, char *bootenv, int flags)
return (set_error(lbh, BE_ERR_UNKNOWN)); return (set_error(lbh, BE_ERR_UNKNOWN));
} }
} }
zfs_close(root_hdl);
return (set_error(lbh, BE_ERR_SUCCESS)); return (BE_ERR_SUCCESS);
} }