rpm/waitlock.diff

101 lines
3.1 KiB
Diff

Fix global (DB_PRIVATE) lock code: fix recursion counter, retry
failed lock operations for up to 3 minutes.
Index: rpmdb/db3.c
===================================================================
--- rpmdb/db3.c.orig
+++ rpmdb/db3.c
@@ -769,6 +769,8 @@ assert(db != NULL);
}
/*@=mustmod@*/
+static int _lockdbfd = 0;
+
/*@-moduncon@*/ /* FIX: annotate db3 methods */
static int db3close(/*@only@*/ dbiIndex dbi, /*@unused@*/ unsigned int flags)
/*@globals rpmGlobalMacroContext, h_errno,
@@ -828,6 +830,10 @@ static int db3close(/*@only@*/ dbiIndex
rpmMessage(RPMMESS_DEBUG, _("closed db index %s/%s\n"),
dbhome, (dbfile ? dbfile : tagName(dbi->dbi_rpmtag)));
+ if (dbi->dbi_lockdbfd &&
+ !((dbi->dbi_ecflags & DB_CLIENT) && dbi->dbi_host) &&
+ _lockdbfd)
+ _lockdbfd--;
}
@@ -1148,8 +1154,6 @@ static int db3open(rpmdb rpmdb, rpmTag r
prDbiOpenFlags(oflags, 0), dbi->dbi_mode);
if (rc == 0) {
- static int _lockdbfd = 0;
-
/*@-moduncon@*/ /* FIX: annotate db3 methods */
rc = db_create(&db, dbenv, dbi->dbi_cflags);
/*@=moduncon@*/
@@ -1366,6 +1370,7 @@ static int db3open(rpmdb rpmdb, rpmTag r
if (!(db->fd(db, &fdno) == 0 && fdno >= 0)) {
rc = 1;
} else {
+ int tries;
struct flock l;
/*@-boundswrite@*/
memset(&l, 0, sizeof(l));
@@ -1377,24 +1382,40 @@ static int db3open(rpmdb rpmdb, rpmTag r
? F_WRLCK : F_RDLCK;
l.l_pid = 0;
- rc = fcntl(fdno, F_SETLK, (void *) &l);
- if (rc) {
- /* Warning iff using non-private CDB locking. */
- rc = ((dbi->dbi_use_dbenv &&
- (dbi->dbi_eflags & DB_INIT_CDB) &&
- !(dbi->dbi_eflags & DB_PRIVATE))
- ? 0 : 1);
- rpmError( (rc ? RPMERR_FLOCK : RPMWARN_FLOCK),
- _("cannot get %s lock on %s/%s\n"),
- ((dbi->dbi_mode & (O_RDWR|O_WRONLY))
- ? _("exclusive") : _("shared")),
- dbhome, (dbfile ? dbfile : ""));
- } else if (dbfile) {
- rpmMessage(RPMMESS_DEBUG,
- _("locked db index %s/%s\n"),
- dbhome, dbfile);
+ for (tries = 0; ; tries++) {
+ rc = fcntl(fdno, F_SETLK, (void *) &l);
+ if (rc) {
+ /* Warning iff using non-private CDB locking. */
+ rc = ((dbi->dbi_use_dbenv &&
+ (dbi->dbi_eflags & DB_INIT_CDB) &&
+ !(dbi->dbi_eflags & DB_PRIVATE))
+ ? 0 : 1);
+ if (errno == EAGAIN && rc) {
+ struct timespec ts;
+ if (tries == 0)
+ rpmMessage(RPMMESS_WARNING, _("waiting for %s lock on %s/%s\n"), ((dbi->dbi_mode & (O_RDWR|O_WRONLY)) ? _("exclusive") : _("shared")), dbhome, (dbfile ? dbfile : ""));
+ ts.tv_sec = (time_t)0;
+ ts.tv_nsec = 100000000;
+ if (tries < 10*60*3) {
+ nanosleep(&ts, (struct timespec *)0);
+ continue;
+ }
+ }
+ rpmError( (rc ? RPMERR_FLOCK : RPMWARN_FLOCK),
+ _("cannot get %s lock on %s/%s\n"),
+ ((dbi->dbi_mode & (O_RDWR|O_WRONLY))
+ ? _("exclusive") : _("shared")),
+ dbhome, (dbfile ? dbfile : ""));
+ } else if (dbfile) {
+ rpmMessage(RPMMESS_DEBUG,
+ _("locked db index %s/%s\n"),
+ dbhome, dbfile);
+ }
+ break;
}
}
+ if (rc && dbi->dbi_use_dbenv)
+ _lockdbfd--;
}
}
}