RPM Community Forums

Mailing List Message of <rpm-devel>

Re: Conflicts on files not symmetric

From: Jeff Johnson <n3npq@mac.com>
Date: Fri 19 Sep 2008 - 12:50:40 CEST
Message-id: <4B740F29-7796-48A7-971A-68564504B344@mac.com>

On Sep 19, 2008, at 5:07 AM, Michael Schroeder wrote:

> Hi rpm-4 and rpm-5,
> while implementing virtual triggers I stumbled over the fact
> that conflicts on files only work in one direction. Example:
> Package A contains /foo
> Package B has "Conflicts: /foo"
> If A is already installed and one tries to install B, a dependency
> conflict is reported:
>    error: Failed dependencies:
> 	    /foo conflicts with B-1-1.i586
> If B is already installed and one tries to install A, no error
> is displayed and the package is installed.

Likely true.

> So, is this a known bug? Is it worth fixing?

Obsoletes: has the same (or at least closely related) issue, a lack of  
checking the dependency after install is performed.

E.g. s/Conflicts/Obsoletes/ in your reproducer.

In the first case, the end-result will have B installed, the 2nd
case end-result will have both A and B installed.

Persistent dependency assertions, not just while installing a  
will lead to many new corner cases, and packaging flaws will
force per-package, not per-transaction, disablers so that
packaging errors can be handled and the pretense of
legacy compatibility is preserved.

Dunno "bug", rpm has always behaved this way, perfectly sensible
for rpm's installer hysterical roots.

Sure can be fixed if there is need.

> If this needs fixing, here's an idea: As it probably costs too
> much time to test each file in the file list for conflicts, how
> about creating a index of the conflicts first and only test
> the files that match the index?
> I.e. add a function
> char *rpmdbKeyIterator(rpmdbMatchIterator mi) {
>    int rc, xx;
>    dbiIndex dbi;
>    dbi = dbiOpen(mi->mi_db, mi->mi_rpmtag, 0);
>    if (mi->mi_dbc == NULL)
>        xx = dbiCopen(dbi, dbi->dbi_txnid, &mi->mi_dbc, mi->mi_cflags);
>    rc = dbiGet(dbi, mi->mi_dbc, &mi->mi_key, &mi->mi_data, DB_NEXT);
>    if (rc)
>        return 0;
>    if (mi->mi_keyp)
>        free((char *)mi->mi_keyp);
>    mi->mi_keyp = (void *)xmalloc(mi->mi_key.size + 1);
>    memcpy((char *)mi->mi_keyp, mi->mi_key.data, mi->mi_key.size);
>    ((char *)mi->mi_keyp)[mi->mi_key.size] = 0;
>    mi->mi_keylen = mi->mi_key.size;
>    return (char *)mi->mi_keyp;
> }
> to rpmdb.c, then use
>    mi = rpmtsInitIterator(ts, RPMTAG_CONFLICTNAME, 0, 0);
>    while ((key = rpmdbKeyIterator(mi)) != 0)
>      ...
> to create an array of basenames, sort it and then go through the
> filelist and match only if bsearch for the basename returns true.

Sure an iterator over index keys without header loads can be attempted.

The core problem is that Conflicts are sometimes a scalar, and
sometimes a triple with comparison operator and EVR.

And even if a scalar, there are files starting with '/', and name spaces
structured as "foo(bar)", and the usual other elements contained in
the index. So perhaps a new table instead of filtering.

Any filtering based on basenames triggers many stat(2) calls, as you  
well know.

(aside) I'd likely attempt more general than rpmdbKeyIterator() if an  
is needed. A far more important issue imho is handling SQL row's and  
within an iteration framework. Note "char *" only in your  
rpmdbKeyIterator() return.

The specific flaw with
     Conflicts: /foo
is that current repo-md goes to lengths to avoid including file
paths. So in your second case the about-to-be-installed A
has a file path that needs to be compared against the already
installed B Conflicts: /foo.

Your proposal stores Conflicts: after install efficiently, but does  
not address
the issue that all (well the subset of paths mentioned in Conflicts:  
has slightly
smaller measure than "all" ;-) file paths for about-to-be-installed A
packages that will need to be distributed within repo-md fileinfo.xml.

I don't see repo-md distributing file paths happening anytime soon ...

73 de Jeff
Received on Fri Sep 19 12:50:45 2008
Driven by Jeff Johnson and the RPM project team.
Hosted by OpenPKG and Ralf S. Engelschall.
Powered by FreeBSD and OpenPKG.