File util-linux-libmount-moving-mount-point-sub-mounts.patch of Package python3-libmount.33156

From a04149fbb7c1952da1194d1514e298ff07dbc7ca Mon Sep 17 00:00:00 2001
From: Franck Bui <fbui@suse.com>
Date: Fri, 22 Apr 2022 11:30:09 +0200
Subject: [PATCH 1/2] 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 https://github.com/systemd/systemd/issues/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
---
 libmount/src/tab_update.c | 44 +++++++++++++++++++++++++++++++++------
 1 file changed, 38 insertions(+), 6 deletions(-)

diff --git a/libmount/src/tab_update.c b/libmount/src/tab_update.c
index b68553515..51f2fae26 100644
--- a/libmount/src/tab_update.c
+++ b/libmount/src/tab_update.c
@@ -30,6 +30,7 @@
 #include "mountP.h"
 #include "mangle.h"
 #include "pathnames.h"
+#include "strutils.h"
 
 struct libmnt_update {
 	char		*target;
@@ -762,13 +763,44 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l
 	tb = __mnt_new_table_from_file(upd->filename,
 			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
 	if (tb) {
-		struct libmnt_fs *cur = mnt_table_find_target(tb,
-				mnt_fs_get_srcpath(upd->fs), MNT_ITER_BACKWARD);
-		if (cur) {
-			rc = mnt_fs_set_target(cur, mnt_fs_get_target(upd->fs));
-			if (!rc)
-				rc = update_table(upd, tb);
+		const char *upd_source = mnt_fs_get_srcpath(upd->fs);
+		const char *upd_target = mnt_fs_get_target(upd->fs);
+		struct libmnt_iter itr;
+		struct libmnt_fs *fs;
+
+		mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
+		while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
+			char *p, *e;
+			size_t len;
+
+			e = startswith(mnt_fs_get_target(fs), upd_source);
+			if (!e)
+				continue;
+
+			len = strlen(upd_target) + strlen(e) + 2;
+			p = malloc(len);
+			if (!p)
+				rc = -ENOMEM;
+			else {
+				char *cn;
+
+				strcpy(p, upd_target);
+				strcat(p, "/");
+				strcat(p, e);
+
+				cn = mnt_resolve_path(p, NULL);
+				rc = mnt_fs_set_target(fs, cn);
+
+				free(cn);
+				free(p);
+			}
+
+			if (rc < 0)
+				break;
 		}
+
+		if (!rc)
+			rc = update_table(upd, tb);
 	}
 
 	if (lc)
-- 
2.35.1

openSUSE Build Service is sponsored by