95 lines
2.5 KiB
Diff
95 lines
2.5 KiB
Diff
From 1ec32f426c0f4705ea4e6e33b812b3b4c2c47faa Mon Sep 17 00:00:00 2001
|
|
From: Karel Zak <kzak@redhat.com>
|
|
Date: Wed, 4 May 2022 12:13:08 +0200
|
|
Subject: [PATCH 2/2] libmount: fix and improve utab update on MS_MOVE
|
|
|
|
* avoid double '//'
|
|
|
|
* don't update /fooxxx when /foo update requested (make sure that
|
|
startswith() returns path terminated by '/')
|
|
|
|
* canonicalize only once the new path -- all in utab/mtab is already
|
|
canonicalized, so after MS_MOVE we need to care about the new path
|
|
only
|
|
|
|
* use asprintf() rather than strcpy() and strcat(), don't compose a
|
|
new path from prefix and subdir when replace entire path
|
|
|
|
Addresses: https://github.com/util-linux/util-linux/pull/1660
|
|
Signed-off-by: Karel Zak <kzak@redhat.com>
|
|
---
|
|
libmount/src/tab_update.c | 41 +++++++++++++++++++++------------------
|
|
1 file changed, 22 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/libmount/src/tab_update.c b/libmount/src/tab_update.c
|
|
index 51f2fae26..3a22e7188 100644
|
|
--- a/libmount/src/tab_update.c
|
|
+++ b/libmount/src/tab_update.c
|
|
@@ -767,33 +767,34 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l
|
|
const char *upd_target = mnt_fs_get_target(upd->fs);
|
|
struct libmnt_iter itr;
|
|
struct libmnt_fs *fs;
|
|
+ char *cn_target = mnt_resolve_path(upd_target, NULL);
|
|
+
|
|
+ if (!cn_target) {
|
|
+ rc = -ENOMEM;
|
|
+ goto done;
|
|
+ }
|
|
|
|
mnt_reset_iter(&itr, MNT_ITER_BACKWARD);
|
|
- while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
|
|
- char *p, *e;
|
|
- size_t len;
|
|
+ while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
|
|
+ char *p;
|
|
+ const char *e;
|
|
|
|
e = startswith(mnt_fs_get_target(fs), upd_source);
|
|
- if (!e)
|
|
+ if (!e || (*e && *e != '/'))
|
|
continue;
|
|
+ if (*e == '/')
|
|
+ e++; /* remove extra '/' */
|
|
|
|
- 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);
|
|
+ /* no subdirectory, replace entire path */
|
|
+ if (!*e)
|
|
+ rc = mnt_fs_set_target(fs, cn_target);
|
|
|
|
- free(cn);
|
|
+ /* update start of the path, keep subdirectory */
|
|
+ else if (asprintf(&p, "%s/%s", cn_target, e) > 0) {
|
|
+ rc = mnt_fs_set_target(fs, p);
|
|
free(p);
|
|
- }
|
|
+ } else
|
|
+ rc = -ENOMEM;
|
|
|
|
if (rc < 0)
|
|
break;
|
|
@@ -801,8 +802,10 @@ static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *l
|
|
|
|
if (!rc)
|
|
rc = update_table(upd, tb);
|
|
+ free(cn_target);
|
|
}
|
|
|
|
+done:
|
|
if (lc)
|
|
mnt_unlock_file(lc);
|
|
|
|
--
|
|
2.35.1
|
|
|