From: Karel Zak Date: Thu, 31 Jul 2025 10:28:33 +0000 (+0200) Subject: libmount: Add support for FSCONFIG_CMD_CREATE_EXCL X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=be65bf2d93df3f89d488250575400449a6a1ae3c;p=thirdparty%2Futil-linux.git libmount: Add support for FSCONFIG_CMD_CREATE_EXCL * Add API functions mnt_context_enable_exclusive() and mnt_context_is_exclusive() * Use the new flag when creating the superblock Signed-off-by: Karel Zak --- diff --git a/libmount/docs/libmount-sections.txt b/libmount/docs/libmount-sections.txt index bb43f71f2..60dffba7e 100644 --- a/libmount/docs/libmount-sections.txt +++ b/libmount/docs/libmount-sections.txt @@ -31,6 +31,7 @@ mnt_context_disable_canonicalize mnt_context_disable_helpers mnt_context_disable_mtab mnt_context_disable_swapmatch +mnt_context_enable_exclusive mnt_context_enable_fake mnt_context_enable_force mnt_context_enable_fork @@ -71,6 +72,7 @@ mnt_context_helper_executed mnt_context_helper_setopt mnt_context_init_helper mnt_context_is_child +mnt_context_is_exclusive mnt_context_is_fake mnt_context_is_force mnt_context_is_fork diff --git a/libmount/src/context.c b/libmount/src/context.c index 55cf75ddd..122d2dbf2 100644 --- a/libmount/src/context.c +++ b/libmount/src/context.c @@ -572,7 +572,7 @@ int mnt_context_is_lazy(struct libmnt_context *cxt) * @cxt: mount context * @enable: TRUE or FALSE * - * Enable/disable only-once mount (check if FS is not already mounted). + * Enable/disable only-once mount (check if source + target is not already mounted). * * Returns: 0 on success, negative number in case of error. */ @@ -592,6 +592,31 @@ int mnt_context_is_onlyonce(struct libmnt_context *cxt) return cxt->flags & MNT_FL_ONLYONCE ? 1 : 0; } +/** + * mnt_context_enable_exclusive + * @cxt: mount context + * @enable: TRUE or FALSE + * + * Enable/disable exclusive mount (only one FS instance is allowed). + * + * Returns: 0 on success, negative number in case of error. + */ +int mnt_context_enable_exclusive(struct libmnt_context *cxt, int enable) +{ + return set_flag(cxt, MNT_FL_EXCL, enable); +} + +/** + * mnt_context_is_exclusive: + * @cxt: mount context + * + * Returns: 1 if exclisive mount is enabled or 0 + */ +int mnt_context_is_exclusive(struct libmnt_context *cxt) +{ + return cxt->flags & MNT_FL_EXCL ? 1 : 0; +} + /** * mnt_context_enable_fork: * @cxt: mount context diff --git a/libmount/src/hook_mount.c b/libmount/src/hook_mount.c index 35f3a8d74..b545d2441 100644 --- a/libmount/src/hook_mount.c +++ b/libmount/src/hook_mount.c @@ -216,6 +216,26 @@ done: return rc != 0 && errno ? -errno : rc; } +static int create_superblock(struct libmnt_context *cxt, + const struct libmnt_hookset *hs, int fd) +{ + int rc = 0; + + DBG(HOOK, ul_debugobj(hs, " create FS %s", + mnt_context_is_exclusive(cxt) ? "excl" : "")); + errno = 0; + + if (mnt_context_is_exclusive(cxt)) + rc = fsconfig(fd, FSCONFIG_CMD_CREATE_EXCL, NULL, NULL, 0); + else + rc = fsconfig(fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0); + + hookset_set_syscall_status(cxt, "fsconfig", rc == 0); + + DBG(HOOK, ul_debugobj(hs, " create done [rc=%d]", rc)); + return rc != 0 && errno ? -errno : rc;; +} + static int open_fs_configuration_context(struct libmnt_context *cxt, struct libmnt_sysapi *api, const char *type) @@ -272,11 +292,8 @@ static int hook_create_mount(struct libmnt_context *cxt, if (!rc) rc = configure_superblock(cxt, hs, api->fd_fs, 0); - if (!rc) { - DBG(HOOK, ul_debugobj(hs, "create FS")); - rc = fsconfig(api->fd_fs, FSCONFIG_CMD_CREATE, NULL, NULL, 0); - hookset_set_syscall_status(cxt, "fsconfig", rc == 0); - } + if (!rc) + rc = create_superblock(cxt, hs, api->fd_fs); if (!rc) { int fd = fsmount(api->fd_fs, FSMOUNT_CLOEXEC, 0); diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index 9d173ff0e..f30f94cdc 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -803,6 +803,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_exclusive(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); @@ -820,6 +821,8 @@ 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_exclusive(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 284869a35..cbef26fb0 100644 --- a/libmount/src/libmount.sym +++ b/libmount/src/libmount.sym @@ -408,3 +408,8 @@ MOUNT_2_41 { mnt_table_refer_statmnt; mnt_unref_statmnt; } MOUNT_2_40; + +MOUNT_2_42 { + mnt_context_enable_exclusive; + mnt_context_is_exclusive; +} MOUNT_2_41; diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index f4d80c5df..7c504f95c 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -516,6 +516,7 @@ struct libmnt_context #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_EXCL (1 << 16) #define MNT_FL_MOUNTDATA (1 << 20) #define MNT_FL_TAB_APPLIED (1 << 21) /* fstab merged to cxt->fs */