Blame waitlock.diff

Bernhard M. Wiedemann 1250f9
Fix global (DB_PRIVATE) lock code: fix recursion counter, retry
Bernhard M. Wiedemann 1250f9
failed lock operations for up to 3 minutes.
Bernhard M. Wiedemann 1250f9
Bernhard M. Wiedemann 1250f9
--- ./lib/backend/db3.c.orig	2017-01-19 14:59:01.432807649 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/backend/db3.c	2017-01-19 15:13:18.034716068 +0000
Bernhard M. Wiedemann 1250f9
@@ -33,6 +33,8 @@ struct dbiCursor_s {
Bernhard M. Wiedemann 1250f9
 static struct dbiConfig_s staticdbicfg;
Bernhard M. Wiedemann 1250f9
 static struct dbConfig_s staticcfg;
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
+static int _lockdbfd = 0;
Bernhard M. Wiedemann 1250f9
+
Bernhard M. Wiedemann 1250f9
 /** \ingroup dbi
Bernhard M. Wiedemann 1250f9
  */
Bernhard M. Wiedemann 1250f9
 static const struct poptOption rdbOptions[] = {
Bernhard M. Wiedemann 1250f9
@@ -744,6 +746,8 @@ static int db3_dbiClose(dbiIndex dbi, un
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
 	rpmlog(RPMLOG_DEBUG, "closed   db index       %s/%s\n",
Bernhard M. Wiedemann 1250f9
 		dbhome, dbi->dbi_file);
Bernhard M. Wiedemann 1250f9
+	if (dbi->cfg.dbi_lockdbfd && !(dbi->dbi_flags & DBI_VERIFYONLY) && _lockdbfd)
Bernhard M. Wiedemann 1250f9
+	    _lockdbfd--;
Bernhard M. Wiedemann 1250f9
     }
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
     db_fini(rdb, dbhome ? dbhome : "");
Bernhard M. Wiedemann 1250f9
@@ -783,6 +787,7 @@ static int dbiFlock(dbiIndex dbi, int mo
Bernhard M. Wiedemann 1250f9
 	rc = 1;
Bernhard M. Wiedemann 1250f9
     } else {
Bernhard M. Wiedemann 1250f9
 	const char *dbhome = rpmdbHome(dbi->dbi_rpmdb);
Bernhard M. Wiedemann 1250f9
+	int tries;
Bernhard M. Wiedemann 1250f9
 	struct flock l;
Bernhard M. Wiedemann 1250f9
 	memset(&l, 0, sizeof(l));
Bernhard M. Wiedemann 1250f9
 	l.l_whence = 0;
Bernhard M. Wiedemann 1250f9
@@ -792,20 +797,38 @@ static int dbiFlock(dbiIndex dbi, int mo
Bernhard M. Wiedemann 1250f9
 		    ? F_RDLCK : F_WRLCK;
Bernhard M. Wiedemann 1250f9
 	l.l_pid = 0;
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
-	rc = fcntl(fdno, F_SETLK, (void *) &l);
Bernhard M. Wiedemann 1250f9
-	if (rc) {
Bernhard M. Wiedemann 1250f9
-	    uint32_t eflags = db_envflags(db);
Bernhard M. Wiedemann 1250f9
-	    /* Warning iff using non-private CDB locking. */
Bernhard M. Wiedemann 1250f9
-	    rc = (((eflags & DB_INIT_CDB) && !(eflags & DB_PRIVATE)) ? 0 : 1);
Bernhard M. Wiedemann 1250f9
-	    rpmlog( (rc ? RPMLOG_ERR : RPMLOG_WARNING),
Bernhard M. Wiedemann 1250f9
-		    _("cannot get %s lock on %s/%s\n"),
Bernhard M. Wiedemann 1250f9
-		    ((mode & O_ACCMODE) == O_RDONLY)
Bernhard M. Wiedemann 1250f9
-			    ? _("shared") : _("exclusive"),
Bernhard M. Wiedemann 1250f9
-		    dbhome, dbi->dbi_file);
Bernhard M. Wiedemann 1250f9
-	} else {
Bernhard M. Wiedemann 1250f9
-	    rpmlog(RPMLOG_DEBUG,
Bernhard M. Wiedemann 1250f9
-		    "locked   db index       %s/%s\n",
Bernhard M. Wiedemann 1250f9
-		    dbhome, dbi->dbi_file);
Bernhard M. Wiedemann 1250f9
+	for (tries = 0; ; tries++) {
Bernhard M. Wiedemann 1250f9
+	    rc = fcntl(fdno, F_SETLK, (void *) &l);
Bernhard M. Wiedemann 1250f9
+	    if (rc) {
Bernhard M. Wiedemann 1250f9
+		uint32_t eflags = db_envflags(db);
Bernhard M. Wiedemann 1250f9
+		/* Warning iff using non-private CDB locking. */
Bernhard M. Wiedemann 1250f9
+		rc = (((eflags & DB_INIT_CDB) && !(eflags & DB_PRIVATE)) ? 0 : 1);
Bernhard M. Wiedemann 1250f9
+		if (errno == EAGAIN && rc) {
Bernhard M. Wiedemann 1250f9
+		    struct timespec ts;
Bernhard M. Wiedemann 1250f9
+		    if (tries == 0)
Bernhard M. Wiedemann 1250f9
+			rpmlog(RPMLOG_WARNING,
Bernhard M. Wiedemann 1250f9
+				_("waiting for %s lock on %s/%s\n"),
Bernhard M. Wiedemann 1250f9
+				((mode & O_ACCMODE) == O_RDONLY)
Bernhard M. Wiedemann 1250f9
+					? _("shared") : _("exclusive"),
Bernhard M. Wiedemann 1250f9
+				dbhome, dbi->dbi_file);
Bernhard M. Wiedemann 1250f9
+		    ts.tv_sec = (time_t)0;
Bernhard M. Wiedemann 1250f9
+		    ts.tv_nsec = 100000000;	/* .1 seconds */
Bernhard M. Wiedemann 1250f9
+		    if (tries < 10*60*3) {	/* 3 minutes */
Bernhard M. Wiedemann 1250f9
+			nanosleep(&ts, (struct timespec *)0);
Bernhard M. Wiedemann 1250f9
+			continue;
Bernhard M. Wiedemann 1250f9
+		    }
Bernhard M. Wiedemann 1250f9
+		}
Bernhard M. Wiedemann 1250f9
+		rpmlog( (rc ? RPMLOG_ERR : RPMLOG_WARNING),
Bernhard M. Wiedemann 1250f9
+			_("cannot get %s lock on %s/%s\n"),
Bernhard M. Wiedemann 1250f9
+			((mode & O_ACCMODE) == O_RDONLY)
Bernhard M. Wiedemann 1250f9
+				? _("shared") : _("exclusive"),
Bernhard M. Wiedemann 1250f9
+			dbhome, dbi->dbi_file);
Bernhard M. Wiedemann 1250f9
+	    } else {
Bernhard M. Wiedemann 1250f9
+		rpmlog(RPMLOG_DEBUG,
Bernhard M. Wiedemann 1250f9
+			"locked   db index       %s/%s\n",
Bernhard M. Wiedemann 1250f9
+			dbhome, dbi->dbi_file);
Bernhard M. Wiedemann 1250f9
+	    }
Bernhard M. Wiedemann 1250f9
+	    break;
Bernhard M. Wiedemann 1250f9
 	}
Bernhard M. Wiedemann 1250f9
     }
Bernhard M. Wiedemann 1250f9
     return rc;
Bernhard M. Wiedemann 1250f9
@@ -822,7 +845,6 @@ static int db3_dbiOpen(rpmdb rdb, rpmDbi
Bernhard M. Wiedemann 1250f9
     DB * db = NULL;
Bernhard M. Wiedemann 1250f9
     DBTYPE dbtype = DB_UNKNOWN;
Bernhard M. Wiedemann 1250f9
     uint32_t oflags;
Bernhard M. Wiedemann 1250f9
-    static int _lockdbfd = 0;
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
     if (dbip)
Bernhard M. Wiedemann 1250f9
 	*dbip = NULL;
Bernhard M. Wiedemann 1250f9
@@ -902,6 +924,8 @@ static int db3_dbiOpen(rpmdb rdb, rpmDbi
Bernhard M. Wiedemann 1250f9
 	dbi->dbi_flags |= DBI_CREATED;
Bernhard M. Wiedemann 1250f9
     if (oflags & DB_RDONLY)
Bernhard M. Wiedemann 1250f9
 	dbi->dbi_flags |= DBI_RDONLY;
Bernhard M. Wiedemann 1250f9
+    if (verifyonly)
Bernhard M. Wiedemann 1250f9
+	dbi->dbi_flags |= DBI_VERIFYONLY;
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
     if (!verifyonly && rc == 0 && dbi->cfg.dbi_lockdbfd && _lockdbfd++ == 0) {
Bernhard M. Wiedemann 1250f9
 	rc = dbiFlock(dbi, rdb->db_mode);
Bernhard M. Wiedemann 1250f9
--- ./lib/backend/dbi.h.orig	2017-01-19 15:12:26.833899257 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/backend/dbi.h	2017-01-19 15:05:43.958347554 +0000
Bernhard M. Wiedemann 1250f9
@@ -83,6 +83,7 @@ enum dbiFlags_e {
Bernhard M. Wiedemann 1250f9
     DBI_NONE		= 0,
Bernhard M. Wiedemann 1250f9
     DBI_CREATED		= (1 << 0),
Bernhard M. Wiedemann 1250f9
     DBI_RDONLY		= (1 << 1),
Bernhard M. Wiedemann 1250f9
+    DBI_VERIFYONLY	= (1 << 2),
Bernhard M. Wiedemann 1250f9
 };
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
 enum dbcFlags_e {