[arch-commits] Commit in pacman/trunk (3 files)
Allan McRae
allan at archlinux.org
Tue Jul 10 21:49:41 UTC 2012
Date: Tuesday, July 10, 2012 @ 17:49:41
Author: allan
Revision: 163212
upgpkg: pacman 4.0.3-3
add patches to fix conflict checking issues for /lib -> usr/lib move
Added:
pacman/trunk/0001-Add-conflict-for-replacing-owned-empty-directory.patch
pacman/trunk/0002-Check-empty-subdirectory-ownership.patch
Modified:
pacman/trunk/PKGBUILD
-------------------------------------------------------------+
0001-Add-conflict-for-replacing-owned-empty-directory.patch | 152 ++++++++++
0002-Check-empty-subdirectory-ownership.patch | 61 ++++
PKGBUILD | 9
3 files changed, 221 insertions(+), 1 deletion(-)
Added: 0001-Add-conflict-for-replacing-owned-empty-directory.patch
===================================================================
--- 0001-Add-conflict-for-replacing-owned-empty-directory.patch (rev 0)
+++ 0001-Add-conflict-for-replacing-owned-empty-directory.patch 2012-07-10 21:49:41 UTC (rev 163212)
@@ -0,0 +1,152 @@
+From 717fdb8ee0fd23cf72fc7d2832317f513caefa2c Mon Sep 17 00:00:00 2001
+From: Allan McRae <allan at archlinux.org>
+Date: Sun, 8 Jul 2012 21:36:36 +1000
+Subject: [PATCH 1/4] Add conflict for replacing owned empty directory
+
+When two packages own an empty directory, pacman finds no conflict when
+one of those packages wants to replace the directory with a file or a
+symlink. When it comes to actually extracting the new file/symlink,
+pacman sees the directory is still there (we do not remove empty
+directories if they are owned by a package) and refuses to extract.
+
+Detect this potential conflict early and bail. Note that it is a
+_potential_ conflict and not a guaranteed one as the other package owning
+the directory could be updated or removed first which would remove
+the conflict. However, pacman currently can not sort package installation
+order to ensure this, so this conflict requires manual upgrade ordering.
+
+Signed-off-by: Allan McRae <allan at archlinux.org>
+Signed-off-by: Dan McGee <dan at archlinux.org>
+---
+ lib/libalpm/conflict.c | 32 ++++++++++++++++++++++++++------
+ test/pacman/tests/fileconflict009.py | 20 ++++++++++++++++++++
+ test/pacman/tests/fileconflict010.py | 20 ++++++++++++++++++++
+ 3 files changed, 66 insertions(+), 6 deletions(-)
+ create mode 100644 test/pacman/tests/fileconflict009.py
+ create mode 100644 test/pacman/tests/fileconflict010.py
+
+diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
+index 32f6f30..efa1a87 100644
+--- a/lib/libalpm/conflict.c
++++ b/lib/libalpm/conflict.c
+@@ -328,15 +328,35 @@ const alpm_file_t *_alpm_filelist_contains(alpm_filelist_t *filelist,
+ return NULL;
+ }
+
+-static int dir_belongsto_pkg(const char *root, const char *dirpath,
++static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath,
+ alpm_pkg_t *pkg)
+ {
++ alpm_list_t *i;
+ struct stat sbuf;
+ char path[PATH_MAX];
+ char abspath[PATH_MAX];
+- struct dirent *ent = NULL;
+ DIR *dir;
++ struct dirent *ent = NULL;
++ const char *root = handle->root;
++
++ /* TODO: this is an overly strict check but currently pacman will not
++ * overwrite a directory with a file (case 10/11 in add.c). Adjusting that
++ * is not simple as even if the directory is being unowned by a conflicting
++ * package, pacman does not sort this to ensure all required directory
++ * "removals" happen before installation of file/symlink */
++
++ /* check that no other _installed_ package owns the directory */
++ for(i = _alpm_db_get_pkgcache(handle->db_local); i; i = i->next) {
++ if(pkg == i->data) {
++ continue;
++ }
++
++ if(_alpm_filelist_contains(alpm_pkg_get_files(i->data), dirpath)) {
++ return 0;
++ }
++ }
+
++ /* check all files in directory are owned by the package */
+ snprintf(abspath, PATH_MAX, "%s%s", root, dirpath);
+ dir = opendir(abspath);
+ if(dir == NULL) {
+@@ -349,13 +369,13 @@ static int dir_belongsto_pkg(const char *root, const char *dirpath,
+ if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) {
+ continue;
+ }
+- snprintf(path, PATH_MAX, "%s/%s", dirpath, name);
++ snprintf(path, PATH_MAX, "%s%s", dirpath, name);
+ snprintf(abspath, PATH_MAX, "%s%s", root, path);
+ if(stat(abspath, &sbuf) != 0) {
+ continue;
+ }
+ if(S_ISDIR(sbuf.st_mode)) {
+- if(dir_belongsto_pkg(root, path, pkg)) {
++ if(dir_belongsto_pkg(handle, path, pkg)) {
+ continue;
+ } else {
+ closedir(dir);
+@@ -529,9 +549,9 @@ alpm_list_t *_alpm_db_find_fileconflicts(alpm_handle_t *handle,
+ sprintf(dir, "%s/", filestr);
+ if(_alpm_filelist_contains(alpm_pkg_get_files(dbpkg), dir)) {
+ _alpm_log(handle, ALPM_LOG_DEBUG,
+- "check if all files in %s belongs to %s\n",
++ "check if all files in %s belong to %s\n",
+ dir, dbpkg->name);
+- resolved_conflict = dir_belongsto_pkg(handle->root, filestr, dbpkg);
++ resolved_conflict = dir_belongsto_pkg(handle, dir, dbpkg);
+ }
+ free(dir);
+ }
+diff --git a/test/pacman/tests/fileconflict009.py b/test/pacman/tests/fileconflict009.py
+new file mode 100644
+index 0000000..904af4a
+--- /dev/null
++++ b/test/pacman/tests/fileconflict009.py
+@@ -0,0 +1,20 @@
++self.description = "dir->symlink change during package upgrade (directory conflict)"
++
++lp1 = pmpkg("pkg1")
++lp1.files = ["dir/"]
++self.addpkg2db("local", lp1)
++
++lp2 = pmpkg("pkg2")
++lp2.files = ["dir/"]
++self.addpkg2db("local", lp2)
++
++p = pmpkg("pkg1", "1.0-2")
++p.files = ["dir -> /usr/dir"]
++self.addpkg2db("sync", p)
++
++self.args = "-S pkg1"
++
++self.addrule("PACMAN_RETCODE=1")
++self.addrule("PKG_VERSION=pkg1|1.0-1")
++self.addrule("PKG_VERSION=pkg2|1.0-1")
++self.addrule("DIR_EXIST=dir/")
+diff --git a/test/pacman/tests/fileconflict010.py b/test/pacman/tests/fileconflict010.py
+new file mode 100644
+index 0000000..0a3ce83
+--- /dev/null
++++ b/test/pacman/tests/fileconflict010.py
+@@ -0,0 +1,20 @@
++self.description = "dir->file change during package upgrade (directory conflict)"
++
++lp1 = pmpkg("pkg1")
++lp1.files = ["dir/"]
++self.addpkg2db("local", lp1)
++
++lp2 = pmpkg("pkg2")
++lp2.files = ["dir/"]
++self.addpkg2db("local", lp2)
++
++p = pmpkg("pkg1", "1.0-2")
++p.files = ["dir"]
++self.addpkg2db("sync", p)
++
++self.args = "-S pkg1"
++
++self.addrule("PACMAN_RETCODE=1")
++self.addrule("PKG_VERSION=pkg1|1.0-1")
++self.addrule("PKG_VERSION=pkg2|1.0-1")
++self.addrule("DIR_EXIST=dir/")
+--
+1.7.11.1
+
Added: 0002-Check-empty-subdirectory-ownership.patch
===================================================================
--- 0002-Check-empty-subdirectory-ownership.patch (rev 0)
+++ 0002-Check-empty-subdirectory-ownership.patch 2012-07-10 21:49:41 UTC (rev 163212)
@@ -0,0 +1,61 @@
+From 44e9fdd0e848382337edb97d41e7317638a67bac Mon Sep 17 00:00:00 2001
+From: Allan McRae <allan at archlinux.org>
+Date: Sun, 8 Jul 2012 23:58:37 +1000
+Subject: [PATCH 2/4] Check empty subdirectory ownership
+
+When checking if a package owns a directory, it is important to check
+not only that all the files in the directory are part of the package,
+but also if the directory is part of a package. This catches empty
+subdirectories during conflict checking for directory to file/symlink
+replacements.
+
+Signed-off-by: Allan McRae <allan at archlinux.org>
+Signed-off-by: Dan McGee <dan at archlinux.org>
+---
+ lib/libalpm/conflict.c | 5 +++++
+ test/pacman/tests/fileconflict012.py | 17 +++++++++++++++++
+ 2 files changed, 22 insertions(+)
+ create mode 100644 test/pacman/tests/fileconflict012.py
+
+diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c
+index efa1a87..d6e5d8c 100644
+--- a/lib/libalpm/conflict.c
++++ b/lib/libalpm/conflict.c
+@@ -339,6 +339,11 @@ static int dir_belongsto_pkg(alpm_handle_t *handle, const char *dirpath,
+ struct dirent *ent = NULL;
+ const char *root = handle->root;
+
++ /* check directory is actually in package - used for subdirectory checks */
++ if(!_alpm_filelist_contains(alpm_pkg_get_files(pkg), dirpath)) {
++ return 0;
++ }
++
+ /* TODO: this is an overly strict check but currently pacman will not
+ * overwrite a directory with a file (case 10/11 in add.c). Adjusting that
+ * is not simple as even if the directory is being unowned by a conflicting
+diff --git a/test/pacman/tests/fileconflict012.py b/test/pacman/tests/fileconflict012.py
+new file mode 100644
+index 0000000..421b739
+--- /dev/null
++++ b/test/pacman/tests/fileconflict012.py
+@@ -0,0 +1,17 @@
++self.description = "dir->file change during package upgrade (filesystem file conflict)"
++
++lp1 = pmpkg("pkg1")
++lp1.files = ["dir/"]
++self.addpkg2db("local", lp1)
++
++self.filesystem = ["dir/file"]
++
++p = pmpkg("pkg1", "1.0-2")
++p.files = ["dir"]
++self.addpkg2db("sync", p)
++
++self.args = "-S pkg1"
++
++self.addrule("PACMAN_RETCODE=1")
++self.addrule("PKG_VERSION=pkg1|1.0-1")
++self.addrule("DIR_EXIST=dir/")
+--
+1.7.11.1
+
Modified: PKGBUILD
===================================================================
--- PKGBUILD 2012-07-10 21:37:43 UTC (rev 163211)
+++ PKGBUILD 2012-07-10 21:49:41 UTC (rev 163212)
@@ -5,7 +5,7 @@
pkgname=pacman
pkgver=4.0.3
-pkgrel=2
+pkgrel=3
pkgdesc="A library-based package manager with dependency support"
arch=('i686' 'x86_64')
url="http://www.archlinux.org/pacman/"
@@ -19,11 +19,15 @@
install=pacman.install
options=(!libtool)
source=(ftp://ftp.archlinux.org/other/pacman/$pkgname-$pkgver.tar.gz{,.sig}
+ 0001-Add-conflict-for-replacing-owned-empty-directory.patch
+ 0002-Check-empty-subdirectory-ownership.patch
pacman.conf
pacman.conf.x86_64
makepkg.conf)
md5sums=('387965c7125e60e5f0b9ff3b427fe0f9'
'1a70392526c8768470da678b31905a6e'
+ '1a9b79788640907a2b34e8671cacc94a'
+ 'a9ddd43891bed364e1e97d27b2887bf1'
'99734ea46795f466d41c503e9e23b6d4'
'556d49489e82b5750cf026d3b18c8f4f'
'589cd34eb9d5b678455e8289394f523e')
@@ -31,6 +35,9 @@
build() {
cd $srcdir/$pkgname-$pkgver
+ patch -p1 -i $srcdir/0001-Add-conflict-for-replacing-owned-empty-directory.patch
+ patch -p1 -i $srcdir/0002-Check-empty-subdirectory-ownership.patch
+
./configure --prefix=/usr --sysconfdir=/etc \
--localstatedir=/var --enable-doc
make
More information about the arch-commits
mailing list