Blame SOURCES/db-5.3.28-rpm-lock-check.patch

b1d0b3
diff -up db-5.3.28/src/dbinc_auto/int_def.in.rpmlock db-5.3.28/src/dbinc_auto/int_def.in
b1d0b3
--- db-5.3.28/src/dbinc_auto/int_def.in.rpmlock	2017-06-26 15:09:17.883356255 +0200
b1d0b3
+++ db-5.3.28/src/dbinc_auto/int_def.in	2017-06-26 15:09:27.421170401 +0200
b1d0b3
@@ -1573,6 +1573,7 @@
b1d0b3
 #define	__os_posix_err __os_posix_err@DB_VERSION_UNIQUE_NAME@
b1d0b3
 #define	__os_fileid __os_fileid@DB_VERSION_UNIQUE_NAME@
b1d0b3
 #define	__check_lock_fn __check_lock_fn@DB_VERSION_UNIQUE_NAME@
b1d0b3
+#define	__rpm_lock_free __rpm_lock_free@DB_VERSION_UNIQUE_NAME@
b1d0b3
 #define	__os_fdlock __os_fdlock@DB_VERSION_UNIQUE_NAME@
b1d0b3
 #define	__os_fsync __os_fsync@DB_VERSION_UNIQUE_NAME@
b1d0b3
 #define	__os_getenv __os_getenv@DB_VERSION_UNIQUE_NAME@
b1d0b3
diff -up db-5.3.28/src/dbinc_auto/os_ext.h.rpmlock db-5.3.28/src/dbinc_auto/os_ext.h
b1d0b3
--- db-5.3.28/src/dbinc_auto/os_ext.h.rpmlock	2017-06-26 15:09:21.940277203 +0200
b1d0b3
+++ db-5.3.28/src/dbinc_auto/os_ext.h	2017-06-26 15:09:27.354171707 +0200
b1d0b3
@@ -42,6 +42,7 @@ char *__os_strerror __P((int, char *, si
b1d0b3
 int __os_posix_err __P((int));
b1d0b3
 int __os_fileid __P((ENV *, const char *, int, u_int8_t *));
b1d0b3
 int __check_lock_fn __P((char *, pid_t));
b1d0b3
+int __rpm_lock_free __P((ENV *));
b1d0b3
 int __os_fdlock __P((ENV *, DB_FH *, off_t, db_lockmode_t, int));
b1d0b3
 int __os_fsync __P((ENV *, DB_FH *));
b1d0b3
 int __os_getenv __P((ENV *, const char *, char **, size_t));
b1d0b3
diff -up db-5.3.28/src/env/env_region.c.rpmlock db-5.3.28/src/env/env_region.c
b1d0b3
--- db-5.3.28/src/env/env_region.c.rpmlock	2017-06-26 15:09:12.479461558 +0200
b1d0b3
+++ db-5.3.28/src/env/env_region.c	2017-06-26 15:09:12.481461519 +0200
b1d0b3
@@ -291,18 +291,23 @@ user_map_functions:
b1d0b3
 	if (create_ok &&
b1d0b3
 	    ret == DB_OLD_VERSION &&
b1d0b3
 	    ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1) == 0) {
b1d0b3
-		if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY))
b1d0b3
-			__db_msg(env, "Recreating idle environment");
b1d0b3
-		F_SET(infop, REGION_CREATE_OK);
b1d0b3
+		/* If the rpm transaction lock is taken we cannot safely rebuild */
b1d0b3
+        if (!__rpm_lock_free(env))
b1d0b3
+            ENV_PRIMARY_UNLOCK(env);
b1d0b3
+        else {
b1d0b3
+            if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY))
b1d0b3
+                __db_msg(env, "Recreating idle environment");
b1d0b3
+            F_SET(infop, REGION_CREATE_OK);
b1d0b3
 
b1d0b3
-		/*
b1d0b3
-		 * Detach from the environment region; we need to unmap it (and
b1d0b3
-		 * close any file handle) so that we don't leak memory or files.
b1d0b3
-		 */
b1d0b3
-		DB_ASSERT(env, infop->rp == NULL);
b1d0b3
-		infop->rp = &tregion;
b1d0b3
-		(void)__env_sys_detach(env, infop, 0);
b1d0b3
-		goto creation;
b1d0b3
+            /*
b1d0b3
+             * Detach from the environment region; we need to unmap it (and
b1d0b3
+             * close any file handle) so that we don't leak memory or files.
b1d0b3
+             */
b1d0b3
+            DB_ASSERT(env, infop->rp == NULL);
b1d0b3
+            infop->rp = &tregion;
b1d0b3
+            (void)__env_sys_detach(env, infop, 0);
b1d0b3
+            goto creation;
b1d0b3
+        }
b1d0b3
 	}
b1d0b3
 
b1d0b3
 	if (renv->majver != DB_VERSION_MAJOR ||
b1d0b3
diff -up db-5.3.28/src/os/os_flock.c.rpmlock db-5.3.28/src/os/os_flock.c
b1d0b3
--- db-5.3.28/src/os/os_flock.c.rpmlock	2017-06-26 15:09:12.480461538 +0200
b1d0b3
+++ db-5.3.28/src/os/os_flock.c	2017-06-26 15:09:12.481461519 +0200
b1d0b3
@@ -79,6 +79,35 @@ int __check_lock_fn(fn, pid)
b1d0b3
 }
b1d0b3
 
b1d0b3
 /*
b1d0b3
+ * __rpm_lock_free --
b1d0b3
+ * Try to look at a lock used by rpm to see if libdb is being
b1d0b3
+ * updated and it is safe to access its environment files.
b1d0b3
+ * PUBLIC: int __rpm_lock_free __P((ENV *));
b1d0b3
+ */
b1d0b3
+
b1d0b3
+#define RPM_PATH SHAREDSTATEDIR "/rpm"
b1d0b3
+#define RPMLOCK_PATH RPM_PATH "/.rpm.lock"
b1d0b3
+
b1d0b3
+int __rpm_lock_free(env)
b1d0b3
+    ENV *env;
b1d0b3
+{
b1d0b3
+    int ret;
b1d0b3
+
b1d0b3
+    /* No need to check the transaction lock if not in rpm */
b1d0b3
+    if (strstr(env->db_home, RPM_PATH) == NULL)
b1d0b3
+        return 1;
b1d0b3
+
b1d0b3
+    /* Assume it is safe to rebuild if the lock file does not exist */
b1d0b3
+    if (access(RPMLOCK_PATH, F_OK) && errno == ENOENT)
b1d0b3
+        return 1;
b1d0b3
+
b1d0b3
+    ret = __check_lock_fn(RPMLOCK_PATH, 0);
b1d0b3
+    /* __check_lock_fn can return -1 on failure - return 0 (taken) instead */
b1d0b3
+    return ret == -1 ? 0: ret;
b1d0b3
+
b1d0b3
+}
b1d0b3
+
b1d0b3
+/*
b1d0b3
  * __os_fdlock --
b1d0b3
  *	Acquire/release a lock on a byte in a file.
b1d0b3
  *