Blob Blame History Raw
diff -up db-5.3.28/src/env/env_region.c.rpmlock db-5.3.28/src/env/env_region.c
--- db-5.3.28/src/env/env_region.c.rpmlock	2017-06-19 09:53:42.727715374 +0200
+++ db-5.3.28/src/env/env_region.c	2017-06-19 09:55:28.195688220 +0200
@@ -291,18 +291,23 @@ user_map_functions:
 	if (create_ok &&
 	    ret == DB_OLD_VERSION &&
 	    ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1) == 0) {
-		if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY))
-			__db_msg(env, "Recreating idle environment");
-		F_SET(infop, REGION_CREATE_OK);
+		/* If the rpm transaction lock is taken we cannot safely rebuild */
+        if (!__rpm_lock_free(env))
+            ENV_PRIMARY_UNLOCK(env);
+        else {
+            if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY))
+                __db_msg(env, "Recreating idle environment");
+            F_SET(infop, REGION_CREATE_OK);
 
-		/*
-		 * Detach from the environment region; we need to unmap it (and
-		 * close any file handle) so that we don't leak memory or files.
-		 */
-		DB_ASSERT(env, infop->rp == NULL);
-		infop->rp = &tregion;
-		(void)__env_sys_detach(env, infop, 0);
-		goto creation;
+            /*
+             * Detach from the environment region; we need to unmap it (and
+             * close any file handle) so that we don't leak memory or files.
+             */
+            DB_ASSERT(env, infop->rp == NULL);
+            infop->rp = &tregion;
+            (void)__env_sys_detach(env, infop, 0);
+            goto creation;
+        }
 	}
 
 	if (renv->majver != DB_VERSION_MAJOR ||
diff -up db-5.3.28/src/os/os_flock.c.rpmlock db-5.3.28/src/os/os_flock.c
--- db-5.3.28/src/os/os_flock.c.rpmlock	2017-06-19 09:52:49.418740004 +0200
+++ db-5.3.28/src/os/os_flock.c	2017-06-19 09:53:16.428220866 +0200
@@ -70,6 +70,34 @@ int __check_lock_fn(fn, pid)
 }
 
 /*
+ * __rpm_lock_free --
+ * Try to look at a lock used by rpm to see if libdb is being
+ * updated and it is safe to access its environment files.
+ */
+
+#define RPM_PATH SHAREDSTATEDIR "/rpm"
+#define RPMLOCK_PATH RPM_PATH "/.rpm.lock"
+
+int __rpm_lock_free(env)
+    ENV *env;
+{
+    int ret;
+
+    /* No need to check the transaction lock if not in rpm */
+    if (strstr(env->db_home, RPM_PATH) == NULL)
+        return 1;
+
+    /* Assume it is safe to rebuild if the lock file does not exist */
+    if (access(RPMLOCK_PATH, F_OK) && errno == ENOENT)
+        return 1;
+
+    ret = __check_lock_fn(RPMLOCK_PATH, 0);
+    /* __check_lock_fn can return -1 on failure - return 0 (taken) instead */
+    return ret == -1 ? 0: ret;
+
+}
+
+/*
  * __os_fdlock --
  *	Acquire/release a lock on a byte in a file.
  *