3a3ae67b51
As flock-style locks have no way to check whether another lock on the file is held by the current process and is safe for libdb to access the its environment (in read-mode only), a helper function that parses /proc/locks for this information has been added. Additionally, db-5.3.28-rpm-lock-check.patch has been modified to use the helper function in order for libdb to not have to leak file descriptors while checking for rpm's transaction lock when accessing rpm's environment.
77 lines
2.6 KiB
Diff
77 lines
2.6 KiB
Diff
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.
|
|
*
|