115 lines
3.7 KiB
Diff
115 lines
3.7 KiB
Diff
|
|
From 31c14ba6610568c2d634647fed1fb57221178da9 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Michal Domonkos <mdomonko@redhat.com>
|
||
|
|
Date: Fri, 26 Jul 2024 10:43:50 +0200
|
||
|
|
Subject: [PATCH] Make sure dirs are not relocated twice
|
||
|
|
|
||
|
|
Conflict:adapt context
|
||
|
|
Reference:https://github.com/rpm-software-management/rpm/commit/31c14ba6610568c2d634647fed1fb57221178da9
|
||
|
|
|
||
|
|
When processing relocations, new dirnames are added to dirNames[] first
|
||
|
|
and then the rest is relocated. However, we go through the entire array
|
||
|
|
in the latter step, meaning that we may accidentally relocate an already
|
||
|
|
relocated path.
|
||
|
|
|
||
|
|
Most relocations are fine as they involve two separate directory trees,
|
||
|
|
and we already skip over directories that don't match the old prefix.
|
||
|
|
However, that breaks apart if we're relocating to a nested subdirectory
|
||
|
|
(e.g. /opt -> /opt/new/dir).
|
||
|
|
|
||
|
|
Fix this by simply stopping at the original dirCount as the new entries
|
||
|
|
are always added to the end of dirNames[].
|
||
|
|
|
||
|
|
Such relocations are perhaps not very common (or even unsupported) but
|
||
|
|
relocating the root directory itself may be useful (see the next commit
|
||
|
|
for details) and that is subject to the same issue.
|
||
|
|
|
||
|
|
Note that we currently don't handle root relocations properly to start
|
||
|
|
with but that will be addressed in the next commit, this prepares the
|
||
|
|
ground.
|
||
|
|
---
|
||
|
|
lib/relocation.c | 6 +++---
|
||
|
|
tests/rpmi.at | 35 +++++++++++++++++++++++++++++++++++
|
||
|
|
2 files changed, 38 insertions(+), 3 deletions(-)
|
||
|
|
|
||
|
|
diff --git a/lib/relocation.c b/lib/relocation.c
|
||
|
|
index 1eab60211..d31cf4779 100644
|
||
|
|
--- a/lib/relocation.c
|
||
|
|
+++ b/lib/relocation.c
|
||
|
|
@@ -124,7 +124,7 @@ void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations,
|
||
|
|
char ** baseNames;
|
||
|
|
char ** dirNames;
|
||
|
|
uint32_t * dirIndexes;
|
||
|
|
- rpm_count_t fileCount, dirCount;
|
||
|
|
+ rpm_count_t fileCount, dirCount, dirCountOrig;
|
||
|
|
int nrelocated = 0;
|
||
|
|
int fileAlloced = 0;
|
||
|
|
char * fn = NULL;
|
||
|
|
@@ -163,7 +163,7 @@ void rpmRelocateFileList(rpmRelocation *relocations, int numRelocations,
|
||
|
|
baseNames = bnames.data;
|
||
|
|
dirIndexes = dindexes.data;
|
||
|
|
fileCount = rpmtdCount(&bnames);
|
||
|
|
- dirCount = rpmtdCount(&dnames);
|
||
|
|
+ dirCount = dirCountOrig = rpmtdCount(&dnames);
|
||
|
|
/* XXX TODO: use rpmtdDup() instead */
|
||
|
|
dirNames = dnames.data = duparray(dnames.data, dirCount);
|
||
|
|
dnames.flags |= RPMTD_PTR_ALLOCED;
|
||
|
|
@@ -297,7 +297,7 @@ assert(fn != NULL); /* XXX can't happen */
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Finish off by relocating directories. */
|
||
|
|
- for (i = dirCount - 1; i >= 0; i--) {
|
||
|
|
+ for (i = dirCountOrig - 1; i >= 0; i--) {
|
||
|
|
for (j = numRelocations - 1; j >= 0; j--) {
|
||
|
|
|
||
|
|
if (relocations[j].oldPath == NULL) /* XXX can't happen */
|
||
|
|
diff --git a/tests/rpmi.at b/tests/rpmi.at
|
||
|
|
index 7d1a0a871..372be0a8b 100644
|
||
|
|
--- a/tests/rpmi.at
|
||
|
|
+++ b/tests/rpmi.at
|
||
|
|
@@ -1135,6 +1135,42 @@ runroot rpm -U --relocate /opt/bin=/bin \
|
||
|
|
],
|
||
|
|
[])
|
||
|
|
RPMTEST_CLEANUP
|
||
|
|
+
|
||
|
|
+AT_SETUP([rpm -i relocatable package 2])
|
||
|
|
+AT_KEYWORDS([install relocate])
|
||
|
|
+RPMDB_INIT
|
||
|
|
+
|
||
|
|
+runroot rpmbuild --quiet -bb /data/SPECS/reloc.spec
|
||
|
|
+runroot rpmbuild --quiet -bb /data/SPECS/fakeshell.spec
|
||
|
|
+
|
||
|
|
+runroot rpm -U /build/RPMS/noarch/fakeshell-1.0-1.noarch.rpm
|
||
|
|
+
|
||
|
|
+RPMTEST_CHECK([
|
||
|
|
+runroot rpm -U \
|
||
|
|
+ --relocate /opt/bin=/opt/bin/foo/bar \
|
||
|
|
+ --relocate /opt/etc=/opt/etc/foo/bar \
|
||
|
|
+ --relocate /opt/lib=/opt/lib/foo/bar \
|
||
|
|
+ /build/RPMS/noarch/reloc-1.0-1.noarch.rpm
|
||
|
|
+runroot rpm -ql reloc
|
||
|
|
+],
|
||
|
|
+[0],
|
||
|
|
+[1: /opt/bin/foo/bar
|
||
|
|
+2: /opt/etc/foo/bar
|
||
|
|
+3: /opt/lib/foo/bar
|
||
|
|
+0: /opt/bin/foo/bar
|
||
|
|
+1: /opt/etc/foo/bar
|
||
|
|
+2: /opt/lib/foo/bar
|
||
|
|
+/opt
|
||
|
|
+/opt/bin/foo/bar
|
||
|
|
+/opt/bin/foo/bar/typo
|
||
|
|
+/opt/etc/foo/bar
|
||
|
|
+/opt/etc/foo/bar/conf
|
||
|
|
+/opt/lib/foo/bar
|
||
|
|
+/opt/lib/foo/bar/notlib
|
||
|
|
+],
|
||
|
|
+[])
|
||
|
|
+RPMTEST_CLEANUP
|
||
|
|
+
|
||
|
|
AT_SETUP([rpm -i with/without --excludedocs])
|
||
|
|
AT_KEYWORDS([install excludedocs])
|
||
|
|
RPMTEST_CHECK([
|
||
|
|
--
|
||
|
|
2.33.0
|
||
|
|
|