Jan Engelhardt
ae5a1c3844
- Add patch to fix regression with mount options handling (gh#util-linux/util-linux#2326): * 0001-libmount-fix-sync-options-between-context-and-fs-str.patch - Set --disable-libmount-mountfd-support, it's very broken and needs both util-linux and kernel fixes (gh#util-linux/util-linux#2287) OBS-URL: https://build.opensuse.org/request/show/1094801 OBS-URL: https://build.opensuse.org/package/show/Base:System/util-linux?expand=0&rev=516
214 lines
5.3 KiB
Diff
214 lines
5.3 KiB
Diff
From 7b37d5b5667103beac16f7ae3cca5feaf00a21b0 Mon Sep 17 00:00:00 2001
|
|
From: Karel Zak <kzak@redhat.com>
|
|
Date: Thu, 22 Jun 2023 13:11:57 +0200
|
|
Subject: [PATCH] libmount: fix sync options between context and fs structs
|
|
|
|
Since v2.39 libmount prefers "struct libmnt_optlist" to keep mount options
|
|
rather than the original "struct libmnt_fs". This is problem if the
|
|
"fs" struct is defined and maintained outside the context.
|
|
|
|
The library has already a way how to sync "fs" and "optlist", but this
|
|
needs to be improved and used more widely. Changes:
|
|
|
|
* force "fs" from context to always read options from "optlist"
|
|
|
|
* copy options from "fs" to "optlist" in mnt_context_set_fs()
|
|
|
|
* internally redirect mnt_fs_* API for options to "optlist" if optlist
|
|
defined
|
|
|
|
* add simple test to make sure options from different sources are
|
|
always merged together
|
|
|
|
Addresses: https://github.com/util-linux/util-linux/issues/2326
|
|
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
---
|
|
libmount/src/context.c | 82 ++++++++++++++++++++++++++++++++++++++++--
|
|
libmount/src/fs.c | 23 +++++++++---
|
|
2 files changed, 97 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/libmount/src/context.c b/libmount/src/context.c
|
|
index 4c5e65659..0cd320190 100644
|
|
--- a/libmount/src/context.c
|
|
+++ b/libmount/src/context.c
|
|
@@ -911,9 +911,29 @@ int mnt_context_set_fs(struct libmnt_context *cxt, struct libmnt_fs *fs)
|
|
if (!cxt)
|
|
return -EINVAL;
|
|
|
|
+ if (cxt->fs == fs)
|
|
+ return 0;
|
|
+
|
|
DBG(CXT, ul_debugobj(cxt, "setting new FS"));
|
|
- mnt_ref_fs(fs); /* new */
|
|
- mnt_unref_fs(cxt->fs); /* old */
|
|
+
|
|
+ /* new */
|
|
+ if (fs) {
|
|
+ struct libmnt_optlist *ol = mnt_context_get_optlist(cxt);
|
|
+
|
|
+ if (!ol)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ mnt_ref_fs(fs);
|
|
+
|
|
+ mnt_optlist_set_optstr(ol, mnt_fs_get_options(fs), NULL);
|
|
+ mnt_fs_follow_optlist(fs, ol);
|
|
+ }
|
|
+
|
|
+ /* old */
|
|
+ if (cxt->fs)
|
|
+ mnt_fs_follow_optlist(cxt->fs, NULL);
|
|
+ mnt_unref_fs(cxt->fs);
|
|
+
|
|
cxt->fs = fs;
|
|
return 0;
|
|
}
|
|
@@ -932,8 +952,17 @@ struct libmnt_fs *mnt_context_get_fs(struct libmnt_context *cxt)
|
|
{
|
|
if (!cxt)
|
|
return NULL;
|
|
- if (!cxt->fs)
|
|
+ if (!cxt->fs) {
|
|
+ struct libmnt_optlist *ol = mnt_context_get_optlist(cxt);
|
|
+
|
|
+ if (!ol)
|
|
+ return NULL;
|
|
cxt->fs = mnt_new_fs();
|
|
+ if (!cxt->fs)
|
|
+ return NULL;
|
|
+
|
|
+ mnt_fs_follow_optlist(cxt->fs, ol);
|
|
+ }
|
|
return cxt->fs;
|
|
}
|
|
|
|
@@ -3314,6 +3343,50 @@ static int test_flags(struct libmnt_test *ts, int argc, char *argv[])
|
|
return rc;
|
|
}
|
|
|
|
+static int test_cxtsync(struct libmnt_test *ts, int argc, char *argv[])
|
|
+{
|
|
+ struct libmnt_context *cxt;
|
|
+ struct libmnt_fs *fs;
|
|
+ unsigned long flags = 0;
|
|
+ int rc;
|
|
+
|
|
+ if (argc != 4)
|
|
+ return -EINVAL;
|
|
+
|
|
+ fs = mnt_new_fs();
|
|
+ if (!fs)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ rc = mnt_fs_set_options(fs, argv[1]);
|
|
+ if (rc)
|
|
+ return rc;
|
|
+
|
|
+ cxt = mnt_new_context();
|
|
+ if (!cxt)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ rc = mnt_context_set_fs(cxt, fs);
|
|
+ if (rc)
|
|
+ return rc;
|
|
+
|
|
+ rc = mnt_context_append_options(cxt, argv[2]);
|
|
+ if (rc)
|
|
+ return rc;
|
|
+
|
|
+ rc = mnt_fs_append_options(fs, argv[3]);
|
|
+ if (rc)
|
|
+ return rc;
|
|
+
|
|
+ mnt_context_get_mflags(cxt, &flags);
|
|
+
|
|
+ printf(" fs options: %s\n", mnt_fs_get_options(fs));
|
|
+ printf("context options: %s\n", mnt_context_get_options(cxt));
|
|
+ printf(" context mflags: %08lx\n", flags);
|
|
+
|
|
+ mnt_free_context(cxt);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int test_mountall(struct libmnt_test *ts, int argc, char *argv[])
|
|
{
|
|
struct libmnt_context *cxt;
|
|
@@ -3361,6 +3434,8 @@ static int test_mountall(struct libmnt_test *ts, int argc, char *argv[])
|
|
return 0;
|
|
}
|
|
|
|
+
|
|
+
|
|
int main(int argc, char *argv[])
|
|
{
|
|
struct libmnt_test tss[] = {
|
|
@@ -3368,6 +3443,7 @@ int main(int argc, char *argv[])
|
|
{ "--umount", test_umount, "[-t <type>] [-f][-l][-r] <src>|<target>" },
|
|
{ "--mount-all", test_mountall, "[-O <pattern>] [-t <pattern] mount all filesystems from fstab" },
|
|
{ "--flags", test_flags, "[-o <opts>] <spec>" },
|
|
+ { "--cxtsync", test_cxtsync, "<fsopts> <cxtopts> <fsopts>" },
|
|
{ "--search-helper", test_search_helper, "<fstype>" },
|
|
{ NULL }};
|
|
|
|
diff --git a/libmount/src/fs.c b/libmount/src/fs.c
|
|
index 655f07171..79e32a170 100644
|
|
--- a/libmount/src/fs.c
|
|
+++ b/libmount/src/fs.c
|
|
@@ -228,10 +228,14 @@ int mnt_fs_follow_optlist(struct libmnt_fs *fs, struct libmnt_optlist *ol)
|
|
|
|
if (fs->optlist == ol)
|
|
return 0;
|
|
+ if (fs->optlist)
|
|
+ mnt_unref_optlist(fs->optlist);
|
|
|
|
fs->opts_age = 0;
|
|
fs->optlist = ol;
|
|
- mnt_ref_optlist(ol);
|
|
+
|
|
+ if (ol)
|
|
+ mnt_ref_optlist(ol);
|
|
return 0;
|
|
}
|
|
|
|
@@ -919,7 +923,11 @@ int mnt_fs_set_options(struct libmnt_fs *fs, const char *optstr)
|
|
|
|
if (!fs)
|
|
return -EINVAL;
|
|
- fs->opts_age = 0;
|
|
+
|
|
+ if (fs->optlist) {
|
|
+ fs->opts_age = 0;
|
|
+ return mnt_optlist_set_optstr(fs->optlist, optstr, NULL);
|
|
+ }
|
|
|
|
if (optstr) {
|
|
int rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0);
|
|
@@ -968,8 +976,10 @@ int mnt_fs_append_options(struct libmnt_fs *fs, const char *optstr)
|
|
return -EINVAL;
|
|
if (!optstr)
|
|
return 0;
|
|
-
|
|
- fs->opts_age = 0;
|
|
+ if (fs->optlist) {
|
|
+ fs->opts_age = 0;
|
|
+ return mnt_optlist_append_optstr(fs->optlist, optstr, NULL);
|
|
+ }
|
|
|
|
rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0);
|
|
if (rc)
|
|
@@ -1013,7 +1023,10 @@ int mnt_fs_prepend_options(struct libmnt_fs *fs, const char *optstr)
|
|
if (!optstr)
|
|
return 0;
|
|
|
|
- fs->opts_age = 0;
|
|
+ if (fs->optlist) {
|
|
+ fs->opts_age = 0;
|
|
+ return mnt_optlist_prepend_optstr(fs->optlist, optstr, NULL);
|
|
+ }
|
|
|
|
rc = mnt_split_optstr(optstr, &u, &v, &f, 0, 0);
|
|
if (rc)
|
|
--
|
|
2.41.0
|
|
|