summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/query.c4
-rw-r--r--lib/rpminstall.c36
-rw-r--r--lib/rpmts.c45
-rw-r--r--lib/rpmts.h9
-rw-r--r--lib/verify.c8
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;
}