RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: [EMAIL PROTECTED] Module: rpm Date: 05-Jun-2008 14:35:35 Branch: rpm-5_1 Handle: 2008060512353400 Modified files: (Branch: rpm-5_1) rpm CHANGES rpm/lib depends.c Log: - jbj: debuginfo: refactor 2 existing upgrade policy rules before adding a new contextually sensitive rule for -debuginfo packages. Summary: Revision Changes Path 1.2288.2.46 +2 -0 rpm/CHANGES 1.394.2.3 +310 -147 rpm/lib/depends.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/CHANGES ============================================================================ $ cvs diff -u -r1.2288.2.45 -r1.2288.2.46 CHANGES --- rpm/CHANGES 4 Jun 2008 22:46:07 -0000 1.2288.2.45 +++ rpm/CHANGES 5 Jun 2008 12:35:34 -0000 1.2288.2.46 @@ -1,4 +1,6 @@ 5.1.2 -> 5.1.3: + - jbj: debuginfo: refactor 2 existing upgrade policy rules before + adding a new contextually sensitive rule for -debuginfo packages. - jbj: add %_build_iconsize macro to permit configuration. - jbj: trash-and-restore macro config for multiple CLI arg builds. - jbj: rpmrepo: correct requiressqlentry tag name typo. @@ . patch -p0 <<'@@ .' Index: rpm/lib/depends.c ============================================================================ $ cvs diff -u -r1.394.2.2 -r1.394.2.3 depends.c --- rpm/lib/depends.c 19 May 2008 06:00:32 -0000 1.394.2.2 +++ rpm/lib/depends.c 5 Jun 2008 12:35:34 -0000 1.394.2.3 @@ -180,26 +180,306 @@ /[EMAIL PROTECTED]@*/ static rpmTag _upgrade_tag; /[EMAIL PROTECTED]@*/ +static rpmTag _debuginfo_tag; +/[EMAIL PROTECTED]@*/ static rpmTag _obsolete_tag; +/** + * Add upgrade erasures to a transaction set. + * @param ts transaction set + * @param p transaction element + * @param hcolor header color + * @param h header + * @return 0 on success + */ +static int rpmtsAddUpgrades(rpmts ts, rpmte p, uint32_t hcolor, Header h) +{ + HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); + uint32_t tscolor = rpmtsColor(ts); + alKey pkgKey = rpmteAddedKey(p); + uint32_t ohcolor; + rpmdbMatchIterator mi; + Header oh; + int xx; + + if (_upgrade_tag == 0) { + const char * t = rpmExpand("%{?_upgrade_tag}", NULL); +/[EMAIL PROTECTED]@*/ + _upgrade_tag = (!strcmp(t, "name") ? RPMTAG_NAME : RPMTAG_PROVIDENAME); +/[EMAIL PROTECTED]@*/ + t = _free(t); + } + + mi = rpmtsInitIterator(ts, _upgrade_tag, rpmteN(p), 0); + while((oh = rpmdbNextIterator(mi)) != NULL) { + int lastx; + rpmte q; + + /* Ignore colored packages not in our rainbow. */ + ohcolor = hGetColor(oh); + if (tscolor && hcolor && ohcolor && !(hcolor & ohcolor)) + continue; + + /* Snarf the original install tid & time from older package(s). */ + he->tag = RPMTAG_ORIGINTID; + xx = headerGet(oh, he, 0); + if (xx && he->p.ui32p != NULL) { + if (p->originTid[0] == 0 || p->originTid[0] > he->p.ui32p[0] + || (he->c > 1 && p->originTid[0] == he->p.ui32p[0] && p->originTid[1] > he->p.ui32p[1])) + { + p->originTid[0] = he->p.ui32p[0]; + p->originTid[1] = (he->c > 1 ? he->p.ui32p[1] : 0); + } + he->p.ptr = _free(he->p.ptr); + } + he->tag = RPMTAG_ORIGINTIME; + xx = headerGet(oh, he, 0); + if (xx && he->p.ui32p != NULL) { + if (p->originTime[0] == 0 || p->originTime[0] > he->p.ui32p[0] + || (he->c > 1 && p->originTime[0] == he->p.ui32p[0] && p->originTime[1] > he->p.ui32p[1])) + { + p->originTime[0] = he->p.ui32p[0]; + p->originTime[1] = (he->c > 1 ? he->p.ui32p[1] : 0); + } + he->p.ptr = _free(he->p.ptr); + } + + /* Skip identical packages. */ + if (rpmHeadersIdentical(h, oh)) + continue; + + /* Create an erasure element. */ + lastx = -1; + xx = removePackage(ts, oh, rpmdbGetIteratorOffset(mi), &lastx, pkgKey); +assert(lastx >= 0 && lastx < ts->orderCount); + q = ts->order[lastx]; + + /* Chain through upgrade flink. */ + xx = rpmteChain(p, q, oh, "Upgrades"); + +/[EMAIL PROTECTED]@*/ + rpmlog(RPMLOG_DEBUG, D_(" upgrade erases %s\n"), rpmteNEVRA(q)); +/[EMAIL PROTECTED]@*/ + + } + mi = rpmdbFreeIterator(mi); + + return 0; +} + +#if defined(SUPPORT_DEBUGINFO_UPGRADE_MODEL) +/** + * Check string for a suffix. + * @param fn string + * @param suffix suffix + * @return 1 if string ends with suffix + */ +static inline int chkSuffix(const char * fn, const char * suffix) + /[EMAIL PROTECTED]/ +{ + size_t flen = strlen(fn); + size_t slen = strlen(suffix); + return (flen > slen && !strcmp(fn + flen - slen, suffix)); +} + +/** + * Add unreferenced debuginfo erasures to a transaction set. + * @param ts transaction set + * @param p transaction element + * @param h header + * @param pkgKey added package key (erasure uses RPMAL_NOKEY) + * @return no. of references from build set + */ +static int rpmtsEraseDebuginfo(rpmts ts, rpmte p, Header h, alKey pkgKey) +{ + HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); + const void *keyval = NULL; + size_t keylen = 0; + size_t nrefs = 0; + uint32_t debuginfoInstance = 0; + Header debuginfoHeader = NULL; + rpmdbMatchIterator mi; + Header oh; + int xx; + + /* XXX SOURCEPKGID is not populated reliably, do not use (yet). */ + if (_debuginfo_tag == 0) { + const char * t = rpmExpand("%{?_debuginfo_tag}", NULL); +/[EMAIL PROTECTED]@*/ + _debuginfo_tag = (*t != '\0' && !strcmp(t, "pkgid") + ? RPMTAG_SOURCEPKGID : RPMTAG_SOURCERPM); +/[EMAIL PROTECTED]@*/ + t = _free(t); + } + + /* Grab the retrieval key. */ + switch (_debuginfo_tag) { + default: return 0; /[EMAIL PROTECTED]@*/ break; + case RPMTAG_SOURCERPM: keyval = rpmteSourcerpm(p); break; + } + + /* Count remaining members in build set, excluding -debuginfo (if any). */ + mi = rpmtsInitIterator(ts, _debuginfo_tag, keyval, keylen); + xx = rpmdbPruneIterator(mi, ts->removedPackages, ts->numRemovedPackages, 1); + while((oh = rpmdbNextIterator(mi)) != NULL) { + /* Skip identical packages. */ + if (rpmHeadersIdentical(h, oh)) + continue; + + he->tag = RPMTAG_NAME; + xx = headerGet(oh, he, 0); + if (!xx || he->p.str == NULL) + continue; + /* Save the -debuginfo member. */ + if (chkSuffix(he->p.str, "-debuginfo")) { + debuginfoInstance = rpmdbGetIteratorOffset(mi); + debuginfoHeader = headerLink(oh); + } else + nrefs++; + he->p.str = _free(he->p.str); + } + mi = rpmdbFreeIterator(mi); + + /* Remove -debuginfo package when last build member is erased. */ + if (nrefs == 0 && debuginfoInstance > 0 && debuginfoHeader != NULL) { + int lastx = -1; + rpmte q; + + /* Create an erasure element. */ + lastx = -1; + xx = removePackage(ts, debuginfoHeader, debuginfoInstance, + &lastx, pkgKey); +assert(lastx >= 0 && lastx < ts->orderCount); + q = ts->order[lastx]; + + /* Chain through upgrade flink. */ + /* XXX avoid assertion failure when erasing. */ + if (pkgKey != RPMAL_NOMATCH) + xx = rpmteChain(p, q, oh, "Upgrades"); + +/[EMAIL PROTECTED]@*/ + rpmlog(RPMLOG_DEBUG, D_(" lastref erases %s\n"), rpmteNEVRA(q)); +/[EMAIL PROTECTED]@*/ + + } + debuginfoHeader = headerFree(debuginfoHeader); + + return nrefs; +} +#endif /* SUPPORT_DEBUGINFO_UPGRADE_MODEL */ + +/** + * Add Obsoletes: erasures to a transaction set. + * @param ts transaction set + * @param p transaction element + * @param hcolor header color + * @return 0 on success + */ +static int rpmtsAddObsoletes(rpmts ts, rpmte p, uint32_t hcolor) +{ + uint32_t tscolor = rpmtsColor(ts); + alKey pkgKey = rpmteAddedKey(p); + uint32_t ohcolor; + rpmds obsoletes; + uint32_t dscolor; + rpmdbMatchIterator mi; + Header oh; + int xx; + + if (_obsolete_tag == 0) { + const char *t = rpmExpand("%{?_obsolete_tag}", NULL); +/[EMAIL PROTECTED]@*/ + _obsolete_tag = (!strcmp(t, "name") ? RPMTAG_NAME : RPMTAG_PROVIDENAME); +/[EMAIL PROTECTED]@*/ + t = _free(t); + } + + obsoletes = rpmdsLink(rpmteDS(p, RPMTAG_OBSOLETENAME), "Obsoletes"); + obsoletes = rpmdsInit(obsoletes); + if (obsoletes != NULL) + while (rpmdsNext(obsoletes) >= 0) { + const char * Name; + + if ((Name = rpmdsN(obsoletes)) == NULL) + continue; /* XXX can't happen */ + + /* Ignore colored obsoletes not in our rainbow. */ +#if 0 + /* XXX obsoletes are never colored, so this is for future devel. */ + dscolor = rpmdsColor(obsoletes); +#else + dscolor = hcolor; +#endif + if (tscolor && dscolor && !(tscolor & dscolor)) + continue; + + /* XXX avoid self-obsoleting packages. */ + if (!strcmp(rpmteN(p), Name)) + continue; + + /* Obsolete containing package if given a file, otherwise provide. */ + if (Name[0] == '/') + mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, Name, 0); + else + mi = rpmtsInitIterator(ts, _obsolete_tag, Name, 0); + + xx = rpmdbPruneIterator(mi, + ts->removedPackages, ts->numRemovedPackages, 1); + + while((oh = rpmdbNextIterator(mi)) != NULL) { + int lastx; + rpmte q; + + /* Ignore colored packages not in our rainbow. */ + ohcolor = hGetColor(oh); + + /* XXX provides *are* colored, effectively limiting Obsoletes: + to matching only colored Provides: based on pkg coloring. */ + if (tscolor && hcolor && ohcolor && !(hcolor & ohcolor)) + /[EMAIL PROTECTED]@*/ continue; + + /* + * Rpm prior to 3.0.3 does not have versioned obsoletes. + * If no obsoletes version info is available, match all names. + */ + if (!(rpmdsEVR(obsoletes) == NULL + || rpmdsAnyMatchesDep(oh, obsoletes, _rpmds_nopromote))) + /[EMAIL PROTECTED]@*/ continue; + + /* Create an erasure element. */ + lastx = -1; + xx = removePackage(ts, oh, rpmdbGetIteratorOffset(mi), &lastx, pkgKey); +assert(lastx >= 0 && lastx < ts->orderCount); + q = ts->order[lastx]; + + /* Chain through obsoletes flink. */ + xx = rpmteChain(p, q, oh, "Obsoletes"); + +/[EMAIL PROTECTED]@*/ + rpmlog(RPMLOG_DEBUG, D_(" Obsoletes: %s\t\terases %s\n"), + rpmdsDNEVR(obsoletes)+2, rpmteNEVRA(q)); +/[EMAIL PROTECTED]@*/ + } + mi = rpmdbFreeIterator(mi); + } + obsoletes = rpmdsFree(obsoletes); + + return 0; +} + int rpmtsAddInstallElement(rpmts ts, Header h, fnpyKey key, int upgrade, rpmRelocation relocs) { HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he)); rpmdepFlags depFlags = rpmtsDFlags(ts); uint32_t tscolor = rpmtsColor(ts); - uint32_t dscolor; uint32_t hcolor; - rpmdbMatchIterator mi; - Header oh; - uint32_t ohcolor; int isSource; int duplicate = 0; rpmtsi pi = NULL; rpmte p; const char * arch = NULL; const char * os = NULL; rpmds oldChk, newChk; - rpmds obsoletes; alKey pkgKey; /* addedPackages key */ int xx; int ec = 0; @@ -389,6 +669,7 @@ if (!(upgrade & 0x1)) goto exit; + /* If source rpm, then we're done. */ if (isSource) goto exit; @@ -398,149 +679,28 @@ goto exit; } - /* On upgrade, erase older packages of same color (if any). */ - if (_upgrade_tag == 0) { - const char *t = rpmExpand("%{?_upgrade_tag}", NULL); -/[EMAIL PROTECTED]@*/ - _upgrade_tag = (!strcmp(t, "name") ? RPMTAG_NAME : RPMTAG_PROVIDENAME); -/[EMAIL PROTECTED]@*/ - t = _free(t); - } - - if (!(depFlags & RPMDEPS_FLAG_NOUPGRADE)) { - mi = rpmtsInitIterator(ts, _upgrade_tag, rpmteN(p), 0); - while((oh = rpmdbNextIterator(mi)) != NULL) { - int lastx; - rpmte q; - - /* Ignore colored packages not in our rainbow. */ - ohcolor = hGetColor(oh); - if (tscolor && hcolor && ohcolor && !(hcolor & ohcolor)) - continue; - - /* Snarf the original install tid & time from older package(s). */ - he->tag = RPMTAG_ORIGINTID; - xx = headerGet(oh, he, 0); - if (xx && he->p.ui32p != NULL) { - if (p->originTid[0] == 0 || p->originTid[0] > he->p.ui32p[0] - || (he->c > 1 && p->originTid[0] == he->p.ui32p[0] && p->originTid[1] > he->p.ui32p[1])) - { - p->originTid[0] = he->p.ui32p[0]; - p->originTid[1] = (he->c > 1 ? he->p.ui32p[1] : 0); - } - he->p.ptr = _free(he->p.ptr); - } - he->tag = RPMTAG_ORIGINTIME; - xx = headerGet(oh, he, 0); - if (xx && he->p.ui32p != NULL) { - if (p->originTime[0] == 0 || p->originTime[0] > he->p.ui32p[0] - || (he->c > 1 && p->originTime[0] == he->p.ui32p[0] && p->originTime[1] > he->p.ui32p[1])) - { - p->originTime[0] = he->p.ui32p[0]; - p->originTime[1] = (he->c > 1 ? he->p.ui32p[1] : 0); - } - he->p.ptr = _free(he->p.ptr); - } - - /* Skip identical packages. */ - if (rpmHeadersIdentical(h, oh)) - continue; - - /* Create an erasure element. */ - lastx = -1; - xx = removePackage(ts, oh, rpmdbGetIteratorOffset(mi), &lastx, pkgKey); -assert(lastx >= 0 && lastx < ts->orderCount); - q = ts->order[lastx]; - - /* Chain through upgrade flink. */ - xx = rpmteChain(p, q, oh, "Upgrades"); - -/[EMAIL PROTECTED]@*/ - rpmlog(RPMLOG_DEBUG, D_(" upgrade erases %s\n"), rpmteNEVRA(q)); -/[EMAIL PROTECTED]@*/ - + /* Add upgrades to the transaction (if not disabled). */ + if (!(depFlags & RPMDEPS_FLAG_NOUPGRADE)) { +#if defined(SUPPORT_DEBUGINFO_UPGRADE_MODEL) + /* + * Don't upgrade -debuginfo until build set is empty. + * + * XXX Almost, but not quite, correct since the test depends on + * added package arrival order. + * I.e. -debuginfo additions must always follow all + * other additions so that erasures of other members in the + * same build set are seen if/when included in the same transaction. + */ + xx = rpmtsEraseDebuginfo(ts, p, h, pkgKey); + if (!chkSuffix(rpmteN(p), "-debuginfo") || xx == 0) +#endif /* SUPPORT_DEBUGINFO_UPGRADE_MODEL */ + xx = rpmtsAddUpgrades(ts, p, hcolor, h); } - mi = rpmdbFreeIterator(mi); - } - if (_obsolete_tag == 0) { - const char *t = rpmExpand("%{?_obsolete_tag}", NULL); -/[EMAIL PROTECTED]@*/ - _obsolete_tag = (!strcmp(t, "name") ? RPMTAG_NAME : RPMTAG_PROVIDENAME); -/[EMAIL PROTECTED]@*/ - t = _free(t); + /* Add Obsoletes: to the transaction (if not disabled). */ + if (!(depFlags & RPMDEPS_FLAG_NOOBSOLETES)) { + xx = rpmtsAddObsoletes(ts, p, hcolor); } - if (!(depFlags & RPMDEPS_FLAG_NOOBSOLETES)) { - obsoletes = rpmdsLink(rpmteDS(p, RPMTAG_OBSOLETENAME), "Obsoletes"); - obsoletes = rpmdsInit(obsoletes); - if (obsoletes != NULL) - while (rpmdsNext(obsoletes) >= 0) { - const char * Name; - - if ((Name = rpmdsN(obsoletes)) == NULL) - continue; /* XXX can't happen */ - - /* Ignore colored obsoletes not in our rainbow. */ -#if 0 - dscolor = rpmdsColor(obsoletes); -#else - dscolor = hcolor; -#endif - /* XXX obsoletes are never colored, so this is for future devel. */ - if (tscolor && dscolor && !(tscolor & dscolor)) - continue; - - /* XXX avoid self-obsoleting packages. */ - if (!strcmp(rpmteN(p), Name)) - continue; - - /* Obsolete containing package if given a file, otherwise provide. */ - if (Name[0] == '/') - mi = rpmtsInitIterator(ts, RPMTAG_BASENAMES, Name, 0); - else - mi = rpmtsInitIterator(ts, _obsolete_tag, Name, 0); - - xx = rpmdbPruneIterator(mi, - ts->removedPackages, ts->numRemovedPackages, 1); - - while((oh = rpmdbNextIterator(mi)) != NULL) { - int lastx; - rpmte q; - - /* Ignore colored packages not in our rainbow. */ - ohcolor = hGetColor(oh); - - /* XXX provides *are* colored, effectively limiting Obsoletes: - to matching only colored Provides: based on pkg coloring. */ - if (tscolor && hcolor && ohcolor && !(hcolor & ohcolor)) - /[EMAIL PROTECTED]@*/ continue; - - /* - * Rpm prior to 3.0.3 does not have versioned obsoletes. - * If no obsoletes version info is available, match all names. - */ - if (!(rpmdsEVR(obsoletes) == NULL - || rpmdsAnyMatchesDep(oh, obsoletes, _rpmds_nopromote))) - /[EMAIL PROTECTED]@*/ continue; - - /* Create an erasure element. */ - lastx = -1; - xx = removePackage(ts, oh, rpmdbGetIteratorOffset(mi), &lastx, pkgKey); -assert(lastx >= 0 && lastx < ts->orderCount); - q = ts->order[lastx]; - - /* Chain through obsoletes flink. */ - xx = rpmteChain(p, q, oh, "Obsoletes"); - -/[EMAIL PROTECTED]@*/ - rpmlog(RPMLOG_DEBUG, D_(" Obsoletes: %s\t\terases %s\n"), - rpmdsDNEVR(obsoletes)+2, rpmteNEVRA(q)); -/[EMAIL PROTECTED]@*/ - } - mi = rpmdbFreeIterator(mi); - } - obsoletes = rpmdsFree(obsoletes); - } ec = 0; @@ -555,9 +715,12 @@ { int oc = -1; int rc = removePackage(ts, h, dboffset, &oc, RPMAL_NOMATCH); - if (rc == 0 && oc >= 0 && oc < ts->orderCount) + if (rc == 0 && oc >= 0 && oc < ts->orderCount) { +#if defined(SUPPORT_DEBUGINFO_UPGRADE_MODEL) + (void) rpmtsEraseDebuginfo(ts, ts->order[oc], h, RPMAL_NOMATCH); +#endif /* SUPPORT_DEBUGINFO_UPGRADE_MODEL */ ts->teErase = ts->order[oc]; - else + } else ts->teErase = NULL; return rc; } @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org