Comment 8 for bug 347749

Revision history for this message
Patryk Zawadzki (patrys) wrote :

What we dicovered in rpm:

lib/psm.c, rpmpsmStage @ 1643:

  hdrid = rpmteHdrid(psm->te);
  psm->mi = rpmtsInitIterator(ts, RPMTAG_SHA1HEADER, hdrid, 0);

This initiates a search for earlier installation of the very same package. In theory it should only find the exact NEVRA in case where reinstall was required.

lib/psm.c, rpmpsmStage @ 1660:

  while ((psm->oh = rpmdbNextIterator(psm->mi)) != NULL) {
    fi->record = rpmdbGetIteratorOffset(psm->mi);
    psm->oh = NULL;
    break;
  }

This consumes the iterator from above and checks if there was a match. It then takes the first match and remembers it in fi->record.

lib/psm.c, rpmpsmStage @ 2075:

  if (fi->record && !(rpmtsFlags(ts) & RPMTRANS_FLAG_APPLYONLY)) {
    rc = rpmpsmNext(psm, PSM_RPMDB_REMOVE);
    if (rc) break;
  }

This checks if fi->record contains any matches and if so, forces their removal from DB, assuming the header will be readded during the same transaction (if a match was found, we are reinstalling the same package, remember?).

Now what is completely weird is that the search in the first step tends to return completely random results. Like glibc header matching ncurses. This causes random bugs where installing one package will silently remove another package from rpmdb.

At first we though it was some sort of SHA1 substring collision but it seems to happen with completely random data.

glen should be able to give precise versions of db4.7 and rpm4.5 we used for testing.