rpm/rpm-4.9.0-fstate-deps.patch
Panu Matilainen 5a40a02fce - verify some properties of replaced and wrong-colored files (#528383)
- only list packages that would be generated on spec query (#693338)
- preferred color packages should be erased last (#680261)
- fix leaks when freeing a populated transaction set
- take file state into account for file dependencies
2011-04-05 18:24:15 +03:00

52 lines
2.1 KiB
Diff

commit 566a15c9c08aa593d05e2f55f1c171a48bc1b1bc
Author: Panu Matilainen <pmatilai@redhat.com>
Date: Wed Mar 9 09:39:32 2011 +0200
Take file state into account for file dependencies
- Files which are not installed, have been replaced or are of wrong
color can not actually satisfy a dependency despite what the package's
file list says.
- This prevents breaking the system despite seemingly correct dependencies
in some situations, such as on multilib systems where a colored
files can appear to be shared between primary and secondary architecture
packages, but only the file from primary arch package is physically
present, and removing the primary arch package would remove the
file and silently break any dependencies on such files in practise.
Similarly replaced files become owned by the replacing package in
practise, so the original package whose files were replaced can no
longer satisfy dependency on those files.
diff --git a/lib/depends.c b/lib/depends.c
index 4daa512..69aecbb 100644
--- a/lib/depends.c
+++ b/lib/depends.c
@@ -345,12 +345,25 @@ static int rpmdbProvides(rpmts ts, depCache dcache, rpmds dep)
return rc;
}
- /* See if a filename dependency is a real file in some package */
+ /*
+ * See if a filename dependency is a real file in some package,
+ * taking file state into account: replaced, wrong colored and
+ * not installed files can not satisfy a dependency.
+ */
if (Name[0] == '/') {
mi = rpmtsPrunedIterator(ts, RPMDBI_BASENAMES, Name);
while ((h = rpmdbNextIterator(mi)) != NULL) {
- rpmdsNotify(dep, "(db files)", rc);
- break;
+ int fs = RPMFILE_STATE_MISSING;
+ struct rpmtd_s states;
+ if (headerGet(h, RPMTAG_FILESTATES, &states, HEADERGET_MINMEM)) {
+ rpmtdSetIndex(&states, rpmdbGetIteratorFileNum(mi));
+ fs = rpmtdGetNumber(&states);
+ rpmtdFreeData(&states);
+ }
+ if (fs == RPMFILE_STATE_NORMAL || fs == RPMFILE_STATE_NETSHARED) {
+ rpmdsNotify(dep, "(db files)", rc);
+ break;
+ }
}
rpmdbFreeIterator(mi);
}