From: Karel Zak Date: Tue, 5 Apr 2022 09:43:24 +0000 (+0200) Subject: libmount: add --onlyonce X-Git-Tag: v2.39-rc1~734 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3d1c41c8cff0872d5ee6db8e9ba152ab8eb67e03;p=thirdparty%2Futil-linux.git libmount: add --onlyonce Signed-off-by: Karel Zak --- diff --git a/libmount/docs/libmount-sections.txt b/libmount/docs/libmount-sections.txt index 097e2f0663..f989688329 100644 --- a/libmount/docs/libmount-sections.txt +++ b/libmount/docs/libmount-sections.txt @@ -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 diff --git a/libmount/src/context.c b/libmount/src/context.c index 69fd8bf231..99ca58b9ff 100644 --- a/libmount/src/context.c +++ b/libmount/src/context.c @@ -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 diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c index 1fc3ff2cce..f09e688602 100644 --- a/libmount/src/context_mount.c +++ b/libmount/src/context_mount.c @@ -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")); } diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index 3bcf746828..43d8e44ceb 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -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) diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym index aa96091b1a..b8198c3dd2 100644 --- a/libmount/src/libmount.sym +++ b/libmount/src/libmount.sym @@ -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; diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index 908bf90b31..561ddcd8c1 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -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 */ diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc index 343d7e297f..7465fcd0d9 100644 --- a/sys-utils/mount.8.adoc +++ b/sys-utils/mount.8.adoc @@ -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. diff --git a/sys-utils/mount.c b/sys-utils/mount.c index ba4c78e3b0..283998f3be 100644 --- a/sys-utils/mount.c +++ b/sys-utils/mount.c @@ -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 comma-separated list of mount options\n" " -O, --test-opts 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();