From e7a7167eccba512c2dc324ff0de35d8938781920 Mon Sep 17 00:00:00 2001 From: Damian Szuberski Date: Tue, 8 Feb 2022 19:53:23 +0100 Subject: [PATCH] `mount.zfs -o zfsutil` leverages `zfs_mount_at()` Using `zfs_mount_at()` gives opportunity to properly propagate mountopts from what's stored in a pool to the `mount(2)` syscall invocation. It fixes cases when mount options are set to incorrect values and rectification is impossible (e. g. Linux initrd boot sequence in #7947). Moved debug information printing after all variables are initialized - printed text reflects what is passed to `mount(2)`. Reviewed-by: Brian Behlendorf Signed-off-by: szubersk Issue #7947 Closes #13021 --- cmd/mount_zfs/mount_zfs.c | 47 ++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/cmd/mount_zfs/mount_zfs.c b/cmd/mount_zfs/mount_zfs.c index de3833698a2b..55968ac88ffa 100644 --- a/cmd/mount_zfs/mount_zfs.c +++ b/cmd/mount_zfs/mount_zfs.c @@ -246,13 +246,6 @@ main(int argc, char **argv) } } - if (verbose) - (void) fprintf(stdout, gettext("mount.zfs:\n" - " dataset: \"%s\"\n mountpoint: \"%s\"\n" - " mountflags: 0x%lx\n zfsflags: 0x%lx\n" - " mountopts: \"%s\"\n mtabopts: \"%s\"\n"), - dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt); - if (mntflags & MS_REMOUNT) { nomtab = 1; remount = 1; @@ -275,7 +268,10 @@ main(int argc, char **argv) return (MOUNT_USAGE); } - zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt); + if (!zfsutil || sloppy || + libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) { + zfs_adjust_mount_options(zhp, mntpoint, mntopts, mtabopt); + } /* treat all snapshots as legacy mount points */ if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) @@ -293,12 +289,11 @@ main(int argc, char **argv) if (zfs_version == 0) { fprintf(stderr, gettext("unable to fetch " "ZFS version for filesystem '%s'\n"), dataset); + zfs_close(zhp); + libzfs_fini(g_zfs); return (MOUNT_SYSERR); } - zfs_close(zhp); - libzfs_fini(g_zfs); - /* * Legacy mount points may only be mounted using 'mount', never using * 'zfs mount'. However, since 'zfs mount' actually invokes 'mount' @@ -316,6 +311,8 @@ main(int argc, char **argv) "Use 'zfs set mountpoint=%s' or 'mount -t zfs %s %s'.\n" "See zfs(8) for more information.\n"), dataset, mntpoint, dataset, mntpoint); + zfs_close(zhp); + libzfs_fini(g_zfs); return (MOUNT_USAGE); } @@ -326,14 +323,38 @@ main(int argc, char **argv) "Use 'zfs set mountpoint=%s' or 'zfs mount %s'.\n" "See zfs(8) for more information.\n"), dataset, "legacy", dataset); + zfs_close(zhp); + libzfs_fini(g_zfs); return (MOUNT_USAGE); } + if (verbose) + (void) fprintf(stdout, gettext("mount.zfs:\n" + " dataset: \"%s\"\n mountpoint: \"%s\"\n" + " mountflags: 0x%lx\n zfsflags: 0x%lx\n" + " mountopts: \"%s\"\n mtabopts: \"%s\"\n"), + dataset, mntpoint, mntflags, zfsflags, mntopts, mtabopt); + if (!fake) { - error = mount(dataset, mntpoint, MNTTYPE_ZFS, - mntflags, mntopts); + if (zfsutil && !sloppy && + !libzfs_envvar_is_set("ZFS_MOUNT_HELPER")) { + error = zfs_mount_at(zhp, mntopts, mntflags, mntpoint); + if (error) { + (void) fprintf(stderr, "zfs_mount_at() failed: " + "%s", libzfs_error_description(g_zfs)); + zfs_close(zhp); + libzfs_fini(g_zfs); + return (MOUNT_SYSERR); + } + } else { + error = mount(dataset, mntpoint, MNTTYPE_ZFS, + mntflags, mntopts); + } } + zfs_close(zhp); + libzfs_fini(g_zfs); + if (error) { switch (errno) { case ENOENT: