Description of problem: Sometimes when running a rollback I was seeing the current package removed without restoring the previous package. This was consistant with a given package on a particular system, but not accross multiple systems. As it turned out the problem was that rpmRollback() was assuming that that the order that IDTXglob() returned the package headers from the repackaged packages was in the correct order. This was not the case, as IDTXglob() was depending on rpmglob() for the order of the package headers, when in reality they needed to be sorted by REMOVETID. Version-Release number of selected component (if applicable): 4.2-0.69 How reproducible: It depends on what state your repackaged package dir is in. When it gets in the right state, it fails everytime. Steps to Reproduce: I am not sure how to get the repackage directory in the state such that this occurs, but I suspect it involves upgrading and removing a package, and then installing it and upgrading again all with the --repackage switch. Once the repackage package directory is in right state then run a script like this: rpm -e normal rpm -Uvh /root/work/build/RPM/RPMS/noarch/normal-1.0-1.noarch.rpm echo "Rollback Goal: $(date +%s)" X="$(date '+%m/%d/%Y %H:%M:%S')" echo "Rollback Goal: ${X}" sleep 10 rpm -Uvh /root/work/build/RPM/RPMS/noarch/normal-1.1-1.noarch.rpm sleep 5 rpm -Fvvh --rollback "${X}" Actual results: The package is completely removed. No repackaged packages are added as install elements to any transactions. Expected results: The package would be downgraded (i.e. the repackaged package would have made it into a transaction as an install element). Additional info: Here is the patch that fixes this problem (sorry no doxygen): --- rpm-4.2/lib/rpminstall.c.delta 2003-04-28 17:43:21.000000000 -0400 +++ rpm-4.2/lib/rpminstall.c 2003-04-28 17:47:01.000000000 -0400 @@ -1050,9 +1050,19 @@ av[i] = _free(av[i]); av = _free(av); ac = 0; + /* Sort by REMOVETID */ + qsort((void *) idtx->idt, idtx->nidt, sizeof(*idtx->idt), IDTcmp); return idtx; } +int IDTcmp(const void * a, const void * b) +{ + IDT idta = (IDT) a; + IDT idtb = (IDT) b; + + return (idtb->val.u32 - idta->val.u32); +} + /** @todo Transaction handling, more, needs work. */ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv) { --- rpm-4.2/lib/rpmcli.h.delta 2003-04-28 17:44:46.000000000 -0400 +++ rpm-4.2/lib/rpmcli.h 2003-04-28 17:45:43.000000000 -0400 @@ -667,6 +667,8 @@ /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/ /*@modifies ts, rpmGlobalMacroContext, fileSystem, internalState @*/; +int IDTcmp(const void * a, const void * b); + /** \ingroup rpmcli * Rollback transactions, erasing new, reinstalling old, package(s). * @param ts transaction set
Eeek, yes rpm-4.0.4 had return IDTXsort(idtx); at the end of IDTXglob Fix in rpm-4.3 CVS momentarily. Thanks for noticing.
Created attachment 92228 [details] First patch was not checking if the IDTX was empty Jeff, you probably don't need this, but just in case someone was using this patch, the one attached gets rid of a segfault. I was not checking the whether the IDTX was empty. This patch simply does: if(as > 0) and then does the sort. Course I would highly recommend people using your rawhide patched version for this purpose.