From 53ff0fcdab12d69c60c971c69a3d0d173fa46ca9 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 5 Jun 2023 13:21:11 +0200 Subject: [PATCH] libmount: introduce LIBMOUNT_FORCE_MOUNT2={always,never,auto} Let's introduce a stable workaround for use cases where new kernel API is not ready to use. The patch does not use "goto enosys" to exit as nothing in the hookset is initialized yet. Addresses: https://github.com/util-linux/util-linux/issues/1992 Addresses: https://github.com/util-linux/util-linux/issues/2283 Signed-off-by: Karel Zak --- libmount/src/hook_mount.c | 54 +++++++++++++++++++++++++++++---------- sys-utils/mount.8.adoc | 3 +++ 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c index 91483afa68..76fb36d49b 100644 --- a/libmount/src/hook_mount.c +++ b/libmount/src/hook_mount.c @@ -609,6 +609,43 @@ fake: return 0; } +static int force_classic_mount(struct libmnt_context *cxt) +{ + const char *env = getenv("LIBMOUNT_FORCE_MOUNT2"); + + if (env) { + if (strcmp(env, "always") == 0) + return 1; + if (strcmp(env, "never") == 0) + return 0; + } + + /* "auto" (default) -- try to be smart */ + + /* For external /sbin/mount. helpers we use the new API only for + * propagation setting. In this case, the usability of mount_setattr() + * will be verified later */ + if (cxt->helper) + return 0; + + /* + * The current kernel btrfs driver does not completely implement + * fsconfig() as it does not work with selinux stuff. + * + * Don't use the new mount API in this situation. Let's hope this issue + * is temporary. + */ + { + const char *type = mnt_fs_get_fstype(cxt->fs); + + if (type && strcmp(type, "btrfs") == 0 && cxt->has_selinux_opt) + return 1; + } + + return 0; +} + + /* * Analyze library context and register hook to call mount-like syscalls. * @@ -629,20 +666,9 @@ static int hook_prepare(struct libmnt_context *cxt, assert(cxt); assert(hs == &hookset_mount); - /* - * The current kernel btrfs driver does not completely implement - * fsconfig() as it does not work with selinux stuff. - * - * Don't use the new mount API in this situation. Let's hope this issue - * is temporary. - */ - { - const char *type = mnt_fs_get_fstype(cxt->fs); - - if (type && strcmp(type, "btrfs") == 0 && cxt->has_selinux_opt) { - DBG(HOOK, ul_debugobj(hs, "don't use new API (btrfs issue)")); - return 0; - } + if (force_classic_mount(cxt)) { + DBG(HOOK, ul_debugobj(hs, "new API disabled")); + return 0; } DBG(HOOK, ul_debugobj(hs, "prepare mount")); diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc index 511853b4a7..08c8468e0d 100644 --- a/sys-utils/mount.8.adoc +++ b/sys-utils/mount.8.adoc @@ -1608,6 +1608,9 @@ The command *mount* does not pass the mount options *unbindable*, *runbindable*, == ENVIRONMENT +*LIBMOUNT_FORCE_MOUNT2*={always|never|auto}:: +force to use classic mount(2) system call (requires support for new file descriptors based mount API). The default is *auto*; in this case, libmount tries to be smart and use classic mount(2) only for well-known issues. If the new mount API is unavailable, libmount can still use traditional mount(2), although LIBMOUNT_FORCE_MOUNT2 is set to *never*. + *LIBMOUNT_FSTAB*=:: overrides the default location of the _fstab_ file (ignored for suid) -- 2.47.3