Blame suspendlock.diff

Bernhard M. Wiedemann 1250f9
Suspend exclusive database lock when scriptlets get called, allowing
Bernhard M. Wiedemann 1250f9
read access in scriptlets. Only needed for DB_PRIVATE (aka global)
Bernhard M. Wiedemann 1250f9
locking.
Bernhard M. Wiedemann 1250f9
Bernhard M. Wiedemann 1250f9
--- ./lib/backend/db3.c.orig	2017-12-01 14:27:03.193486711 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/backend/db3.c	2017-12-01 14:27:23.747426200 +0000
Bernhard M. Wiedemann 1250f9
@@ -552,6 +552,46 @@ static void db3_dbSetFSync(rpmdb rdb, in
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
 static int db3_Ctrl(rpmdb rdb, dbCtrlOp ctrl)
Bernhard M. Wiedemann 1250f9
 {
Bernhard M. Wiedemann 1250f9
+    struct flock l;
Bernhard M. Wiedemann 1250f9
+    int tries;
Bernhard M. Wiedemann 1250f9
+    int fdno = -1;
Bernhard M. Wiedemann 1250f9
+    dbiIndex dbi;
Bernhard M. Wiedemann 1250f9
+    DB * db;
Bernhard M. Wiedemann 1250f9
+
Bernhard M. Wiedemann 1250f9
+    switch (ctrl) {
Bernhard M. Wiedemann 1250f9
+    case DB_CTRL_SUSPEND_DBLOCK:
Bernhard M. Wiedemann 1250f9
+    case DB_CTRL_RESUME_DBLOCK:
Bernhard M. Wiedemann 1250f9
+	dbi = rdb->db_pkgs;	/* packages db only */
Bernhard M. Wiedemann 1250f9
+	if (!dbi)
Bernhard M. Wiedemann 1250f9
+	    return 1;
Bernhard M. Wiedemann 1250f9
+	if (!dbi->cfg.dbi_lockdbfd || (dbi->dbi_flags & DBI_VERIFYONLY) != 0)
Bernhard M. Wiedemann 1250f9
+	    return 0;
Bernhard M. Wiedemann 1250f9
+	if (!(dbi->dbi_rpmdb->db_mode & (O_RDWR|O_WRONLY)))
Bernhard M. Wiedemann 1250f9
+	    return 0;
Bernhard M. Wiedemann 1250f9
+	if (_lockdbfd == 0)
Bernhard M. Wiedemann 1250f9
+	    return 0;
Bernhard M. Wiedemann 1250f9
+        db = dbi->dbi_db;
Bernhard M. Wiedemann 1250f9
+	if (!(db->fd(db, &fdno) == 0 && fdno >= 0))
Bernhard M. Wiedemann 1250f9
+	    return 1;
Bernhard M. Wiedemann 1250f9
+	for (tries = 0; tries < 2; tries++) {
Bernhard M. Wiedemann 1250f9
+	    memset(&l, 0, sizeof(l));
Bernhard M. Wiedemann 1250f9
+	    l.l_whence = 0;
Bernhard M. Wiedemann 1250f9
+	    l.l_start = 0;
Bernhard M. Wiedemann 1250f9
+	    l.l_len = 0;
Bernhard M. Wiedemann 1250f9
+	    l.l_type = ctrl == DB_CTRL_SUSPEND_DBLOCK ? F_RDLCK : F_WRLCK;
Bernhard M. Wiedemann 1250f9
+	    if (!fcntl(fdno, tries ? F_SETLKW : F_SETLK, (void *)&l))
Bernhard M. Wiedemann 1250f9
+		return 0;
Bernhard M. Wiedemann 1250f9
+	    if (ctrl == DB_CTRL_SUSPEND_DBLOCK) {
Bernhard M. Wiedemann 1250f9
+		rpmlog(RPMLOG_WARNING, _("could not suspend database lock\n"));
Bernhard M. Wiedemann 1250f9
+		return 1;
Bernhard M. Wiedemann 1250f9
+	    }
Bernhard M. Wiedemann 1250f9
+	    if (tries == 0)
Bernhard M. Wiedemann 1250f9
+		rpmlog(RPMLOG_WARNING, _("waiting to reestablish exclusive database lock\n"));
Bernhard M. Wiedemann 1250f9
+	}
Bernhard M. Wiedemann 1250f9
+	return 1;
Bernhard M. Wiedemann 1250f9
+    default:
Bernhard M. Wiedemann 1250f9
+        break;
Bernhard M. Wiedemann 1250f9
+    }
Bernhard M. Wiedemann 1250f9
     return 0;
Bernhard M. Wiedemann 1250f9
 }
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
--- ./lib/backend/dbi.h.orig	2017-12-01 14:27:03.193486711 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/backend/dbi.h	2017-12-01 14:27:23.747426200 +0000
Bernhard M. Wiedemann 1250f9
@@ -17,7 +17,9 @@ typedef enum dbCtrlOp_e {
Bernhard M. Wiedemann 1250f9
     DB_CTRL_UNLOCK_RO		= 2,
Bernhard M. Wiedemann 1250f9
     DB_CTRL_LOCK_RW		= 3,
Bernhard M. Wiedemann 1250f9
     DB_CTRL_UNLOCK_RW		= 4,
Bernhard M. Wiedemann 1250f9
-    DB_CTRL_INDEXSYNC		= 5
Bernhard M. Wiedemann 1250f9
+    DB_CTRL_INDEXSYNC		= 5,
Bernhard M. Wiedemann 1250f9
+    DB_CTRL_SUSPEND_DBLOCK      = 100,
Bernhard M. Wiedemann 1250f9
+    DB_CTRL_RESUME_DBLOCK       = 101
Bernhard M. Wiedemann 1250f9
 } dbCtrlOp;
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
 typedef struct dbiIndex_s * dbiIndex;
Bernhard M. Wiedemann 1250f9
--- ./lib/rpmdb.c.orig	2017-12-01 14:27:03.190486720 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/rpmdb.c	2017-12-01 14:27:23.748426197 +0000
Bernhard M. Wiedemann 1250f9
@@ -2639,6 +2639,12 @@ int rpmdbCtrl(rpmdb db, rpmdbCtrlOp ctrl
Bernhard M. Wiedemann 1250f9
     case RPMDB_CTRL_INDEXSYNC:
Bernhard M. Wiedemann 1250f9
 	dbctrl = DB_CTRL_INDEXSYNC;
Bernhard M. Wiedemann 1250f9
 	break;
Bernhard M. Wiedemann 1250f9
+    case RPMDB_CTRL_SUSPEND_DBLOCK:
Bernhard M. Wiedemann 1250f9
+	dbctrl = DB_CTRL_SUSPEND_DBLOCK;
Bernhard M. Wiedemann 1250f9
+	break;
Bernhard M. Wiedemann 1250f9
+    case RPMDB_CTRL_RESUME_DBLOCK:
Bernhard M. Wiedemann 1250f9
+	dbctrl = DB_CTRL_RESUME_DBLOCK;
Bernhard M. Wiedemann 1250f9
+	break;
Bernhard M. Wiedemann 1250f9
     }
Bernhard M. Wiedemann 1250f9
     return dbctrl ? dbCtrl(db, dbctrl) : 1;
Bernhard M. Wiedemann 1250f9
 }
Bernhard M. Wiedemann 1250f9
--- ./lib/rpmdb.h.orig	2017-10-05 10:04:57.035602138 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/rpmdb.h	2017-12-01 14:27:23.748426197 +0000
Bernhard M. Wiedemann 1250f9
@@ -35,7 +35,9 @@ typedef enum rpmdbCtrlOp_e {
Bernhard M. Wiedemann 1250f9
     RPMDB_CTRL_UNLOCK_RO       = 2,
Bernhard M. Wiedemann 1250f9
     RPMDB_CTRL_LOCK_RW         = 3,
Bernhard M. Wiedemann 1250f9
     RPMDB_CTRL_UNLOCK_RW       = 4,
Bernhard M. Wiedemann 1250f9
-    RPMDB_CTRL_INDEXSYNC       = 5
Bernhard M. Wiedemann 1250f9
+    RPMDB_CTRL_INDEXSYNC       = 5,
Bernhard M. Wiedemann 1250f9
+    RPMDB_CTRL_SUSPEND_DBLOCK  = 100,
Bernhard M. Wiedemann 1250f9
+    RPMDB_CTRL_RESUME_DBLOCK   = 101
Bernhard M. Wiedemann 1250f9
 } rpmdbCtrlOp;
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
 /** \ingroup rpmdb
Bernhard M. Wiedemann 1250f9
--- ./lib/transaction.c.orig	2017-12-01 14:27:23.750426192 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/transaction.c	2017-12-01 14:28:43.232192224 +0000
Bernhard M. Wiedemann 1250f9
@@ -1457,6 +1457,7 @@ rpmRC runScript(rpmts ts, rpmte te, Head
Bernhard M. Wiedemann 1250f9
 		     stag != RPMTAG_PREUN &&
Bernhard M. Wiedemann 1250f9
 		     stag != RPMTAG_PRETRANS &&
Bernhard M. Wiedemann 1250f9
 		     stag != RPMTAG_VERIFYSCRIPT);
Bernhard M. Wiedemann 1250f9
+    rpmdb rdb = rpmtsGetRdb(ts);
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
     /* Fake up a transaction element for triggers from rpmdb */
Bernhard M. Wiedemann 1250f9
     if (te == NULL) {
Bernhard M. Wiedemann 1250f9
@@ -1468,10 +1469,12 @@ rpmRC runScript(rpmts ts, rpmte te, Head
Bernhard M. Wiedemann 1250f9
     if (sfd == NULL)
Bernhard M. Wiedemann 1250f9
 	sfd = rpmtsScriptFd(ts);
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
+    rpmdbCtrl(rdb, RPMDB_CTRL_SUSPEND_DBLOCK);
Bernhard M. Wiedemann 1250f9
     rpmswEnter(rpmtsOp(ts, RPMTS_OP_SCRIPTLETS), 0);
Bernhard M. Wiedemann 1250f9
     rc = rpmScriptRun(script, arg1, arg2, sfd,
Bernhard M. Wiedemann 1250f9
 		      prefixes, warn_only, rpmtsPlugins(ts));
Bernhard M. Wiedemann 1250f9
     rpmswExit(rpmtsOp(ts, RPMTS_OP_SCRIPTLETS), 0);
Bernhard M. Wiedemann 1250f9
+    rpmdbCtrl(rdb, RPMDB_CTRL_RESUME_DBLOCK);
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
     /* Map warn-only errors to "notfound" for script stop callback */
Bernhard M. Wiedemann 1250f9
     stoprc = (rc != RPMRC_OK && warn_only) ? RPMRC_NOTFOUND : rc;