aboutsummaryrefslogtreecommitdiffstats
path: root/libmount/src
diff options
context:
space:
mode:
authorKarel Zak <kzak@redhat.com>2025-06-19 12:23:57 +0200
committerKarel Zak <kzak@redhat.com>2025-06-19 12:27:35 +0200
commitc8e5b8a818323af30ec656f079c7feadaeeb13c3 (patch)
treea0b1d26284de9e84ca033f8078d695dcefd2f7bf /libmount/src
parent10f0de325d016d7f0fcdbb07372292bd406fdb96 (diff)
downloadutil-linux-c8e5b8a818323af30ec656f079c7feadaeeb13c3.tar.gz
libmount: don't update utab when moving /run
It's bad idea to try update /run/mount/utab when moving any directory in way to the file (like /run). It's also unnecessary to prepare any updates if the utab file is empty. This is already done for umount, and we can use it for mount move as well. Fixes: https://github.com/util-linux/util-linux/issues/3619 Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src')
-rw-r--r--libmount/src/context.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/libmount/src/context.c b/libmount/src/context.c
index 46bbe378a3..dfecab788d 100644
--- a/libmount/src/context.c
+++ b/libmount/src/context.c
@@ -2201,8 +2201,9 @@ int mnt_context_merge_mflags(struct libmnt_context *cxt)
int mnt_context_prepare_update(struct libmnt_context *cxt)
{
int rc;
- const char *target, *name;
+ const char *target, *source, *name;
unsigned long flags = 0;
+ struct libmnt_optlist *ol;
assert(cxt);
assert(cxt->fs);
@@ -2217,6 +2218,7 @@ int mnt_context_prepare_update(struct libmnt_context *cxt)
}
target = mnt_fs_get_target(cxt->fs);
+ source = mnt_fs_get_srcpath(cxt->fs);
if (cxt->action == MNT_ACT_UMOUNT && target && !strcmp(target, "/")) {
DBG(CXT, ul_debugobj(cxt, "root umount: setting NOMTAB"));
@@ -2231,6 +2233,7 @@ int mnt_context_prepare_update(struct libmnt_context *cxt)
DBG(CXT, ul_debugobj(cxt, "skip update: no writable destination"));
return 0;
}
+
/* 0 = success, 1 = not called yet */
if (cxt->syscall_status != 1 && cxt->syscall_status != 0) {
DBG(CXT, ul_debugobj(cxt,
@@ -2239,12 +2242,24 @@ int mnt_context_prepare_update(struct libmnt_context *cxt)
return 0;
}
- if (!cxt->update) {
- if (cxt->action == MNT_ACT_UMOUNT && is_file_empty(name)) {
- DBG(CXT, ul_debugobj(cxt, "skip update: umount, no table"));
- return 0;
- }
+ ol = mnt_context_get_optlist(cxt);
+ if (!ol)
+ return -ENOMEM;
+ if ((cxt->action == MNT_ACT_UMOUNT || mnt_optlist_is_move(ol))
+ && is_file_empty(name)) {
+ DBG(CXT, ul_debugobj(cxt, "skip update: umount/move, empty table"));
+ return 0;
+ }
+
+ if (mnt_optlist_is_move(ol) &&
+ ((target && startswithpath(name, target))
+ || (source && startswithpath(name, source)))) {
+ DBG(CXT, ul_debugobj(cxt, "skip update: utab move"));
+ return 0;
+ }
+
+ if (!cxt->update) {
cxt->update = mnt_new_update();
if (!cxt->update)
return -ENOMEM;