From: Karel Zak Date: Tue, 1 Aug 2023 12:49:48 +0000 (+0200) Subject: libmount: cleanup --fake mode X-Git-Tag: v2.40-rc1~309^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b42e4e2350a26b13a6165b78990e8814535ceb80;p=thirdparty%2Futil-linux.git libmount: cleanup --fake mode It was originally designed to play nasty games with /etc/mtab (mount when /etc is read-only and update later when it's write-able). The --fake is completely useless with the new API due to complexity where we cannot skip any step, because the next stuff depends on it. So, it makes more sense skip all functionality where libmount does anything significant. This commit add --fake check to hooks logic to skip all hooks as the hooks are place where libmount implements mount related invasive operations (create mountpoint, namespaces, create superblock, move, mount, etc.). Frankly, --fake without mtab is useless. Fixes: https://github.com/util-linux/util-linux/issues/2395 Signed-off-by: Karel Zak --- diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c index 05c84f1702..619e696326 100644 --- a/libmount/src/context_mount.c +++ b/libmount/src/context_mount.c @@ -541,6 +541,11 @@ static int do_mount(struct libmnt_context *cxt, const char *try_type) if (!rc) rc = mnt_context_call_hooks(cxt, MNT_STAGE_MOUNT); + if (rc == 0 && mnt_context_is_fake(cxt)) { + DBG(CXT, ul_debugobj(cxt, "FAKE (-f) set status=0")); + cxt->syscall_status = 0; + } + if (org_type && rc != 0) __mnt_fs_set_fstype_ptr(cxt->fs, org_type); org_type = NULL; diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c index ed4ec349ca..d69a018ecc 100644 --- a/libmount/src/hook_mount.c +++ b/libmount/src/hook_mount.c @@ -576,9 +576,6 @@ static int init_sysapi(struct libmnt_context *cxt, if (!api) return -ENOMEM; - if (mnt_context_is_fake(cxt)) - goto fake; - if (path) { api->fd_tree = open_mount_tree(cxt, path, flags); if (api->fd_tree < 0) @@ -611,10 +608,6 @@ static int init_sysapi(struct libmnt_context *cxt, fail: DBG(HOOK, ul_debugobj(hs, "init fs/tree failed [errno=%d %m]", errno)); return -errno; -fake: - DBG(CXT, ul_debugobj(cxt, " FAKE (-f)")); - cxt->syscall_status = 0; - return 0; } static int force_classic_mount(struct libmnt_context *cxt) diff --git a/libmount/src/hook_mount_legacy.c b/libmount/src/hook_mount_legacy.c index 2c07a015b8..7e62864673 100644 --- a/libmount/src/hook_mount_legacy.c +++ b/libmount/src/hook_mount_legacy.c @@ -61,12 +61,6 @@ static int hook_propagation(struct libmnt_context *cxt, hd->flags, hd->flags & MS_REC ? " (recursive)" : "")); - if (mnt_context_is_fake(cxt)) { - DBG(CXT, ul_debugobj(cxt, " FAKE (-f)")); - cxt->syscall_status = 0; - return 0; - } - /* * hd->flags are propagation flags as set in prepare_propagation() * @@ -156,12 +150,6 @@ static int hook_bindremount(struct libmnt_context *cxt, hd->flags, hd->flags & MS_REC ? " (recursive)" : "")); - if (mnt_context_is_fake(cxt)) { - DBG(CXT, ul_debugobj(cxt, " FAKE (-f)")); - cxt->syscall_status = 0; - return 0; - } - if (mnt_optlist_is_silent(cxt->optlist)) extra |= MS_SILENT; @@ -251,12 +239,6 @@ static int hook_mount(struct libmnt_context *cxt, options ? (cxt->flags & MNT_FL_MOUNTDATA) ? "binary" : options : "")); - if (mnt_context_is_fake(cxt)) { - DBG(HOOK, ul_debugobj(hs, " FAKE (-f)")); - cxt->syscall_status = 0; - return 0; - } - if (mount(src, target, type, flags, options)) { cxt->syscall_status = -errno; cxt->syscall_name = "mount"; diff --git a/libmount/src/hooks.c b/libmount/src/hooks.c index 88cf68d611..2d79162605 100644 --- a/libmount/src/hooks.c +++ b/libmount/src/hooks.c @@ -313,7 +313,12 @@ int mnt_context_has_hook(struct libmnt_context *cxt, static int call_hook(struct libmnt_context *cxt, struct hookset_hook *hook) { - int rc = hook->func(cxt, hook->hookset, hook->data); + int rc = 0; + + if (mnt_context_is_fake(cxt)) + DBG(CXT, ul_debugobj(cxt, " FAKE call")); + else + rc = hook->func(cxt, hook->hookset, hook->data); hook->executed = 1; if (!rc) @@ -359,7 +364,10 @@ int mnt_context_call_hooks(struct libmnt_context *cxt, int stage) DBG(CXT, ul_debugobj(cxt, "calling %s [first]", hs->name)); - rc = hs->firstcall(cxt, hs, NULL); + if (mnt_context_is_fake(cxt)) + DBG(CXT, ul_debugobj(cxt, " FAKE call")); + else + rc = hs->firstcall(cxt, hs, NULL); if (!rc) rc = call_depend_hooks(cxt, hs->name, stage); if (rc < 0) diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc index 74d2960e54..6283b535be 100644 --- a/sys-utils/mount.8.adoc +++ b/sys-utils/mount.8.adoc @@ -325,7 +325,11 @@ Note that *mount* does not pass this option to the **/sbin/mount.**__type__ help (Used in conjunction with *-a*.) Fork off a new incarnation of *mount* for each device. This will do the mounts on different devices or different NFS servers in parallel. This has the advantage that it is faster; also NFS timeouts proceed in parallel. A disadvantage is that the order of the mount operations is undefined. Thus, you cannot use this option if you want to mount both _/usr_ and _/usr/spool_. *-f, --fake*:: -Causes everything to be done except for the actual system call; if it's not obvious, this "fakes" mounting the filesystem. This option is useful in conjunction with the *-v* flag to determine what the *mount* command is trying to do. It can also be used to add entries for devices that were mounted earlier with the *-n* option. The *-f* option checks for an existing record in _/etc/mtab_ and fails when the record already exists (with a regular non-fake mount, this check is done by the kernel). +Causes everything to be done except for the mount-related system calls. The --fake option was originally designed to write an entry to /etc/mtab without actually mounting. ++ +The /etc/mtab is no longer maintained in userspace, and starting from version 2.39, the mount operation can be a complex chain of operations with dependencies between the syscalls. The --fake option forces libmount to skip all mount source preparation, mount option analysis, and the actual mounting process. ++ +The difference between fake and non-fake execution is huge. This is the reason why the --fake option has minimal significance for the current mount(8) implementation and it is maintained mostly for backward compatibility. *-i, --internal-only*:: Don't call the **/sbin/mount.**__filesystem__ helper even if it exists.