libdb/db-5.3.28-rpm-lock-check.patch
Petr Kubat c7f48db775 Reintroduce upstream patch for rhbz#1394862
Do not rebuild rpm's environment during a rpm transaction
2017-06-01 13:32:50 +02:00

71 lines
2.3 KiB
Diff

diff -up db-5.3.28/src/env/env_region.c.rpmchk db-5.3.28/src/env/env_region.c
--- db-5.3.28/src/env/env_region.c.rpmchk 2017-06-01 12:09:49.191891965 +0200
+++ db-5.3.28/src/env/env_region.c 2017-06-01 12:09:49.193891929 +0200
@@ -289,7 +289,8 @@ user_map_functions:
if (create_ok &&
__env_check_recreate(env, renv, signature) == DB_OLD_VERSION &&
- (ret = ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1)) == 0) {
+ (ret = ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1)) == 0 &&
+ (ret = __rpm_lock_check(env)) == 0 ) {
if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY))
__db_msg(env, "Recreating idle environment");
F_SET(infop, REGION_CREATE_OK);
diff -up db-5.3.28/src/os/os_flock.c.rpmchk db-5.3.28/src/os/os_flock.c
--- db-5.3.28/src/os/os_flock.c.rpmchk 2017-06-01 12:09:49.191891965 +0200
+++ db-5.3.28/src/os/os_flock.c 2017-06-01 12:16:28.309175645 +0200
@@ -15,6 +15,53 @@ static int __os_filelocking_notsup __P((
#endif
/*
+ * __rpm_lock_check --
+ * Try to acquire and release a lock used by rpm to see
+ * if libdb is being updated and it is safe to access
+ * its environment files.
+ *
+ * FIXME: This function leaks the file descriptor on purpose
+ * so that rpm's transaction lock is not dropped due to
+ * how fcntl locks interact with close(2).
+ */
+
+#define RPM_PATH SHAREDSTATEDIR "/rpm"
+#define RPMLOCK_PATH RPM_PATH "/.rpm.lock"
+
+int __rpm_lock_check(env)
+ ENV *env;
+{
+#ifdef HAVE_FCNTL
+ struct flock info;
+ int fd;
+ int ret;
+
+ if (strstr(env->db_home, RPM_PATH) == NULL)
+ /* No need to check the transaction lock if not in rpm */
+ return 0;
+
+ fd = open(RPMLOCK_PATH, O_RDWR);
+ if (fd == -1)
+ return 1;
+ /* Try to get an exclusive lock on rpm's lock file */
+ info.l_type = F_WRLCK;
+ info.l_whence = SEEK_SET;
+ info.l_start = 0;
+ info.l_len = 0;
+ info.l_pid = 0;
+ /* We do not want to hold so just check if we can get it */
+ if ((ret = fcntl(fd, F_GETLK, &info)) != -1 && info.l_type == F_UNLCK)
+ /* Lock is not taken, the environment can be rebuilt */
+ return 0;
+ else
+ return 1;
+#else
+ /* fcntl not supported, fail with error message */
+ return __os_filelocking_notsup(env);
+#endif
+}
+
+/*
* __os_fdlock --
* Acquire/release a lock on a byte in a file.
*