Add support for %transfiletriggerun.
This commit is contained in:
parent
ec78eea7fe
commit
30a5603159
60
lib/psm.c
60
lib/psm.c
|
@ -23,6 +23,7 @@
|
|||
#include "lib/rpmte_internal.h" /* XXX internal apis */
|
||||
#include "lib/rpmdb_internal.h" /* rpmdbAdd/Remove */
|
||||
#include "lib/rpmts_internal.h" /* rpmtsPlugins() etc */
|
||||
#include "lib/rpmds_internal.h" /* rpmdsFilterTi() */
|
||||
#include "lib/rpmscript.h"
|
||||
#include "lib/misc.h"
|
||||
|
||||
|
@ -712,6 +713,62 @@ static rpmRC rpmPackageInstall(rpmts ts, rpmpsm psm)
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare post trans uninstall file triggers. After transcation uninstalled
|
||||
* files are not saved anywhere. So we need during uninstalation of every
|
||||
* package, in time when the files to uninstall are still available,
|
||||
* to determine and store triggers that should be set off after transaction.
|
||||
*/
|
||||
static void prepPostUnTransFileTrigs(rpmts ts, rpmte te)
|
||||
{
|
||||
rpmdbMatchIterator mi;
|
||||
rpmdbIndexIterator ii;
|
||||
Header trigH;
|
||||
const void *key;
|
||||
size_t keylen;
|
||||
rpmfiles files;
|
||||
rpmds rpmdsTriggers;
|
||||
rpmds rpmdsTrigger;
|
||||
int tix = 0;
|
||||
|
||||
ii = rpmdbIndexIteratorInit(rpmtsGetRdb(ts), RPMDBI_TRANSFILETRIGGERNAME);
|
||||
mi = rpmdbNewIterator(rpmtsGetRdb(ts), RPMDBI_PACKAGES);
|
||||
files = rpmteFiles(te);
|
||||
|
||||
/* Iterate over file triggers in rpmdb */
|
||||
while ((rpmdbIndexIteratorNext(ii, &key, &keylen)) == 0) {
|
||||
/* Check if file trigger matches any file in this te */
|
||||
rpmfi fi = rpmfilesFindPrefix(files, key);
|
||||
if (rpmfiFC(fi) > 0) {
|
||||
/* If yes then store it */
|
||||
rpmdbAppendIterator(mi, rpmdbIndexIteratorPkgOffsets(ii),
|
||||
rpmdbIndexIteratorNumPkgs(ii));
|
||||
}
|
||||
rpmfiFree(fi);
|
||||
}
|
||||
rpmdbIndexIteratorFree(ii);
|
||||
|
||||
rpmdbUniqIterator(mi);
|
||||
if (rpmdbGetIteratorCount(mi)) {
|
||||
/* Filter triggers and save only trans postun triggers into ts */
|
||||
while((trigH = rpmdbNextIterator(mi)) != NULL) {
|
||||
rpmdsTriggers = rpmdsNew(trigH, RPMTAG_TRANSFILETRIGGERNAME, 0);
|
||||
while ((rpmdsTrigger = rpmdsFilterTi(rpmdsTriggers, tix))) {
|
||||
if ((rpmdsNext(rpmdsTrigger) >= 0) &&
|
||||
(rpmdsFlags(rpmdsTrigger) & RPMSENSE_TRIGGERPOSTUN)) {
|
||||
|
||||
rpmtsAddTrigger(ts, rpmdbGetIteratorOffset(mi) ,tix);
|
||||
|
||||
}
|
||||
rpmdsFree(rpmdsTrigger);
|
||||
tix++;
|
||||
}
|
||||
rpmdsFree(rpmdsTriggers);
|
||||
}
|
||||
}
|
||||
rpmdbFreeIterator(mi);
|
||||
}
|
||||
|
||||
static rpmRC rpmPackageErase(rpmts ts, rpmpsm psm)
|
||||
{
|
||||
rpmRC rc = RPMRC_OK;
|
||||
|
@ -762,6 +819,9 @@ static rpmRC rpmPackageErase(rpmts ts, rpmpsm psm)
|
|||
RPMSCRIPT_FILETRIGGER);
|
||||
if (rc) break;
|
||||
|
||||
/* Prepare post transaction uninstall triggers */
|
||||
prepPostUnTransFileTrigs(psm->ts, psm->te);
|
||||
|
||||
rc = dbRemove(ts, psm->te);
|
||||
}
|
||||
|
||||
|
|
|
@ -678,7 +678,7 @@ int rpmdbVerify(const char * prefix)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static Header rpmdbGetHeaderAt(rpmdb db, unsigned int offset)
|
||||
Header rpmdbGetHeaderAt(rpmdb db, unsigned int offset)
|
||||
{
|
||||
rpmdbMatchIterator mi = rpmdbInitIterator(db, RPMDBI_PACKAGES,
|
||||
&offset, sizeof(offset));
|
||||
|
|
|
@ -200,6 +200,15 @@ void rpmdbSetIteratorIndex(rpmdbMatchIterator mi, unsigned int ix);
|
|||
RPM_GNUC_INTERNAL
|
||||
unsigned int rpmdbGetIteratorOffsetFor(rpmdbMatchIterator mi, unsigned int ix);
|
||||
|
||||
/** \ingroup rpmdb
|
||||
* Return header located in rpmdb at given offset.
|
||||
* @param db rpm database
|
||||
* @param offset database offset
|
||||
* @return header at given offset
|
||||
*/
|
||||
RPM_GNUC_INTERNAL
|
||||
Header rpmdbGetHeaderAt(rpmdb db, unsigned int offset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
70
lib/rpmts.c
70
lib/rpmts.c
|
@ -56,6 +56,72 @@ static rpmts rpmtsUnlink(rpmts ts)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Prepare space in memory for storing transaction triggers */
|
||||
static void rpmtsInitTriggers(rpmts ts)
|
||||
{
|
||||
if (ts) {
|
||||
ts->trigs2run.count = 0;
|
||||
ts->trigs2run.alloced = 10;
|
||||
ts->trigs2run.trigger = xmalloc(sizeof(*ts->trigs2run.trigger) *
|
||||
ts->trigs2run.alloced);
|
||||
}
|
||||
}
|
||||
|
||||
static void rpmtsFreeTriggers(rpmts ts)
|
||||
{
|
||||
free(ts->trigs2run.trigger);
|
||||
}
|
||||
|
||||
/* Add transaction trigger that should be set off after transaction */
|
||||
void rpmtsAddTrigger(rpmts ts, unsigned int hdrNum, int index)
|
||||
{
|
||||
if (ts->trigs2run.alloced < ts->trigs2run.count + 1) {
|
||||
ts->trigs2run.alloced <<= 1;
|
||||
ts->trigs2run.trigger = xrealloc(ts->trigs2run.trigger,
|
||||
sizeof(*ts->trigs2run.trigger) * ts->trigs2run.alloced);
|
||||
}
|
||||
|
||||
ts->trigs2run.trigger[ts->trigs2run.count].hdrNum = hdrNum;
|
||||
ts->trigs2run.trigger[ts->trigs2run.count].index = index;
|
||||
ts->trigs2run.count++;
|
||||
}
|
||||
|
||||
static int triggerCmp(const void *one, const void *two)
|
||||
{
|
||||
int rc;
|
||||
const tsTrigger *a = one, *b = two;
|
||||
|
||||
rc = a->hdrNum - b->hdrNum;
|
||||
if (rc == 0)
|
||||
rc = a->index - b->index;
|
||||
return rc;
|
||||
}
|
||||
|
||||
void rpmtsUniqTriggers(rpmts ts)
|
||||
{
|
||||
unsigned int from;
|
||||
unsigned int to = 0;
|
||||
unsigned int count = ts->trigs2run.count;
|
||||
|
||||
if (ts->trigs2run.count > 1) {
|
||||
qsort(ts->trigs2run.trigger, ts->trigs2run.count,
|
||||
sizeof(*ts->trigs2run.trigger), triggerCmp);
|
||||
}
|
||||
|
||||
for (from = 0; from < count; from++) {
|
||||
if (from > 0 &&
|
||||
!triggerCmp((const void *) &ts->trigs2run.trigger[from - 1],
|
||||
(const void *) &ts->trigs2run.trigger[from])) {
|
||||
|
||||
ts->trigs2run.count--;
|
||||
continue;
|
||||
}
|
||||
if (from != to)
|
||||
ts->trigs2run.trigger[to] = ts->trigs2run.trigger[from];
|
||||
to++;
|
||||
}
|
||||
}
|
||||
|
||||
rpmts rpmtsLink(rpmts ts)
|
||||
{
|
||||
if (ts)
|
||||
|
@ -678,6 +744,8 @@ rpmts rpmtsFree(rpmts ts)
|
|||
|
||||
ts->plugins = rpmpluginsFree(ts->plugins);
|
||||
|
||||
rpmtsFreeTriggers(ts);
|
||||
|
||||
if (_rpmts_stats)
|
||||
rpmtsPrintStats(ts);
|
||||
|
||||
|
@ -980,6 +1048,8 @@ rpmts rpmtsCreate(void)
|
|||
|
||||
ts->plugins = NULL;
|
||||
|
||||
rpmtsInitTriggers(ts);
|
||||
|
||||
return rpmtsLink(ts);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,17 @@ typedef struct tsMembers_s {
|
|||
int delta; /*!< Delta for reallocation. */
|
||||
} * tsMembers;
|
||||
|
||||
typedef struct tsTrigger_s {
|
||||
unsigned int hdrNum;
|
||||
int index;
|
||||
} tsTrigger;
|
||||
|
||||
typedef struct tsTriggers_s {
|
||||
tsTrigger *trigger;
|
||||
int count;
|
||||
int alloced;
|
||||
} tsTriggers;
|
||||
|
||||
/** \ingroup rpmts
|
||||
* The set of packages to be installed/removed atomically.
|
||||
*/
|
||||
|
@ -70,6 +81,8 @@ struct rpmts_s {
|
|||
rpmPlugins plugins; /*!< Transaction plugins */
|
||||
|
||||
int nrefs; /*!< Reference count. */
|
||||
|
||||
tsTriggers trigs2run; /*!< Transaction file triggers */
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -112,6 +125,12 @@ rpmRC runImmedFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense,
|
|||
RPM_GNUC_INTERNAL
|
||||
rpmRC runScript(rpmts ts, rpmte te, ARGV_const_t prefixes,
|
||||
rpmScript script, int arg1, int arg2);
|
||||
RPM_GNUC_INTERNAL
|
||||
void rpmtsAddTrigger(rpmts ts, unsigned int hdrNum, int index);
|
||||
|
||||
RPM_GNUC_INTERNAL
|
||||
void rpmtsUniqTriggers(rpmts ts);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -1819,6 +1819,42 @@ rpmRC runImmedFileTriggers(rpmts ts, rpmte te, rpmsenseFlags sense,
|
|||
return (nerrors == 0) ? RPMRC_OK : RPMRC_FAIL;
|
||||
}
|
||||
|
||||
/* Run triggers stored in ts */
|
||||
static int runPostUnTransFileTrigs(rpmts ts)
|
||||
{
|
||||
int i;
|
||||
Header trigH;
|
||||
struct rpmtd_s installPrefixes;
|
||||
rpmScript script;
|
||||
int nerrors = 0;
|
||||
|
||||
rpmtsUniqTriggers(ts);
|
||||
/* Iterate over stored triggers */
|
||||
for (i = 0; i < ts->trigs2run.count; i++) {
|
||||
/* Get header containing trigger script */
|
||||
trigH = rpmdbGetHeaderAt(rpmtsGetRdb(ts),
|
||||
ts->trigs2run.trigger[i].hdrNum);
|
||||
|
||||
/* Maybe package whith this trigger is already uninstalled */
|
||||
if (trigH == NULL)
|
||||
continue;
|
||||
|
||||
/* Prepare and run script */
|
||||
script = rpmScriptFromTriggerTag(trigH, RPMSENSE_TRIGGERPOSTUN,
|
||||
RPMSCRIPT_TRANSFILETRIGGER, ts->trigs2run.trigger[i].index);
|
||||
|
||||
headerGet(trigH, RPMTAG_INSTPREFIXES, &installPrefixes,
|
||||
HEADERGET_ALLOC|HEADERGET_ARGV);
|
||||
|
||||
nerrors += runScript(ts, NULL, installPrefixes.data, script, 0, 0);
|
||||
rpmtdFreeData(&installPrefixes);
|
||||
rpmScriptFree(script);
|
||||
headerFree(trigH);
|
||||
|
||||
}
|
||||
return nerrors;
|
||||
}
|
||||
|
||||
int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
|
||||
{
|
||||
int rc = -1; /* assume failure */
|
||||
|
@ -1911,6 +1947,7 @@ int rpmtsRun(rpmts ts, rpmps okProbs, rpmprobFilterFlags ignoreSet)
|
|||
|
||||
/* Run file triggers in other package(s) this package sets off. */
|
||||
runFileTriggers(ts, NULL, RPMSENSE_TRIGGERIN, RPMSCRIPT_TRANSFILETRIGGER);
|
||||
runPostUnTransFileTrigs(ts);
|
||||
|
||||
/* Run file triggers in this package other package(s) set off. */
|
||||
runTransScripts(ts, PKG_TRANSFILETRIGGERIN);
|
||||
|
|
Loading…
Reference in New Issue