* RPM_TRANS_AUTOROLLBACK
*
* ROLLBACK and AUTOROLLBACK transactions should always be ran as
- * a best effort. In particular this important to the autorollback
+ * a best effort. In particular this is important to the autorollback
* feature to avoid rolling back a rollback (otherwise known as
* dueling rollbacks (-;). AUTOROLLBACK's additionally need instance
* counts passed to scriptlets to be altered.
ts = xcalloc(1, sizeof(*ts));
memset(&ts->ops, 0, sizeof(ts->ops));
(void) rpmswEnter(rpmtsOp(ts, RPMTS_OP_TOTAL), -1);
- ts->type = RPMTRANS_TYPE_NORMAL;
+ ts->type = RPMTRANS_TYPE_NORMAL;
ts->goal = TSM_UNKNOWN;
ts->filesystemCount = 0;
ts->filesystems = NULL;
ts->dig = NULL;
/*
- We only use the score in an autorollback. So set this to
- NULL by default.
+ * We only use the score in an autorollback. So set this to
+ * NULL by default.
*/
ts->score = NULL;
/*
* XXX: Do not get the score and then store it aside for later use.
- * we will delete it out from under you. There is not rpmtsScoreLink()
+ * we will delete it out from under you. There is no rpmtsScoreLink()
* as this may be a very temporary fix for autorollbacks.
*/
rpmtsScore rpmtsGetScore(rpmts ts)
/*
* XXX: Do not get the score entry and then store it aside for later use.
- * we will delete it out from under you. There is not an
+ * we will delete it out from under you. There is no
* rpmtsScoreEntryLink() as this may be a very temporary fix
* for autorollbacks.
* XXX: The scores are not sorted. This should be fixed at earliest
/*
* This is needed for the IDTX definitions. I think probably those need
* to be moved into a different source file (idtx.{c,h}), but that is up
- * Jeff Johnson.
+ * to Jeff Johnson.
*/
#include "rpmcli.h"
if (rc > 0 && rpmpsNumProblems(ps) > 0)
rpmpsPrint(stderr, ps);
ps = rpmpsFree(ps);
+
+ /*
+ * After we have ran through the transaction we need to
+ * remove any repackaged packages we just installed/upgraded
+ * from the rp repository.
+ */
+ tsi = rpmtsiInit(rollbackTransaction);
+ while((te = rpmtsiNext(tsi, 0)) != NULL) {
+ rpmMessage(RPMMESS_NORMAL, _("Cleaning up repackaged packages:\n"));
+ switch (rpmteType(te)) {
+ /* The install elements are repackaged packages */
+ case TR_ADDED:
+ /* Make sure the filename is still there. XXX: Can't happen */
+ if(te->key) {
+ rpmMessage(RPMMESS_NORMAL, _("\tRemoving %s:\n"), te->key);
+ (void) unlink(te->key); /* XXX: Should check for an error? */
+ }
+ /*@switchbreak@*/ break;
+
+ /* Ignore erase elements...nothing to do */
+ default:
+ /*@switchbreak@*/ break;
+ }
+ }
+ tsi = rpmtsiFree(tsi);
+
+ /* Free the rollback transaction */
rollbackTransaction = rpmtsFree(rollbackTransaction);
return rc;
* the next one. Perhaps I should return an error at this
* point, but if this was not the correct one, at least the correct one
* would be found.
- * XXX: Should I be matching name and arch?
+ * XXX: Should Match NAC!
*/
rpmMessage(RPMMESS_DEBUG, _("\tREMOVETID matched INSTALLTID.\n"));
if (headerGetEntry(rpIDT->h, RPMTAG_NAME, NULL, (void **) &rpname, NULL)) {
/**
* This is not a generalized function to be called from outside
* librpm. It is called internally by rpmtsRun() to add elements
- * to its rollback transaction.
+ * to its autorollback transaction.
* @param rollbackTransaction rollback transaction
* @param runningTransaction running transaction (the one you want to rollback)
* @param te Transaction element.
/* Add the install element, as we had a repackaged package */
rpmMessage(RPMMESS_DEBUG,
_("\tAdded repackaged package header: %s.\n"), rpn);
+ rpmMessage(RPMMESS_DEBUG,
+ _("\tAdded from install element %s.\n"), rpmteNEVRA(te));
rc = rpmtsAddInstallElement(rollbackTransaction, headerLink(rph),
(fnpyKey) rpn, 1, te->relocs);
/*@innerbreak@*/ break;
* have a repackaged package
*/
rpmMessage(RPMMESS_DEBUG, _("\tAdded erase element.\n"));
+ rpmMessage(RPMMESS_DEBUG,
+ _("\tAdded from install element %s.\n"), rpmteNEVRA(te));
rc = rpmtsAddEraseElement(rollbackTransaction, h, db_instance);
/*@innerbreak@*/ break;
case TR_REMOVED:
rpmMessage(RPMMESS_DEBUG,
_("Add erase element to auto-rollback transaction.\n"));
-
- /* See if this element has already been added as an upgrade.
- * If so we want to do nothing.
+ /* See if this element has already been added.
+ * If so we want to do nothing. Compare N's for match.
+ * XXX: Really should compare NAC's.
*/
pi = rpmtsiInit(rollbackTransaction);
- while ((p = rpmtsiNext(pi, TR_ADDED)) != NULL) {
- if (rpmteType(p) == TR_ADDED) continue;
+ while ((p = rpmtsiNext(pi, 0)) != NULL) {
if (!strcmp(rpmteN(p), rpmteN(te))) {
rpmMessage(RPMMESS_DEBUG, _("\tFound existing upgrade element.\n"));
rpmMessage(RPMMESS_DEBUG, _("\tNot adding erase element for %s.\n"),
rpmteN(te));
rc = RPMRC_OK;
pi = rpmtsiFree(pi);
- /*@loopbreak@*/ break;
+ goto cleanup;
}
}
pi = rpmtsiFree(pi);
-
/* Get the repackage header from the current transaction
* element.
*/
/* Add the install element */
rpmMessage(RPMMESS_DEBUG,
_("\tAdded repackaged package %s.\n"), rpn);
+ rpmMessage(RPMMESS_DEBUG,
+ _("\tAdded from erase element %s.\n"), rpmteNEVRA(te));
rc = rpmtsAddInstallElement(rollbackTransaction, rph,
(fnpyKey) rpn, 1, te->relocs);
if (rc != RPMRC_OK)
* free(rpn);
*/
+cleanup:
/* Clean up */
if (h != NULL)
h = headerFree(h);
rph = headerFree(rph);
return rc;
}
+
#define NOTIFY(_ts, _al) /*@i@*/ if ((_ts)->notify) (void) (_ts)->notify _al
int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
void * lock = NULL;
int xx;
-
/* XXX programmer error segfault avoidance. */
if (rpmtsNElements(ts) <= 0)
return -1;