diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/query.c | 4 | ||||
-rw-r--r-- | lib/rpminstall.c | 36 | ||||
-rw-r--r-- | lib/rpmts.c | 45 | ||||
-rw-r--r-- | lib/rpmts.h | 9 | ||||
-rw-r--r-- | lib/verify.c | 8 |
5 files changed, 75 insertions, 27 deletions
diff --git a/lib/query.c b/lib/query.c index e34c483f8..13799e805 100644 --- a/lib/query.c +++ b/lib/query.c @@ -589,7 +589,7 @@ restart: if (rpmrc == RPMRC_OK) { res = qva->qva_showPackage(qva, ts, h); h = headerFree(h); - rpmtsClean(ts); + rpmtsEmpty(ts); continue; } @@ -944,7 +944,7 @@ int rpmcliQuery(rpmts ts, QVA_t qva, const char ** argv) if (argv != NULL) while ((arg = *argv++) != NULL) { ec += rpmQueryVerify(qva, ts, arg); - rpmtsClean(ts); + rpmtsEmpty(ts); } /*@=boundsread@*/ } diff --git a/lib/rpminstall.c b/lib/rpminstall.c index b6df7d1da..7bc250502 100644 --- a/lib/rpminstall.c +++ b/lib/rpminstall.c @@ -714,6 +714,8 @@ exit: eiu->pkgURL = _free(eiu->pkgURL); eiu->argv = _free(eiu->argv); + rpmtsEmpty(ts); + return eiu->numFailed; } /*@=bounds@*/ @@ -811,6 +813,8 @@ int rpmErase(rpmts ts, ps = rpmpsFree(ps); } + rpmtsEmpty(ts); + return numFailed; } @@ -1049,12 +1053,16 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv) int numAdded; int numRemoved; rpmps ps; + int _unsafe_rollbacks = 0; + rpmtransFlags transFlags = ia->transFlags; if (argv != NULL && *argv != NULL) { rc = -1; goto exit; } + _unsafe_rollbacks = rpmExpandNumeric("%{?_unsafe_rollbacks}"); + vsflags = rpmExpandNumeric("%{?_vsflags_erase}"); if (ia->qva_flags & VERIFY_DIGEST) vsflags |= _RPMVSF_NODIGESTS; @@ -1065,7 +1073,7 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv) vsflags |= RPMVSF_NEEDPAYLOAD; /* XXX no legacy signatures */ ovsflags = rpmtsSetVSFlags(ts, vsflags); - (void) rpmtsSetFlags(ts, ia->transFlags); + (void) rpmtsSetFlags(ts, transFlags); itids = IDTXload(ts, RPMTAG_INSTALLTID); if (itids != NULL) { @@ -1119,12 +1127,14 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv) if (thistid == 0 || thistid < ia->rbtid) break; + rpmtsEmpty(ts); + (void) rpmtsSetFlags(ts, transFlags); + /* Install the previously erased packages for this transaction. */ while (rp != NULL && rp->val.u32 == thistid) { -/*@-nullpass@*/ /* FIX: rp->key may be NULL */ - rpmMessage(RPMMESS_DEBUG, "\t+++ %s\n", rp->key); -/*@=nullpass@*/ + rpmMessage(RPMMESS_DEBUG, "\t+++ install %s\n", + (rp->key ? rp->key : "???")); /*@-abstract@*/ rc = rpmtsAddInstallElement(ts, rp->h, (fnpyKey)rp->key, @@ -1152,18 +1162,21 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv) while (ip != NULL && ip->val.u32 == thistid) { rpmMessage(RPMMESS_DEBUG, - "\t--- rpmdb instance #%u\n", ip->instance); + "\t--- erase h#%u\n", ip->instance); rc = rpmtsAddEraseElement(ts, ip->h, ip->instance); if (rc != 0) goto exit; numRemoved++; -#ifdef NOTYET /* XXX don't count erasures yet */ - rpmcliPackagesTotal++; -#endif - if (!(ia->installInterfaceFlags & ifmask)) + + if (_unsafe_rollbacks) + rpmcliPackagesTotal++; + + if (!(ia->installInterfaceFlags & ifmask)) { ia->installInterfaceFlags |= INSTALL_ERASE; + (void) rpmtsSetFlags(ts, (transFlags | RPMTRANS_FLAG_REVERSE)); + } #ifdef NOTYET ip->instance = 0; @@ -1222,12 +1235,15 @@ int rpmRollback(rpmts ts, struct rpmInstallArguments_s * ia, const char ** argv) } } + } while (1); exit: - rtids = IDTXfree(rtids); itids = IDTXfree(itids); + rpmtsEmpty(ts); + (void) rpmtsSetFlags(ts, transFlags); + return rc; } diff --git a/lib/rpmts.c b/lib/rpmts.c index da8a9567c..d06d658ee 100644 --- a/lib/rpmts.c +++ b/lib/rpmts.c @@ -546,6 +546,7 @@ void rpmtsCleanDig(rpmts ts) void rpmtsClean(rpmts ts) { rpmtsi pi; rpmte p; + if (ts == NULL) return; @@ -566,10 +567,35 @@ void rpmtsClean(rpmts ts) rpmtsCleanDig(ts); } +void rpmtsEmpty(rpmts ts) +{ + rpmtsi pi; rpmte p; + int oc; + + if (ts == NULL) + return; + +/*@-nullstate@*/ /* FIX: partial annotations */ + rpmtsClean(ts); +/*@=nullstate@*/ + + for (pi = rpmtsiInit(ts), oc = 0; (p = rpmtsiNext(pi, 0)) != NULL; oc++) { +/*@-type -unqualifiedtrans @*/ + ts->order[oc] = rpmteFree(ts->order[oc]); +/*@=type =unqualifiedtrans @*/ + } + pi = rpmtsiFree(pi); + + ts->orderCount = 0; + + ts->numRemovedPackages = 0; +} + rpmts rpmtsFree(rpmts ts) { rpmtsi pi; rpmte p; int oc; + if (ts == NULL) return NULL; @@ -579,15 +605,21 @@ rpmts rpmtsFree(rpmts ts) if (ts->nrefs > 0) return NULL; +/*@-nullstate@*/ /* FIX: partial annotations */ + rpmtsEmpty(ts); +/*@=nullstate@*/ + (void) rpmtsCloseDB(ts); (void) rpmtsCloseSDB(ts); + ts->removedPackages = _free(ts->removedPackages); + ts->availablePackages = rpmalFree(ts->availablePackages); ts->numAvailablePackages = 0; ts->dsi = _free(ts->dsi); - ts->removedPackages = _free(ts->removedPackages); + if (ts->scriptFd != NULL) { ts->scriptFd = fdFree(ts->scriptFd, "rpmtsFree"); ts->scriptFd = NULL; @@ -595,25 +627,16 @@ rpmts rpmtsFree(rpmts ts) ts->rootDir = _free(ts->rootDir); ts->currDir = _free(ts->currDir); - for (pi = rpmtsiInit(ts), oc = 0; (p = rpmtsiNext(pi, 0)) != NULL; oc++) { -/*@-type -unqualifiedtrans @*/ - ts->order[oc] = rpmteFree(ts->order[oc]); -/*@=type =unqualifiedtrans @*/ - } - pi = rpmtsiFree(pi); /*@-type +voidabstract @*/ /* FIX: double indirection */ ts->order = _free(ts->order); /*@=type =voidabstract @*/ + ts->orderAlloced = 0; if (ts->pkpkt != NULL) ts->pkpkt = _free(ts->pkpkt); ts->pkpktlen = 0; memset(ts->pksignid, 0, sizeof(ts->pksignid)); -/*@-nullstate@*/ /* FIX: partial annotations */ - rpmtsClean(ts); -/*@=nullstate@*/ - /*@-refcounttrans@*/ ts = _free(ts); /*@=refcounttrans@*/ /*@=usereleased@*/ diff --git a/lib/rpmts.h b/lib/rpmts.h index d729d7d51..1aa882e78 100644 --- a/lib/rpmts.h +++ b/lib/rpmts.h @@ -424,13 +424,20 @@ void rpmtsCleanDig(rpmts ts) /*@modifies ts @*/; /** \ingroup rpmts - * Re-create an empty transaction set. + * Free memory needed only for dependency checks and ordering. * @param ts transaction set */ void rpmtsClean(rpmts ts) /*@modifies ts @*/; /** \ingroup rpmts + * Re-create an empty transaction set. + * @param ts transaction set + */ +void rpmtsEmpty(rpmts ts) + /*@modifies ts @*/; + +/** \ingroup rpmts * Destroy transaction set, closing the database as well. * @param ts transaction set * @return NULL always diff --git a/lib/verify.c b/lib/verify.c index a58612564..fcb7f3a2b 100644 --- a/lib/verify.c +++ b/lib/verify.c @@ -372,7 +372,7 @@ static int verifyDependencies(/*@unused@*/ QVA_t qva, rpmts ts, int xx; int i; - rpmtsClean(ts); + rpmtsEmpty(ts); (void) rpmtsAddInstallElement(ts, h, NULL, 0, NULL); xx = rpmtsCheck(ts); @@ -419,7 +419,7 @@ static int verifyDependencies(/*@unused@*/ QVA_t qva, rpmts ts, ps = rpmpsFree(ps); - rpmtsClean(ts); + rpmtsEmpty(ts); return rc; } @@ -493,7 +493,7 @@ int rpmcliVerify(rpmts ts, QVA_t qva, const char ** argv) if (argv != NULL) while ((arg = *argv++) != NULL) { ec += rpmQueryVerify(qva, ts, arg); - rpmtsClean(ts); + rpmtsEmpty(ts); } /*@=boundsread@*/ } @@ -502,5 +502,7 @@ int rpmcliVerify(rpmts ts, QVA_t qva, const char ** argv) if (qva->qva_showPackage == showVerifyPackage) qva->qva_showPackage = NULL; + rpmtsEmpty(ts); + return ec; } |