]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add --onlyonce
authorKarel Zak <kzak@redhat.com>
Tue, 5 Apr 2022 09:43:24 +0000 (11:43 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 5 Apr 2022 09:43:24 +0000 (11:43 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/docs/libmount-sections.txt
libmount/src/context.c
libmount/src/context_mount.c
libmount/src/libmount.h.in
libmount/src/libmount.sym
libmount/src/mountP.h
sys-utils/mount.8.adoc
sys-utils/mount.c

index 097e2f06630e986f1379980d88e51afb4612b70b..f989688329eb96f28223bbee35620eeaa190b4b3 100644 (file)
@@ -35,6 +35,7 @@ mnt_context_enable_force
 mnt_context_enable_fork
 mnt_context_enable_lazy
 mnt_context_enable_loopdel
+mnt_context_enable_onlyonce
 mnt_context_enable_rdonly_umount
 mnt_context_enable_rwonly_mount
 mnt_context_enable_sloppy
@@ -77,6 +78,7 @@ mnt_context_is_loopdel
 mnt_context_is_nocanonicalize
 mnt_context_is_nohelpers
 mnt_context_is_nomtab
+mnt_context_is_onlyonce
 mnt_context_is_parent
 mnt_context_is_rdonly_umount
 mnt_context_is_restricted
index 69fd8bf2314464044e37cf7c68a85c26fea74f94..99ca58b9ffc80ca1801053de060fd9614b20b577 100644 (file)
@@ -569,6 +569,31 @@ int mnt_context_is_lazy(struct libmnt_context *cxt)
        return cxt->flags & MNT_FL_LAZY ? 1 : 0;
 }
 
+/**
+ * mnt_context_enable_onlyonce:
+ * @cxt: mount context
+ * @enable: TRUE or FALSE
+ *
+ * Enable/disable only-once mount (check if FS is not already mounted).
+ *
+ * Returns: 0 on success, negative number in case of error.
+ */
+int mnt_context_enable_onlyonce(struct libmnt_context *cxt, int enable)
+{
+       return set_flag(cxt, MNT_FL_ONLYONCE, enable);
+}
+
+/**
+ * mnt_context_is_lazy:
+ * @cxt: mount context
+ *
+ * Returns: 1 if lazy umount is enabled or 0
+ */
+int mnt_context_is_onlyonce(struct libmnt_context *cxt)
+{
+       return cxt->flags & MNT_FL_ONLYONCE ? 1 : 0;
+}
+
 /**
  * mnt_context_enable_fork:
  * @cxt: mount context
index 1fc3ff2cce5da44bcd90e7c7d8965c796bf4bdb9..f09e6886020d88abed163539f9df9b80417ea587 100644 (file)
@@ -1066,10 +1066,20 @@ int mnt_context_prepare_mount(struct libmnt_context *cxt)
                rc = mnt_context_prepare_target(cxt);
        if (!rc)
                rc = mnt_context_prepare_helper(cxt, "mount", NULL);
+
+       if (!rc && mnt_context_is_onlyonce(cxt)) {
+               int mounted = 0;
+               rc = mnt_context_is_fs_mounted(cxt, cxt->fs, &mounted);
+               if (rc == 0 && mounted == 1) {
+                       rc = -MNT_ERR_ONLYONCE;
+                       goto end;
+               }
+       }
        if (rc) {
                DBG(CXT, ul_debugobj(cxt, "mount: preparing failed"));
                goto end;
        }
+
        cxt->flags |= MNT_FL_PREPARED;
 
 end:
@@ -1411,6 +1421,9 @@ int mnt_context_next_mount(struct libmnt_context *cxt,
        if (!cxt || !fs || !itr)
                return -EINVAL;
 
+       /* ingore --onlyonce, it's default behavior for --all */
+       mnt_context_enable_onlyonce(cxt, 0);
+
        rc = mnt_context_get_fstab(cxt, &fstab);
        if (rc)
                return rc;
@@ -1805,6 +1818,10 @@ int mnt_context_get_mount_excode(
                        if (buf)
                                snprintf(buf, bufsz, _("failed to switch namespace"));
                        return MNT_EX_SYSERR;
+               case -MNT_ERR_ONLYONCE:
+                       if (buf)
+                               snprintf(buf, bufsz, _("filesystem already mounted"));
+                       return MNT_EX_FAIL;
                default:
                        return mnt_context_get_generic_excode(rc, buf, bufsz, _("mount failed: %m"));
                }
index 3bcf746828a4c3437793bd5ab969012e8959f100..43d8e44cebadf2c702477ed511278fa663ce58a5 100644 (file)
@@ -214,6 +214,12 @@ enum {
  * failed to switch namespace
  */
 #define MNT_ERR_NAMESPACE    5009
+/**
+ * MNT_ERR_ONLYONCE:
+ *
+ * filesystem mounted, but --onlyonce specified
+ */
+#define MNT_ERR_ONLYONCE    5010
 
 
 /*
@@ -717,6 +723,7 @@ extern int mnt_context_helper_setopt(struct libmnt_context *cxt, int c, char *ar
 
 extern int mnt_context_set_optsmode(struct libmnt_context *cxt, int mode);
 extern int mnt_context_disable_canonicalize(struct libmnt_context *cxt, int disable);
+extern int mnt_context_enable_onlyonce(struct libmnt_context *cxt, int enable);
 extern int mnt_context_enable_lazy(struct libmnt_context *cxt, int enable);
 extern int mnt_context_enable_rdonly_umount(struct libmnt_context *cxt, int enable);
 extern int mnt_context_enable_rwonly_mount(struct libmnt_context *cxt, int enable);
@@ -732,6 +739,8 @@ extern int mnt_context_disable_swapmatch(struct libmnt_context *cxt, int disable
 
 extern int mnt_context_get_optsmode(struct libmnt_context *cxt);
 
+extern int mnt_context_is_onlyonce(struct libmnt_context *cxt)
+                       __ul_attribute__((nonnull));
 extern int mnt_context_is_lazy(struct libmnt_context *cxt)
                        __ul_attribute__((nonnull));
 extern int mnt_context_is_rdonly_umount(struct libmnt_context *cxt)
index aa96091b1abcb4c5e5b871037984a86f61ade774..b8198c3dd2d8b3284e9a47a04c624a6b27ec43c6 100644 (file)
@@ -366,3 +366,8 @@ MOUNT_2_37 {
 MOUNT_2_38 {
        mnt_fs_is_regularfs;
 } MOUNT_2_37;
+
+MOUNT_2_39 {
+       mnt_context_enable_onlyonce;
+       mnt_context_is_lazy;
+} MOUNT_2_38;
index 908bf90b310d9c52a1c73169be197396c758c587..561ddcd8c1c0f057b408608f9c10a997b965fc93 100644 (file)
@@ -368,6 +368,7 @@ struct libmnt_context
 #define MNT_FL_FORK            (1 << 12)
 #define MNT_FL_NOSWAPMATCH     (1 << 13)
 #define MNT_FL_RWONLY_MOUNT    (1 << 14)       /* explicit mount -w; never try read-only  */
+#define MNT_FL_ONLYONCE                (1 << 15)
 
 #define MNT_FL_MOUNTDATA       (1 << 20)
 #define MNT_FL_TAB_APPLIED     (1 << 21)       /* mtab/fstab merged to cxt->fs */
index 343d7e297f82df98b227957109c4e06464dfe67b..7465fcd0d99af8317f3741c8772a7749487813aa 100644 (file)
@@ -372,6 +372,9 @@ Use the specified mount options. The _opts_ argument is a comma-separated list.
 +
 For more details, see the *FILESYSTEM-INDEPENDENT MOUNT OPTIONS* and *FILESYSTEM-SPECIFIC MOUNT OPTIONS* sections.
 
+*--onlyonce*::
+Forces mount command to check if the filesystem is already mounted. This behavior is the default for *--all*; otherwise, it depends on the kernel filesystem driver. Some filesystems may be mounted more than once on the same mount point (e.g. tmpfs).
+
 *--options-mode* _mode_::
 Controls how to combine options from _fstab_/_mtab_ with options from the command line. _mode_ can be one of *ignore*, *append*, *prepend* or *replace*. For example, *append* means that options from _fstab_ are appended to options from the command line. The default value is *prepend* -- it means command line options are evaluated after _fstab_ options. Note that the last option wins if there are conflicting ones.
 
index ba4c78e3b01df5b1915846836a56deb73989f0ed..283998f3be3f8c7dced0b21adb2635c1a5576f35 100644 (file)
@@ -513,6 +513,8 @@ static void __attribute__((__noreturn__)) usage(void)
        "     --options-source-force\n"
        "                         force use of options from fstab/mtab\n"));
        fprintf(out, _(
+       "     --onlyonce          check if filesystem is already mounted\n"));
+       fprintf(out, _(
        " -o, --options <list>    comma-separated list of mount options\n"
        " -O, --test-opts <list>  limit the set of filesystems (use with -a)\n"
        " -r, --read-only         mount the filesystem read-only (same as -o ro)\n"
@@ -647,7 +649,8 @@ int main(int argc, char **argv)
                MOUNT_OPT_SOURCE,
                MOUNT_OPT_OPTMODE,
                MOUNT_OPT_OPTSRC,
-               MOUNT_OPT_OPTSRC_FORCE
+               MOUNT_OPT_OPTSRC_FORCE,
+               MOUNT_OPT_ONLYONCE
        };
 
        static const struct option longopts[] = {
@@ -686,6 +689,7 @@ int main(int argc, char **argv)
                { "target",           required_argument, NULL, MOUNT_OPT_TARGET      },
                { "target-prefix",    required_argument, NULL, MOUNT_OPT_TARGET_PREFIX },
                { "source",           required_argument, NULL, MOUNT_OPT_SOURCE      },
+               { "onlyonce",         no_argument,       NULL, MOUNT_OPT_ONLYONCE    },
                { "options-mode",     required_argument, NULL, MOUNT_OPT_OPTMODE     },
                { "options-source",   required_argument, NULL, MOUNT_OPT_OPTSRC      },
                { "options-source-force",   no_argument, NULL, MOUNT_OPT_OPTSRC_FORCE},
@@ -891,7 +895,9 @@ int main(int argc, char **argv)
                case MOUNT_OPT_OPTSRC_FORCE:
                        optmode |= MNT_OMODE_FORCE;
                        break;
-
+               case MOUNT_OPT_ONLYONCE:
+                       mnt_context_enable_onlyonce(cxt, 1);
+                       break;
                case 'h':
                        mnt_free_context(cxt);
                        usage();