[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