]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: cleanup --fake mode
authorKarel Zak <kzak@redhat.com>
Tue, 1 Aug 2023 12:49:48 +0000 (14:49 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 1 Aug 2023 12:49:48 +0000 (14:49 +0200)
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 <kzak@redhat.com>
libmount/src/context_mount.c
libmount/src/hook_mount.c
libmount/src/hook_mount_legacy.c
libmount/src/hooks.c
sys-utils/mount.8.adoc

index 05c84f17021d52ed3d078cba096235619c58c7fb..619e696326721826f32b2437f3f2791d2faa48c5 100644 (file)
@@ -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;
index ed4ec349ca32fe93c02b5dcbe78b5189710e2e80..d69a018ecc11006978afbd7899eb33ef12043ab0 100644 (file)
@@ -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)
index 2c07a015b8c5d3a6ed9217433667f09947bcd90f..7e62864673a46584607475536e69b160e71bcf79 100644 (file)
@@ -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 : "<none>"));
 
-       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";
index 88cf68d611104d2fa07ba32befc098f813bcb70e..2d7916260587ae76c34faafdeb212b22e727a7e6 100644 (file)
@@ -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)
index 74d2960e5401f4cf128553d741b6e96cf28a0d02..6283b535be4aa48c17fb62c8d304e17c1e195787 100644 (file)
@@ -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.