[Rpm-maint] [Suse patch] Checking for identical packages on install/upgrade

Michael Schroeder mls at suse.de
Tue May 29 11:12:07 UTC 2007


On Tue, May 29, 2007 at 10:29:45AM +0300, Panu Matilainen wrote:
> What JBJ does here is checks HDRID for identifying identical packages if 
> present, version comparison if not. But I don't think it's actually 
> identicality of headers (or not) we're really interested in here but 
> upgradability. It's trivial to produce packages with different HDRID 
> but same NEVRA (just rebuild the package and there you have it), I don't 
> think it makes much sense to allow to packages with same NEVRA in the 
> transaction, ever.
> 
> I'd rather just use rpmdsCompare() for the check rather than add yet 
> another codepath for NEVRA comparison within rpm like the included patch 
> does. Optionally we could check for the HDRID as well (identical packages 
> are never wanted in ts) but dunno if it's worth the couple of more lines 
> because most of the time we'd be doing the version comparison anyway.

The patch is actually about something different: rpm has two modes
of operation: rpm refresh and rpm update. rpm refresh is done
(after the patch) when the NEVRA matches. It differs from an update
because rpm doesn't do an uninstall in that case. As there's no
uninstall, the code must fake it by deleting the old header from the
database when doing the install. Unfortunatelly this is detected in a
different way: there are some some rpmdbSetIteratorRE() calls in
rpmpsmStage(), stage PSM_PKGINSTALL. 

I think checking the HDRID is actually the right thing to do. The
patch stems from rpm-3, where there was no HDRID. Maybe there
should be some rpmSameHeader() function as an abstraction. The
code in psm.c should be changed to:

    psm->mi = rpmtsInitIterator(ts, RPMTAG_NAME, rpmteN(psm->te), 0);
    while ((psm->oh = rpmdbNextIterator(psm->mi)) != NULL) {
        if (!rpmSameHeader(fi->h, psm->oh))
	    continue;
	fi->record = rpmdbGetIteratorOffset(psm->mi);
	psm->oh = NULL;
	/*@loopbreak@*/ break;
    }

This doesn't slow down the installation, as all the rpmdbSetIteratorRE()
are currently also done after fetching the header.

Cheers,
  Michael.

-- 
Michael Schroeder                                   mls at suse.de
SUSE LINUX Products GmbH, GF Markus Rex, HRB 16746 AG Nuernberg
main(_){while(_=~getchar())putchar(~_-1/(~(_|32)/13*2-11)*13);}



More information about the Rpm-maint mailing list