Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:11.4:Update
rpm
suspendlock.diff
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File suspendlock.diff of Package rpm
Suspend exclusive database lock when scriptlets get called, allowing read access in scriptlets. Only needed for DB_PRIVATE (aka global) locking. I hijacked the dbiSync function for this because I did not want to change the ABI. --- ./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: return rc; } +static int db3SuspendResumeLock(dbiIndex dbi, int mode); + static int db3sync(dbiIndex dbi, unsigned int flags) { DB * db = dbi->dbi_db; int rc = 0; + if (flags == (unsigned int)-1) + return db3SuspendResumeLock(dbi, 0); + if (flags == (unsigned int)-2) + return db3SuspendResumeLock(dbi, 1); if (db != NULL) { rc = db->sync(db, flags); rc = cvtdberr(dbi, "db->sync", rc, _debug); @@ -848,6 +854,48 @@ static int db3open(rpmdb rpmdb, rpmTag r return rc; } +static int +db3SuspendResumeLock(dbiIndex dbi, int mode) +{ + struct flock l; + int rc = 0; + int tries; + int fdno = -1; + + if (!dbi->dbi_lockdbfd) + return 0; + if (!(dbi->dbi_mode & (O_RDWR|O_WRONLY))) + return 0; + if (dbi->dbi_use_dbenv && _lockdbfd == 0) + return 0; + if (!(dbi->dbi_db->fd(dbi->dbi_db, &fdno) == 0 && fdno >= 0)) + return 1; + if (mode == 0) { + memset(&l, 0, sizeof(l)); + l.l_whence = 0; + l.l_start = 0; + l.l_len = 0; + l.l_type = F_RDLCK; + rc = fcntl(fdno, F_SETLK, (void *) &l); + if (rc) + rpmlog(RPMLOG_WARNING, _("could not suspend database lock\n")); + } 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) + rpmlog(RPMLOG_WARNING, _("waiting to reestablish exclusive database lock\n")); + } + } + return rc; +} + /** \ingroup db3 */ RPM_GNUC_INTERNAL --- ./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) return rc; } +int rpmdbSuspendResumeDBLock(rpmdb db, int mode) +{ + int dbix; + int rc = 0; + if (db == NULL) return 0; + 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; +} + /* FIX: dbTemplate structure assignment */ static rpmdb newRpmdb(const char * root, --- ./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
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor