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

Reply via email to