6f0dbde58a
Resolves: RHEL-12783 RHEL-14612 RHEL-16048 RHEL-16071 RHEL-21257
189 lines
5.5 KiB
Diff
189 lines
5.5 KiB
Diff
From bc5aaf0e8b9105e5abd6aa6ff28294a39f5822bc Mon Sep 17 00:00:00 2001
|
|
From: Karel Zak <kzak@redhat.com>
|
|
Date: Wed, 29 Nov 2023 12:37:52 +0100
|
|
Subject: libmount: add missing utab options after helper call
|
|
|
|
libmount is able to add missing entry to /run/mount/utab after
|
|
external /sbin/mouht.<type> helper execution. This is not enough, it's
|
|
possible that the helper write proper entry to the utab, but there is
|
|
missing some options expected by libmount (usually because the options
|
|
are irrelevant fro the helper.
|
|
|
|
Reproducer:
|
|
|
|
Create a stupid mount.foo which writes x-foo=123 to utab:
|
|
|
|
# echo -e '#!/bin/bash\n\n/bin/mount -i "$1" "$2" -o x-foo=123' > /sbin/mount.foo
|
|
# chmod +x /sbin/mount.foo
|
|
|
|
Run mount which needs to write x-bar=BAR options to utab and executes
|
|
the helper (due to "-t foo", /dev/sdc1 is ext4):
|
|
|
|
# mount -t foo /dev/sdc1 /mnt/test -o x-bar=BAR
|
|
|
|
old mount:
|
|
|
|
# cat /run/mount/utab
|
|
ID=121 SRC=/dev/sdc1 TARGET=/mnt/test ROOT=/ OPTS=x-foo=123
|
|
|
|
fixed mount:
|
|
|
|
# cat /run/mount/utab
|
|
ID=121 SRC=/dev/sdc1 TARGET=/mnt/test ROOT=/ OPTS=x-foo=123,x-bar=BAR
|
|
|
|
Addresses: https://issues.redhat.com/browse/RHEL-14612
|
|
Upstream: http://github.com/util-linux/util-linux/commit/477401f0de404aafbc7630f70c2f8b1d670e32f8
|
|
Fixes: https://github.com/util-linux/util-linux/issues/2554
|
|
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
---
|
|
libmount/src/tab_update.c | 81 +++++++++++++++++++++++++++++++++++----
|
|
1 file changed, 74 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/libmount/src/tab_update.c b/libmount/src/tab_update.c
|
|
index b68553515..f60f522ce 100644
|
|
--- a/libmount/src/tab_update.c
|
|
+++ b/libmount/src/tab_update.c
|
|
@@ -37,7 +37,9 @@ struct libmnt_update {
|
|
char *filename;
|
|
unsigned long mountflags;
|
|
int userspace_only;
|
|
- int ready;
|
|
+
|
|
+ unsigned int ready : 1,
|
|
+ missing_options : 1;
|
|
|
|
struct libmnt_table *mountinfo;
|
|
};
|
|
@@ -183,7 +185,7 @@ int mnt_update_set_fs(struct libmnt_update *upd, unsigned long mountflags,
|
|
|
|
mnt_unref_fs(upd->fs);
|
|
free(upd->target);
|
|
- upd->ready = FALSE;
|
|
+ upd->ready = 0;
|
|
upd->fs = NULL;
|
|
upd->target = NULL;
|
|
upd->mountflags = 0;
|
|
@@ -218,7 +220,7 @@ int mnt_update_set_fs(struct libmnt_update *upd, unsigned long mountflags,
|
|
|
|
|
|
DBG(UPDATE, ul_debugobj(upd, "ready"));
|
|
- upd->ready = TRUE;
|
|
+ upd->ready = 1;
|
|
return 0;
|
|
}
|
|
|
|
@@ -778,6 +780,7 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l
|
|
return rc;
|
|
}
|
|
|
|
+/* replaces option in the table entry by new options from @udp */
|
|
static int update_modify_options(struct libmnt_update *upd, struct libmnt_lock *lc)
|
|
{
|
|
struct libmnt_table *tb = NULL;
|
|
@@ -820,6 +823,58 @@ static int update_modify_options(struct libmnt_update *upd, struct libmnt_lock *
|
|
return rc;
|
|
}
|
|
|
|
+/* add user options missing in the table entry by new options from @udp */
|
|
+static int update_add_options(struct libmnt_update *upd, struct libmnt_lock *lc)
|
|
+{
|
|
+ struct libmnt_table *tb = NULL;
|
|
+ int rc = 0;
|
|
+ struct libmnt_fs *fs;
|
|
+
|
|
+ assert(upd);
|
|
+ assert(upd->fs);
|
|
+
|
|
+ if (!upd->fs->user_optstr)
|
|
+ return 0;
|
|
+
|
|
+ DBG(UPDATE, ul_debugobj(upd, "%s: add options", upd->filename));
|
|
+
|
|
+ fs = upd->fs;
|
|
+
|
|
+ if (lc)
|
|
+ rc = mnt_lock_file(lc);
|
|
+ if (rc)
|
|
+ return -MNT_ERR_LOCK;
|
|
+
|
|
+ tb = __mnt_new_table_from_file(upd->filename, MNT_FMT_UTAB, 1);
|
|
+ if (tb) {
|
|
+ struct libmnt_fs *cur = mnt_table_find_target(tb,
|
|
+ mnt_fs_get_target(fs),
|
|
+ MNT_ITER_BACKWARD);
|
|
+ if (cur) {
|
|
+ char *u = NULL;
|
|
+
|
|
+ rc = mnt_optstr_get_missing(cur->user_optstr, upd->fs->user_optstr, &u);
|
|
+ if (!rc && u) {
|
|
+ DBG(UPDATE, ul_debugobj(upd, " add missing: %s", u));
|
|
+ rc = mnt_optstr_append_option(&cur->user_optstr, u, NULL);
|
|
+ }
|
|
+ if (!rc && u)
|
|
+ rc = update_table(upd, tb);
|
|
+
|
|
+ if (rc == 1) /* nothing is missing */
|
|
+ rc = 0;
|
|
+ } else
|
|
+ rc = add_file_entry(tb, upd); /* not found, add new */
|
|
+ }
|
|
+
|
|
+ if (lc)
|
|
+ mnt_unlock_file(lc);
|
|
+
|
|
+ mnt_unref_table(tb);
|
|
+ return rc;
|
|
+
|
|
+}
|
|
+
|
|
/**
|
|
* mnt_update_table:
|
|
* @upd: update
|
|
@@ -862,10 +917,12 @@ int mnt_update_table(struct libmnt_update *upd, struct libmnt_lock *lc)
|
|
rc = update_modify_target(upd, lc); /* move */
|
|
else if (upd->mountflags & MS_REMOUNT)
|
|
rc = update_modify_options(upd, lc); /* remount */
|
|
+ else if (upd->fs && upd->missing_options)
|
|
+ rc = update_add_options(upd, lc); /* mount by externel helper */
|
|
else if (upd->fs)
|
|
- rc = update_add_entry(upd, lc); /* mount */
|
|
+ rc = update_add_entry(upd, lc); /* mount */
|
|
|
|
- upd->ready = FALSE;
|
|
+ upd->ready = 1;
|
|
DBG(UPDATE, ul_debugobj(upd, "%s: update tab: done [rc=%d]",
|
|
upd->filename, rc));
|
|
if (lc != lc0)
|
|
@@ -908,16 +965,26 @@ int mnt_update_already_done(struct libmnt_update *upd, struct libmnt_lock *lc)
|
|
|
|
if (upd->fs) {
|
|
/* mount */
|
|
+ struct libmnt_fs *fs;
|
|
const char *tgt = mnt_fs_get_target(upd->fs);
|
|
const char *src = mnt_fs_get_bindsrc(upd->fs) ?
|
|
mnt_fs_get_bindsrc(upd->fs) :
|
|
mnt_fs_get_source(upd->fs);
|
|
|
|
- if (mnt_table_find_pair(tb, src, tgt, MNT_ITER_BACKWARD)) {
|
|
+ fs = mnt_table_find_pair(tb, src, tgt, MNT_ITER_BACKWARD);
|
|
+ if (fs) {
|
|
DBG(UPDATE, ul_debugobj(upd, "%s: found %s %s",
|
|
upd->filename, src, tgt));
|
|
+
|
|
+ /* Check if utab entry (probably writen by /sbin/mount.<type>
|
|
+ * helper) contains all options expected by this update */
|
|
+ if (mnt_optstr_get_missing(fs->user_optstr, upd->fs->user_optstr, NULL) == 0) {
|
|
+ upd->missing_options = 1;
|
|
+ DBG(UPDATE, ul_debugobj(upd, " missing options detected"));
|
|
+ }
|
|
+ } else
|
|
rc = 1;
|
|
- }
|
|
+
|
|
} else if (upd->target) {
|
|
/* umount */
|
|
if (!mnt_table_find_target(tb, upd->target, MNT_ITER_BACKWARD)) {
|
|
--
|
|
2.43.0
|
|
|