Reintroduce patches removed in 5.3.28-22

Modify upstream patch to fail on pthread version mismatch

Resolves: #1460003
This commit is contained in:
Petr Kubat 2017-06-13 11:52:53 +02:00
parent 8e9ddaf1be
commit 273921eda9
3 changed files with 420 additions and 458 deletions

View File

@ -1,9 +1,6 @@
# HG changeset patch diff -up db-5.3.28/dist/android/android_config.in.pthreads db-5.3.28/dist/android/android_config.in
# Parent 2ef463e657e6564c9792d499bbaaa09a9cc8a004 --- db-5.3.28/dist/android/android_config.in.pthreads 2013-09-09 17:35:02.000000000 +0200
+++ db-5.3.28/dist/android/android_config.in 2017-06-13 11:15:15.323215161 +0200
diff -r db78da0996b1 dist/android/android_config.in
--- a/dist/android/android_config.in Mon Sep 09 11:09:35 2013 -0400
+++ b/dist/android/android_config.in Sat Apr 29 04:10:18 2017 -0700
@@ -123,6 +123,9 @@ @@ -123,6 +123,9 @@
/* Define to 1 if allocated filesystem blocks are not zeroed. */ /* Define to 1 if allocated filesystem blocks are not zeroed. */
/* #undef HAVE_FILESYSTEM_NOTZERO */ /* #undef HAVE_FILESYSTEM_NOTZERO */
@ -14,9 +11,9 @@ diff -r db78da0996b1 dist/android/android_config.in
/* Define to 1 if you have the `fopen' function. */ /* Define to 1 if you have the `fopen' function. */
#define HAVE_FOPEN 1 #define HAVE_FOPEN 1
diff -r db78da0996b1 dist/config.hin diff -up db-5.3.28/dist/config.hin.pthreads db-5.3.28/dist/config.hin
--- a/dist/config.hin Mon Sep 09 11:09:35 2013 -0400 --- db-5.3.28/dist/config.hin.pthreads 2013-09-09 17:35:02.000000000 +0200
+++ b/dist/config.hin Sat Apr 29 04:10:18 2017 -0700 +++ db-5.3.28/dist/config.hin 2017-06-13 11:15:15.000000000 +0200
@@ -92,6 +92,9 @@ @@ -92,6 +92,9 @@
/* Define to 1 if you have the <dlfcn.h> header file. */ /* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H #undef HAVE_DLFCN_H
@ -47,82 +44,22 @@ diff -r db78da0996b1 dist/config.hin
/* Define to 1 if it is OK to initialize an already initialized /* Define to 1 if it is OK to initialize an already initialized
pthread_cond_t. */ pthread_cond_t. */
#undef HAVE_PTHREAD_COND_REINIT_OKAY #undef HAVE_PTHREAD_COND_REINIT_OKAY
diff -r db78da0996b1 dist/configure @@ -620,6 +629,11 @@
--- a/dist/configure Mon Sep 09 11:09:35 2013 -0400 /* Define to 1 to mask harmless uninitialized memory read/writes. */
+++ b/dist/configure Sat Apr 29 04:10:18 2017 -0700 #undef UMRW
@@ -23368,7 +23368,7 @@
# Check for system functions we optionally use.
for ac_func in \
_fstati64 backtrace backtrace_symbols directio fchmod fclose\
- fcntl fdatasync fgetc fgets fopen fwrite getgid\
+ fcntl fdatasync fgetc fgets flock fopen fwrite getgid\
getrusage getuid hstrerror mprotect pstat_getdynamic\
pthread_self pthread_yield random sched_yield select setgid setuid\
sigaction snprintf stat sysconf vsnprintf yield
@@ -24668,6 +24668,59 @@
fi +/* Enable large inode numbers on Mac OS X 10.5. */
+#ifndef _DARWIN_USE_64_BIT_INODE
+# define _DARWIN_USE_64_BIT_INODE 1
+#endif
+
/* Number of bits in a file offset, on hosts where this is settable. */
#undef _FILE_OFFSET_BITS
+# Check for dl_iterate_phdr; do the test explicitly instead of using diff -up db-5.3.28/dist/configure.ac.pthreads db-5.3.28/dist/configure.ac
+# AC_CHECK_FUNCS because <netdb.h> isn't a standard include file. --- db-5.3.28/dist/configure.ac.pthreads 2017-06-13 11:15:15.309215434 +0200
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dl_iterate_phdr" >&5 +++ db-5.3.28/dist/configure.ac 2017-06-13 11:15:15.323215161 +0200
+$as_echo_n "checking for dl_iterate_phdr... " >&6; } @@ -698,7 +698,7 @@ AC_REPLACE_FUNCS(\
+if ${db_cv_dl_iterate_phdr+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#include <sys/types.h>
+#include <netdb.h>
+int
+main ()
+{
+
+ dl_iterate_phdr(0, 0);
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ db_cv_dl_iterate_phdr=yes
+else
+ db_cv_dl_iterate_phdr=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $db_cv_dl_iterate_phdr" >&5
+$as_echo "$db_cv_dl_iterate_phdr" >&6; }
+if test "$db_cv_dl_iterate_phdr" = "yes"; then
+ $as_echo "#define HAVE_DL_ITERATE_PHDR 1" >>confdefs.h
+
+
+fi
+
+# If we are using pthread mutex or condition variables, and dl_iterate_phdr() is
+# available, then we try to detect when libpthread is updated -- which can
+# render existing environment invalid. DB_ENV->open() tries to rebuild such
+# environments when they are idle.
+case "$db_cv_mutex" in
+ *pthreads*)
+ if test "$db_cv_dl_iterate_phdr" = "yes" ; then
+ $as_echo "#define HAVE_PTHREADS_TIMESTAMP 1" >>confdefs.h
+
+
+ fi
+ ;;
+esac
+
# We need to add the additional object files into the Makefile with the correct
# suffix. We can't use $LTLIBOBJS itself, because that variable has $U encoded
# in it for automake, and that's not what we want. See SR #7227 for additional
diff -r db78da0996b1 dist/configure.ac
--- a/dist/configure.ac Mon Sep 09 11:09:35 2013 -0400
+++ b/dist/configure.ac Sat Apr 29 04:10:18 2017 -0700
@@ -698,7 +698,7 @@
# Check for system functions we optionally use. # Check for system functions we optionally use.
AC_CHECK_FUNCS(\ AC_CHECK_FUNCS(\
_fstati64 backtrace backtrace_symbols directio fchmod fclose\ _fstati64 backtrace backtrace_symbols directio fchmod fclose\
@ -131,7 +68,7 @@ diff -r db78da0996b1 dist/configure.ac
getrusage getuid hstrerror mprotect pstat_getdynamic\ getrusage getuid hstrerror mprotect pstat_getdynamic\
pthread_self pthread_yield random sched_yield select setgid setuid\ pthread_self pthread_yield random sched_yield select setgid setuid\
sigaction snprintf stat sysconf vsnprintf yield) sigaction snprintf stat sysconf vsnprintf yield)
@@ -1042,6 +1042,34 @@ @@ -1042,6 +1042,34 @@ if test "$db_cv_localization" = "yes"; t
[Define to 1 if you have localization function to support globalization.]) [Define to 1 if you have localization function to support globalization.])
fi fi
@ -166,10 +103,10 @@ diff -r db78da0996b1 dist/configure.ac
# We need to add the additional object files into the Makefile with the correct # We need to add the additional object files into the Makefile with the correct
# suffix. We can't use $LTLIBOBJS itself, because that variable has $U encoded # suffix. We can't use $LTLIBOBJS itself, because that variable has $U encoded
# in it for automake, and that's not what we want. See SR #7227 for additional # in it for automake, and that's not what we want. See SR #7227 for additional
diff -r db78da0996b1 src/db/db_meta.c diff -up db-5.3.28/src/db/db_meta.c.pthreads db-5.3.28/src/db/db_meta.c
--- a/src/db/db_meta.c Mon Sep 09 11:09:35 2013 -0400 --- db-5.3.28/src/db/db_meta.c.pthreads 2013-09-09 17:35:07.000000000 +0200
+++ b/src/db/db_meta.c Sat Apr 29 04:10:18 2017 -0700 +++ db-5.3.28/src/db/db_meta.c 2017-06-13 11:15:15.323215161 +0200
@@ -1330,8 +1330,9 @@ @@ -1330,8 +1330,9 @@ __db_haslock(env, locker, dbmfp, pgno, m
} }
/* /*
* __db_has_pagelock -- * __db_has_pagelock --
@ -181,7 +118,7 @@ diff -r db78da0996b1 src/db/db_meta.c
* *
* PUBLIC: #ifdef DIAGNOSTIC * PUBLIC: #ifdef DIAGNOSTIC
* PUBLIC: int __db_has_pagelock __P((ENV *, DB_LOCKER *, * PUBLIC: int __db_has_pagelock __P((ENV *, DB_LOCKER *,
@@ -1348,6 +1349,9 @@ @@ -1348,6 +1349,9 @@ __db_has_pagelock(env, locker, dbmfp, pa
{ {
int ret; int ret;
@ -191,10 +128,41 @@ diff -r db78da0996b1 src/db/db_meta.c
switch (pagep->type) { switch (pagep->type) {
case P_OVERFLOW: case P_OVERFLOW:
case P_INVALID: case P_INVALID:
diff -r db78da0996b1 src/dbinc/region.h diff -up db-5.3.28/src/dbinc_auto/int_def.in.pthreads db-5.3.28/src/dbinc_auto/int_def.in
--- a/src/dbinc/region.h Mon Sep 09 11:09:35 2013 -0400 --- db-5.3.28/src/dbinc_auto/int_def.in.pthreads 2017-06-13 11:15:15.317215278 +0200
+++ b/src/dbinc/region.h Sat Apr 29 04:10:18 2017 -0700 +++ db-5.3.28/src/dbinc_auto/int_def.in 2017-06-13 11:15:15.324215141 +0200
@@ -178,6 +178,16 @@ @@ -1545,6 +1545,7 @@
#if defined(HAVE_REPLICATION_THREADS)
#define __os_freeaddrinfo __os_freeaddrinfo@DB_VERSION_UNIQUE_NAME@
#endif
+#define __os_pthreads_timestamp __os_pthreads_timestamp@DB_VERSION_UNIQUE_NAME@
#define __os_umalloc __os_umalloc@DB_VERSION_UNIQUE_NAME@
#define __os_urealloc __os_urealloc@DB_VERSION_UNIQUE_NAME@
#define __os_ufree __os_ufree@DB_VERSION_UNIQUE_NAME@
diff -up db-5.3.28/src/dbinc_auto/os_ext.h.pthreads db-5.3.28/src/dbinc_auto/os_ext.h
--- db-5.3.28/src/dbinc_auto/os_ext.h.pthreads 2013-09-09 17:35:08.000000000 +0200
+++ db-5.3.28/src/dbinc_auto/os_ext.h 2017-06-13 11:15:15.324215141 +0200
@@ -14,6 +14,7 @@ int __os_getaddrinfo __P((ENV *, const c
#if defined(HAVE_REPLICATION_THREADS)
void __os_freeaddrinfo __P((ENV *, ADDRINFO *));
#endif
+time_t __os_pthreads_timestamp __P((ENV *));
int __os_umalloc __P((ENV *, size_t, void *));
int __os_urealloc __P((ENV *, size_t, void *));
void __os_ufree __P((ENV *, void *));
@@ -40,7 +41,7 @@ void __os_set_errno __P((int));
char *__os_strerror __P((int, char *, size_t));
int __os_posix_err __P((int));
int __os_fileid __P((ENV *, const char *, int, u_int8_t *));
-int __os_fdlock __P((ENV *, DB_FH *, off_t, int, int));
+int __os_fdlock __P((ENV *, DB_FH *, off_t, db_lockmode_t, int));
int __os_fsync __P((ENV *, DB_FH *));
int __os_getenv __P((ENV *, const char *, char **, size_t));
int __os_openhandle __P((ENV *, const char *, int, int, DB_FH **));
diff -up db-5.3.28/src/dbinc/region.h.pthreads db-5.3.28/src/dbinc/region.h
--- db-5.3.28/src/dbinc/region.h.pthreads 2013-09-09 17:35:08.000000000 +0200
+++ db-5.3.28/src/dbinc/region.h 2017-06-13 11:15:15.324215141 +0200
@@ -178,6 +178,16 @@ typedef struct __db_reg_env { /* SHARED
u_int32_t envid; /* Unique environment ID. */ u_int32_t envid; /* Unique environment ID. */
u_int32_t signature; /* Structure signatures. */ u_int32_t signature; /* Structure signatures. */
@ -211,41 +179,10 @@ diff -r db78da0996b1 src/dbinc/region.h
time_t timestamp; /* Creation time. */ time_t timestamp; /* Creation time. */
diff -r db78da0996b1 src/dbinc_auto/int_def.in diff -up db-5.3.28/src/env/env_open.c.pthreads db-5.3.28/src/env/env_open.c
--- a/src/dbinc_auto/int_def.in Mon Sep 09 11:09:35 2013 -0400 --- db-5.3.28/src/env/env_open.c.pthreads 2013-09-09 17:35:08.000000000 +0200
+++ b/src/dbinc_auto/int_def.in Sat Apr 29 04:10:18 2017 -0700 +++ db-5.3.28/src/env/env_open.c 2017-06-13 11:15:15.324215141 +0200
@@ -1542,6 +1542,7 @@ @@ -1031,11 +1031,11 @@ __env_attach_regions(dbenv, flags, orig_
#if defined(HAVE_REPLICATION_THREADS)
#define __os_freeaddrinfo __os_freeaddrinfo@DB_VERSION_UNIQUE_NAME@
#endif
+#define __os_pthreads_timestamp __os_pthreads_timestamp@DB_VERSION_UNIQUE_NAME@
#define __os_umalloc __os_umalloc@DB_VERSION_UNIQUE_NAME@
#define __os_urealloc __os_urealloc@DB_VERSION_UNIQUE_NAME@
#define __os_ufree __os_ufree@DB_VERSION_UNIQUE_NAME@
diff -r db78da0996b1 src/dbinc_auto/os_ext.h
--- a/src/dbinc_auto/os_ext.h Mon Sep 09 11:09:35 2013 -0400
+++ b/src/dbinc_auto/os_ext.h Sat Apr 29 04:10:18 2017 -0700
@@ -14,6 +14,7 @@
#if defined(HAVE_REPLICATION_THREADS)
void __os_freeaddrinfo __P((ENV *, ADDRINFO *));
#endif
+time_t __os_pthreads_timestamp __P((ENV *));
int __os_umalloc __P((ENV *, size_t, void *));
int __os_urealloc __P((ENV *, size_t, void *));
void __os_ufree __P((ENV *, void *));
@@ -40,7 +41,7 @@
char *__os_strerror __P((int, char *, size_t));
int __os_posix_err __P((int));
int __os_fileid __P((ENV *, const char *, int, u_int8_t *));
-int __os_fdlock __P((ENV *, DB_FH *, off_t, int, int));
+int __os_fdlock __P((ENV *, DB_FH *, off_t, db_lockmode_t, int));
int __os_fsync __P((ENV *, DB_FH *));
int __os_getenv __P((ENV *, const char *, char **, size_t));
int __os_openhandle __P((ENV *, const char *, int, int, DB_FH **));
diff -r db78da0996b1 src/env/env_open.c
--- a/src/env/env_open.c Mon Sep 09 11:09:35 2013 -0400
+++ b/src/env/env_open.c Sat Apr 29 04:10:18 2017 -0700
@@ -1031,11 +1033,11 @@
goto err; goto err;
/* /*
@ -260,9 +197,307 @@ diff -r db78da0996b1 src/env/env_open.c
*/ */
if (FLD_ISSET(init_flags, DB_INITENV_CDB)) if (FLD_ISSET(init_flags, DB_INITENV_CDB))
LF_SET(DB_INIT_CDB); LF_SET(DB_INIT_CDB);
diff -r db78da0996b1 src/env/env_register.c diff -up db-5.3.28/src/env/env_region.c.pthreads db-5.3.28/src/env/env_region.c
--- a/src/env/env_register.c Mon Sep 09 11:09:35 2013 -0400 --- db-5.3.28/src/env/env_region.c.pthreads 2013-09-09 17:35:08.000000000 +0200
+++ b/src/env/env_register.c Sat Apr 29 04:10:18 2017 -0700 +++ db-5.3.28/src/env/env_region.c 2017-06-13 11:16:02.159299222 +0200
@@ -18,13 +18,49 @@ static int __env_des_get __P((ENV *, RE
static int __env_faultmem __P((ENV *, void *, size_t, int));
static int __env_sys_attach __P((ENV *, REGINFO *, REGION *));
static int __env_sys_detach __P((ENV *, REGINFO *, int));
+static int __env_check_recreate __P((ENV *, REGENV *, u_int32_t));
static void __env_des_destroy __P((ENV *, REGION *));
static void __env_remove_file __P((ENV *));
+
+/*
+ * If the system supports flock()-like file locking, then the primary region
+ * file __db.001 is exclusively locked during creation, and is read-locked while
+ * the environment is open. Most Unix-like systems have flock(), with the
+ * notable exception of Solaris.
+ * Note: fcntl cannot be used for this locking because of the unfortunate
+ * definition of its interaction with close(2). A process's fcntl locks are
+ * released whenever it closes any file descriptor for that file. So, if an
+ * environment is opened more than once, closing one of the DB_ENV handles would
+ * release the read lock that protects the other handle.
+ */
+#ifdef HAVE_FLOCK
+#define ENV_PRIMARY_LOCK(env, lockmode, async) \
+ ((env)->lockfhp == NULL ? 0 : \
+ __os_fdlock((env), (env)->lockfhp, -1, lockmode, async))
+#define ENV_PRIMARY_UNLOCK(env) \
+ ((env)->lockfhp == NULL ? 0 : \
+ __os_fdlock((env), (env)->lockfhp, -1, DB_LOCK_NG, 0))
+#else
+#define ENV_PRIMARY_LOCK(env, lockmode, async) (0)
+#define ENV_PRIMARY_UNLOCK(env) (0)
+#endif
+
/*
* __env_attach
* Join/create the environment
*
+ * Safely detecting and managing multiple processes' environment handles:
+ * BDB uses a shared or exclusive fcntl()-style lock on the first byte
+ * of the primary region file (__db.001) to detect whether other processes
+ * have the environment open, and to single-thread attempts to create the
+ * environment. If the open includes DB_CREATE, an exclusive lock is
+ * obtained during the open call. After the creation is finished, and
+ * anytime during a non-DB_CREATE env open, the process holds a shared
+ * lock.
+ * - single-thread creation of the environment
+ * - detect whether any other processes are currently attached to it.
+ *
* PUBLIC: int __env_attach __P((ENV *, u_int32_t *, int, int));
*/
int
@@ -122,7 +158,11 @@ loop: renv = NULL;
if ((ret = __os_open(
env, infop->name, 0, DB_OSO_REGION, 0, &env->lockfhp)) != 0)
goto err;
-
+ /* Wait to get shared access to the primary region. */
+ if ((ret = ENV_PRIMARY_LOCK(env, DB_LOCK_READ, 0)) != 0) {
+ __db_err(env, ret, "__env_attach: existing: shared lock error");
+ goto err;
+ }
/*
* !!!
* The region may be in system memory not backed by the filesystem
@@ -218,11 +258,10 @@ loop: renv = NULL;
segid = ref.segid;
}
-#ifndef HAVE_MUTEX_FCNTL
+#if !defined(HAVE_FCNTL) && !defined(HAVE_PTHREADS_TIMESTAMP)
/*
- * If we're not doing fcntl locking, we can close the file handle. We
- * no longer need it and the less contact between the buffer cache and
- * the VM, the better.
+ * Without fcntl-like support, we no longer need the file handle. Close
+ * it to limit the interaction between the buffer cache and the VM.
*/
(void)__os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
@@ -233,6 +272,8 @@ loop: renv = NULL;
tregion.size = (roff_t)size;
tregion.max = (roff_t)max;
tregion.segid = segid;
+ /* Attach to the existing primary region. */
+ /* The leaking db.001 gets open inside of here, in __os_attach(). */
if ((ret = __env_sys_attach(env, infop, &tregion)) != 0)
goto err;
@@ -245,21 +286,48 @@ user_map_functions:
infop->primary = infop->addr;
infop->head = (u_int8_t *)infop->addr + sizeof(REGENV);
renv = infop->primary;
+ ret = __env_check_recreate(env, renv, signature);
+
+ 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);
+
+ /*
+ * 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;
+ }
+
+ /* We have an old environment but cannot rebuild it safely. */
+ if (ret == DB_OLD_VERSION) {
+ __db_errx(env, DB_STR("1539",
+ "Build signature doesn't match environment"));
+ ret = DB_VERSION_MISMATCH;
+ goto err;
+ }
- /*
- * Make sure the region matches our build. Special case a region
- * that's all nul bytes, just treat it like any other corruption.
- */
if (renv->majver != DB_VERSION_MAJOR ||
renv->minver != DB_VERSION_MINOR) {
- if (renv->majver != 0 || renv->minver != 0) {
+ /*
+ * Special case a region that's all nul bytes, just treat it
+ * like any other corruption.
+ */
+ if (renv->majver == 0 && renv->minver == 0)
+ ret = EINVAL;
+ else {
__db_errx(env, DB_STR_A("1538",
- "Program version %d.%d doesn't match environment version %d.%d",
+ "Program version %d.%d doesn't match in-use environment version %d.%d",
"%d %d %d %d"), DB_VERSION_MAJOR, DB_VERSION_MINOR,
renv->majver, renv->minver);
ret = DB_VERSION_MISMATCH;
- } else
- ret = EINVAL;
+ }
goto err;
}
if (renv->signature != signature) {
@@ -289,6 +357,18 @@ user_map_functions:
}
if (renv->magic != DB_REGION_MAGIC)
goto retry;
+ /*
+ * A bad magic number means that the env is new and not yet available:
+ * wait a while and try again. If the magic number says recovery is in
+ * process, remember the env creation time to record that recovery was
+ * the reason that the open failed.
+ */
+ if (renv->magic != DB_REGION_MAGIC) {
+ __db_msg(env, "attach sees bad region magic 0x%lx",
+ (u_long)renv->magic);
+ goto retry;
+ }
+
/*
* Get a reference to the underlying REGION information for this
@@ -346,6 +426,12 @@ user_map_functions:
return (0);
creation:
+ /* Should this wait for the lock (passing 0 instead of 1)? */
+ if ((ret = ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1)) != 0) {
+ __db_err(env, ret, "__env_attach: creation could not lock %s",
+ env->lockfhp->name);
+ goto err;
+ }
/* Create the environment region. */
F_SET(infop, REGION_CREATE);
@@ -437,7 +523,14 @@ creation:
renv->minver = (u_int32_t)minver;
renv->patchver = (u_int32_t)patchver;
renv->signature = signature;
-
+#ifdef HAVE_PTHREADS_TIMESTAMP
+ renv->pthreads_timestamp = __os_pthreads_timestamp(env);
+ {
+ char *s = getenv("TS_ADJUST");
+ if (s != NULL)
+ renv->pthreads_timestamp -= atoi(s);
+ }
+#endif
(void)time(&renv->timestamp);
__os_unique_id(env, &renv->envid);
@@ -513,16 +606,24 @@ find_err: __db_errx(env, DB_STR_A("1544"
}
}
-#ifndef HAVE_MUTEX_FCNTL
- /*
- * If we're not doing fcntl locking, we can close the file handle. We
- * no longer need it and the less contact between the buffer cache and
- * the VM, the better.
- */
+#ifdef HAVE_FCNTL
+ if ((ret = ENV_PRIMARY_UNLOCK(env)) != 0) {
+ __db_err(env, ret, "__env_attach: release exclusive lock");
+ goto err;
+ }
+ if ((ret = ENV_PRIMARY_LOCK(env, DB_LOCK_READ, 0)) != 0) {
+ __db_err(env, ret, "__env_attach: new: acquire shared lock");
+ goto err;
+ }
+#else
+ /*
+ * We no longer need the primary region file's handle and the less
+ * contact between the buffer cache and the VM, the better.
+ */
if (env->lockfhp != NULL) {
(void)__os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
- }
+ }
#endif
/* Everything looks good, we're done. */
@@ -562,9 +663,9 @@ retry: /* Close any open file handle. */
/* If we had a temporary error, wait awhile and try again. */
if (ret == 0) {
if (!retry_ok || ++retry_cnt > 3) {
+ ret = EAGAIN;
__db_errx(env, DB_STR("1546",
"unable to join the environment"));
- ret = EAGAIN;
} else {
__os_yield(env, retry_cnt * 3, 0);
goto loop;
@@ -575,6 +676,59 @@ retry: /* Close any open file handle. */
}
/*
+ * __env_check_recreate --
+ * Determine whether an existing on-disk environment should be recreated
+ * because it is not compatible with this compiled BDB library.
+ *
+ * Returns:
+ * 0 -
+ * The env was generated by this library. No recreation needed.
+ * DB_OLD_VERSION -
+ * It was created by an earlier BDB version, or by an earlier
+ * version of libpthreads (on certain Linux systems). The caller
+ * will try to recreate it with the currently configured settings.
+ * DB_VERSION_MISMATCH -
+ * It was created by a newer version of BDB. Do not attempt to
+ * fix it, something is probably wrong with the application setup.
+ */
+static int
+__env_check_recreate(env, renv, signature)
+ ENV *env;
+ REGENV *renv;
+ u_int32_t signature;
+{
+#ifdef HAVE_PTHREADS_TIMESTAMP
+ time_t pthreads_time;
+ char envtime[CTIME_BUFLEN], libtime[CTIME_BUFLEN];
+#endif
+
+ /* First, bail out if the env is too new for this code to handle. */
+ if (renv->majver > DB_VERSION_MAJOR ||
+ (renv->majver == DB_VERSION_MAJOR &&
+ renv->minver > DB_VERSION_MINOR))
+ return (DB_VERSION_MISMATCH);
+
+#ifdef HAVE_PTHREADS_TIMESTAMP
+ pthreads_time = __os_pthreads_timestamp(env);
+ if (pthreads_time != renv->pthreads_timestamp) {
+ if (FLD_ISSET(env->dbenv->verbose, DB_VERB_RECOVERY))
+ __db_msg(env,
+ "Pthreads timestamp changed: env %.24s current %.24s",
+ __os_ctime(&renv->pthreads_timestamp, envtime),
+ __os_ctime(&pthreads_time, libtime));
+ return (DB_OLD_VERSION);
+ }
+#endif
+ if (renv->signature != signature || renv->majver != DB_VERSION_MAJOR ||
+ renv->minver != DB_VERSION_MINOR) {
+ if (FLD_ISSET(env->dbenv->verbose, DB_VERB_RECOVERY))
+ __db_msg(env, "Signature or version changed");
+ return (DB_OLD_VERSION);
+ }
+ return (0);
+}
+
+/*
* __env_turn_on --
* Turn on the created environment.
*
diff -up db-5.3.28/src/env/env_register.c.pthreads db-5.3.28/src/env/env_register.c
--- db-5.3.28/src/env/env_register.c.pthreads 2013-09-09 17:35:08.000000000 +0200
+++ db-5.3.28/src/env/env_register.c 2017-06-13 11:15:15.325215121 +0200
@@ -19,9 +19,9 @@ @@ -19,9 +19,9 @@
#define PID_LEN (25) /* PID entry length */ #define PID_LEN (25) /* PID entry length */
@ -275,10 +510,10 @@ diff -r db78da0996b1 src/env/env_register.c
#define REGISTRY_EXCL_LOCK(env, nowait) \ #define REGISTRY_EXCL_LOCK(env, nowait) \
REGISTRY_LOCK(env, 1, nowait) REGISTRY_LOCK(env, 1, nowait)
#define REGISTRY_EXCL_UNLOCK(env) \ #define REGISTRY_EXCL_UNLOCK(env) \
diff -r db78da0996b1 src/env/env_stat.c diff -up db-5.3.28/src/env/env_stat.c.pthreads db-5.3.28/src/env/env_stat.c
--- a/src/env/env_stat.c Mon Sep 09 11:09:35 2013 -0400 --- db-5.3.28/src/env/env_stat.c.pthreads 2013-09-09 17:35:08.000000000 +0200
+++ b/src/env/env_stat.c Sat Apr 29 04:10:18 2017 -0700 +++ db-5.3.28/src/env/env_stat.c 2017-06-13 11:15:15.325215121 +0200
@@ -177,6 +177,10 @@ @@ -177,6 +177,10 @@ __env_print_stats(env, flags)
STAT_LONG("Txn version", DB_TXNVERSION); STAT_LONG("Txn version", DB_TXNVERSION);
__db_msg(env, __db_msg(env,
"%.24s\tCreation time", __os_ctime(&renv->timestamp, time_buf)); "%.24s\tCreation time", __os_ctime(&renv->timestamp, time_buf));
@ -289,9 +524,9 @@ diff -r db78da0996b1 src/env/env_stat.c
STAT_HEX("Environment ID", renv->envid); STAT_HEX("Environment ID", renv->envid);
__mutex_print_debug_single(env, __mutex_print_debug_single(env,
"Primary region allocation and reference count mutex", "Primary region allocation and reference count mutex",
diff -r db78da0996b1 src/os/os_addrinfo.c diff -up db-5.3.28/src/os/os_addrinfo.c.pthreads db-5.3.28/src/os/os_addrinfo.c
--- a/src/os/os_addrinfo.c Mon Sep 09 11:09:35 2013 -0400 --- db-5.3.28/src/os/os_addrinfo.c.pthreads 2013-09-09 17:35:09.000000000 +0200
+++ b/src/os/os_addrinfo.c Sat Apr 29 04:10:18 2017 -0700 +++ db-5.3.28/src/os/os_addrinfo.c 2017-06-13 11:15:15.325215121 +0200
@@ -10,6 +10,10 @@ @@ -10,6 +10,10 @@
#include "db_int.h" #include "db_int.h"
@ -303,7 +538,7 @@ diff -r db78da0996b1 src/os/os_addrinfo.c
/* /*
* __os_getaddrinfo and __os_freeaddrinfo wrap the getaddrinfo and freeaddrinfo * __os_getaddrinfo and __os_freeaddrinfo wrap the getaddrinfo and freeaddrinfo
* calls, as well as the associated platform dependent error handling, mapping * calls, as well as the associated platform dependent error handling, mapping
@@ -177,3 +181,48 @@ @@ -177,3 +181,48 @@ __os_freeaddrinfo(env, ai)
} }
#endif #endif
} }
@ -352,9 +587,9 @@ diff -r db78da0996b1 src/os/os_addrinfo.c
+ return (timestamp); + return (timestamp);
+} +}
+#endif +#endif
diff -r db78da0996b1 src/os/os_flock.c diff -up db-5.3.28/src/os/os_flock.c.pthreads db-5.3.28/src/os/os_flock.c
--- a/src/os/os_flock.c Mon Sep 09 11:09:35 2013 -0400 --- db-5.3.28/src/os/os_flock.c.pthreads 2013-09-09 17:35:09.000000000 +0200
+++ b/src/os/os_flock.c Sat Apr 29 04:10:18 2017 -0700 +++ db-5.3.28/src/os/os_flock.c 2017-06-13 11:15:15.325215121 +0200
@@ -10,41 +10,98 @@ @@ -10,41 +10,98 @@
#include "db_int.h" #include "db_int.h"
@ -425,6 +660,14 @@ diff -r db78da0996b1 src/os/os_flock.c
- "fileops: flock %s %s offset %lu", "%s %s %lu"), fhp->name, - "fileops: flock %s %s offset %lu", "%s %s %lu"), fhp->name,
- acquire ? DB_STR_P("acquire"): DB_STR_P("release"), - acquire ? DB_STR_P("acquire"): DB_STR_P("release"),
- (u_long)offset); - (u_long)offset);
-
- fl.l_start = offset;
- fl.l_len = 1;
- fl.l_type = acquire ? F_WRLCK : F_UNLCK;
- fl.l_whence = SEEK_SET;
-
- RETRY_CHK_EINTR_ONLY(
- (fcntl(fhp->fd, nowait ? F_SETLK : F_SETLKW, &fl)), ret);
+ if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL)) { + if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL)) {
+ if (offset < 0) + if (offset < 0)
+ __db_msg(env, DB_STR_A("####", + __db_msg(env, DB_STR_A("####",
@ -436,11 +679,7 @@ diff -r db78da0996b1 src/os/os_flock.c
+ "fileops: fcntls %s %s offset %lu", "%s %s %lu"), + "fileops: fcntls %s %s offset %lu", "%s %s %lu"),
+ fhp->name, mode_string[lockmode], (u_long)offset); + fhp->name, mode_string[lockmode], (u_long)offset);
+ } + }
+
- fl.l_start = offset;
- fl.l_len = 1;
- fl.l_type = acquire ? F_WRLCK : F_UNLCK;
- fl.l_whence = SEEK_SET;
+ if (offset < 0) { + if (offset < 0) {
+#ifdef HAVE_FLOCK +#ifdef HAVE_FLOCK
+ RETRY_CHK_EINTR_ONLY(flock(fhp->fd, + RETRY_CHK_EINTR_ONLY(flock(fhp->fd,
@ -456,9 +695,7 @@ diff -r db78da0996b1 src/os/os_flock.c
+ RETRY_CHK_EINTR_ONLY( + RETRY_CHK_EINTR_ONLY(
+ fcntl(fhp->fd, nowait ? F_SETLK : F_SETLKW, &fl), ret); + fcntl(fhp->fd, nowait ? F_SETLK : F_SETLKW, &fl), ret);
+ } + }
+
- RETRY_CHK_EINTR_ONLY(
- (fcntl(fhp->fd, nowait ? F_SETLK : F_SETLKW, &fl)), ret);
+ if (offset < 0 && dbenv != NULL && + if (offset < 0 && dbenv != NULL &&
+ FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL)) + FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+ __db_msg(env, DB_STR_A("####", + __db_msg(env, DB_STR_A("####",
@ -468,7 +705,7 @@ diff -r db78da0996b1 src/os/os_flock.c
if (ret == 0) if (ret == 0)
return (0); return (0);
@@ -53,12 +110,29 @@ @@ -53,12 +110,29 @@ __os_fdlock(env, fhp, offset, acquire, n
__db_syserr(env, ret, DB_STR("0139", "fcntl")); __db_syserr(env, ret, DB_STR("0139", "fcntl"));
return (t_ret); return (t_ret);
#else #else
@ -497,12 +734,13 @@ diff -r db78da0996b1 src/os/os_flock.c
__db_syserr(env, DB_OPNOTSUP, DB_STR("0140", __db_syserr(env, DB_OPNOTSUP, DB_STR("0140",
"advisory file locking unavailable")); "advisory file locking unavailable"));
return (DB_OPNOTSUP); return (DB_OPNOTSUP);
+} -#endif
#endif }
-} +#endif
--- b/src/os/os_map.c.pthreads 2013-09-09 17:35:09.000000000 +0200 diff -up db-5.3.28/src/os/os_map.c.pthreads db-5.3.28/src/os/os_map.c
+++ b/src/os/os_map.c 2017-05-16 09:31:30.535713279 +0200 --- db-5.3.28/src/os/os_map.c.pthreads 2013-09-09 17:35:09.000000000 +0200
@@ -32,7 +32,7 @@ +++ db-5.3.28/src/os/os_map.c 2017-06-13 11:15:15.325215121 +0200
@@ -32,7 +32,7 @@ static int __no_system_mem __P((ENV *));
/* /*
* __os_attach -- * __os_attach --
@ -511,7 +749,7 @@ diff -r db78da0996b1 src/os/os_flock.c
* *
* PUBLIC: int __os_attach __P((ENV *, REGINFO *, REGION *)); * PUBLIC: int __os_attach __P((ENV *, REGINFO *, REGION *));
*/ */
@@ -50,6 +50,7 @@ @@ -50,6 +50,7 @@ __os_attach(env, infop, rp)
* so there must be a valid handle. * so there must be a valid handle.
*/ */
DB_ASSERT(env, env != NULL && env->dbenv != NULL); DB_ASSERT(env, env != NULL && env->dbenv != NULL);
@ -519,291 +757,3 @@ diff -r db78da0996b1 src/os/os_flock.c
dbenv = env->dbenv; dbenv = env->dbenv;
if (DB_GLOBAL(j_region_map) != NULL) { if (DB_GLOBAL(j_region_map) != NULL) {
--- b/src/env/env_region.c.pthreads 2013-09-09 17:35:08.000000000 +0200
+++ b/src/env/env_region.c 2017-05-22 13:18:21.898595006 +0200
@@ -18,13 +18,49 @@
static int __env_faultmem __P((ENV *, void *, size_t, int));
static int __env_sys_attach __P((ENV *, REGINFO *, REGION *));
static int __env_sys_detach __P((ENV *, REGINFO *, int));
+static int __env_check_recreate __P((ENV *, REGENV *, u_int32_t));
static void __env_des_destroy __P((ENV *, REGION *));
static void __env_remove_file __P((ENV *));
+
+/*
+ * If the system supports flock()-like file locking, then the primary region
+ * file __db.001 is exclusively locked during creation, and is read-locked while
+ * the environment is open. Most Unix-like systems have flock(), with the
+ * notable exception of Solaris.
+ * Note: fcntl cannot be used for this locking because of the unfortunate
+ * definition of its interaction with close(2). A process's fcntl locks are
+ * released whenever it closes any file descriptor for that file. So, if an
+ * environment is opened more than once, closing one of the DB_ENV handles would
+ * release the read lock that protects the other handle.
+ */
+#ifdef HAVE_FLOCK
+#define ENV_PRIMARY_LOCK(env, lockmode, async) \
+ ((env)->lockfhp == NULL ? 0 : \
+ __os_fdlock((env), (env)->lockfhp, -1, lockmode, async))
+#define ENV_PRIMARY_UNLOCK(env) \
+ ((env)->lockfhp == NULL ? 0 : \
+ __os_fdlock((env), (env)->lockfhp, -1, DB_LOCK_NG, 0))
+#else
+#define ENV_PRIMARY_LOCK(env, lockmode, async) (0)
+#define ENV_PRIMARY_UNLOCK(env) (0)
+#endif
+
/*
* __env_attach
* Join/create the environment
*
+ * Safely detecting and managing multiple processes' environment handles:
+ * BDB uses a shared or exclusive fcntl()-style lock on the first byte
+ * of the primary region file (__db.001) to detect whether other processes
+ * have the environment open, and to single-thread attempts to create the
+ * environment. If the open includes DB_CREATE, an exclusive lock is
+ * obtained during the open call. After the creation is finished, and
+ * anytime during a non-DB_CREATE env open, the process holds a shared
+ * lock.
+ * - single-thread creation of the environment
+ * - detect whether any other processes are currently attached to it.
+ *
* PUBLIC: int __env_attach __P((ENV *, u_int32_t *, int, int));
*/
int
@@ -122,7 +158,11 @@
if ((ret = __os_open(
env, infop->name, 0, DB_OSO_REGION, 0, &env->lockfhp)) != 0)
goto err;
-
+ /* Wait to get shared access to the primary region. */
+ if ((ret = ENV_PRIMARY_LOCK(env, DB_LOCK_READ, 0)) != 0) {
+ __db_err(env, ret, "__env_attach: existing: shared lock error");
+ goto err;
+ }
/*
* !!!
* The region may be in system memory not backed by the filesystem
@@ -218,11 +258,10 @@
segid = ref.segid;
}
-#ifndef HAVE_MUTEX_FCNTL
+#if !defined(HAVE_FCNTL) && !defined(HAVE_PTHREADS_TIMESTAMP)
/*
- * If we're not doing fcntl locking, we can close the file handle. We
- * no longer need it and the less contact between the buffer cache and
- * the VM, the better.
+ * Without fcntl-like support, we no longer need the file handle. Close
+ * it to limit the interaction between the buffer cache and the VM.
*/
(void)__os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
@@ -233,6 +272,8 @@
tregion.size = (roff_t)size;
tregion.max = (roff_t)max;
tregion.segid = segid;
+ /* Attach to the existing primary region. */
+ /* The leaking db.001 gets open inside of here, in __os_attach(). */
if ((ret = __env_sys_attach(env, infop, &tregion)) != 0)
goto err;
@@ -246,20 +287,38 @@
infop->head = (u_int8_t *)infop->addr + sizeof(REGENV);
renv = infop->primary;
- /*
- * Make sure the region matches our build. Special case a region
- * that's all nul bytes, just treat it like any other corruption.
- */
+ if (create_ok &&
+ __env_check_recreate(env, renv, signature) == DB_OLD_VERSION &&
+ (ret = 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);
+
+ /*
+ * 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 ||
renv->minver != DB_VERSION_MINOR) {
- if (renv->majver != 0 || renv->minver != 0) {
+ /*
+ * Special case a region that's all nul bytes, just treat it
+ * like any other corruption.
+ */
+ if (renv->majver == 0 && renv->minver == 0)
+ ret = EINVAL;
+ else {
__db_errx(env, DB_STR_A("1538",
- "Program version %d.%d doesn't match environment version %d.%d",
+ "Program version %d.%d doesn't match in-use environment version %d.%d",
"%d %d %d %d"), DB_VERSION_MAJOR, DB_VERSION_MINOR,
renv->majver, renv->minver);
ret = DB_VERSION_MISMATCH;
- } else
- ret = EINVAL;
+ }
goto err;
}
if (renv->signature != signature) {
@@ -289,6 +348,18 @@
}
if (renv->magic != DB_REGION_MAGIC)
goto retry;
+ /*
+ * A bad magic number means that the env is new and not yet available:
+ * wait a while and try again. If the magic number says recovery is in
+ * process, remember the env creation time to record that recovery was
+ * the reason that the open failed.
+ */
+ if (renv->magic != DB_REGION_MAGIC) {
+ __db_msg(env, "attach sees bad region magic 0x%lx",
+ (u_long)renv->magic);
+ goto retry;
+ }
+
/*
* Get a reference to the underlying REGION information for this
@@ -346,6 +417,12 @@
return (0);
creation:
+ /* Should this wait for the lock (passing 0 instead of 1)? */
+ if ((ret = ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1)) != 0) {
+ __db_err(env, ret, "__env_attach: creation could not lock %s",
+ env->lockfhp->name);
+ goto err;
+ }
/* Create the environment region. */
F_SET(infop, REGION_CREATE);
@@ -437,7 +514,14 @@
renv->minver = (u_int32_t)minver;
renv->patchver = (u_int32_t)patchver;
renv->signature = signature;
-
+#ifdef HAVE_PTHREADS_TIMESTAMP
+ renv->pthreads_timestamp = __os_pthreads_timestamp(env);
+ {
+ char *s = getenv("TS_ADJUST");
+ if (s != NULL)
+ renv->pthreads_timestamp -= atoi(s);
+ }
+#endif
(void)time(&renv->timestamp);
__os_unique_id(env, &renv->envid);
@@ -513,16 +597,24 @@
}
}
-#ifndef HAVE_MUTEX_FCNTL
- /*
- * If we're not doing fcntl locking, we can close the file handle. We
- * no longer need it and the less contact between the buffer cache and
- * the VM, the better.
- */
+#ifdef HAVE_FCNTL
+ if ((ret = ENV_PRIMARY_UNLOCK(env)) != 0) {
+ __db_err(env, ret, "__env_attach: release exclusive lock");
+ goto err;
+ }
+ if ((ret = ENV_PRIMARY_LOCK(env, DB_LOCK_READ, 0)) != 0) {
+ __db_err(env, ret, "__env_attach: new: acquire shared lock");
+ goto err;
+ }
+#else
+ /*
+ * We no longer need the primary region file's handle and the less
+ * contact between the buffer cache and the VM, the better.
+ */
if (env->lockfhp != NULL) {
(void)__os_closehandle(env, env->lockfhp);
env->lockfhp = NULL;
- }
+ }
#endif
/* Everything looks good, we're done. */
@@ -562,9 +654,9 @@
/* If we had a temporary error, wait awhile and try again. */
if (ret == 0) {
if (!retry_ok || ++retry_cnt > 3) {
+ ret = EAGAIN;
__db_errx(env, DB_STR("1546",
"unable to join the environment"));
- ret = EAGAIN;
} else {
__os_yield(env, retry_cnt * 3, 0);
goto loop;
@@ -575,6 +667,59 @@
}
/*
+ * __env_check_recreate --
+ * Determine whether an existing on-disk environment should be recreated
+ * because it is not compatible with this compiled BDB library.
+ *
+ * Returns:
+ * 0 -
+ * The env was generated by this library. No recreation needed.
+ * DB_OLD_VERSION -
+ * It was created by an earlier BDB version, or by an earlier
+ * version of libpthreads (on certain Linux systems). The caller
+ * will try to recreate it with the currently configured settings.
+ * DB_VERSION_MISMATCH -
+ * It was created by a newer version of BDB. Do not attempt to
+ * fix it, something is probably wrong with the application setup.
+ */
+static int
+__env_check_recreate(env, renv, signature)
+ ENV *env;
+ REGENV *renv;
+ u_int32_t signature;
+{
+#ifdef HAVE_PTHREADS_TIMESTAMP
+ time_t pthreads_time;
+ char envtime[CTIME_BUFLEN], libtime[CTIME_BUFLEN];
+#endif
+
+ /* First, bail out if the env is too new for this code to handle. */
+ if (renv->majver > DB_VERSION_MAJOR ||
+ (renv->majver == DB_VERSION_MAJOR &&
+ renv->minver > DB_VERSION_MINOR))
+ return (DB_VERSION_MISMATCH);
+
+#ifdef HAVE_PTHREADS_TIMESTAMP
+ pthreads_time = __os_pthreads_timestamp(env);
+ if (pthreads_time != renv->pthreads_timestamp) {
+ if (FLD_ISSET(env->dbenv->verbose, DB_VERB_RECOVERY))
+ __db_msg(env,
+ "Pthreads timestamp changed: env %.24s current %.24s",
+ __os_ctime(&renv->pthreads_timestamp, envtime),
+ __os_ctime(&pthreads_time, libtime));
+ return (DB_OLD_VERSION);
+ }
+#endif
+ if (renv->signature != signature || renv->majver != DB_VERSION_MAJOR ||
+ renv->minver != DB_VERSION_MINOR) {
+ if (FLD_ISSET(env->dbenv->verbose, DB_VERB_RECOVERY))
+ __db_msg(env, "Signature or version changed");
+ return (DB_OLD_VERSION);
+ }
+ return (0);
+}
+
+/*
* __env_turn_on --
* Turn on the created environment.
*

View File

@ -1,19 +1,19 @@
diff -up db-5.3.28/src/env/env_region.c.rpmchk db-5.3.28/src/env/env_region.c 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.rpmchk 2017-06-01 12:09:49.191891965 +0200 --- db-5.3.28/src/env/env_region.c.rpmlock 2017-06-13 11:17:13.750899154 +0200
+++ db-5.3.28/src/env/env_region.c 2017-06-01 12:09:49.193891929 +0200 +++ db-5.3.28/src/env/env_region.c 2017-06-13 11:18:22.221560122 +0200
@@ -289,7 +289,8 @@ user_map_functions: @@ -290,7 +290,8 @@ user_map_functions:
if (create_ok && if (create_ok &&
__env_check_recreate(env, renv, signature) == DB_OLD_VERSION && ret == DB_OLD_VERSION &&
- (ret = ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1)) == 0) { - ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1) == 0) {
+ (ret = ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1)) == 0 && + ENV_PRIMARY_LOCK(env, DB_LOCK_WRITE, 1) == 0 &&
+ (ret = __rpm_lock_check(env)) == 0 ) { + __rpm_lock_check(env) == 0) {
if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY)) if (FLD_ISSET(dbenv->verbose, DB_VERB_RECOVERY))
__db_msg(env, "Recreating idle environment"); __db_msg(env, "Recreating idle environment");
F_SET(infop, REGION_CREATE_OK); 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 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.rpmchk 2017-06-01 12:09:49.191891965 +0200 --- db-5.3.28/src/os/os_flock.c.rpmlock 2017-06-13 11:17:13.748899193 +0200
+++ db-5.3.28/src/os/os_flock.c 2017-06-01 12:16:28.309175645 +0200 +++ db-5.3.28/src/os/os_flock.c 2017-06-13 11:17:13.750899154 +0200
@@ -15,6 +15,53 @@ static int __os_filelocking_notsup __P(( @@ -15,6 +15,53 @@ static int __os_filelocking_notsup __P((
#endif #endif

View File

@ -4,7 +4,7 @@
Summary: The Berkeley DB database library for C Summary: The Berkeley DB database library for C
Name: libdb Name: libdb
Version: 5.3.28 Version: 5.3.28
Release: 22%{?dist} Release: 23%{?dist}
Source0: http://download.oracle.com/berkeley-db/db-%{version}.tar.gz Source0: http://download.oracle.com/berkeley-db/db-%{version}.tar.gz
Source1: http://download.oracle.com/berkeley-db/db.1.85.tar.gz Source1: http://download.oracle.com/berkeley-db/db.1.85.tar.gz
# For mt19937db.c # For mt19937db.c
@ -32,6 +32,12 @@ Patch27: db-5.3.21-memp_stat-upstream-fix.patch
Patch28: db-5.3.21-mutex_leak.patch Patch28: db-5.3.21-mutex_leak.patch
# fix for overflowing hash variable inside bundled lemon # fix for overflowing hash variable inside bundled lemon
Patch29: db-5.3.28-lemon_hash.patch Patch29: db-5.3.28-lemon_hash.patch
# upstream patch adding the ability to recreate libdb's environment on version mismatch
# or when libpthread.so is modified (rhbz#1394862)
Patch30: db-5.3.28-condition_variable.patch
# downstream patch to check whether there is a rpm transaction going on when rpm's environment needs to be rebuilt
# TODO: remove this patch as soon as we can afford to
Patch31: db-5.3.28-rpm-lock-check.patch
URL: http://www.oracle.com/database/berkeley-db/ URL: http://www.oracle.com/database/berkeley-db/
License: BSD and LGPLv2 and Sleepycat License: BSD and LGPLv2 and Sleepycat
@ -224,6 +230,8 @@ popd
%patch27 -p1 %patch27 -p1
%patch28 -p1 %patch28 -p1
%patch29 -p1 %patch29 -p1
%patch30 -p1
%patch31 -p1
cd dist cd dist
./s_config ./s_config
@ -432,6 +440,10 @@ rm -rf ${RPM_BUILD_ROOT}
%{_libdir}/libdb_java.so %{_libdir}/libdb_java.so
%changelog %changelog
* Tue Jun 13 2017 Petr Kubat <pkubat@redhat.com> - 5.3.28-23
- Reintroduce patches removed in 5.3.28-22
- Modify upstream patch to fail on pthread version mismatch (#1460003)
* Fri Jun 09 2017 Adam Williamson <awilliam@redhat.com> - 5.3.28-22 * Fri Jun 09 2017 Adam Williamson <awilliam@redhat.com> - 5.3.28-22
- Drop rhbz#1394862 patches again, DB corruption still being reported - Drop rhbz#1394862 patches again, DB corruption still being reported