Skip to content

Commit a04149f

Browse files
committed
libmount: when moving a mount point, all sub mount entries in utab should also be updated
Given that /run/mount/utab stores paths, this file needs to be adjusted when a mount tree is moved. However the moved tree may contains sub mount points in which case their utab entries (if any) need to also be translated. This patch takes care of that. As suggested in systemd/systemd#15266, a better approach might be to store mount IDs instead of paths since mount IDs remain unchanged when mount trees are moved. Fixes: #1659
1 parent ef7d50a commit a04149f

File tree

1 file changed

+38
-6
lines changed

1 file changed

+38
-6
lines changed

libmount/src/tab_update.c

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "mountP.h"
3131
#include "mangle.h"
3232
#include "pathnames.h"
33+
#include "strutils.h"
3334

3435
struct libmnt_update {
3536
char *target;
@@ -762,13 +763,44 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l
762763
tb = __mnt_new_table_from_file(upd->filename,
763764
upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
764765
if (tb) {
765-
struct libmnt_fs *cur = mnt_table_find_target(tb,
766-
mnt_fs_get_srcpath(upd->fs), MNT_ITER_BACKWARD);
767-
if (cur) {
768-
rc = mnt_fs_set_target(cur, mnt_fs_get_target(upd->fs));
769-
if (!rc)
770-
rc = update_table(upd, tb);
766+
const char *upd_source = mnt_fs_get_srcpath(upd->fs);
767+
const char *upd_target = mnt_fs_get_target(upd->fs);
768+
struct libmnt_iter itr;
769+
struct libmnt_fs *fs;
770+
771+
mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
772+
while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
773+
char *p, *e;
774+
size_t len;
775+
776+
e = startswith(mnt_fs_get_target(fs), upd_source);
777+
if (!e)
778+
continue;
779+
780+
len = strlen(upd_target) + strlen(e) + 2;
781+
p = malloc(len);
782+
if (!p)
783+
rc = -ENOMEM;
784+
else {
785+
char *cn;
786+
787+
strcpy(p, upd_target);
788+
strcat(p, "/");
789+
strcat(p, e);
790+
791+
cn = mnt_resolve_path(p, NULL);
792+
rc = mnt_fs_set_target(fs, cn);
793+
794+
free(cn);
795+
free(p);
796+
}
797+
798+
if (rc < 0)
799+
break;
771800
}
801+
802+
if (!rc)
803+
rc = update_table(upd, tb);
772804
}
773805

774806
if (lc)

0 commit comments

Comments
 (0)