Hi, Trying to debug my package installation 'LOOP:' problems I have instrumented the RPM source code with many 'rpmlog(RPMLOG_DEBUG, ...)', so I could understand what is happening there.
After hours of such debugging I found out what is going on: for each dependency rpmalSatisfiesDepend() is called from order.c to build the dependency graph. There, for every file dependency (package requires '/something') rpmalAllFileSatisfiesDepend() is called which finds out what packages provide the required file. And here is the problem: rpmalAllFileSatisfiesDepend() uses a Bloom filter look-up to find out if a package contain a file. But Bloom filter, to its very nature, gives false positives, which are not verified further. So, it can happen that rpmalSatisfiesDepend() returns wrong package for a required file or directory, which adds an extra edge to the dependency graph. RPM reports this as a 'LOOP' problem and tries to work-around it by changing the installation order, which totally breaks the order for me. The attached patch is a quick fix to the problem: after rpmbfChk() states a file is provided by a package, its answer is additionally verified by scanning the file index of the package. I am sure this can be implemented in a more elegant way, but I don't know the internal RPM architecture well enough and I cannot spend much more time on fixing this problem. Greets, Jacek
diff -dur rpm-5.4.12.orig/lib/rpmal.c rpm-5.4.12/lib/rpmal.c --- rpm-5.4.12.orig/lib/rpmal.c 2012-04-15 23:20:57.000000000 +0200 +++ rpm-5.4.12/lib/rpmal.c 2013-08-13 13:46:28.000000000 +0200 @@ -7,6 +7,10 @@ #include <rpmio.h> #include <rpmiotypes.h> /* XXX fnpyKey */ #include <rpmbf.h> +#include <rpmlog.h> + +#define _RPMFI_INTERNAL +#include <rpmfi.h> #include <rpmtag.h> #include <rpmtypes.h> @@ -38,6 +42,7 @@ rpmds provides; /*!< Provides: dependencies. */ /*@refcounted@*/ /*@null@*/ rpmbf bf; /*!< File name Bloom filter. */ + rpmfi fi; /*!< File name Bloom filter. */ rpmuint32_t tscolor; /*!< Transaction color bits. */ @@ -149,6 +154,8 @@ alp->provides = NULL; (void)rpmbfFree(alp->bf); alp->bf = NULL; + (void)rpmbfFree(alp->fi); + alp->fi = NULL; } al->list = _free(al->list); @@ -205,6 +212,8 @@ alp->provides = NULL; (void)rpmbfFree(alp->bf); alp->bf = NULL; + (void)rpmbfFree(alp->fi); + alp->fi = NULL; memset(alp, 0, sizeof(*alp)); /* XXX trash and burn */ return; @@ -244,6 +253,7 @@ /*@-assignexpose -castexpose @*/ alp->provides = rpmdsLink(provides, "Provides (rpmalAdd)"); alp->bf = rpmbfLink(rpmfiFNBF(fi)); + alp->fi = rpmfiLink(fi, "file list (rpmalAdd)"); /*@=assignexpose =castexpose @*/ rpmalFreeIndex(al); @@ -350,17 +360,17 @@ rpmalAllFileSatisfiesDepend(const rpmal al, const rpmds ds, alKey * keyp) { fnpyKey * ret = NULL; - int found = 0; + int found = 0, verified = 0; const char * fn; size_t nfn; - int i; + int i, j; if (keyp) *keyp = RPMAL_NOMATCH; if (al == NULL || (fn = rpmdsN(ds)) == NULL || *fn != '/') goto exit; nfn = strlen(fn); - + if (al->list != NULL) /* XXX always true */ for (i = 0; i < al->size; i++) { availablePackage alp = al->list + i; @@ -368,6 +378,24 @@ if (!rpmbfChk(alp->bf, fn, nfn)) continue; + verified = 0; + char * fifn = (char *) malloc(alp->fi->fnlen + 1); + for(j=0; j<(int)alp->fi->fc; j++) { + const char * dn = NULL; + (void) urlPath(alp->fi->dnl[alp->fi->dil[j]], &dn); + strcpy(stpcpy(fifn, dn), alp->fi->bnl[j]); + if (!strcmp(fn, fifn)) { + verified = 1; + break; + } + } + free(fifn); + + if (!verified) { + rpmlog(RPMLOG_DEBUG, " False positive: '%s'\n", fn); + continue; + } + rpmdsNotify(ds, _("(added files)"), 0); ret = (fnpyKey *) xrealloc(ret, (found + 2) * sizeof(*ret));
_______________________________________________ pld-devel-en mailing list pld-devel-en@lists.pld-linux.org http://lists.pld-linux.org/mailman/listinfo/pld-devel-en