Michael Schröder
cebe6dd1a8
OBS-URL: https://build.opensuse.org/package/show/Base:System/rpm?expand=0&rev=93
149 lines
4.3 KiB
Diff
149 lines
4.3 KiB
Diff
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 2011-05-12 10:24:20.000000000 +0000
|
|
+++ ./lib/backend/db3.c 2011-05-12 10:26:14.000000000 +0000
|
|
@@ -640,3 +640,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 2010-12-21 09:48:21.000000000 +0000
|
|
+++ ./lib/backend/dbi.h 2011-05-12 10:24:57.000000000 +0000
|
|
@@ -263,6 +263,24 @@ int dbiFlags(dbiIndex dbi);
|
|
RPM_GNUC_INTERNAL
|
|
const char * dbiName(dbiIndex dbi);
|
|
|
|
+/** \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);
|
|
+
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
--- ./lib/psm.c.orig 2011-05-12 10:23:47.000000000 +0000
|
|
+++ ./lib/psm.c 2011-05-12 10:24:57.000000000 +0000
|
|
@@ -412,10 +412,12 @@ static rpmRC runScript(rpmpsm psm, ARGV_
|
|
script->tag != RPMTAG_VERIFYSCRIPT);
|
|
int selinux = !(rpmtsFlags(psm->ts) & RPMTRANS_FLAG_NOCONTEXTS);
|
|
|
|
+ rpmtsSuspendResumeDBLock(psm->ts, 0);
|
|
rpmswEnter(rpmtsOp(psm->ts, RPMTS_OP_SCRIPTLETS), 0);
|
|
rc = rpmScriptRun(script, arg1, arg2, rpmtsScriptFd(psm->ts),
|
|
prefixes, warn_only, selinux);
|
|
rpmswExit(rpmtsOp(psm->ts, RPMTS_OP_SCRIPTLETS), 0);
|
|
+ rpmtsSuspendResumeDBLock(psm->ts, 1);
|
|
|
|
/*
|
|
* Notify callback for all errors. "total" abused for warning/error,
|
|
--- ./lib/rpmdb.c.orig 2011-05-12 10:23:47.000000000 +0000
|
|
+++ ./lib/rpmdb.c 2011-05-12 10:24:57.000000000 +0000
|
|
@@ -674,6 +674,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 2010-12-22 11:17:20.000000000 +0000
|
|
+++ ./lib/rpmts.c 2011-05-12 10:24:57.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 2010-12-21 09:50:50.000000000 +0000
|
|
+++ ./lib/rpmts.h 2011-05-12 10:24:57.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
|