Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.3
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. --- ./lib/backend/db3.c.orig 2012-06-01 10:50:11.000000000 +0000 +++ ./lib/backend/db3.c 2012-06-01 10:50:19.000000000 +0000 @@ -628,3 +628,59 @@ int dbiOpen(rpmdb rdb, rpmDbiTagVal rpmt return rc; } + +int dbiSuspendDBLock(dbiIndex dbi, unsigned int flags) +{ + struct flock l; + int rc = 0; + int fdno = -1; + + if (!dbi->dbi_lockdbfd) + return 0; + if (!(dbi->dbi_rpmdb->db_mode & (O_RDWR|O_WRONLY))) + return 0; + if (_lockdbfd == 0) + return 0; + if (!(dbi->dbi_db->fd(dbi->dbi_db, &fdno) == 0 && fdno >= 0)) + return 1; + 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")); + return rc; +} + +int dbiResumeDBLock(dbiIndex dbi, unsigned int flags) +{ + struct flock l; + int rc = 0; + int tries; + int fdno = -1; + + if (!dbi->dbi_lockdbfd) + return 0; + if (!(dbi->dbi_rpmdb->db_mode & (O_RDWR|O_WRONLY))) + return 0; + if (_lockdbfd == 0) + return 0; + if (!(dbi->dbi_db->fd(dbi->dbi_db, &fdno) == 0 && fdno >= 0)) + return 1; + 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; +} + --- ./lib/backend/dbi.h.orig 2012-03-20 08:07:25.000000000 +0000 +++ ./lib/backend/dbi.h 2012-06-01 10:53:43.000000000 +0000 @@ -90,6 +90,24 @@ struct dbiIndex_s { extern "C" { #endif +/** \ingroup dbi + * Suspend the exclusive lock on the dbi + * @param dbi index database handle + * @param flags (unused) + * @return 0 on success + */ +RPM_GNUC_INTERNAL +int dbiSuspendDBLock(dbiIndex dbi, unsigned int flags); + +/** \ingroup dbi + * Reacquire an exclusive lock on the dbi + * @param dbi index database handle + * @param flags (unused) + * @return 0 on success + */ +RPM_GNUC_INTERNAL +int dbiResumeDBLock(dbiIndex dbi, unsigned int flags); + RPM_GNUC_INTERNAL /* Globally enable/disable fsync in the backend */ --- ./lib/psm.c.orig 2012-06-01 10:50:11.000000000 +0000 +++ ./lib/psm.c 2012-06-01 10:51:34.000000000 +0000 @@ -419,10 +419,12 @@ static rpmRC runScript(rpmpsm psm, ARGV_ if (sfd == NULL) sfd = rpmtsScriptFd(psm->ts); + rpmtsSuspendResumeDBLock(psm->ts, 0); rpmswEnter(rpmtsOp(psm->ts, RPMTS_OP_SCRIPTLETS), 0); rc = rpmScriptRun(script, arg1, arg2, sfd, prefixes, warn_only, selinux); rpmswExit(rpmtsOp(psm->ts, RPMTS_OP_SCRIPTLETS), 0); + rpmtsSuspendResumeDBLock(psm->ts, 1); /* Map warn-only errors to "notfound" for script stop callback */ stoprc = (rc != RPMRC_OK && warn_only) ? RPMRC_NOTFOUND : rc; --- ./lib/rpmdb.c.orig 2012-06-01 10:50:11.000000000 +0000 +++ ./lib/rpmdb.c 2012-06-01 10:50:19.000000000 +0000 @@ -769,6 +769,12 @@ int rpmdbSync(rpmdb db) return dbiForeach(db->_dbi, dbiSync, 0); } +int rpmdbSuspendResumeDBLock(rpmdb db, int mode) +{ + if (db == NULL) return 0; + return dbiForeach(db->_dbi, mode ? dbiResumeDBLock : dbiSuspendDBLock, 0); +} + static rpmdb newRpmdb(const char * root, const char * home, int mode, int perms, int flags) { --- ./lib/rpmts.c.orig 2012-03-20 08:07:25.000000000 +0000 +++ ./lib/rpmts.c 2012-06-01 10:50:19.000000000 +0000 @@ -95,6 +95,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) { rpmlock lock = rpmtsAcquireLock(ts); --- ./lib/rpmts.h.orig 2012-03-20 08:07:25.000000000 +0000 +++ ./lib/rpmts.h 2012-06-01 10:50:19.000000000 +0000 @@ -423,6 +423,8 @@ 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); + /** \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