2006-12-19 00:17:44 +01:00
|
|
|
Suspend exclusive database lock when scriptlets get called, allowing
|
|
|
|
read access in scriptlets. Only needed for DB_PRIVATE (aka global)
|
|
|
|
locking.
|
|
|
|
|
2006-12-19 00:17:44 +01:00
|
|
|
I hijacked the dbiSync function for this because I did not want
|
|
|
|
to change the ABI.
|
|
|
|
|
2010-04-01 18:15:26 +02:00
|
|
|
--- ./lib/backend/db3.c.orig 2010-03-25 14:35:39.000000000 +0000
|
|
|
|
+++ ./lib/backend/db3.c 2010-03-25 14:44:42.000000000 +0000
|
|
|
|
@@ -208,11 +208,17 @@ errxit:
|
2009-08-28 15:54:03 +02:00
|
|
|
return rc;
|
2006-12-19 00:17:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
+static int db3SuspendResumeLock(dbiIndex dbi, int mode);
|
|
|
|
+
|
|
|
|
static int db3sync(dbiIndex dbi, unsigned int flags)
|
2009-08-28 15:54:03 +02:00
|
|
|
{
|
|
|
|
DB * db = dbi->dbi_db;
|
2006-12-19 00:17:44 +01:00
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
+ if (flags == (unsigned int)-1)
|
|
|
|
+ return db3SuspendResumeLock(dbi, 0);
|
|
|
|
+ if (flags == (unsigned int)-2)
|
|
|
|
+ return db3SuspendResumeLock(dbi, 1);
|
2010-04-01 18:15:26 +02:00
|
|
|
if (db != NULL) {
|
2006-12-19 00:17:44 +01:00
|
|
|
rc = db->sync(db, flags);
|
2010-04-01 18:15:26 +02:00
|
|
|
rc = cvtdberr(dbi, "db->sync", rc, _debug);
|
|
|
|
@@ -848,6 +854,48 @@ static int db3open(rpmdb rpmdb, rpmTag r
|
2009-08-28 15:54:03 +02:00
|
|
|
return rc;
|
2006-12-19 00:17:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
+static int
|
|
|
|
+db3SuspendResumeLock(dbiIndex dbi, int mode)
|
2006-12-19 00:17:44 +01:00
|
|
|
+{
|
|
|
|
+ struct flock l;
|
|
|
|
+ int rc = 0;
|
|
|
|
+ int tries;
|
|
|
|
+ int fdno = -1;
|
|
|
|
+
|
|
|
|
+ if (!dbi->dbi_lockdbfd)
|
|
|
|
+ return 0;
|
2006-12-19 00:17:44 +01:00
|
|
|
+ if (!(dbi->dbi_mode & (O_RDWR|O_WRONLY)))
|
|
|
|
+ return 0;
|
|
|
|
+ if (dbi->dbi_use_dbenv && _lockdbfd == 0)
|
2006-12-19 00:17:44 +01:00
|
|
|
+ return 0;
|
|
|
|
+ if (!(dbi->dbi_db->fd(dbi->dbi_db, &fdno) == 0 && fdno >= 0))
|
|
|
|
+ return 1;
|
2006-12-19 00:17:44 +01:00
|
|
|
+ if (mode == 0) {
|
2006-12-19 00:17:44 +01:00
|
|
|
+ memset(&l, 0, sizeof(l));
|
|
|
|
+ l.l_whence = 0;
|
|
|
|
+ l.l_start = 0;
|
|
|
|
+ l.l_len = 0;
|
2006-12-19 00:17:44 +01:00
|
|
|
+ l.l_type = F_RDLCK;
|
|
|
|
+ rc = fcntl(fdno, F_SETLK, (void *) &l);
|
|
|
|
+ if (rc)
|
2009-08-28 15:54:03 +02:00
|
|
|
+ rpmlog(RPMLOG_WARNING, _("could not suspend database lock\n"));
|
2006-12-19 00:17:44 +01:00
|
|
|
+ } else {
|
|
|
|
+ for (tries = 0; tries < 2; tries++) {
|
|
|
|
+ memset(&l, 0, sizeof(l));
|
|
|
|
+ l.l_whence = 0;
|
|
|
|
+ l.l_start = 0;
|
|
|
|
+ l.l_len = 0;
|
|
|
|
+ l.l_type = F_WRLCK;
|
|
|
|
+ rc = fcntl(fdno, tries ? F_SETLKW : F_SETLK, (void *) &l);
|
|
|
|
+ if (!rc)
|
|
|
|
+ break;
|
|
|
|
+ if (tries == 0)
|
2009-08-28 15:54:03 +02:00
|
|
|
+ rpmlog(RPMLOG_WARNING, _("waiting to reestablish exclusive database lock\n"));
|
2006-12-19 00:17:44 +01:00
|
|
|
+ }
|
2006-12-19 00:17:44 +01:00
|
|
|
+ }
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+
|
2006-12-19 00:17:44 +01:00
|
|
|
/** \ingroup db3
|
|
|
|
*/
|
2009-08-28 15:54:03 +02:00
|
|
|
RPM_GNUC_INTERNAL
|
2010-04-01 18:15:26 +02:00
|
|
|
--- ./lib/psm.c.orig 2010-03-25 14:43:29.000000000 +0000
|
|
|
|
+++ ./lib/psm.c 2010-03-25 14:43:41.000000000 +0000
|
|
|
|
@@ -754,6 +754,8 @@ static rpmRC runScript(rpmpsm psm, Heade
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ rpmtsSuspendResumeDBLock(psm->ts, 0);
|
|
|
|
+
|
|
|
|
xx = rpmsqFork(&psm->sq);
|
|
|
|
if (psm->sq.child == 0) {
|
|
|
|
rpmlog(RPMLOG_DEBUG, "%s: %s\texecv(%s) pid %d\n",
|
|
|
|
@@ -768,6 +770,8 @@ static rpmRC runScript(rpmpsm psm, Heade
|
|
|
|
|
|
|
|
(void) psmWait(psm);
|
|
|
|
|
|
|
|
+ rpmtsSuspendResumeDBLock(psm->ts, 1);
|
|
|
|
+
|
|
|
|
if (psm->sq.reaped < 0) {
|
|
|
|
rpmlog(RPMLOG_ERR, _("%s scriptlet failed, waitpid(%d) rc %d: %s\n"),
|
|
|
|
sname, psm->sq.child, psm->sq.reaped, strerror(errno));
|
|
|
|
--- ./lib/rpmdb.c.orig 2010-03-25 14:36:57.000000000 +0000
|
|
|
|
+++ ./lib/rpmdb.c 2010-03-25 14:43:41.000000000 +0000
|
|
|
|
@@ -903,6 +903,21 @@ int rpmdbSync(rpmdb db)
|
2006-12-19 00:17:44 +01:00
|
|
|
return rc;
|
2006-12-19 00:17:44 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
+int rpmdbSuspendResumeDBLock(rpmdb db, int mode)
|
|
|
|
+{
|
2006-12-19 00:17:44 +01:00
|
|
|
+ int dbix;
|
|
|
|
+ int rc = 0;
|
2006-12-19 00:17:44 +01:00
|
|
|
+ if (db == NULL) return 0;
|
2006-12-19 00:17:44 +01:00
|
|
|
+ for (dbix = 0; dbix < db->db_ndbi; dbix++) {
|
|
|
|
+ int xx;
|
|
|
|
+ if (db->_dbi[dbix] == NULL)
|
|
|
|
+ continue;
|
|
|
|
+ xx = dbiSync(db->_dbi[dbix], mode ? -2 : -1);
|
|
|
|
+ if (xx && rc == 0) rc = xx;
|
|
|
|
+ }
|
|
|
|
+ return rc;
|
2010-03-26 11:56:28 +01:00
|
|
|
+}
|
|
|
|
+
|
2009-08-28 15:54:03 +02:00
|
|
|
/* FIX: dbTemplate structure assignment */
|
|
|
|
static
|
|
|
|
rpmdb newRpmdb(const char * root,
|
2010-04-01 18:15:26 +02:00
|
|
|
--- ./lib/rpmts.c.orig 2009-12-17 09:05:37.000000000 +0000
|
|
|
|
+++ ./lib/rpmts.c 2010-03-25 14:43:41.000000000 +0000
|
|
|
|
@@ -89,6 +89,11 @@ int rpmtsOpenDB(rpmts ts, int dbmode)
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
+int rpmtsSuspendResumeDBLock(rpmts ts, int mode)
|
|
|
|
+{
|
|
|
|
+ return rpmdbSuspendResumeDBLock(ts->rdb, mode);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
int rpmtsInitDB(rpmts ts, int dbmode)
|
|
|
|
{
|
|
|
|
void *lock = rpmtsAcquireLock(ts);
|
|
|
|
--- ./lib/rpmts.h.orig 2009-12-17 09:05:37.000000000 +0000
|
|
|
|
+++ ./lib/rpmts.h 2010-03-25 14:43:41.000000000 +0000
|
|
|
|
@@ -469,6 +469,10 @@ rpmdb rpmtsGetRdb(rpmts ts);
|
|
|
|
void * rpmtsNotify(rpmts ts, rpmte te,
|
|
|
|
rpmCallbackType what, rpm_loff_t amount, rpm_loff_t total);
|
|
|
|
|
|
|
|
+int rpmtsSuspendResumeDBLock(rpmts ts, int mode)
|
|
|
|
+ /*@globals fileSystem @*/
|
|
|
|
+ /*@modifies fileSystem @*/;
|
|
|
|
+
|
|
|
|
/** \ingroup rpmts
|
|
|
|
* Return number of (ordered) transaction set elements.
|
|
|
|
* @param ts transaction set
|