diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..81a929e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+SOURCES/db-5.3.28.tar.gz
+SOURCES/db.1.85.tar.gz
+SOURCES/libdb-5.3.28-manpages.tar.gz
diff --git a/.libdb.metadata b/.libdb.metadata
new file mode 100644
index 0000000..e8c2e4e
--- /dev/null
+++ b/.libdb.metadata
@@ -0,0 +1,3 @@
+fa3f8a41ad5101f43d08bc0efb6241c9b6fc1ae9 SOURCES/db-5.3.28.tar.gz
+ccb057b07761d1b2b34626e748c7392c749d5e6d SOURCES/db.1.85.tar.gz
+c90635ffef230707c87f1353495972f8041882bd SOURCES/libdb-5.3.28-manpages.tar.gz
diff --git a/SOURCES/007-mt19937db.c_license.patch b/SOURCES/007-mt19937db.c_license.patch
new file mode 100644
index 0000000..eab05d7
--- /dev/null
+++ b/SOURCES/007-mt19937db.c_license.patch
@@ -0,0 +1,49 @@
+Description: mt19937db.c license should include the GPL
+ This file is distributed from upstream Berkeley DB under the Artistic
+ License (no version specified), althouth it was later released by the
+ original author under both GPL2+ and BSD.
+ .
+ References:
+ http://web.archive.org/web/20010806225716/http://www.math.keio.ac.jp/matumoto/mt19937int.c
+ http://web.archive.org/web/20130127064020/http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c
+ https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=886838
+ https://lists.nongnu.org/archive/html/gnu-linux-libre/2010-05/msg00000.html
+ .
+Author: Ruben Rodriguez <ruben@trisquel.info>
+
+
+--- db-5.3.21/src/crypto/mersenne/mt19937db.c.licensefix
++++ db-5.3.21/src/crypto/mersenne/mt19937db.c
+@@ -16,16 +16,27 @@
+ /*   Coded by Takuji Nishimura, considering the suggestions by    */
+ /* Topher Cooper and Marc Rieffel in July-Aug. 1997.              */
+ 
+-/* This library is free software under the Artistic license:       */
+-/* see the file COPYING distributed together with this code.       */
+-/* For the verification of the code, its output sequence file      */
+-/* mt19937int.out is attached (2001/4/2)                           */
+-
+ /* Copyright (C) 1997, 1999 Makoto Matsumoto and Takuji Nishimura. */
+ /* Any feedback is very welcome. For any question, comments,       */
+ /* see http://www.math.keio.ac.jp/matumoto/emt.html or email       */
+ /* matumoto@math.keio.ac.jp                                        */
+ 
++/* This library is free software; you can redistribute it and/or   */
++/* modify it under the terms of the GNU Library General Public     */
++/* License as published by the Free Software Foundation; either    */
++/* version 2 of the License, or (at your option) any later         */
++/* version.                                                        */
++/* This library is distributed in the hope that it will be useful, */
++/* but WITHOUT ANY WARRANTY; without even the implied warranty of  */
++/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.            */
++/* See the GNU Library General Public License for more details.    */
++/* You should have received a copy of the GNU Library General      */
++/* Public License along with this library; if not, write to the    */
++/* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA   */ 
++/* 02111-1307  USA                                                 */
++
++/* This library is free software under the Artistic license:       */
++
+ /* REFERENCE                                                       */
+ /* M. Matsumoto and T. Nishimura,                                  */
+ /* "Mersenne Twister: A 623-Dimensionally Equidistributed Uniform  */
diff --git a/SOURCES/checkpoint-opd-deadlock.patch b/SOURCES/checkpoint-opd-deadlock.patch
new file mode 100644
index 0000000..7aab6e1
--- /dev/null
+++ b/SOURCES/checkpoint-opd-deadlock.patch
@@ -0,0 +1,14 @@
+--- db-5.3.21/src/db/db_cam.c.opd_deadlock	2017-10-31 12:20:54.118979690 +0100
++++ db-5.3.21/src/db/db_cam.c	2017-10-31 12:21:06.828739341 +0100
+@@ -868,6 +868,11 @@
+ 	    flags == DB_PREV || flags == DB_PREV_DUP)) {
+ 		if (tmp_rmw && (ret = dbc->am_writelock(dbc)) != 0)
+ 			goto err;
++        /* Latch the primary tree page here in order to not deadlock later. */
++		if (cp->page == NULL &&
++		    (ret = __memp_fget(mpf, &cp->pgno,
++			 dbc->thread_info, dbc->txn, 0, &cp->page)) != 0)
++			goto err;
+ 		if (F_ISSET(dbc, DBC_TRANSIENT))
+ 			opd = cp->opd;
+ 		else if ((ret = __dbc_idup(cp->opd, &opd, DB_POSITION)) != 0)
diff --git a/SOURCES/db-1.85-errno.patch b/SOURCES/db-1.85-errno.patch
new file mode 100644
index 0000000..ccc9ddf
--- /dev/null
+++ b/SOURCES/db-1.85-errno.patch
@@ -0,0 +1,89 @@
+glibc doesn't like errno as the name of a field.
+--- db.1.85/hash/hash.h	Mon Feb 18 19:12:14 2002
++++ db.1.85/hash/hash.h	Mon Feb 18 19:12:20 2002
+@@ -103,7 +103,7 @@
+ 	BUFHEAD 	*cpage;		/* Current page */
+ 	int		cbucket;	/* Current bucket */
+ 	int		cndx;		/* Index of next item on cpage */
+-	int		errno;		/* Error Number -- for DBM 
++	int		err;		/* Error Number -- for DBM 
+ 					 * compatability */
+ 	int		new_file;	/* Indicates if fd is backing store 
+ 					 * or no */
+--- db.1.85/hash/hash.c	Mon Feb 18 19:12:24 2002
++++ db.1.85/hash/hash.c	Mon Feb 18 19:12:44 2002
+@@ -505,7 +505,7 @@
+ 	else
+ 		if (wsize != sizeof(HASHHDR)) {
+ 			errno = EFTYPE;
+-			hashp->errno = errno;
++			hashp->err = errno;
+ 			return (-1);
+ 		}
+ 	for (i = 0; i < NCACHED; i++)
+@@ -536,7 +536,7 @@
+ 
+ 	hashp = (HTAB *)dbp->internal;
+ 	if (flag) {
+-		hashp->errno = errno = EINVAL;
++		hashp->err = errno = EINVAL;
+ 		return (ERROR);
+ 	}
+ 	return (hash_access(hashp, HASH_GET, (DBT *)key, data));
+@@ -553,11 +553,11 @@
+ 
+ 	hashp = (HTAB *)dbp->internal;
+ 	if (flag && flag != R_NOOVERWRITE) {
+-		hashp->errno = errno = EINVAL;
++		hashp->err = errno = EINVAL;
+ 		return (ERROR);
+ 	}
+ 	if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+-		hashp->errno = errno = EPERM;
++		hashp->err = errno = EPERM;
+ 		return (ERROR);
+ 	}
+ 	return (hash_access(hashp, flag == R_NOOVERWRITE ?
+@@ -574,11 +574,11 @@
+ 
+ 	hashp = (HTAB *)dbp->internal;
+ 	if (flag && flag != R_CURSOR) {
+-		hashp->errno = errno = EINVAL;
++		hashp->err = errno = EINVAL;
+ 		return (ERROR);
+ 	}
+ 	if ((hashp->flags & O_ACCMODE) == O_RDONLY) {
+-		hashp->errno = errno = EPERM;
++		hashp->err = errno = EPERM;
+ 		return (ERROR);
+ 	}
+ 	return (hash_access(hashp, HASH_DELETE, (DBT *)key, NULL));
+@@ -729,7 +729,7 @@
+ 
+ 	hashp = (HTAB *)dbp->internal;
+ 	if (flag && flag != R_FIRST && flag != R_NEXT) {
+-		hashp->errno = errno = EINVAL;
++		hashp->err = errno = EINVAL;
+ 		return (ERROR);
+ 	}
+ #ifdef HASH_STATISTICS
+--- db.1.85/hash/ndbm.c	Mon Feb 18 19:12:58 2002
++++ db.1.85/hash/ndbm.c	Mon Feb 18 19:13:05 2002
+@@ -180,7 +180,7 @@
+ 	HTAB *hp;
+ 
+ 	hp = (HTAB *)db->internal;
+-	return (hp->errno);
++	return (hp->err);
+ }
+ 
+ extern int
+@@ -190,7 +190,7 @@
+ 	HTAB *hp;
+ 
+ 	hp = (HTAB *)db->internal;
+-	hp->errno = 0;
++	hp->err = 0;
+ 	return (0);
+ }
+ 
diff --git a/SOURCES/db-4.5.20-jni-include-dir.patch b/SOURCES/db-4.5.20-jni-include-dir.patch
new file mode 100644
index 0000000..b0881c3
--- /dev/null
+++ b/SOURCES/db-4.5.20-jni-include-dir.patch
@@ -0,0 +1,12 @@
+diff -up db-4.7.25/dist/configure.ac.jni db-4.7.25/dist/configure.ac
+--- db-4.7.25/dist/configure.ac.jni	2008-08-20 14:22:59.000000000 +0200
++++ db-4.7.25/dist/configure.ac	2008-08-20 14:23:39.000000000 +0200
+@@ -418,7 +418,7 @@ if test "$db_cv_java" = "yes"; then
+ 	AC_PROG_JAVAC
+ 	AC_PROG_JAR
+ 	AC_PROG_JAVA
+-	AC_JNI_INCLUDE_DIR
++	JNI_INCLUDE_DIRS="/usr/lib/jvm/java/include /usr/lib/jvm/java/include/linux"
+ 
+ 	AC_MSG_CHECKING(java version)
+         case "$JAVA" in
diff --git a/SOURCES/db-4.6.21-1.85-compat.patch b/SOURCES/db-4.6.21-1.85-compat.patch
new file mode 100644
index 0000000..62ae950
--- /dev/null
+++ b/SOURCES/db-4.6.21-1.85-compat.patch
@@ -0,0 +1,14 @@
+diff -up db-5.1.19/dist/Makefile.in.185compat db-5.1.19/dist/Makefile.in
+--- db-5.1.19/dist/Makefile.in.185compat	2010-08-27 17:08:03.000000000 +0200
++++ db-5.1.19/dist/Makefile.in	2010-09-10 10:02:32.974640425 +0200
+@@ -193,8 +193,8 @@ libtso_major=	$(libtcl_base)-$(LIBMAJOR)
+ # local libraries, for example.  Do that by adding -I options to the DB185INC
+ # line, and -l options to the DB185LIB line.
+ ##################################################
+-DB185INC=	-c @CFLAGS@ -I$(topdir) @CPPFLAGS@
+-DB185LIB=
++DB185INC=	-c @CFLAGS@ -I$(srcdir) -I$(srcdir)/db.1.85/PORT/linux/include @CPPFLAGS@
++DB185LIB=	${srcdir}/db.1.85/PORT/linux/libdb.a
+ 
+ ##################################################
+ # Performance Event Monitoring definitions
diff --git a/SOURCES/db-5.3.21-memp_stat-upstream-fix.patch b/SOURCES/db-5.3.21-memp_stat-upstream-fix.patch
new file mode 100644
index 0000000..9e3d52b
--- /dev/null
+++ b/SOURCES/db-5.3.21-memp_stat-upstream-fix.patch
@@ -0,0 +1,183 @@
+diff -r -u db-5.3.21_orig/src/mp/mp_stat.c db-5.3.21/src/mp/mp_stat.c
+--- db-5.3.21_orig/src/mp/mp_stat.c	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_stat.c	2015-05-19 15:07:09.000000000 +0800
+@@ -87,6 +87,13 @@
+ 	u_int32_t i;
+ 	uintmax_t tmp_wait, tmp_nowait;
+ 
++	/*
++	 * The array holding the lengths related to the buffer allocated for *fspp.
++	 * The first element of the array holds the number of entries allocated.
++	 * The second element of the array holds the total number of bytes allocated.
++	 */
++	u_int32_t fsp_len[2];
++
+ 	dbmp = env->mp_handle;
+ 	mp = dbmp->reginfo[0].primary;
+ 
+@@ -193,32 +200,53 @@
+ 	if (fspp != NULL) {
+ 		*fspp = NULL;
+ 
+-		/* Count the MPOOLFILE structures. */
+-		i = 0;
+-		len = 0;
+-		if ((ret = __memp_walk_files(env,
+-		     mp, __memp_count_files, &len, &i, flags)) != 0)
+-			return (ret);
++		while (*fspp == NULL) {
++			/* Count the MPOOLFILE structures. */
++			i = 0;
++			/*
++			 * Allow space for the first __memp_get_files() to align the
++			 * structure array to uintmax_t, DB_MPOOL_STAT's most
++			 * restrictive field.  [#23150]
++			 */
++			len = sizeof(uintmax_t);
++			if ((ret = __memp_walk_files(env,
++			     mp, __memp_count_files, &len, &i, flags)) != 0)
++				return (ret);
++
++			if (i == 0)
++				return (0);
++
++			/* 
++			 * Copy the number of DB_MPOOL_FSTAT entries and the number of
++			 * bytes allocated for them into fsp_len. Do not count the space
++			 * reserved for allignment.
++			 */
++			fsp_len[0] = i;
++			fsp_len[1] = len - sizeof(uintmax_t);
+ 
+-		if (i == 0)
+-			return (0);
+-		len += sizeof(DB_MPOOL_FSTAT *);	/* Trailing NULL */
++			len += sizeof(DB_MPOOL_FSTAT *);	/* Trailing NULL */
+ 
+-		/* Allocate space */
+-		if ((ret = __os_umalloc(env, len, fspp)) != 0)
+-			return (ret);
++			/* Allocate space */
++			if ((ret = __os_umalloc(env, len, fspp)) != 0)
++				return (ret);
+ 
+-		tfsp = *fspp;
+-		*tfsp = NULL;
+-
+-		/*
+-		 * Files may have been opened since we counted, don't walk
+-		 * off the end of the allocated space.
+-		 */
+-		if ((ret = __memp_walk_files(env,
+-		    mp, __memp_get_files, &tfsp, &i, flags)) != 0)
+-			return (ret);
++			tfsp = *fspp;
++			*tfsp = NULL;
+ 
++			/*
++			 * Files may have been opened since we counted, if we walk off
++			 * the end of the allocated space specified in fsp_len, retry.
++			 */
++			if ((ret = __memp_walk_files(env,
++			    mp, __memp_get_files, &tfsp, fsp_len, flags)) != 0) {
++				if (ret == DB_BUFFER_SMALL) {
++					__os_ufree(env, *fspp);
++					*fspp = NULL;
++					tfsp = NULL;
++				} else
++					return (ret);
++			}
++		}
+ 		*++tfsp = NULL;
+ 	}
+ 
+@@ -286,28 +314,35 @@
+  * for the text file names.
+  */
+ static int
+-__memp_get_files(env, mfp, argp, countp, flags)
++__memp_get_files(env, mfp, argp, fsp_len, flags)
+ 	ENV *env;
+ 	MPOOLFILE *mfp;
+ 	void *argp;
+-	u_int32_t *countp;
++	u_int32_t fsp_len[];
+ 	u_int32_t flags;
+ {
+ 	DB_MPOOL *dbmp;
+ 	DB_MPOOL_FSTAT **tfsp, *tstruct;
+ 	char *name, *tname;
+-	size_t nlen;
++	size_t nlen, tlen;
+ 
+-	if (*countp == 0)
+-		return (0);
++	/* We walked through more files than argp was allocated for. */
++	if (fsp_len[0] == 0)
++		return DB_BUFFER_SMALL;
+ 
+ 	dbmp = env->mp_handle;
+ 	tfsp = *(DB_MPOOL_FSTAT ***)argp;
+ 
+ 	if (*tfsp == NULL) {
+-		/* Add 1 to count because we need to skip over the NULL. */
+-		tstruct = (DB_MPOOL_FSTAT *)(tfsp + *countp + 1);
+-		tname = (char *)(tstruct + *countp);
++		/*
++		 * Add 1 to count because to skip over the NULL end marker.
++		 * Align it further for DB_MPOOL_STAT's most restrictive field
++		 * because uintmax_t might require stricter alignment than
++		 * pointers; e.g., IP32 LL64 SPARC. [#23150]
++		 */
++		tstruct = (DB_MPOOL_FSTAT *)&tfsp[fsp_len[0] + 1];
++		tstruct = ALIGNP_INC(tstruct, sizeof(uintmax_t));
++		tname = (char *)&tstruct[fsp_len[0]];
+ 		*tfsp = tstruct;
+ 	} else {
+ 		tstruct = *tfsp + 1;
+@@ -317,6 +352,15 @@
+ 
+ 	name = __memp_fns(dbmp, mfp);
+ 	nlen = strlen(name) + 1;
++
++	/* The space required for file names is larger than argp was allocated for. */
++	tlen = sizeof(DB_MPOOL_FSTAT *) + sizeof(DB_MPOOL_FSTAT) + nlen;
++	if (fsp_len[1] < tlen)
++		return DB_BUFFER_SMALL;
++	else
++		/* Count down the number of bytes left in argp. */
++		fsp_len[1] -= tlen;
++
+ 	memcpy(tname, name, nlen);
+ 	memcpy(tstruct, &mfp->stat, sizeof(mfp->stat));
+ 	tstruct->file_name = tname;
+@@ -325,7 +369,9 @@
+ 	tstruct->st_pagesize = mfp->pagesize;
+ 
+ 	*(DB_MPOOL_FSTAT ***)argp = tfsp;
+-	(*countp)--;
++
++	/* Count down the number of entries left in argp. */
++	fsp_len[0]--;
+ 
+ 	if (LF_ISSET(DB_STAT_CLEAR))
+ 		memset(&mfp->stat, 0, sizeof(mfp->stat));
+diff -r -u db-5.3.21_orig/src/mp/mp_sync.c db-5.3.21/src/mp/mp_sync.c
+--- db-5.3.21_orig/src/mp/mp_sync.c	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_sync.c	2015-05-19 15:08:05.000000000 +0800
+@@ -57,11 +57,13 @@
+ 			if ((t_ret = func(env,
+ 			    mfp, arg, countp, flags)) != 0 && ret == 0)
+ 				ret = t_ret;
+-			if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
++			if (ret != 0 &&
++			    (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
+ 				break;
+ 		}
+ 		MUTEX_UNLOCK(env, hp->mtx_hash);
+-		if (ret != 0 && !LF_ISSET(DB_STAT_MEMP_NOERROR))
++		if (ret != 0 &&
++		    (!LF_ISSET(DB_STAT_MEMP_NOERROR) || ret == DB_BUFFER_SMALL))
+ 			break;
+ 	}
+ 	return (ret);
diff --git a/SOURCES/db-5.3.21-mutex_leak.patch b/SOURCES/db-5.3.21-mutex_leak.patch
new file mode 100644
index 0000000..0738dab
--- /dev/null
+++ b/SOURCES/db-5.3.21-mutex_leak.patch
@@ -0,0 +1,718 @@
+diff -U 5 -r db-5.3.21.old/src/dbinc_auto/int_def.in db-5.3.21/src/dbinc_auto/int_def.in
+--- db-5.3.21.old/src/dbinc_auto/int_def.in	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/dbinc_auto/int_def.in	2016-10-25 22:40:58.000000000 +0800
+@@ -1371,10 +1371,11 @@
+ #define	__memp_failchk __memp_failchk@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_bhwrite __memp_bhwrite@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_pgread __memp_pgread@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_pg __memp_pg@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_bhfree __memp_bhfree@DB_VERSION_UNIQUE_NAME@
++#define	__memp_bh_clear_dirty __memp_bh_clear_dirty@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fget_pp __memp_fget_pp@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fget __memp_fget@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fcreate_pp __memp_fcreate_pp@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fcreate __memp_fcreate@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_set_clear_len __memp_set_clear_len@DB_VERSION_UNIQUE_NAME@
+@@ -1395,10 +1396,11 @@
+ #define	__memp_fopen __memp_fopen@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fclose_pp __memp_fclose_pp@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fclose __memp_fclose@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_mf_discard __memp_mf_discard@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_inmemlist __memp_inmemlist@DB_VERSION_UNIQUE_NAME@
++#define	__memp_mf_mark_dead __memp_mf_mark_dead@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fput_pp __memp_fput_pp@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fput __memp_fput@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_unpin_buffers __memp_unpin_buffers@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_dirty __memp_dirty@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_shared __memp_shared@DB_VERSION_UNIQUE_NAME@
+@@ -1453,10 +1455,11 @@
+ #define	__memp_fsync_pp __memp_fsync_pp@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_fsync __memp_fsync@DB_VERSION_UNIQUE_NAME@
+ #define	__mp_xxx_fh __mp_xxx_fh@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_sync_int __memp_sync_int@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_mf_sync __memp_mf_sync@DB_VERSION_UNIQUE_NAME@
++#define	__memp_purge_dead_files __memp_purge_dead_files@DB_VERSION_UNIQUE_NAME@
+ #define	__memp_trickle_pp __memp_trickle_pp@DB_VERSION_UNIQUE_NAME@
+ #define	__mutex_alloc __mutex_alloc@DB_VERSION_UNIQUE_NAME@
+ #define	__mutex_alloc_int __mutex_alloc_int@DB_VERSION_UNIQUE_NAME@
+ #define	__mutex_free __mutex_free@DB_VERSION_UNIQUE_NAME@
+ #define	__mutex_free_int __mutex_free_int@DB_VERSION_UNIQUE_NAME@
+diff -U 5 -r db-5.3.21.old/src/dbinc_auto/mp_ext.h db-5.3.21/src/dbinc_auto/mp_ext.h
+--- db-5.3.21.old/src/dbinc_auto/mp_ext.h	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/dbinc_auto/mp_ext.h	2016-10-25 22:40:58.000000000 +0800
+@@ -14,10 +14,11 @@
+ int __memp_failchk __P((ENV *));
+ int __memp_bhwrite __P((DB_MPOOL *, DB_MPOOL_HASH *, MPOOLFILE *, BH *, int));
+ int __memp_pgread __P((DB_MPOOLFILE *, BH *, int));
+ int __memp_pg __P((DB_MPOOLFILE *, db_pgno_t, void *, int));
+ int __memp_bhfree __P((DB_MPOOL *, REGINFO *, MPOOLFILE *, DB_MPOOL_HASH *, BH *, u_int32_t));
++void __memp_bh_clear_dirty __P((ENV*, DB_MPOOL_HASH *, BH *));
+ int __memp_fget_pp __P((DB_MPOOLFILE *, db_pgno_t *, DB_TXN *, u_int32_t, void *));
+ int __memp_fget __P((DB_MPOOLFILE *, db_pgno_t *, DB_THREAD_INFO *, DB_TXN *, u_int32_t, void *));
+ int __memp_fcreate_pp __P((DB_ENV *, DB_MPOOLFILE **, u_int32_t));
+ int __memp_fcreate __P((ENV *, DB_MPOOLFILE **));
+ int __memp_set_clear_len __P((DB_MPOOLFILE *, u_int32_t));
+@@ -38,10 +39,11 @@
+ int __memp_fopen __P((DB_MPOOLFILE *, MPOOLFILE *, const char *, const char **, u_int32_t, int, size_t));
+ int __memp_fclose_pp __P((DB_MPOOLFILE *, u_int32_t));
+ int __memp_fclose __P((DB_MPOOLFILE *, u_int32_t));
+ int __memp_mf_discard __P((DB_MPOOL *, MPOOLFILE *, int));
+ int __memp_inmemlist __P((ENV *, char ***, int *));
++void __memp_mf_mark_dead __P((DB_MPOOL *, MPOOLFILE *, int*));
+ int __memp_fput_pp __P((DB_MPOOLFILE *, void *, DB_CACHE_PRIORITY, u_int32_t));
+ int __memp_fput __P((DB_MPOOLFILE *, DB_THREAD_INFO *, void *, DB_CACHE_PRIORITY));
+ int __memp_unpin_buffers __P((ENV *, DB_THREAD_INFO *));
+ int __memp_dirty __P((DB_MPOOLFILE *, void *, DB_THREAD_INFO *, DB_TXN *, DB_CACHE_PRIORITY, u_int32_t));
+ int __memp_shared __P((DB_MPOOLFILE *, void *));
+@@ -96,10 +98,11 @@
+ int __memp_fsync_pp __P((DB_MPOOLFILE *));
+ int __memp_fsync __P((DB_MPOOLFILE *));
+ int __mp_xxx_fh __P((DB_MPOOLFILE *, DB_FH **));
+ int __memp_sync_int __P((ENV *, DB_MPOOLFILE *, u_int32_t, u_int32_t, u_int32_t *, int *));
+ int __memp_mf_sync __P((DB_MPOOL *, MPOOLFILE *, int));
++int __memp_purge_dead_files __P((ENV *));
+ int __memp_trickle_pp __P((DB_ENV *, int, int *));
+ 
+ #if defined(__cplusplus)
+ }
+ #endif
+diff -U 5 -r db-5.3.21.old/src/mp/mp_bh.c db-5.3.21/src/mp/mp_bh.c
+--- db-5.3.21.old/src/mp/mp_bh.c	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_bh.c	2016-10-25 17:09:35.000000000 +0800
+@@ -472,15 +472,12 @@
+ 	 * a shared latch.
+ 	 */
+ 	if (F_ISSET(bhp, BH_DIRTY | BH_TRASH)) {
+ 		MUTEX_LOCK(env, hp->mtx_hash);
+ 		DB_ASSERT(env, !SH_CHAIN_HASNEXT(bhp, vc));
+-		if (ret == 0 && F_ISSET(bhp, BH_DIRTY)) {
+-			F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+-			DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
+-			atomic_dec(env, &hp->hash_page_dirty);
+-		}
++		if (ret == 0)
++			__memp_bh_clear_dirty(env, hp, bhp);
+ 
+ 		/* put the page back if necessary. */
+ 		if ((ret != 0 || BH_REFCOUNT(bhp) > 1) &&
+ 		    F_ISSET(bhp, BH_TRASH)) {
+ 			ret = __memp_pg(dbmfp, bhp->pgno, bhp->buf, 1);
+@@ -686,5 +683,31 @@
+ 	} else
+ 		MUTEX_UNLOCK(env, mfp->mutex);
+ 
+ 	return (ret);
+ }
++
++/*
++ * __memp_bh_clear_dirty --
++ *	Clear the dirty flag of of a buffer. Calls on the same buffer must be
++ *	serialized to get the accounting correct. This can be achieved by
++ *	acquiring an exclusive lock on the buffer, a shared lock on the
++ *	buffer plus an exclusive lock on the hash bucket, or some other
++ *	mechanism that guarantees single-thread access to the entire region
++ *	(e.g. during __memp_region_bhfree()).
++ *
++ * PUBLIC: void __memp_bh_clear_dirty __P((ENV*, DB_MPOOL_HASH *, BH *));
++ */
++void
++__memp_bh_clear_dirty(env, hp, bhp)
++	ENV *env;
++	DB_MPOOL_HASH *hp;
++	BH *bhp;
++{
++	COMPQUIET(env, env);
++	if (F_ISSET(bhp, BH_DIRTY)) {
++		F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
++		DB_ASSERT(env, atomic_read(&hp->hash_page_dirty) > 0);
++		(void)atomic_dec(env, &hp->hash_page_dirty);
++	}
++}
++
+diff -U 5 -r db-5.3.21.old/src/mp/mp_fget.c db-5.3.21/src/mp/mp_fget.c
+--- db-5.3.21.old/src/mp/mp_fget.c	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_fget.c	2016-10-25 17:11:08.000000000 +0800
+@@ -437,16 +437,11 @@
+ 		 * complain and get out.
+ 		 */
+ 		if (flags == DB_MPOOL_FREE) {
+ freebuf:		MUTEX_LOCK(env, hp->mtx_hash);
+ 			h_locked = 1;
+-			if (F_ISSET(bhp, BH_DIRTY)) {
+-				F_CLR(bhp, BH_DIRTY | BH_DIRTY_CREATE);
+-				DB_ASSERT(env,
+-				   atomic_read(&hp->hash_page_dirty) > 0);
+-				atomic_dec(env, &hp->hash_page_dirty);
+-			}
++			__memp_bh_clear_dirty(env, hp, bhp);
+ 
+ 			/*
+ 			 * If the buffer we found is already freed, we're done.
+ 			 * If the ref count is not 1 then someone may be
+ 			 * peeking at the buffer.  We cannot free it until they
+diff -U 5 -r db-5.3.21.old/src/mp/mp_fopen.c db-5.3.21/src/mp/mp_fopen.c
+--- db-5.3.21.old/src/mp/mp_fopen.c	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_fopen.c	2016-10-25 22:31:05.000000000 +0800
+@@ -12,10 +12,11 @@
+ #include "dbinc/log.h"
+ #include "dbinc/mp.h"
+ #include "dbinc/db_page.h"
+ #include "dbinc/hash.h"
+ 
++static int __memp_count_dead_mutex __P((DB_MPOOL *, u_int32_t *));
+ static int __memp_mpf_alloc __P((DB_MPOOL *,
+     DB_MPOOLFILE *, const char *, u_int32_t, u_int32_t, MPOOLFILE **));
+ static int __memp_mpf_find __P((ENV *,
+     DB_MPOOLFILE *, DB_MPOOL_HASH *, const char *, u_int32_t, MPOOLFILE **));
+ 
+@@ -709,11 +710,15 @@
+ 		 * We should be able to set mfp to NULL and break out of the
+ 		 * loop, but I like the idea of checking all the entries.
+ 		 */
+ 		if (LF_ISSET(DB_TRUNCATE)) {
+ 			MUTEX_LOCK(env, mfp->mutex);
+-			mfp->deadfile = 1;
++			/*
++			 * We cannot purge dead files here, because the caller
++			 * is holding the mutex of the hash bucket of mfp.
++			 */
++			__memp_mf_mark_dead(dbmp, mfp, NULL);
+ 			MUTEX_UNLOCK(env, mfp->mutex);
+ 			continue;
+ 		}
+ 
+ 		/*
+@@ -907,14 +912,15 @@
+ 	DB_MPOOL *dbmp;
+ 	ENV *env;
+ 	MPOOLFILE *mfp;
+ 	char *rpath;
+ 	u_int32_t ref;
+-	int deleted, ret, t_ret;
++	int deleted, purge_dead, ret, t_ret;
+ 
+ 	env = dbmfp->env;
+ 	dbmp = env->mp_handle;
++	purge_dead = 0;
+ 	ret = 0;
+ 
+ 	/*
+ 	 * Remove the DB_MPOOLFILE from the process' list.
+ 	 *
+@@ -1004,11 +1010,11 @@
+ 	}
+ 	DB_ASSERT(env, mfp->neutral_cnt < mfp->mpf_cnt);
+ 	if (--mfp->mpf_cnt == 0 || LF_ISSET(DB_MPOOL_DISCARD)) {
+ 		if (LF_ISSET(DB_MPOOL_DISCARD) ||
+ 		    F_ISSET(mfp, MP_TEMP) || mfp->unlink_on_close) {
+-			mfp->deadfile = 1;
++			__memp_mf_mark_dead(dbmp, mfp, &purge_dead);
+ 		}
+ 		if (mfp->unlink_on_close) {
+ 			if ((t_ret = __db_appname(dbmp->env, DB_APP_DATA,
+ 			    R_ADDR(dbmp->reginfo, mfp->path_off), NULL,
+ 			    &rpath)) != 0 && ret == 0)
+@@ -1037,10 +1043,12 @@
+ 			deleted = 1;
+ 		}
+ 	}
+ 	if (!deleted && !LF_ISSET(DB_MPOOL_NOLOCK))
+ 		MUTEX_UNLOCK(env, mfp->mutex);
++	if (purge_dead)
++		(void)__memp_purge_dead_files(env);
+ 
+ done:	/* Discard the DB_MPOOLFILE structure. */
+ 	if (dbmfp->pgcookie != NULL) {
+ 		__os_free(env, dbmfp->pgcookie->data);
+ 		__os_free(env, dbmfp->pgcookie);
+@@ -1091,11 +1099,11 @@
+ 	/*
+ 	 * We have to release the MPOOLFILE mutex before acquiring the region
+ 	 * mutex so we don't deadlock.  Make sure nobody ever looks at this
+ 	 * structure again.
+ 	 */
+-	mfp->deadfile = 1;
++	__memp_mf_mark_dead(dbmp, mfp, NULL);
+ 
+ 	/* Discard the mutex we're holding and return it too the pool. */
+ 	MUTEX_UNLOCK(env, mfp->mutex);
+ 	if ((t_ret = __mutex_free(env, &mfp->mutex)) != 0 && ret == 0)
+ 		ret = t_ret;
+@@ -1216,5 +1224,106 @@
+ 	/* Make sure we don't return any garbage. */
+ 	*cntp = 0;
+ 	*namesp = NULL;
+ 	return (ret);
+ }
++
++/*
++ * __memp_mf_mark_dead --
++ *	Mark an MPOOLFILE as dead because its contents are no longer necessary.
++ *	This happens when removing, truncation, or closing an unnamed in-memory
++ *	database. Return, in the purgep parameter, whether the caller should
++ *	call __memp_purge_dead_files() after the lock on mfp is released. The
++ *	caller must hold an exclusive lock on the mfp handle.
++ *
++ * PUBLIC: void __memp_mf_mark_dead __P((DB_MPOOL *, MPOOLFILE *, int*));
++ */
++void
++__memp_mf_mark_dead(dbmp, mfp, purgep)
++	DB_MPOOL *dbmp;	
++	MPOOLFILE *mfp;
++	int *purgep;
++{
++	ENV *env;
++#ifdef HAVE_MUTEX_SUPPORT
++	REGINFO *infop;
++	DB_MUTEXREGION *mtxregion;
++	u_int32_t mutex_max, mutex_inuse, dead_mutex;
++#endif
++
++	if (purgep != NULL)
++		*purgep = 0;
++
++	env = dbmp->env;
++
++#ifdef HAVE_MUTEX_SUPPORT
++	MUTEX_REQUIRED(env, mfp->mutex);
++
++	if (MUTEX_ON(env) && mfp->deadfile == 0) {
++		infop = &env->mutex_handle->reginfo;
++		mtxregion = infop->primary;
++
++		mutex_inuse = mtxregion->stat.st_mutex_inuse;
++		if ((mutex_max = env->dbenv->mutex_max) == 0)
++			mutex_max = infop->rp->max / mtxregion->mutex_size;
++
++		/*
++		 * Purging dead pages requires a full scan of the entire cache
++		 * buffer, so it is a slow operation. We only want to do it
++		 * when it is necessary and provides enough benefits. Below is
++		 * a simple heuristic that determines when to purge all dead
++		 * pages.
++		 */
++		if (purgep != NULL && mutex_inuse > mutex_max - 200) {
++			/*
++			 * If the mutex region is almost full and there are
++			 * many mutexes held by dead files, purge dead files.
++			 */
++			(void)__memp_count_dead_mutex(dbmp, &dead_mutex);
++			dead_mutex += mfp->block_cnt + 1;
++
++			if (dead_mutex > mutex_inuse / 20)
++				*purgep = 1;
++		}
++	}
++#endif
++
++	mfp->deadfile = 1;
++}
++
++/*
++ * __memp_count_dead_mutex --
++ *	Estimate the number of mutexes held by dead files.
++ */
++static int
++__memp_count_dead_mutex(dbmp, dead_mutex)
++	DB_MPOOL *dbmp;
++	u_int32_t *dead_mutex;
++{
++	ENV *env;
++	DB_MPOOL_HASH *hp;
++	MPOOL *mp;
++	MPOOLFILE *mfp;
++	u_int32_t mutex_per_file;
++	int busy, i;
++
++	env = dbmp->env;
++	*dead_mutex = 0;
++	mutex_per_file = 1;
++#ifndef HAVE_ATOMICFILEREAD
++	mutex_per_file = 2;
++#endif
++	mp = dbmp->reginfo[0].primary;
++	hp = R_ADDR(dbmp->reginfo, mp->ftab);
++	for (i = 0; i < MPOOL_FILE_BUCKETS; i++, hp++) {
++		busy = MUTEX_TRYLOCK(env, hp->mtx_hash);
++		if (busy)
++			continue;
++		SH_TAILQ_FOREACH(mfp, &hp->hash_bucket, q, __mpoolfile) {
++			if (mfp->deadfile)
++				*dead_mutex += mfp->block_cnt + mutex_per_file;
++		}
++		MUTEX_UNLOCK(env, hp->mtx_hash);
++	}
++
++	return (0);
++}
+diff -U 5 -r db-5.3.21.old/src/mp/mp_method.c db-5.3.21/src/mp/mp_method.c
+--- db-5.3.21.old/src/mp/mp_method.c	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_method.c	2016-10-25 17:22:23.000000000 +0800
+@@ -638,11 +638,11 @@
+ 	DB_MPOOL_HASH *hp, *nhp;
+ 	MPOOL *mp;
+ 	MPOOLFILE *mfp;
+ 	roff_t newname_off;
+ 	u_int32_t bucket;
+-	int locked, ret;
++	int locked, purge_dead, ret;
+ 	size_t nlen;
+ 	void *p;
+ 
+ #undef	op_is_remove
+ #define	op_is_remove	(newname == NULL)
+@@ -655,10 +655,11 @@
+ 	dbmp = NULL;
+ 	mfp = NULL;
+ 	nhp = NULL;
+ 	p = NULL;
+ 	locked = ret = 0;
++	purge_dead = 0;
+ 
+ 	if (!MPOOL_ON(env))
+ 		goto fsop;
+ 
+ 	dbmp = env->mp_handle;
+@@ -747,11 +748,11 @@
+ 		 * they do not get reclaimed as long as they exist.  Since we
+ 		 * are now deleting the database, we need to dec that count.
+ 		 */
+ 		if (mfp->no_backing_file)
+ 			mfp->mpf_cnt--;
+-		mfp->deadfile = 1;
++		__memp_mf_mark_dead(dbmp, mfp, &purge_dead);
+ 		MUTEX_UNLOCK(env, mfp->mutex);
+ 	} else {
+ 		/*
+ 		 * Else, it's a rename.  We've allocated memory for the new
+ 		 * name.  Swap it with the old one.  If it's in memory we
+@@ -806,10 +807,16 @@
+ 	if (locked == 1) {
+ 		MUTEX_UNLOCK(env, hp->mtx_hash);
+ 		if (nhp != NULL && nhp != hp)
+ 			MUTEX_UNLOCK(env, nhp->mtx_hash);
+ 	}
++	/* 
++	 * __memp_purge_dead_files() must be called when the hash bucket is
++	 * unlocked.
++	 */
++	if (purge_dead)
++		(void)__memp_purge_dead_files(env);
+ 	return (ret);
+ }
+ 
+ /*
+  * __memp_ftruncate __
+diff -U 5 -r db-5.3.21.old/src/mp/mp_sync.c db-5.3.21/src/mp/mp_sync.c
+--- db-5.3.21.old/src/mp/mp_sync.c	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_sync.c	2016-10-25 17:26:58.000000000 +0800
+@@ -24,10 +24,11 @@
+ static int __bhcmp __P((const void *, const void *));
+ static int __memp_close_flush_files __P((ENV *, int));
+ static int __memp_sync_files __P((ENV *));
+ static int __memp_sync_file __P((ENV *,
+ 		MPOOLFILE *, void *, u_int32_t *, u_int32_t));
++static inline void __update_err_ret(int, int*);
+ 
+ /*
+  * __memp_walk_files --
+  * PUBLIC: int __memp_walk_files __P((ENV *, MPOOL *,
+  * PUBLIC:	int (*) __P((ENV *, MPOOLFILE *, void *,
+@@ -961,5 +962,125 @@
+ 		return (-1);
+ 	if (bhp1->track_pgno > bhp2->track_pgno)
+ 		return (1);
+ 	return (0);
+ }
++
++/*
++ * __memp_purge_dead_files --
++ *	Remove all dead files and their buffers from the mpool. The caller
++ *	cannot hold any lock on the dead MPOOLFILE handles, their buffers
++ *	or their hash buckets.
++ *
++ * PUBLIC: int __memp_purge_dead_files __P((ENV *));
++ */
++int
++__memp_purge_dead_files(env)
++	ENV *env;
++{
++	BH *bhp;
++	DB_MPOOL *dbmp;
++	DB_MPOOL_HASH *hp, *hp_end;
++	REGINFO *infop;
++	MPOOL *c_mp, *mp;
++	MPOOLFILE *mfp;
++	u_int32_t i_cache;
++	int ret, t_ret, h_lock;
++
++	if (!MPOOL_ON(env))
++		return (0);
++
++	dbmp = env->mp_handle;
++	mp = dbmp->reginfo[0].primary;
++	ret = t_ret = h_lock = 0;
++
++	/*
++	 * Walk each cache's list of buffers and free all buffers whose
++	 * MPOOLFILE is marked as dead.
++	 */
++	for (i_cache = 0; i_cache < mp->nreg; i_cache++) {
++		infop = &dbmp->reginfo[i_cache]; 
++		c_mp = infop->primary;
++
++		hp = R_ADDR(infop, c_mp->htab);
++		hp_end = &hp[c_mp->htab_buckets];
++		for (; hp < hp_end; hp++) {
++			/* Skip empty buckets. */
++			if (SH_TAILQ_FIRST(&hp->hash_bucket, __bh) == NULL)
++				continue;
++
++			/* 
++			 * Search for a dead buffer. Other places that call
++			 * __memp_bhfree() acquire the buffer lock before the
++			 * hash bucket lock. Even though we acquire the two
++			 * locks in reverse order, we cannot deadlock here
++			 * because we don't block waiting for the locks.
++			 */
++			t_ret = MUTEX_TRYLOCK(env, hp->mtx_hash);
++			if (t_ret != 0) {
++				__update_err_ret(t_ret, &ret);
++				continue;
++			}
++			h_lock = 1;
++			SH_TAILQ_FOREACH(bhp, &hp->hash_bucket, hq, __bh) {
++				/* Skip buffers that are being used. */
++				if (BH_REFCOUNT(bhp) > 0)
++					continue;
++
++				mfp = R_ADDR(dbmp->reginfo, bhp->mf_offset);
++				if (!mfp->deadfile)
++					continue;
++
++				/* Found a dead buffer. Prepare to free it. */
++				t_ret = MUTEX_TRYLOCK(env, bhp->mtx_buf);
++				if (t_ret != 0) {
++					__update_err_ret(t_ret, &ret);
++					continue;
++				}
++
++				DB_ASSERT(env, (!F_ISSET(bhp, BH_EXCLUSIVE) &&
++				    BH_REFCOUNT(bhp) == 0));
++				F_SET(bhp, BH_EXCLUSIVE);
++				(void)atomic_inc(env, &bhp->ref);
++
++				__memp_bh_clear_dirty(env, hp, bhp);
++
++				/*
++				 * Free the buffer. The buffer and hash bucket
++				 * are unlocked by __memp_bhfree.
++				 */
++				if ((t_ret = __memp_bhfree(dbmp, infop, mfp,
++				    hp, bhp, BH_FREE_FREEMEM)) == 0)
++					/*
++					 * Decrement hp, so the next turn will
++					 * search the same bucket again.
++					 */
++					hp--;
++				else
++					__update_err_ret(t_ret, &ret);
++
++				/*
++				 * The hash bucket is unlocked, we need to
++				 * start over again.
++				 */
++				h_lock = 0;
++				break;
++			}
++
++			if (h_lock) {
++				MUTEX_UNLOCK(env, hp->mtx_hash);
++				h_lock = 0;
++			}
++		}
++	}
++
++	return (ret);
++}
++
++static inline void
++__update_err_ret(t_ret, retp)
++	int t_ret;
++	int *retp;
++{
++	if (t_ret != 0 && t_ret != DB_LOCK_NOTGRANTED && *retp == 0)
++		*retp = t_ret;
++}
+diff -U 5 -r db-5.3.21.old/src/mp/mp_trickle.c db-5.3.21/src/mp/mp_trickle.c
+--- db-5.3.21.old/src/mp/mp_trickle.c	2012-05-12 01:57:53.000000000 +0800
++++ db-5.3.21/src/mp/mp_trickle.c	2016-10-25 17:27:57.000000000 +0800
+@@ -65,10 +65,14 @@
+ 	    "DB_ENV->memp_trickle: %d: percent must be between 1 and 100",
+ 		    "%d"), pct);
+ 		return (EINVAL);
+ 	}
+ 
++	/* First we purge all dead files and their buffers. */
++	if ((ret = __memp_purge_dead_files(env)) != 0)
++		return (ret);
++
+ 	/*
+ 	 * Loop through the caches counting total/dirty buffers.
+ 	 *
+ 	 * XXX
+ 	 * Using hash_page_dirty is our only choice at the moment, but it's not
+diff -U 5 -r db-5.3.21.old/src/mutex/mut_region.c db-5.3.21/src/mutex/mut_region.c
+--- db-5.3.21.old/src/mutex/mut_region.c	2012-05-12 01:57:54.000000000 +0800
++++ db-5.3.21/src/mutex/mut_region.c	2016-10-25 17:34:22.000000000 +0800
+@@ -15,11 +15,11 @@
+ #include "dbinc/txn.h"
+ 
+ static db_size_t __mutex_align_size __P((ENV *));
+ static int __mutex_region_init __P((ENV *, DB_MUTEXMGR *));
+ static size_t __mutex_region_size __P((ENV *));
+-static size_t __mutex_region_max __P((ENV *));
++static size_t __mutex_region_max __P((ENV *, u_int32_t));
+ 
+ /*
+  * __mutex_open --
+  *	Open a mutex region.
+  *
+@@ -32,11 +32,11 @@
+ {
+ 	DB_ENV *dbenv;
+ 	DB_MUTEXMGR *mtxmgr;
+ 	DB_MUTEXREGION *mtxregion;
+ 	size_t size;
+-	u_int32_t cpu_count;
++	u_int32_t cpu_count, mutex_needed;
+ 	int ret;
+ #ifndef HAVE_ATOMIC_SUPPORT
+ 	u_int i;
+ #endif
+ 
+@@ -59,23 +59,24 @@
+ 		    cpu_count : cpu_count * MUTEX_SPINS_PER_PROCESSOR)) != 0)
+ 			return (ret);
+ 	}
+ 
+ 	/*
+-	 * If the user didn't set an absolute value on the number of mutexes
+-	 * we'll need, figure it out.  We're conservative in our allocation,
+-	 * we need mutexes for DB handles, group-commit queues and other things
+-	 * applications allocate at run-time.  The application may have kicked
+-	 * up our count to allocate its own mutexes, add that in.
++	 * Figure out the number of mutexes we'll need.  We're conservative in
++	 * our allocation, we need mutexes for DB handles, group-commit queues
++	 * and other things applications allocate at run-time.  The application
++	 * may have kicked up our count to allocate its own mutexes, add that
++	 * in.
+ 	 */
++	mutex_needed =
++	    __lock_region_mutex_count(env) +
++	    __log_region_mutex_count(env) +
++	    __memp_region_mutex_count(env) +
++	    __txn_region_mutex_count(env);
+ 	if (dbenv->mutex_cnt == 0 &&
+ 	    F_ISSET(env, ENV_PRIVATE | ENV_THREAD) != ENV_PRIVATE)
+-		dbenv->mutex_cnt =
+-		    __lock_region_mutex_count(env) +
+-		    __log_region_mutex_count(env) +
+-		    __memp_region_mutex_count(env) +
+-		    __txn_region_mutex_count(env);
++		dbenv->mutex_cnt = mutex_needed;
+ 
+ 	if (dbenv->mutex_max != 0 && dbenv->mutex_cnt > dbenv->mutex_max)
+ 		dbenv->mutex_cnt = dbenv->mutex_max;
+ 
+ 	/* Create/initialize the mutex manager structure. */
+@@ -88,12 +89,12 @@
+ 	mtxmgr->reginfo.id = INVALID_REGION_ID;
+ 	mtxmgr->reginfo.flags = REGION_JOIN_OK;
+ 	size = __mutex_region_size(env);
+ 	if (create_ok)
+ 		F_SET(&mtxmgr->reginfo, REGION_CREATE_OK);
+-	if ((ret = __env_region_attach(env,
+-	    &mtxmgr->reginfo, size, size + __mutex_region_max(env))) != 0)
++	if ((ret = __env_region_attach(env, &mtxmgr->reginfo,
++	    size, size + __mutex_region_max(env, mutex_needed))) != 0)
+ 		goto err;
+ 
+ 	/* If we created the region, initialize it. */
+ 	if (F_ISSET(&mtxmgr->reginfo, REGION_CREATE))
+ 		if ((ret = __mutex_region_init(env, mtxmgr)) != 0)
+@@ -350,44 +351,62 @@
+ 
+ 	dbenv = env->dbenv;
+ 
+ 	s = sizeof(DB_MUTEXMGR) + 1024;
+ 
+-	/* We discard one mutex for the OOB slot. */
++	/* 
++	 * We discard one mutex for the OOB slot. Make sure mutex_cnt doesn't
++	 * overflow.
++	 */
+ 	s += __env_alloc_size(
+-	    (dbenv->mutex_cnt + 1) *__mutex_align_size(env));
++	    (dbenv->mutex_cnt + (dbenv->mutex_cnt == UINT32_MAX ? 0 : 1)) *
++	    __mutex_align_size(env));
+ 
+ 	return (s);
+ }
+ 
+ /*
+  * __mutex_region_max --
+  *	 Return the amount of space needed to reach the maximum size.
+  */
+ static size_t
+-__mutex_region_max(env)
++__mutex_region_max(env, mutex_needed)
+ 	ENV *env;
++	u_int32_t mutex_needed;
+ {
+ 	DB_ENV *dbenv;
+-	u_int32_t max;
++	u_int32_t max, mutex_cnt;
+ 
+ 	dbenv = env->dbenv;
++	mutex_cnt = dbenv->mutex_cnt;
+ 
+-	if ((max = dbenv->mutex_max) == 0) {
++	/*
++	 * We want to limit the region size to accommodate at most UINT32_MAX
++	 * mutexes. If mutex_cnt is UINT32_MAX, no more space is allowed.
++	 */
++	if ((max = dbenv->mutex_max) == 0 && mutex_cnt != UINT32_MAX)
+ 		if (F_ISSET(env, ENV_PRIVATE | ENV_THREAD) == ENV_PRIVATE)
+-			max = dbenv->mutex_inc + 1;
+-		else
++			if (dbenv->mutex_inc + 1 < UINT32_MAX - mutex_cnt)
++				max = dbenv->mutex_inc + 1 + mutex_cnt;
++			else
++				max = UINT32_MAX;
++		else {
+ 			max = __lock_region_mutex_max(env) +
+ 			    __txn_region_mutex_max(env) +
+ 			    __log_region_mutex_max(env) +
+ 			    dbenv->mutex_inc + 100;
+-	} else if (max <= dbenv->mutex_cnt)
++			if (max < UINT32_MAX - mutex_needed)
++				max += mutex_needed;
++			else
++				max = UINT32_MAX;
++		}
++
++	if (max <= mutex_cnt)
+ 		return (0);
+ 	else
+-		max -= dbenv->mutex_cnt;
+-
+-	return ( __env_alloc_size(max * __mutex_align_size(env)));
++		return (__env_alloc_size(
++		    (max - mutex_cnt) * __mutex_align_size(env)));
+ }
+ 
+ #ifdef	HAVE_MUTEX_SYSTEM_RESOURCES
+ /*
+  * __mutex_resource_return
+
diff --git a/SOURCES/db-5.3.28-atomic_compare_exchange.patch b/SOURCES/db-5.3.28-atomic_compare_exchange.patch
new file mode 100644
index 0000000..4eab02c
--- /dev/null
+++ b/SOURCES/db-5.3.28-atomic_compare_exchange.patch
@@ -0,0 +1,20 @@
+--- db-5.3.28/src/dbinc/atomic.h.old	2018-05-23 09:20:04.216914922 +0200
++++ db-5.3.28/src/dbinc/atomic.h	2018-05-23 09:20:49.510057897 +0200
+@@ -144,7 +144,7 @@
+ #define	atomic_inc(env, p)	__atomic_inc(p)
+ #define	atomic_dec(env, p)	__atomic_dec(p)
+ #define	atomic_compare_exchange(env, p, o, n)	\
+-	__atomic_compare_exchange((p), (o), (n))
++	__db_atomic_compare_exchange((p), (o), (n))
+ static inline int __atomic_inc(db_atomic_t *p)
+ {
+ 	int	temp;
+@@ -176,7 +176,7 @@
+  * http://gcc.gnu.org/onlinedocs/gcc-4.1.0/gcc/Atomic-Builtins.html
+  * which configure could be changed to use.
+  */
+-static inline int __atomic_compare_exchange(
++static inline int __db_atomic_compare_exchange(
+ 	db_atomic_t *p, atomic_value_t oldval, atomic_value_t newval)
+ {
+ 	atomic_value_t was;
diff --git a/SOURCES/db-5.3.28-condition-variable-ppc.patch b/SOURCES/db-5.3.28-condition-variable-ppc.patch
new file mode 100644
index 0000000..0e9ef6b
--- /dev/null
+++ b/SOURCES/db-5.3.28-condition-variable-ppc.patch
@@ -0,0 +1,135 @@
+diff -up db-5.3.28/src/dbinc_auto/int_def.in.pthreads_ppc db-5.3.28/src/dbinc_auto/int_def.in
+--- db-5.3.28/src/dbinc_auto/int_def.in.pthreads_ppc	2017-06-26 15:06:09.282020804 +0200
++++ db-5.3.28/src/dbinc_auto/int_def.in	2017-06-26 15:06:22.238771039 +0200
+@@ -1572,6 +1572,7 @@
+ #define	__os_strerror __os_strerror@DB_VERSION_UNIQUE_NAME@
+ #define	__os_posix_err __os_posix_err@DB_VERSION_UNIQUE_NAME@
+ #define	__os_fileid __os_fileid@DB_VERSION_UNIQUE_NAME@
++#define	__check_lock_fn __check_lock_fn@DB_VERSION_UNIQUE_NAME@
+ #define	__os_fdlock __os_fdlock@DB_VERSION_UNIQUE_NAME@
+ #define	__os_fsync __os_fsync@DB_VERSION_UNIQUE_NAME@
+ #define	__os_getenv __os_getenv@DB_VERSION_UNIQUE_NAME@
+diff -up db-5.3.28/src/dbinc_auto/os_ext.h.pthreads_ppc db-5.3.28/src/dbinc_auto/os_ext.h
+--- db-5.3.28/src/dbinc_auto/os_ext.h.pthreads_ppc	2017-06-26 15:05:23.792897700 +0200
++++ db-5.3.28/src/dbinc_auto/os_ext.h	2017-06-26 15:06:22.172772311 +0200
+@@ -41,6 +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 __check_lock_fn __P((char *, pid_t));
+ 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));
+diff -up db-5.3.28/src/env/env_region.c.pthreads_ppc db-5.3.28/src/env/env_region.c
+--- db-5.3.28/src/env/env_region.c.pthreads_ppc	2017-06-26 15:04:40.805726365 +0200
++++ db-5.3.28/src/env/env_region.c	2017-06-26 15:04:40.807726326 +0200
+@@ -305,14 +305,6 @@ user_map_functions:
+ 		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;
+-    }
+-
+ 	if (renv->majver != DB_VERSION_MAJOR ||
+ 	    renv->minver != DB_VERSION_MINOR) {
+ 		/*
+@@ -337,6 +329,20 @@ user_map_functions:
+ 		goto err;
+ 	}
+ 
++    /*
++     * We have an old environment but cannot rebuild it safely.
++     * The environment might still be readable by the current process
++     * (only the libpthread timestamp changed) if this process is the one
++     * that is holding the lock on the region file as we can be sure
++     * the environment did not get rebuilt under our feet.
++     */
++    if (ret == DB_OLD_VERSION && __check_lock_fn(env->lockfhp->name, getpid()) ) {
++       __db_errx(env, DB_STR("1539",
++           "Build signature doesn't match environment"));
++       ret = DB_VERSION_MISMATCH;
++        goto err;
++    }
++
+ 	/*
+ 	 * Check if the environment has had a catastrophic failure.
+ 	 *
+diff -up db-5.3.28/src/os/os_flock.c.pthreads_ppc db-5.3.28/src/os/os_flock.c
+--- db-5.3.28/src/os/os_flock.c.pthreads_ppc	2017-06-26 15:04:40.806726346 +0200
++++ db-5.3.28/src/os/os_flock.c	2017-06-26 15:04:40.807726326 +0200
+@@ -15,6 +15,70 @@ static int __os_filelocking_notsup __P((
+ #endif
+ 
+ /*
++ * __check_lock_fn --
++ * Parse /proc/locks to see if the file described by 'fn' is locked.
++ * Additionally (if 'pid' is not 0) check if the process holding
++ * the lock has the same pid value as 'pid'.
++ *
++ * Returns 0 if a lock on fn is found, 1 if it is not found and -1 on error.
++ * PUBLIC: int __check_lock_fn __P((char *, pid_t));
++ */
++
++int __check_lock_fn(fn, pid)
++    char *fn;
++    pid_t pid;
++{
++    FILE* fp;
++    char buffer[PATH_MAX];
++    char *token;
++    int i, inode;
++    struct stat st;
++    pid_t lpid = 0;
++
++    if (!fn)
++       return -1;
++
++    fp = fopen("/proc/locks", "r");
++    if (!fp)
++        return -1;
++
++    /* Get the file's inode */
++    if (stat(fn, &st)) {
++        fclose(fp);
++        return -1;
++    }
++
++    while (fgets(buffer, sizeof(buffer), fp))
++        for (token = strtok(buffer, " "), i = 0; token; token = strtok(NULL, " "), i++) {
++            /* Do not parse any other fields */
++            if (i > 5)
++                break;
++            /* Save the PID */
++            if (i == 4)
++                lpid = atoi(token);
++            /* Check the inode */
++            else if (i == 5) {
++                inode = 0;
++                sscanf(token, "%*02x:%*02x:%d", &inode);
++                /* Not the inode we are looking for */
++                if (inode != st.st_ino)
++                    continue;
++                /*
++                 * We have the correct file.
++                 * We are either looking for a specific process or we do not care at all.
++                 */
++                if (!pid || lpid == pid) {
++                    fclose(fp);
++                    return 0;
++                }
++                /* Not the lock we are looking for */
++            }
++        }
++    fclose(fp);
++    return 1;
++}
++
++/*
+  * __os_fdlock --
+  *	Acquire/release a lock on a byte in a file.
+  *
diff --git a/SOURCES/db-5.3.28-condition_variable.patch b/SOURCES/db-5.3.28-condition_variable.patch
new file mode 100644
index 0000000..ca947e6
--- /dev/null
+++ b/SOURCES/db-5.3.28-condition_variable.patch
@@ -0,0 +1,759 @@
+diff -up db-5.3.28/dist/android/android_config.in.pthreads db-5.3.28/dist/android/android_config.in
+--- 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
+@@ -123,6 +123,9 @@
+ /* Define to 1 if allocated filesystem blocks are not zeroed. */
+ /* #undef HAVE_FILESYSTEM_NOTZERO */
+ 
++/* Define to 1 if you have the `flock' function. */
++#undef HAVE_FLOCK
++
+ /* Define to 1 if you have the `fopen' function. */
+ #define HAVE_FOPEN 1
+ 
+diff -up db-5.3.28/dist/config.hin.pthreads db-5.3.28/dist/config.hin
+--- db-5.3.28/dist/config.hin.pthreads	2013-09-09 17:35:02.000000000 +0200
++++ db-5.3.28/dist/config.hin	2017-06-13 11:15:15.000000000 +0200
+@@ -92,6 +92,9 @@
+ /* Define to 1 if you have the <dlfcn.h> header file. */
+ #undef HAVE_DLFCN_H
+ 
++/* Define to 1 if you have the `dl_iterate_phdr' function. */
++#undef HAVE_DL_ITERATE_PHDR
++
+ /* Define to 1 to use dtrace for performance monitoring. */
+ #undef HAVE_DTRACE
+ 
+@@ -125,6 +128,9 @@
+ /* Define to 1 if allocated filesystem blocks are not zeroed. */
+ #undef HAVE_FILESYSTEM_NOTZERO
+ 
++/* Define to 1 if you have the `flock' function. */
++#undef HAVE_FLOCK
++
+ /* Define to 1 if you have the `fopen' function. */
+ #undef HAVE_FOPEN
+ 
+@@ -360,6 +366,9 @@
+ /* Define to 1 if you have the `pstat_getdynamic' function. */
+ #undef HAVE_PSTAT_GETDYNAMIC
+ 
++/* Define to 1 if you have dl_iterate_phdr and use pthread-based mutexes. */
++#undef HAVE_PTHREADS_TIMESTAMP
++
+ /* Define to 1 if it is OK to initialize an already initialized
+    pthread_cond_t. */
+ #undef HAVE_PTHREAD_COND_REINIT_OKAY
+@@ -620,6 +629,11 @@
+ /* Define to 1 to mask harmless uninitialized memory read/writes. */
+ #undef UMRW
+ 
++/* 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
+ 
+diff -up db-5.3.28/dist/configure.ac.pthreads db-5.3.28/dist/configure.ac
+--- db-5.3.28/dist/configure.ac.pthreads	2017-06-13 11:15:15.309215434 +0200
++++ db-5.3.28/dist/configure.ac	2017-06-13 11:15:15.323215161 +0200
+@@ -698,7 +698,7 @@ AC_REPLACE_FUNCS(\
+ # Check for system functions we optionally use.
+ AC_CHECK_FUNCS(\
+ 	_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)
+@@ -1042,6 +1042,34 @@ if test "$db_cv_localization" = "yes"; t
+ [Define to 1 if you have localization function to support globalization.])
+ fi
+ 
++# Check for dl_iterate_phdr; do the test explicitly instead of using
++# AC_CHECK_FUNCS because <netdb.h> isn't a standard include file.
++AC_CACHE_CHECK([for dl_iterate_phdr], db_cv_dl_iterate_phdr, [
++AC_TRY_LINK([
++#include <sys/types.h>
++#include <netdb.h>], [
++	dl_iterate_phdr(0, 0);
++], [db_cv_dl_iterate_phdr=yes], [db_cv_dl_iterate_phdr=no])])
++if test "$db_cv_dl_iterate_phdr" = "yes"; then
++	AC_DEFINE(HAVE_DL_ITERATE_PHDR)
++	AH_TEMPLATE(HAVE_DL_ITERATE_PHDR,
++	    [Define to 1 if you have the `dl_iterate_phdr' function.])
++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
++	AC_DEFINE(HAVE_PTHREADS_TIMESTAMP)
++	AH_TEMPLATE(HAVE_PTHREADS_TIMESTAMP,
++     [Define to 1 if you have dl_iterate_phdr and use pthread-based mutexes.])
++    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 -up db-5.3.28/src/db/db_meta.c.pthreads db-5.3.28/src/db/db_meta.c
+--- db-5.3.28/src/db/db_meta.c.pthreads	2013-09-09 17:35:07.000000000 +0200
++++ db-5.3.28/src/db/db_meta.c	2017-06-13 11:15:15.323215161 +0200
+@@ -1330,8 +1330,9 @@ __db_haslock(env, locker, dbmfp, pgno, m
+ }
+ /*
+  * __db_has_pagelock --
+- *	Determine if this locker holds a particular page lock.
+- *	Returns 0 if lock is held, non-zero otherwise.
++ *	Determine if this locker holds a particular page lock, and return an
++ *	error if it is missing a page lock that it should have.
++ *	Otherwise (TDS with the page locked, or DS or CDS) return 0.
+  *
+  * PUBLIC: #ifdef DIAGNOSTIC
+  * PUBLIC: int __db_has_pagelock __P((ENV *, DB_LOCKER *,
+@@ -1348,6 +1349,9 @@ __db_has_pagelock(env, locker, dbmfp, pa
+ {
+ 	int ret;
+ 
++	if (!FLD_ISSET(env->open_flags, DB_INIT_TXN))
++		return (0);
++
+ 	switch (pagep->type) {
+ 	case P_OVERFLOW:
+ 	case P_INVALID:
+diff -up db-5.3.28/src/dbinc_auto/int_def.in.pthreads db-5.3.28/src/dbinc_auto/int_def.in
+--- db-5.3.28/src/dbinc_auto/int_def.in.pthreads	2017-06-13 11:15:15.317215278 +0200
++++ db-5.3.28/src/dbinc_auto/int_def.in	2017-06-13 11:15:15.324215141 +0200
+@@ -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 signature;		/* Structure signatures. */
++#if defined(HAVE_PTHREADS_TIMESTAMP) && defined(HAVE_MUTEX_PTHREADS)
++	/*
++	 * Updates to glibc/libpthread can change its pthreads implementation
++	 * and invalidate on-disk environments, even without changing the
++	 * version number.  If using POSIX mutexes and a change in this
++	 * timestamp is detecting when opening an environment with DB_CREATE,
++	 *  __env_attach recreates any existing on-disk environment.
++	 */
++	time_t pthreads_timestamp;
++#endif
+ 
+ 	time_t	  timestamp;		/* Creation time. */
+ 
+diff -up db-5.3.28/src/env/env_open.c.pthreads db-5.3.28/src/env/env_open.c
+--- db-5.3.28/src/env/env_open.c.pthreads	2013-09-09 17:35:08.000000000 +0200
++++ db-5.3.28/src/env/env_open.c	2017-06-13 11:15:15.324215141 +0200
+@@ -1031,11 +1031,11 @@ __env_attach_regions(dbenv, flags, orig_
+ 		goto err;
+ 
+ 	/*
+-	 * __env_attach will return the saved init_flags field, which contains
++	 * __env_attach has returned the saved init_flags field, which contains
+ 	 * the DB_INIT_* flags used when the environment was created.
+ 	 *
+-	 * We may be joining an environment -- reset our flags to match the
+-	 * ones in the environment.
++	 * We may be joining an existing environment -- reset our flags to match
++	 * the ones in the environment.
+ 	 */
+ 	if (FLD_ISSET(init_flags, DB_INITENV_CDB))
+ 		LF_SET(DB_INIT_CDB);
+diff -up db-5.3.28/src/env/env_region.c.pthreads db-5.3.28/src/env/env_region.c
+--- db-5.3.28/src/env/env_region.c.pthreads	2013-09-09 17:35:08.000000000 +0200
++++ 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 @@
+ #define	PID_LEN		(25)				/* PID entry length */
+ 
+ #define	REGISTRY_LOCK(env, pos, nowait)					\
+-	__os_fdlock(env, (env)->dbenv->registry, (off_t)(pos), 1, nowait)
++	__os_fdlock(env, (env)->dbenv->registry, (off_t)(pos), DB_LOCK_WRITE, nowait)
+ #define	REGISTRY_UNLOCK(env, pos)					\
+-	__os_fdlock(env, (env)->dbenv->registry, (off_t)(pos), 0, 0)
++	__os_fdlock(env, (env)->dbenv->registry, (off_t)(pos), DB_LOCK_NG, 0)
+ #define	REGISTRY_EXCL_LOCK(env, nowait)					\
+ 	REGISTRY_LOCK(env, 1, nowait)
+ #define	REGISTRY_EXCL_UNLOCK(env)					\
+diff -up db-5.3.28/src/env/env_stat.c.pthreads db-5.3.28/src/env/env_stat.c
+--- db-5.3.28/src/env/env_stat.c.pthreads	2013-09-09 17:35:08.000000000 +0200
++++ db-5.3.28/src/env/env_stat.c	2017-06-13 11:15:15.325215121 +0200
+@@ -177,6 +177,10 @@ __env_print_stats(env, flags)
+ 	STAT_LONG("Txn version", DB_TXNVERSION);
+ 	__db_msg(env,
+ 	    "%.24s\tCreation time", __os_ctime(&renv->timestamp, time_buf));
++#if defined(HAVE_PTHREADS_TIMESTAMP) && defined(HAVE_MUTEX_PTHREADS)
++	__db_msg(env,
++	    "%.24s\tlibpthread timestamp", __os_ctime(&renv->pthreads_timestamp, time_buf));
++#endif
+ 	STAT_HEX("Environment ID", renv->envid);
+ 	__mutex_print_debug_single(env,
+ 	    "Primary region allocation and reference count mutex",
+diff -up db-5.3.28/src/os/os_addrinfo.c.pthreads db-5.3.28/src/os/os_addrinfo.c
+--- db-5.3.28/src/os/os_addrinfo.c.pthreads	2013-09-09 17:35:09.000000000 +0200
++++ db-5.3.28/src/os/os_addrinfo.c	2017-06-13 11:15:15.325215121 +0200
+@@ -10,6 +10,10 @@
+ 
+ #include "db_int.h"
+ 
++#ifdef HAVE_PTHREADS_TIMESTAMP
++#include <link.h>
++#endif
++
+ /*
+  * __os_getaddrinfo and __os_freeaddrinfo wrap the getaddrinfo and freeaddrinfo
+  * calls, as well as the associated platform dependent error handling, mapping
+@@ -177,3 +181,48 @@ __os_freeaddrinfo(env, ai)
+ 	}
+ #endif
+ }
++
++#ifdef HAVE_PTHREADS_TIMESTAMP
++/*
++ *  callback_find_pthreads --
++ *  	dl_iterate_phdr() calls this once for each loaded library.
++ *
++ * Returns:
++ *	0 - the library does not appear to be libpthreads.
++ *	1 - the library *does* seem to be libpthreads. Its modification time is
++ *	    stored into into the last argument's location.
++ */
++static int
++callback_find_pthreads(struct dl_phdr_info *info, size_t size, void *data)
++{
++	struct stat stbuf;
++
++	/* Stop (return non-zero) when libc is found. */
++	if (strstr(info->dlpi_name, "libpthread") != NULL &&
++	    stat(info->dlpi_name, &stbuf) == 0) {
++		*(time_t *)data = stbuf.st_mtime;
++		return (1);
++	}
++	COMPQUIET(size, 0);
++	COMPQUIET(data, NULL);
++	return (0);
++}
++
++/*
++ * __os_pthreads_timestamp --
++ *
++ * PUBLIC: time_t __os_pthreads_timestamp __P((ENV *));
++ */
++time_t
++__os_pthreads_timestamp(env)
++	ENV *env;
++{
++	time_t	timestamp;
++
++	timestamp = 0;
++	dl_iterate_phdr(callback_find_pthreads, &timestamp);
++
++	COMPQUIET(env, 0);
++	return (timestamp);
++}
++#endif
+diff -up db-5.3.28/src/os/os_flock.c.pthreads db-5.3.28/src/os/os_flock.c
+--- db-5.3.28/src/os/os_flock.c.pthreads	2013-09-09 17:35:09.000000000 +0200
++++ db-5.3.28/src/os/os_flock.c	2017-06-13 11:15:15.325215121 +0200
+@@ -10,41 +10,98 @@
+ 
+ #include "db_int.h"
+ 
++#if !defined(HAVE_FCNTL) || !defined(HAVE_FLOCK)
++static int __os_filelocking_notsup __P((ENV *));
++#endif
++
+ /*
+  * __os_fdlock --
+  *	Acquire/release a lock on a byte in a file.
+  *
+- * PUBLIC: int __os_fdlock __P((ENV *, DB_FH *, off_t, int, int));
++ *	The lock modes supported here are:
++ *	DB_LOCK_NG	- release the lock
++ *	DB_LOCK_READ	- get shared access
++ *	DB_LOCK_WRITE	- get exclusive access
++ *
++ *	Use fcntl()-like semantics most of the time (DB_REGISTER support). Fcntl
++ *	supports range locking, but has the additional broken semantics that
++ *	closing any of the file's descriptors releases any locks, even if its
++ *	other file descriptors remain open. Thanks SYSV & POSIX.
++ *	However, if the offset is negative (which is allowed, because POSIX
++ *	off_t a signed integer) then use flock() instead.  It has only whole-
++ *	file locks, but they persist until explicitly unlocked or the process
++ *	exits.
++ * PUBLIC: int __os_fdlock __P((ENV *, DB_FH *, off_t, db_lockmode_t, int));
+  */
+ int
+-__os_fdlock(env, fhp, offset, acquire, nowait)
++__os_fdlock(env, fhp, offset, lockmode, nowait)
+ 	ENV *env;
+ 	DB_FH *fhp;
+-	int acquire, nowait;
+ 	off_t offset;
++	db_lockmode_t lockmode;
++	int nowait;
+ {
+ #ifdef HAVE_FCNTL
+ 	DB_ENV *dbenv;
+ 	struct flock fl;
+ 	int ret, t_ret;
++	static char *mode_string[DB_LOCK_WRITE + 1] = {
++		"unlock",
++		"read",
++		"write"
++	};
++	short mode_fcntl[DB_LOCK_WRITE + 1] = {
++		F_UNLCK,
++		F_RDLCK,
++		F_WRLCK
++	};
++#ifdef HAVE_FLOCK
++	short mode_flock[DB_LOCK_WRITE + 1] = {
++		LOCK_UN,
++		LOCK_SH,
++		LOCK_EX
++	};
++#endif
+ 
+ 	dbenv = env == NULL ? NULL : env->dbenv;
+ 
+ 	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
++	DB_ASSERT(env, lockmode <= DB_LOCK_WRITE);
+ 
+-	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
+-		__db_msg(env, DB_STR_A("0138",
+-		    "fileops: flock %s %s offset %lu", "%s %s %lu"), fhp->name,
+-		    acquire ? DB_STR_P("acquire"): DB_STR_P("release"),
+-		    (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 (offset < 0)
++		      __db_msg(env, DB_STR_A("####",
++			  "fileops: flock %s %s %s", "%s %s %s"),
++			  fhp->name, mode_string[lockmode],
++			  nowait ? "nowait" : "");
++	      else
++		      __db_msg(env, DB_STR_A("0020",
++			  "fileops: fcntls %s %s offset %lu", "%s %s %lu"),
++			  fhp->name, mode_string[lockmode], (u_long)offset);
++	}
++
++	if (offset < 0) {
++#ifdef HAVE_FLOCK
++	        RETRY_CHK_EINTR_ONLY(flock(fhp->fd,
++	            mode_flock[lockmode] | (nowait ? LOCK_NB : 0)), ret);
++#else
++		ret = __os_filelocking_notsup(env);
++#endif
++	} else {
++	        fl.l_start = offset;
++	        fl.l_len = 1;
++	        fl.l_whence = SEEK_SET;
++	        fl.l_type = mode_fcntl[lockmode];
++	           RETRY_CHK_EINTR_ONLY(
++	            fcntl(fhp->fd, nowait ? F_SETLK : F_SETLKW, &fl), ret);
++	}
++
++	if (offset < 0 && dbenv != NULL &&
++	    FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
++		__db_msg(env, DB_STR_A("####",
++		    "fileops: flock %s %s %s returns %s", "%s %s %s"),
++		    fhp->name, mode_string[lockmode],
++		    nowait ? "nowait" : "", db_strerror(ret));
+ 
+ 	if (ret == 0)
+ 		return (0);
+@@ -53,12 +110,29 @@ __os_fdlock(env, fhp, offset, acquire, n
+ 		__db_syserr(env, ret, DB_STR("0139", "fcntl"));
+ 	return (t_ret);
+ #else
++	ret = __os_filelocking_notsup(env);
+ 	COMPQUIET(fhp, NULL);
+-	COMPQUIET(acquire, 0);
++	COMPQUIET(lockmode, 0);
+ 	COMPQUIET(nowait, 0);
+ 	COMPQUIET(offset, 0);
++	return (ret)
++#endif
++}
++
++
++#if !defined(HAVE_FCNTL) || !defined(HAVE_FLOCK)
++/*
++ * __os_filelocking_notsup --
++ *	Generate an error message if fcntl() or flock() is requested on a
++ *	platform that does not support it.
++ *
++ */
++static int
++__os_filelocking_notsup(env)
++ 	ENV *env;
++{
+ 	__db_syserr(env, DB_OPNOTSUP, DB_STR("0140",
+ 	    "advisory file locking unavailable"));
+ 	return (DB_OPNOTSUP);
+-#endif
+ }
++#endif
+diff -up db-5.3.28/src/os/os_map.c.pthreads db-5.3.28/src/os/os_map.c
+--- db-5.3.28/src/os/os_map.c.pthreads	2013-09-09 17:35:09.000000000 +0200
++++ 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 --
+- *	Create/join a shared memory region.
++ *	Create/join a 'shared' region of Berkeley DB memory.
+  *
+  * PUBLIC: int __os_attach __P((ENV *, REGINFO *, REGION *));
+  */
+@@ -50,6 +50,7 @@ __os_attach(env, infop, rp)
+ 	 * so there must be a valid handle.
+ 	 */
+ 	DB_ASSERT(env, env != NULL && env->dbenv != NULL);
++	DB_ASSERT(env, infop->fhp == NULL);
+ 	dbenv = env->dbenv;
+ 
+ 	if (DB_GLOBAL(j_region_map) != NULL) {
diff --git a/SOURCES/db-5.3.28-cwd-db_config.patch b/SOURCES/db-5.3.28-cwd-db_config.patch
new file mode 100644
index 0000000..652e962
--- /dev/null
+++ b/SOURCES/db-5.3.28-cwd-db_config.patch
@@ -0,0 +1,11 @@
+--- db-5.3.28/src/env/env_open.c.old	2017-06-26 10:32:11.011419981 +0200
++++ db-5.3.28/src/env/env_open.c	2017-06-26 10:32:46.893721233 +0200
+@@ -473,7 +473,7 @@
+ 	env->db_mode = mode == 0 ? DB_MODE_660 : mode;
+ 
+ 	/* Read the DB_CONFIG file. */
+-	if ((ret = __env_read_db_config(env)) != 0)
++	if (env->db_home != NULL && (ret = __env_read_db_config(env)) != 0)
+ 		return (ret);
+ 
+ 	/*
diff --git a/SOURCES/db-5.3.28-lemon_hash.patch b/SOURCES/db-5.3.28-lemon_hash.patch
new file mode 100644
index 0000000..1556d5d
--- /dev/null
+++ b/SOURCES/db-5.3.28-lemon_hash.patch
@@ -0,0 +1,20 @@
+--- db-5.3.28/lang/sql/sqlite/tool/lemon.c.lemon_hash	2013-09-09 17:35:07.000000000 +0200
++++ db-5.3.28/lang/sql/sqlite/tool/lemon.c	2017-02-22 13:12:08.564106051 +0100
+@@ -3428,7 +3428,7 @@
+   int maxdtlength;          /* Maximum length of any ".datatype" field. */
+   char *stddt;              /* Standardized name for a datatype */
+   int i,j;                  /* Loop counters */
+-  int hash;                 /* For hashing the name of a type */
++  unsigned hash;            /* For hashing the name of a type */
+   const char *name;         /* Name of the parser */
+ 
+   /* Allocate and initialize types[] and allocate stddt[] */
+@@ -3491,7 +3491,7 @@
+         break;
+       }
+       hash++;
+-      if( hash>=arraysize ) hash = 0;
++      if( hash>=(unsigned)arraysize ) hash = 0;
+     }
+     if( types[hash]==0 ){
+       sp->dtnum = hash + 1;
diff --git a/SOURCES/db-5.3.28-openssl.patch b/SOURCES/db-5.3.28-openssl.patch
new file mode 100644
index 0000000..782b37c
--- /dev/null
+++ b/SOURCES/db-5.3.28-openssl.patch
@@ -0,0 +1,207 @@
+diff -up db-5.3.28/dist/aclocal/options.m4.openssl db-5.3.28/dist/aclocal/options.m4
+--- db-5.3.28/dist/aclocal/options.m4.openssl	2013-09-09 17:35:02.000000000 +0200
++++ db-5.3.28/dist/aclocal/options.m4	2018-10-22 11:02:08.037182417 +0200
+@@ -406,7 +406,7 @@ AC_ARG_WITH([cryptography],
+ 	AC_HELP_STRING([--with-cryptography=yes|no|ipp], [Build database cryptography support @<:@default=yes@:>@.]),
+ 	[], [with_cryptography=$enable_cryptography])
+ case "$with_cryptography" in
+-yes|no|ipp) ;;
++yes|no|ipp|openssl) ;;
+ *) AC_MSG_ERROR([unknown --with-cryptography argument \'$with_cryptography\']) ;;
+ esac
+ db_cv_build_cryptography="$with_cryptography"
+diff -up db-5.3.28/dist/configure.ac.openssl db-5.3.28/dist/configure.ac
+--- db-5.3.28/dist/configure.ac.openssl	2018-10-22 11:02:08.019182151 +0200
++++ db-5.3.28/dist/configure.ac	2018-10-22 14:40:52.467991248 +0200
+@@ -994,6 +994,18 @@ in the configured include path.]))
+ 		AC_DEFINE(HAVE_CRYPTO_IPP)
+ 		AH_TEMPLATE(HAVE_CRYPTO_IPP,
+ 		    [Define to 1 if using Intel IPP for cryptography.])
++    else
++        if test "$db_cv_build_cryptography" = "openssl"; then
++            AC_CHECK_HEADERS(openssl/conf.h openssl/evp.h, [], AC_MSG_ERROR([\
++Openssl header files required for OPENSSL cryptography support were not found \
++in the configured include path.]))
++            AC_DEFINE(HAVE_CRYPTO_OPENSSL)
++            AC_CHECK_LIB(crypto, EVP_CIPHER_CTX_new,
++                [LDFLAGS="-lcrypto $LDFLAGS"], AC_MSG_ERROR([\
++Libcrypto was not found in the configured library path.]))
++            AH_TEMPLATE(HAVE_CRYPTO_OPENSSL,
++                [Define to 1 if using OpenSSL for cryptography.])
++        fi
+ 	fi
+ else
+ 	CRYPTO_OBJS="crypto_stub${o}"
+diff -up db-5.3.28/dist/Makefile.in.openssl db-5.3.28/dist/Makefile.in
+--- db-5.3.28/dist/Makefile.in.openssl	2018-10-22 11:02:07.997181825 +0200
++++ db-5.3.28/dist/Makefile.in	2018-10-22 11:30:39.442854972 +0200
+@@ -305,9 +305,10 @@ CXX_OBJS=\
+ 	cxx_except@o@ cxx_lock@o@ cxx_logc@o@ cxx_mpool@o@ cxx_multi@o@ \
+ 	cxx_rid@o@ cxx_seq@o@ cxx_site@o@ cxx_txn@o@
+ 
++CRYPTO_OBJS_RIJNDAEL=\
++	rijndael-alg-fst@o@ rijndael-api-fst@o@
+ CRYPTO_OBJS=\
+-	aes_method@o@ crypto@o@ mt19937db@o@ rijndael-alg-fst@o@ \
+-	rijndael-api-fst@o@
++	aes_method@o@ crypto@o@ mt19937db@o@
+ 
+ JAVA_OBJS=\
+ 	db_java_wrap@o@
+diff -up db-5.3.28/src/crypto/aes_method.c.openssl db-5.3.28/src/crypto/aes_method.c
+--- db-5.3.28/src/crypto/aes_method.c.openssl	2013-09-09 17:35:07.000000000 +0200
++++ db-5.3.28/src/crypto/aes_method.c	2018-10-22 17:54:53.439276678 +0200
+@@ -17,6 +17,10 @@
+ 
+ #ifdef HAVE_CRYPTO_IPP
+ #include <ippcp.h>
++#elif defined(HAVE_CRYPTO_OPENSSL)
++#define OPENSSL_AES_ERROR -101
++#include <openssl/conf.h>
++#include <openssl/evp.h>
+ #endif
+ 
+ static void __aes_err __P((ENV *, int));
+@@ -119,11 +123,13 @@ __aes_decrypt(env, aes_data, iv, cipher,
+ 	AES_CIPHER *aes;
+ #ifdef	HAVE_CRYPTO_IPP
+ 	IppStatus ipp_ret;
++#elif defined(HAVE_CRYPTO_OPENSSL)
++   EVP_CIPHER_CTX *ctx;
++   int temp_len;
+ #else
+ 	cipherInstance c;
+-#endif
+ 	int ret;
+-
++#endif
+ 	aes = (AES_CIPHER *)aes_data;
+ 	if (iv == NULL || cipher == NULL)
+ 		return (EINVAL);
+@@ -137,6 +143,32 @@ __aes_decrypt(env, aes_data, iv, cipher,
+ 		__aes_err(env, (int)ipp_ret);
+ 		return (EAGAIN);
+ 	}
++#elif defined(HAVE_CRYPTO_OPENSSL)
++    if(!(ctx = EVP_CIPHER_CTX_new())) {
++		__aes_err(env, OPENSSL_AES_ERROR);
++        return (EAGAIN);
++    }
++    if(1 != EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, aes->key,
++        (unsigned char*)iv)) {
++		__aes_err(env, OPENSSL_AES_ERROR);
++        return (EAGAIN);
++    }
++
++    EVP_CIPHER_CTX_set_padding(ctx, 0);
++
++    if(1 != EVP_DecryptUpdate(ctx, (unsigned char*)cipher, &temp_len,
++        (unsigned char*)cipher, cipher_len)) {
++		__aes_err(env, OPENSSL_AES_ERROR);
++        return (EAGAIN);
++    }
++    cipher_len = temp_len;
++    if(1 != EVP_DecryptFinal_ex(ctx, ((unsigned char*)cipher) + temp_len,
++        &temp_len)) {
++		__aes_err(env, OPENSSL_AES_ERROR);
++        return (EAGAIN);
++    }
++    cipher_len += temp_len;
++    EVP_CIPHER_CTX_free(ctx);
+ #else
+ 	/*
+ 	 * Initialize the cipher
+@@ -174,6 +206,9 @@ __aes_encrypt(env, aes_data, iv, data, d
+ 	AES_CIPHER *aes;
+ #ifdef	HAVE_CRYPTO_IPP
+ 	IppStatus ipp_ret;
++#elif defined(HAVE_CRYPTO_OPENSSL)
++   EVP_CIPHER_CTX *ctx;
++   int temp_len;
+ #else
+ 	cipherInstance c;
+ #endif
+@@ -204,6 +239,32 @@ __aes_encrypt(env, aes_data, iv, data, d
+ 		__aes_err(env, (int)ipp_ret);
+ 		return (EAGAIN);
+ 	}
++#elif defined(HAVE_CRYPTO_OPENSSL)
++    if(!(ctx = EVP_CIPHER_CTX_new())) {
++		__aes_err(env, OPENSSL_AES_ERROR);
++        return (EAGAIN);
++    }
++    if(1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, aes->key,
++        (unsigned char*)tmp_iv)) {
++		__aes_err(env, OPENSSL_AES_ERROR);
++        return (EAGAIN);
++    }
++
++    EVP_CIPHER_CTX_set_padding(ctx, 0);
++
++    if(1 != EVP_EncryptUpdate(ctx, (unsigned char*)data, &temp_len,
++        (unsigned char*)data, data_len)) {
++		__aes_err(env, OPENSSL_AES_ERROR);
++        return (EAGAIN);
++    }
++    data_len = temp_len;
++    if(1 != EVP_EncryptFinal_ex(ctx, ((unsigned char*)data) + temp_len,
++        &temp_len)) {
++		__aes_err(env, OPENSSL_AES_ERROR);
++        return (EAGAIN);
++    }
++    data_len += temp_len;
++    EVP_CIPHER_CTX_free(ctx);
+ #else
+ 	/*
+ 	 * Initialize the cipher
+@@ -254,7 +315,7 @@ __aes_derivekeys(env, db_cipher, passwd,
+ 	SHA1_CTX ctx;
+ #ifdef	HAVE_CRYPTO_IPP
+ 	IppStatus ipp_ret;
+-#else
++#elif !defined(HAVE_CRYPTO_OPENSSL)
+ 	int ret;
+ #endif
+ 	u_int32_t temp[DB_MAC_KEY/4];
+@@ -278,6 +339,8 @@ __aes_derivekeys(env, db_cipher, passwd,
+ 		__aes_err(env, (int)ipp_ret);
+ 		return (EAGAIN);
+ 	}
++#elif defined(HAVE_CRYPTO_OPENSSL)
++    memcpy(aes->key, (unsigned char*) temp, DB_AES_CHUNK);
+ #else
+ 	if ((ret = __db_makeKey(&aes->encrypt_ki, DIR_ENCRYPT,
+ 	    DB_AES_KEYLEN, (char *)temp)) != TRUE) {
+@@ -320,6 +383,10 @@ __aes_err(env, err)
+ 	case ippStsUnderRunErr:
+ 		errstr = DB_STR("0185", "IPP AES srclen size error");
+ 		break;
++#elif defined(HAVE_CRYPTO_OPENSSL)
++	case OPENSSL_AES_ERROR:
++		errstr = DB_STR("0193", "AES unknown error");
++		break;
+ #else
+ 	case BAD_KEY_DIR:
+ 		errstr = DB_STR("0186", "AES key direction is invalid");
+diff -up db-5.3.28/src/dbinc/crypto.h.openssl db-5.3.28/src/dbinc/crypto.h
+--- db-5.3.28/src/dbinc/crypto.h.openssl	2013-09-09 17:35:08.000000000 +0200
++++ db-5.3.28/src/dbinc/crypto.h	2018-10-22 11:02:08.038182432 +0200
+@@ -59,7 +60,9 @@ struct __db_cipher {
+ 
+ #ifdef HAVE_CRYPTO
+ 
++#ifndef HAVE_CRYPTO_OPENSSL
+ #include "crypto/rijndael/rijndael-api-fst.h"
++#endif
+ 
+ /*
+  * Shared ciphering structure
+@@ -77,6 +80,8 @@ typedef struct __cipher {
+ typedef struct __aes_cipher {
+ #ifdef	HAVE_CRYPTO_IPP
+ 	void		*ipp_ctx;	/* IPP key instance */
++#elif defined(HAVE_CRYPTO_OPENSSL)
++    unsigned char key[DB_AES_CHUNK];
+ #else
+ 	keyInstance	decrypt_ki;	/* Decryption key instance */
+ 	keyInstance	encrypt_ki;	/* Encryption key instance */
diff --git a/SOURCES/db-5.3.28-rpm-lock-check.patch b/SOURCES/db-5.3.28-rpm-lock-check.patch
new file mode 100644
index 0000000..2a27898
--- /dev/null
+++ b/SOURCES/db-5.3.28-rpm-lock-check.patch
@@ -0,0 +1,99 @@
+diff -up db-5.3.28/src/dbinc_auto/int_def.in.rpmlock db-5.3.28/src/dbinc_auto/int_def.in
+--- db-5.3.28/src/dbinc_auto/int_def.in.rpmlock	2017-06-26 15:09:17.883356255 +0200
++++ db-5.3.28/src/dbinc_auto/int_def.in	2017-06-26 15:09:27.421170401 +0200
+@@ -1573,6 +1573,7 @@
+ #define	__os_posix_err __os_posix_err@DB_VERSION_UNIQUE_NAME@
+ #define	__os_fileid __os_fileid@DB_VERSION_UNIQUE_NAME@
+ #define	__check_lock_fn __check_lock_fn@DB_VERSION_UNIQUE_NAME@
++#define	__rpm_lock_free __rpm_lock_free@DB_VERSION_UNIQUE_NAME@
+ #define	__os_fdlock __os_fdlock@DB_VERSION_UNIQUE_NAME@
+ #define	__os_fsync __os_fsync@DB_VERSION_UNIQUE_NAME@
+ #define	__os_getenv __os_getenv@DB_VERSION_UNIQUE_NAME@
+diff -up db-5.3.28/src/dbinc_auto/os_ext.h.rpmlock db-5.3.28/src/dbinc_auto/os_ext.h
+--- db-5.3.28/src/dbinc_auto/os_ext.h.rpmlock	2017-06-26 15:09:21.940277203 +0200
++++ db-5.3.28/src/dbinc_auto/os_ext.h	2017-06-26 15:09:27.354171707 +0200
+@@ -42,6 +42,7 @@ char *__os_strerror __P((int, char *, si
+ int __os_posix_err __P((int));
+ int __os_fileid __P((ENV *, const char *, int, u_int8_t *));
+ int __check_lock_fn __P((char *, pid_t));
++int __rpm_lock_free __P((ENV *));
+ 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));
+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-26 15:09:12.479461558 +0200
++++ db-5.3.28/src/env/env_region.c	2017-06-26 15:09:12.481461519 +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-26 15:09:12.480461538 +0200
++++ db-5.3.28/src/os/os_flock.c	2017-06-26 15:09:12.481461519 +0200
+@@ -79,6 +79,35 @@ 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.
++ * PUBLIC: int __rpm_lock_free __P((ENV *));
++ */
++
++#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.
+  *
diff --git a/SOURCES/java8-fix.patch b/SOURCES/java8-fix.patch
new file mode 100644
index 0000000..58e933d
--- /dev/null
+++ b/SOURCES/java8-fix.patch
@@ -0,0 +1,23 @@
+diff -up db-5.3.28/lang/java/src/com/sleepycat/asm/ClassReader.java.fix db-5.3.28/lang/java/src/com/sleepycat/asm/ClassReader.java
+--- db-5.3.28/lang/java/src/com/sleepycat/asm/ClassReader.java.fix	2013-09-09 17:35:04.000000000 +0200
++++ db-5.3.28/lang/java/src/com/sleepycat/asm/ClassReader.java	2014-07-14 11:51:27.584432754 +0200
+@@ -163,7 +163,7 @@ public class ClassReader {
+     public ClassReader(final byte[] b, final int off, final int len) {
+         this.b = b;
+         // checks the class version
+-        if (readShort(6) > Opcodes.V1_7) {
++        if (readShort(6) > Opcodes.V1_8) {
+             throw new IllegalArgumentException();
+         }
+         // parses the constant pool
+diff -up db-5.3.28/lang/java/src/com/sleepycat/asm/Opcodes.java.fix db-5.3.28/lang/java/src/com/sleepycat/asm/Opcodes.java
+--- db-5.3.28/lang/java/src/com/sleepycat/asm/Opcodes.java.fix	2014-07-14 11:50:50.432336160 +0200
++++ db-5.3.28/lang/java/src/com/sleepycat/asm/Opcodes.java	2014-07-14 11:51:36.781456666 +0200
+@@ -56,6 +56,7 @@ public interface Opcodes {
+     int V1_5 = 0 << 16 | 49;
+     int V1_6 = 0 << 16 | 50;
+     int V1_7 = 0 << 16 | 51;
++    int V1_8 = 0 << 16 | 52;
+
+     // access flags
+
diff --git a/SOURCES/lgpl-2.1.txt b/SOURCES/lgpl-2.1.txt
new file mode 100644
index 0000000..4362b49
--- /dev/null
+++ b/SOURCES/lgpl-2.1.txt
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/SOURCES/libdb-5.3.21-region-size-check.patch b/SOURCES/libdb-5.3.21-region-size-check.patch
new file mode 100644
index 0000000..77be25e
--- /dev/null
+++ b/SOURCES/libdb-5.3.21-region-size-check.patch
@@ -0,0 +1,39 @@
+diff -up db-5.3.21/src/env/env_region.c.zero-region db-5.3.21/src/env/env_region.c
+--- db-5.3.21/src/env/env_region.c.zero-region	2012-05-11 19:57:53.000000000 +0200
++++ db-5.3.21/src/env/env_region.c	2017-09-06 08:50:45.310276385 +0200
+@@ -1060,6 +1060,7 @@ __env_region_attach(env, infop, init, ma
+ 	REGION *rp;
+ 	int ret;
+ 	char buf[sizeof(DB_REGION_FMT) + 20];
++	struct stat st;
+ 
+ 	/*
+ 	 * Find or create a REGION structure for this region.  If we create
+@@ -1090,6 +1091,14 @@ __env_region_attach(env, infop, init, ma
+ 	if ((ret = __env_sys_attach(env, infop, rp)) != 0)
+ 		goto err;
+ 
++        /* Check the size of the underlying file */
++        if (infop->fhp != NULL && F_ISSET(infop->fhp, DB_FH_OPENED) &&
++            infop->fhp->fd != -1 && fstat(infop->fhp->fd, &st) != -1 &&
++            st.st_size == 0) {
++            ret = DB_RUNRECOVERY;
++            goto err;
++        }
++
+ 	/*
+ 	 * Fault the pages into memory.  Note, do this BEFORE we initialize
+ 	 * anything because we're writing pages in created regions, not just
+diff -up db-5.3.21/src/os/os_map.c.zero-region db-5.3.21/src/os/os_map.c
+--- db-5.3.21/src/os/os_map.c.zero-region	2012-05-11 19:57:54.000000000 +0200
++++ db-5.3.21/src/os/os_map.c	2017-09-06 08:49:39.144546552 +0200
+@@ -265,6 +265,9 @@ __os_detach(env, infop, destroy)
+ 	dbenv = env->dbenv;
+ 
+ 	rp = infop->rp;
++	/* Do not touch the region information if it no longer exists */
++	if (rp == NULL)
++	    return EINVAL;
+ 
+ 	/* If the user replaced the unmap call, call through their interface. */
+ 	if (DB_GLOBAL(j_region_unmap) != NULL)
diff --git a/SOURCES/libdb-cbd-race.patch b/SOURCES/libdb-cbd-race.patch
new file mode 100644
index 0000000..ad56d06
--- /dev/null
+++ b/SOURCES/libdb-cbd-race.patch
@@ -0,0 +1,110 @@
+From 4ae2eb88fadc256ddf9862b2e72ed216ddbb919d Mon Sep 17 00:00:00 2001
+From: michael brey <michael.brey@oracle.com>
+Date: Tue, 20 May 2014 14:49:44 +0200
+Subject: [PATCH] Fix a CDB race
+
+Report and reproducer here:
+https://community.oracle.com/thread/3514381
+
+From: michael brey <michael.brey@oracle.com>
+To: Lubomir Rintel <lkundrak@v3.sk>
+Subject: Re: BDB crash
+Date: Tue, 13 May 2014 09:07:45 -0600 (05/13/2014 05:07:45 PM)
+Message-id: <53723541.7040203@oracle.com>
+
+  attached are patches for each release.  the 5.3.28 patch will apply on
+top of 5.3.21.
+
+thanks
+mike
+
+RHBZ: #1099509
+---
+ src/env/env_failchk.c | 24 ++++++++++++++++++++++++
+ src/mutex/mut_tas.c   | 18 +++++++++++++++++-
+ 2 files changed, 41 insertions(+), 1 deletion(-)
+
+diff --git a/src/env/env_failchk.c b/src/env/env_failchk.c
+index 05752f0..b09df96 100644
+--- a/src/env/env_failchk.c
++++ b/src/env/env_failchk.c
+@@ -312,6 +312,7 @@ __env_in_api(env)
+ 	REGINFO *infop;
+ 	THREAD_INFO *thread;
+ 	u_int32_t i;
++	pid_t pid;
+ 	int unpin, ret;
+ 
+ 	if ((htab = env->thr_hashtab) == NULL)
+@@ -325,6 +326,7 @@ __env_in_api(env)
+ 
+ 	for (i = 0; i < env->thr_nbucket; i++)
+ 		SH_TAILQ_FOREACH(ip, &htab[i], dbth_links, __db_thread_info) {
++			pid = ip->dbth_pid;
+ 			if (ip->dbth_state == THREAD_SLOT_NOT_IN_USE ||
+ 			    (ip->dbth_state == THREAD_OUT &&
+ 			    thread->thr_count <  thread->thr_max))
+@@ -341,6 +343,28 @@ __env_in_api(env)
+ 				ip->dbth_state = THREAD_SLOT_NOT_IN_USE;
+ 				continue;
+ 			}
++			/*
++			 * The above tests are not atomic, so it is possible that
++			 * the process pointed by ip has changed during the tests.
++			 * In particular, if the process pointed by ip when is_alive
++			 * was executed terminated normally, a new process may reuse
++			 * the same ip structure and change its dbth_state before the
++			 * next two tests were performed. Therefore, we need to test
++			 * here that all four tests above are done on the same process.
++			 * If the process pointed by ip changed, all tests are invalid
++			 * and can be ignored.
++			 * Similarly, it's also possible for two processes racing to
++			 * change the dbth_state of the same ip structure. For example,
++			 * both process A and B reach the above test for the same
++			 * terminated process C where C's dbth_state is THREAD_OUT.
++			 * If A goes into the 'if' block and changes C's dbth_state to
++			 * THREAD_SLOT_NOT_IN_USE before B checks the condition, B
++			 * would incorrectly fail the test and run into this line.
++			 * Therefore, we need to check C's dbth_state again and fail
++			 * the db only if C's dbth_state is indeed THREAD_ACTIVE.
++			 */
++			if (ip->dbth_state != THREAD_ACTIVE || ip->dbth_pid != pid)
++				continue;
+ 			return (__db_failed(env, DB_STR("1507",
+ 			    "Thread died in Berkeley DB library"),
+ 			    ip->dbth_pid, ip->dbth_tid));
+diff --git a/src/mutex/mut_tas.c b/src/mutex/mut_tas.c
+index 0899d23..db95030 100644
+--- a/src/mutex/mut_tas.c
++++ b/src/mutex/mut_tas.c
+@@ -151,10 +151,26 @@ loop:	/* Attempt to acquire the resource for N spins. */
+ 			if (F_ISSET(dbenv, DB_ENV_FAILCHK) &&
+ 			    ip == NULL && dbenv->is_alive(dbenv,
+ 			    mutexp->pid, mutexp->tid, 0) == 0) {
++				/*
++				 * The process owing the mutex is "dead" now, but it may
++				 * have already released the mutex. We need to check again
++				 * by going back to the top of the loop
++				 * if the mutex is still held by the "dead" process. We
++				 * yield 10 us to increase the likelyhood of mutexp fields
++				 * being up-to-date. Set spin so we spin one more time
++				 * because no need to spin more if dead process owns mutex.
++				 */                               
++				if (nspins > 1) {
++					nspins = 2;
++					__os_yield(env, 0, 10);
++					continue;
++				}
+ 				ret = __env_set_state(env, &ip, THREAD_VERIFY);
+ 				if (ret != 0 ||
+-				    ip->dbth_state == THREAD_FAILCHK)
++				    ip->dbth_state == THREAD_FAILCHK) {
++					printf("mut_tas:172, pid: %d, flag: %d\n", mutexp->pid, mutexp->flags);
+ 					return (DB_RUNRECOVERY);
++				}
+ 			}
+ 			if (nowait)
+ 				return (DB_LOCK_NOTGRANTED);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/libdb-limit-cpu.patch b/SOURCES/libdb-limit-cpu.patch
new file mode 100644
index 0000000..475aa50
--- /dev/null
+++ b/SOURCES/libdb-limit-cpu.patch
@@ -0,0 +1,12 @@
+diff -Naurp db_old/src/os/os_cpu.c db_new/src/os/os_cpu.c
+--- db_old/src/os/os_cpu.c	2012-05-11 12:57:54.000000000 -0500
++++ db_new/src/os/os_cpu.c	2015-08-12 14:00:37.232498880 -0500
+@@ -40,6 +40,8 @@ __os_cpu_count()
+ 	long nproc;
+ 
+ 	nproc = sysconf(_SC_NPROCESSORS_ONLN);
++	if (nproc > 1024)
++		nproc = 1024;
+ 	return ((u_int32_t)(nproc > 1 ? nproc : 1));
+ #else
+ 	return (1);
diff --git a/SOURCES/libdb-multiarch.patch b/SOURCES/libdb-multiarch.patch
new file mode 100644
index 0000000..f0e6ff6
--- /dev/null
+++ b/SOURCES/libdb-multiarch.patch
@@ -0,0 +1,12 @@
+diff -up db-5.3.15/dist/aclocal/sequence.m4.multiarch db-5.3.15/dist/aclocal/sequence.m4
+--- db-5.3.15/dist/aclocal/sequence.m4.multiarch	2010-06-25 17:50:36.000000000 +0200
++++ db-5.3.15/dist/aclocal/sequence.m4	2011-12-20 02:00:49.000000000 +0100
+@@ -78,7 +78,7 @@ AC_DEFUN(AM_SEQUENCE_CONFIGURE, [
+ 	fi
+ 	if test "$db_cv_build_sequence" = "yes"; then
+ 		AC_SUBST(db_seq_decl)
+-		db_seq_decl="typedef $db_cv_seq_type db_seq_t;";
++		db_seq_decl="typedef int64_t db_seq_t;";
+ 
+ 		AC_DEFINE(HAVE_64BIT_TYPES)
+ 		AH_TEMPLATE(HAVE_64BIT_TYPES,
diff --git a/SOURCES/patch.1.1 b/SOURCES/patch.1.1
new file mode 100644
index 0000000..fe3177d
--- /dev/null
+++ b/SOURCES/patch.1.1
@@ -0,0 +1,20 @@
+*** Makefile.orig	Wed Jul 13 21:43:16 1994
+--- Makefile	Wed Dec 31 19:00:00 1969
+***************
+*** 15,22 ****
+  
+  ${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC}
+  	rm -f $@
+! 	ar cq $@ \
+! 	    `lorder ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC} | tsort`
+  	ranlib $@
+  
+  clean:
+--- 15,21 ----
+  
+  ${LIBDB}: ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC}
+  	rm -f $@
+! 	ar cq $@ ${OBJ1} ${OBJ2} ${OBJ3} ${OBJ4} ${OBJ5} ${MISC}
+  	ranlib $@
+  
+  clean:
diff --git a/SOURCES/patch.1.2 b/SOURCES/patch.1.2
new file mode 100644
index 0000000..a343909
--- /dev/null
+++ b/SOURCES/patch.1.2
@@ -0,0 +1,19 @@
+*** btree/bt_split.c	Tue Jul 26 14:22:02 1994
+--- btree/bt_split.c	Sat Jan  4 14:38:55 1997
+***************
+*** 673,679 ****
+  		 * where we decide to try and copy too much onto the left page.
+  		 * Make sure that doesn't happen.
+  		 */
+! 		if (skip <= off && used + nbytes >= full) {
+  			--off;
+  			break;
+  		}
+--- 673,679 ----
+  		 * where we decide to try and copy too much onto the left page.
+  		 * Make sure that doesn't happen.
+  		 */
+! 		if (skip <= off && used + nbytes >= full || nxt == top - 1) {
+  			--off;
+  			break;
+  		}
diff --git a/SOURCES/patch.1.3 b/SOURCES/patch.1.3
new file mode 100644
index 0000000..5ca03df
--- /dev/null
+++ b/SOURCES/patch.1.3
@@ -0,0 +1,37 @@
+*** btree/bt_split.c.orig	Sat Feb  8 10:14:10 1997
+--- btree/bt_split.c	Sat Feb  8 10:14:51 1997
+***************
+*** 673,679 ****
+  		 * where we decide to try and copy too much onto the left page.
+  		 * Make sure that doesn't happen.
+  		 */
+! 		if (skip <= off && used + nbytes >= full || nxt == top - 1) {
+  			--off;
+  			break;
+  		}
+--- 673,680 ----
+  		 * where we decide to try and copy too much onto the left page.
+  		 * Make sure that doesn't happen.
+  		 */
+! 		if (skip <= off &&
+! 		    used + nbytes + sizeof(indx_t) >= full || nxt == top - 1) {
+  			--off;
+  			break;
+  		}
+***************
+*** 686,692 ****
+  			memmove((char *)l + l->upper, src, nbytes);
+  		}
+  
+! 		used += nbytes;
+  		if (used >= half) {
+  			if (!isbigkey || bigkeycnt == 3)
+  				break;
+--- 687,693 ----
+  			memmove((char *)l + l->upper, src, nbytes);
+  		}
+  
+! 		used += nbytes + sizeof(indx_t);
+  		if (used >= half) {
+  			if (!isbigkey || bigkeycnt == 3)
+  				break;
diff --git a/SOURCES/patch.1.4 b/SOURCES/patch.1.4
new file mode 100644
index 0000000..cec5fbc
--- /dev/null
+++ b/SOURCES/patch.1.4
@@ -0,0 +1,22 @@
+*** btree/bt_page.c.orig	Wed Jul 13 21:29:02 1994
+--- btree/bt_page.c	Wed Jun 11 20:14:43 1997
+***************
+*** 65,70 ****
+--- 65,71 ----
+  	h->prevpg = P_INVALID;
+  	h->nextpg = t->bt_free;
+  	t->bt_free = h->pgno;
++ 	F_SET(t, B_METADIRTY);
+  
+  	/* Make sure the page gets written back. */
+  	return (mpool_put(t->bt_mp, h, MPOOL_DIRTY));
+***************
+*** 92,97 ****
+--- 93,99 ----
+  	    (h = mpool_get(t->bt_mp, t->bt_free, 0)) != NULL) {
+  		*npg = t->bt_free;
+  		t->bt_free = h->nextpg;
++ 		F_SET(t, B_METADIRTY);
+  		return (h);
+  	}
+  	return (mpool_new(t->bt_mp, npg));
diff --git a/SPECS/libdb.spec b/SPECS/libdb.spec
new file mode 100644
index 0000000..f2e4e72
--- /dev/null
+++ b/SPECS/libdb.spec
@@ -0,0 +1,715 @@
+%define __soversion_major 5
+%define __soversion %{__soversion_major}.3
+
+Summary: The Berkeley DB database library for C
+Name: libdb
+Version: 5.3.28
+Release: 36%{?dist}
+Source0: http://download.oracle.com/berkeley-db/db-%{version}.tar.gz
+Source1: http://download.oracle.com/berkeley-db/db.1.85.tar.gz
+# For mt19937db.c
+Source2: http://www.gnu.org/licenses/lgpl-2.1.txt
+# libdb man pages generated from the 5.3.28 documentation
+Source3: libdb-5.3.28-manpages.tar.gz
+Patch0: libdb-multiarch.patch
+# db-1.85 upstream patches
+Patch10: http://www.oracle.com/technology/products/berkeley-db/db/update/1.85/patch.1.1
+Patch11: http://www.oracle.com/technology/products/berkeley-db/db/update/1.85/patch.1.2
+Patch12: http://www.oracle.com/technology/products/berkeley-db/db/update/1.85/patch.1.3
+Patch13: http://www.oracle.com/technology/products/berkeley-db/db/update/1.85/patch.1.4
+# other patches
+Patch20: db-1.85-errno.patch
+Patch22: db-4.6.21-1.85-compat.patch
+Patch24: db-4.5.20-jni-include-dir.patch
+# License clarification patch
+# http://devel.trisquel.info/gitweb/?p=package-helpers.git;a=blob;f=helpers/DATA/db4.8/007-mt19937db.c_license.patch;h=1036db4d337ce4c60984380b89afcaa63b2ef88f;hb=df48d40d3544088338759e8bea2e7f832a564d48
+Patch25: 007-mt19937db.c_license.patch
+#Adds missing constant to Optcodes.java and changes ClassReader.java to use it. This makes package to build with Java 8. 
+Patch26: java8-fix.patch
+# memp_stat fix provided by upstream (rhbz#1211871)
+Patch27: db-5.3.21-memp_stat-upstream-fix.patch
+# fix for mutexes not being released provided by upstream (rhbz#1277887)
+Patch28: db-5.3.21-mutex_leak.patch
+# fix for overflowing hash variable inside bundled lemon
+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
+# additional changes to the upstream patch to address rhbz#1460003
+Patch31: db-5.3.28-condition-variable-ppc.patch
+# downstream patch that adds a check for rpm transaction lock in order to be able to update libdb
+# FIXME: remove when able
+Patch32: db-5.3.28-rpm-lock-check.patch
+# downstream patch to hotfix rhbz#1464033, sent upstream
+Patch33: db-5.3.28-cwd-db_config.patch
+Patch34: libdb-5.3.21-region-size-check.patch
+# Patch sent upstream
+Patch35: checkpoint-opd-deadlock.patch
+Patch36: db-5.3.28-atomic_compare_exchange.patch
+# CDB race (rhbz #1616259)
+Patch37: libdb-cbd-race.patch
+
+# Use AES from openssl
+Patch38: db-5.3.28-openssl.patch
+# Limit concurrency to max 1024 CPUs (rhbz#1245410)
+# A fix for the issue should be in an upstream release already
+# https://community.oracle.com/message/13274780#13274780
+Patch39: libdb-limit-cpu.patch
+
+URL: http://www.oracle.com/database/berkeley-db/
+License: BSD and LGPLv2 and Sleepycat
+Group: System Environment/Libraries
+BuildRequires: perl-interpreter libtool
+BuildRequires: tcl-devel >= 8.5.2-3
+BuildRequires: java-devel >= 1:1.6.0
+BuildRequires: chrpath
+BuildRequires: zlib-devel
+BuildRequires: openssl-devel
+Conflicts: filesystem < 3
+
+%description
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. The Berkeley DB includes B+tree, Extended
+Linear Hashing, Fixed and Variable-length record access methods,
+transactions, locking, logging, shared memory caching, and database
+recovery. The Berkeley DB supports C, C++, Java, and Perl APIs. It is
+used by many applications, including Python and Perl, so this should
+be installed on all systems.
+
+%package utils
+Summary: Command line tools for managing Berkeley DB databases
+Group: Applications/Databases
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description utils
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. Berkeley DB includes B+tree, Extended
+Linear Hashing, Fixed and Variable-length record access methods,
+transactions, locking, logging, shared memory caching, and database
+recovery. DB supports C, C++, Java and Perl APIs.
+
+%package devel
+Summary: C development files for the Berkeley DB library
+Group: Development/Libraries
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description devel
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. This package contains the header files,
+libraries, and documentation for building programs which use the
+Berkeley DB.
+
+%package devel-doc
+Summary: C development documentation files for the Berkeley DB library
+Group: Documentation
+Requires: %{name} = %{version}-%{release}
+Requires: %{name}-devel = %{version}-%{release}
+BuildArch: noarch
+
+%description devel-doc
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. This package contains the header files,
+libraries, and documentation for building programs which use the
+Berkeley DB.
+
+%package devel-static
+Summary: Berkeley DB static libraries
+Group: Development/Libraries
+Requires: %{name}-devel%{?_isa} = %{version}-%{release}
+
+%description devel-static
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. This package contains static libraries
+needed for applications that require static linking of
+Berkeley DB.
+
+%package cxx
+Summary: The Berkeley DB database library for C++
+Group: System Environment/Libraries
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description cxx
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. The Berkeley DB includes B+tree, Extended
+Linear Hashing, Fixed and Variable-length record access methods,
+transactions, locking, logging, shared memory caching, and database
+recovery. The Berkeley DB supports C, C++, Java, and Perl APIs. It is
+used by many applications, including Python and Perl, so this should
+be installed on all systems.
+
+%package cxx-devel
+Summary: The Berkeley DB database library for C++
+Group: System Environment/Libraries
+Requires: %{name}-cxx%{?_isa} = %{version}-%{release}
+Requires: %{name}-devel%{?_isa} = %{version}-%{release}
+
+%description cxx-devel
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. The Berkeley DB includes B+tree, Extended
+Linear Hashing, Fixed and Variable-length record access methods,
+transactions, locking, logging, shared memory caching, and database
+recovery. The Berkeley DB supports C, C++, Java, and Perl APIs. It is
+used by many applications, including Python and Perl, so this should
+be installed on all systems.
+
+%package tcl
+Summary: Development files for using the Berkeley DB with tcl
+Group: Development/Libraries
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description tcl
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. This package contains the libraries
+for building programs which use the Berkeley DB in Tcl.
+
+%package tcl-devel
+Summary: Development files for using the Berkeley DB with tcl
+Group: Development/Libraries
+Requires: %{name}-tcl%{?_isa} = %{version}-%{release}
+
+%description tcl-devel
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. This package contains the libraries
+for building programs which use the Berkeley DB in Tcl.
+
+%package sql
+Summary: Development files for using the Berkeley DB with sql
+Group: Development/Libraries
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description sql
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. This package contains the libraries
+for building programs which use the Berkeley DB in SQL.
+
+%package sql-devel
+Summary: Development files for using the Berkeley DB with sql
+Group: Development/Libraries
+Requires: %{name}-sql%{?_isa} = %{version}-%{release}
+
+%description sql-devel
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. This package contains the libraries
+for building programs which use the Berkeley DB in SQL.
+
+%package java
+Summary: Development files for using the Berkeley DB with Java
+Group: Development/Libraries
+Requires: %{name}%{?_isa} = %{version}-%{release}
+
+%description java
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. This package contains the libraries
+for building programs which use the Berkeley DB in Java.
+
+%package java-devel
+Summary: Development files for using the Berkeley DB with Java
+Group: Development/Libraries
+Requires: %{name}-java%{?_isa} = %{version}-%{release}
+
+%description java-devel
+The Berkeley Database (Berkeley DB) is a programmatic toolkit that
+provides embedded database support for both traditional and
+client/server applications. This package contains the libraries
+for building programs which use the Berkeley DB in Java.
+
+%prep
+%setup -q -n db-%{version} -a 1
+cp %{SOURCE2} .
+tar -xf %{SOURCE3}
+
+%patch0 -p1
+pushd db.1.85/PORT/linux
+%patch10 -p0
+popd
+pushd db.1.85
+%patch11 -p0
+%patch12 -p0
+%patch13 -p0
+%patch20 -p1
+popd
+
+%patch22 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
+%patch33 -p1
+%patch34 -p1
+%patch35 -p1
+%patch36 -p1
+%patch37 -p1
+%patch38 -p1 -b .openssl
+%patch39 -p1
+
+# Delete internal AES implementation
+rm -rf src/crypto/rijndael
+
+cd dist
+./s_include
+./s_config
+cd ..
+
+%build
+CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing"
+CFLAGS="$CFLAGS -DSHAREDSTATEDIR='\"%{_sharedstatedir}\"' -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_DISABLE_DIRSYNC=1 -DSQLITE_ENABLE_FTS3=3 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_ENABLE_UNLOCK_NOTIFY=1 -I../../../lang/sql/sqlite/ext/fts3/"
+export CFLAGS
+
+# building with PIE
+LDFLAGS="$LDFLAGS $RPM_LD_FLAGS"
+export LDFLAGS
+
+# Build the old db-185 libraries.
+make -C db.1.85/PORT/%{_os} OORG="$CFLAGS"
+
+test -d dist/dist-tls || mkdir dist/dist-tls
+# Static link db_dump185 with old db-185 libraries.
+/bin/sh libtool --tag=CC --mode=compile	%{__cc} $RPM_OPT_FLAGS -Idb.1.85/PORT/%{_os}/include -D_REENTRANT -c util/db_dump185.c -o dist/dist-tls/db_dump185.lo
+/bin/sh libtool --tag=CC --mode=link %{__cc} $RPM_LD_FLAGS -o dist/dist-tls/db_dump185 dist/dist-tls/db_dump185.lo db.1.85/PORT/%{_os}/libdb.a
+
+# Update config files to understand aarch64
+for dir in dist lang/sql/sqlite lang/sql/jdbc lang/sql/odbc; do
+  cp /usr/lib/rpm/redhat/config.{guess,sub} "$dir"
+done
+
+pushd dist/dist-tls
+%define _configure ../configure
+%configure -C \
+	--enable-compat185 --enable-dump185 \
+	--enable-shared --enable-static \
+	--enable-tcl --with-tcl=%{_libdir} \
+	--enable-cxx --enable-sql \
+	--enable-java \
+	--enable-test \
+    --with-cryptography=openssl \
+	--disable-rpath \
+  --with-tcl=%{_libdir}/tcl8.6
+
+# Remove libtool predep_objects and postdep_objects wonkiness so that
+# building without -nostdlib doesn't include them twice.  Because we
+# already link with g++, weird stuff happens if you don't let the
+# compiler handle this.
+perl -pi -e 's/^predep_objects=".*$/predep_objects=""/' libtool
+perl -pi -e 's/^postdep_objects=".*$/postdep_objects=""/' libtool
+perl -pi -e 's/-shared -nostdlib/-shared/' libtool
+
+make %{?_smp_mflags}
+
+# XXX hack around libtool not creating ./libs/libdb_java-X.Y.lai
+LDBJ=./.libs/libdb_java-%{__soversion}.la
+if test -f ${LDBJ} -a ! -f ${LDBJ}i; then
+	sed -e 's,^installed=no,installed=yes,' < ${LDBJ} > ${LDBJ}i
+fi
+
+# Run some quick subsystem checks
+echo "source ../../test/tcl/test.tcl; r env; r mut; r memp" | tclsh
+popd
+
+%install
+rm -rf ${RPM_BUILD_ROOT}
+mkdir -p ${RPM_BUILD_ROOT}%{_includedir}
+mkdir -p ${RPM_BUILD_ROOT}%{_libdir}
+mkdir -p ${RPM_BUILD_ROOT}%{_mandir}/man1
+
+%makeinstall STRIP=/bin/true -C dist/dist-tls
+
+# XXX Nuke non-versioned archives and symlinks
+rm -f ${RPM_BUILD_ROOT}%{_libdir}/{libdb.a,libdb_cxx.a,libdb_tcl.a,libdb_sql.a}
+
+chmod +x ${RPM_BUILD_ROOT}%{_libdir}/*.so*
+
+# Move the header files to a subdirectory, in case we're deploying on a
+# system with multiple versions of DB installed.
+mkdir -p ${RPM_BUILD_ROOT}%{_includedir}/%{name}
+mv ${RPM_BUILD_ROOT}%{_includedir}/*.h ${RPM_BUILD_ROOT}%{_includedir}/%{name}/
+
+# Create symlinks to includes so that "use <db.h> and link with -ldb" works.
+for i in db.h db_cxx.h db_185.h; do
+	ln -s %{name}/$i ${RPM_BUILD_ROOT}%{_includedir}
+done
+
+# Move java jar file to the correct place
+mkdir -p ${RPM_BUILD_ROOT}%{_datadir}/java
+mv ${RPM_BUILD_ROOT}%{_libdir}/*.jar ${RPM_BUILD_ROOT}%{_datadir}/java
+
+# Eliminate installed doco
+rm -rf ${RPM_BUILD_ROOT}%{_prefix}/docs
+
+# XXX Avoid Permission denied. strip when building as non-root.
+chmod u+w ${RPM_BUILD_ROOT}%{_bindir} ${RPM_BUILD_ROOT}%{_bindir}/*
+
+# remove unneeded .la files (#225675)
+rm -f ${RPM_BUILD_ROOT}%{_libdir}/*.la
+
+# remove RPATHs
+chrpath -d ${RPM_BUILD_ROOT}%{_libdir}/*.so ${RPM_BUILD_ROOT}%{_bindir}/*
+
+# unify documentation and examples, remove stuff we don't need
+rm -rf docs/csharp
+rm -rf examples/csharp
+rm -rf docs/installation
+mv examples docs
+mv man/* ${RPM_BUILD_ROOT}%{_mandir}/man1
+
+%clean
+rm -rf ${RPM_BUILD_ROOT}
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%post -p /sbin/ldconfig cxx
+
+%postun -p /sbin/ldconfig cxx
+
+%post -p /sbin/ldconfig sql
+
+%postun -p /sbin/ldconfig sql
+
+%post -p /sbin/ldconfig tcl
+
+%postun -p /sbin/ldconfig tcl
+
+%post -p /sbin/ldconfig java
+
+%postun -p /sbin/ldconfig java
+
+%files
+%defattr(-,root,root,-)
+%{!?_licensedir:%global license %%doc}
+%license LICENSE lgpl-2.1.txt
+%doc README
+%{_libdir}/libdb-%{__soversion}.so
+%{_libdir}/libdb-%{__soversion_major}.so
+
+%files devel
+%defattr(-,root,root,-)
+%{_libdir}/libdb.so
+%dir %{_includedir}/%{name}
+%{_includedir}/%{name}/db.h
+%{_includedir}/%{name}/db_185.h
+%{_includedir}/db.h
+%{_includedir}/db_185.h
+
+%files devel-doc
+%defattr(-,root,root,-)
+%doc	docs/*
+
+%files devel-static
+%defattr(-,root,root,-)
+%{_libdir}/libdb-%{__soversion}.a
+%{_libdir}/libdb_cxx-%{__soversion}.a
+%{_libdir}/libdb_tcl-%{__soversion}.a
+%{_libdir}/libdb_sql-%{__soversion}.a
+%{_libdir}/libdb_java-%{__soversion}.a
+
+%files utils
+%defattr(-,root,root,-)
+%{_bindir}/db*_archive
+%{_bindir}/db*_checkpoint
+%{_bindir}/db*_deadlock
+%{_bindir}/db*_dump*
+%{_bindir}/db*_hotbackup
+%{_bindir}/db*_load
+%{_bindir}/db*_printlog
+%{_bindir}/db*_recover
+%{_bindir}/db*_replicate
+%{_bindir}/db*_stat
+%{_bindir}/db*_upgrade
+%{_bindir}/db*_verify
+%{_bindir}/db*_tuner
+%{_mandir}/man1/db_*
+
+%files cxx
+%defattr(-,root,root,-)
+%{_libdir}/libdb_cxx-%{__soversion}.so
+%{_libdir}/libdb_cxx-%{__soversion_major}.so
+
+%files cxx-devel
+%defattr(-,root,root,-)
+%{_includedir}/%{name}/db_cxx.h
+%{_includedir}/db_cxx.h
+%{_libdir}/libdb_cxx.so
+
+%files tcl
+%defattr(-,root,root,-)
+%{_libdir}/libdb_tcl-%{__soversion}.so
+%{_libdir}/libdb_tcl-%{__soversion_major}.so
+
+%files tcl-devel
+%defattr(-,root,root,-)
+%{_libdir}/libdb_tcl.so
+
+%files sql
+%defattr(-,root,root,-)
+%{_libdir}/libdb_sql-%{__soversion}.so
+%{_libdir}/libdb_sql-%{__soversion_major}.so
+
+%files sql-devel
+%defattr(-,root,root,-)
+%{_bindir}/dbsql
+%{_libdir}/libdb_sql.so
+%{_includedir}/%{name}/dbsql.h
+
+%files java
+%defattr(-,root,root,-)
+%{_libdir}/libdb_java-%{__soversion_major}*.so
+%{_datadir}/java/*.jar
+
+%files java-devel
+%defattr(-,root,root,-)
+%{_libdir}/libdb_java.so
+
+%changelog
+* Tue Jan 22 2019 Petr Kubat <pkubat@redhat.com> - 5.3.28-36
+- Add patch to workaround issues on large systems (>1024 CPU)
+  Resolves: #1664031
+
+* Tue Nov 27 2018 Matej Mužila <mmuzila@redhat.com> - 5.3.28-35
+- Use AES from OpenSSL for encryption
+- Resolves: #1618640
+
+* Mon Oct 08 2018 Matej Mužila <mmuzila@redhat.com> - 5.3.28-33
+- Link db_dump185 with RPM_LD_FLAGS (#1624127)
+
+* Wed Sep 05 2018 Petr Kubat <pkubat@redhat.com> - 5.3.28-32
+- Add patch for CDB race issue (#1616259)
+
+* Wed May 23 2018 Petr Kubat <pkubat@redhat.com> - 5.3.28-31
+- Rename __atomic_compare_exchange to not clash with gcc built-in (#1580756)
+
+* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 5.3.28-30
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Tue Oct 31 2017 Petr Kubat <pkubat@redhat.com> 5.3.28-29
+- Fix deadlocks when reading/writing off-page duplicate tree (#1349779)
+
+* Tue Oct 24 2017 Petr Kubat <pkubat@redhat.com> 5.3.28-28
+- Run a number of quick subsystem checks on build
+
+* Thu Sep 07 2017 Petr Kubat <pkubat@redhat.com> 5.3.28-27
+- Fail properly when encountering removed or 0-byte regions (#1471011)
+
+* Thu Aug 03 2017 Fedora Release Engineering <releng@fedoraproject.org> - 5.3.28-26
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Wed Jul 26 2017 Fedora Release Engineering <releng@fedoraproject.org> - 5.3.28-25
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Mon Jun 26 2017 Petr Kubat <pkubat@redhat.com> - 5.3.28-24
+- Fix some defects found by covscan
+
+* Mon Jun 26 2017 Petr Kubat <pkubat@redhat.com> - 5.3.28-23
+- Try looking at env lock via /proc/locks during env_attach (#1460003)
+- Check rpm's transaction lock via /proc/locks
+- Do not access DB_CONFIG when db_home is not set (#1464033)
+
+* 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
+- Drop rhbz#1394862 patches again, DB corruption still being reported
+
+* Thu Jun 01 2017 Petr Kubat <pkubat@redhat.com> - 5.3.28-21
+- Reintroduce upstream patch for rhbz#1394862
+- Do not rebuild rpm's environment during a rpm transaction
+
+* Fri May 26 2017 Adam Williamson <awilliam@redhat.com> - 5.3.28-20
+- Drop rhbz#1394862 patch for now, it has serious issues
+
+* Wed May 24 2017 Petr Kubat <pkubat@redhat.com> - 5.3.28-19
+- Fix some issues present in the upstream patch for rhbz#1394862
+
+* Tue May 23 2017 Adam Williamson <awilliam@redhat.com> - 5.3.28-18
+- Fix issue causing RPM to hang when glibc/libpthread change (#1394862)
+
+* Wed Feb 22 2017 Petr Kubat <pkubat@redhat.com> - 5.3.28-17
+- Fix overflowing integer in bundled-in lemon.c (#1423842)
+
+* Fri Feb 10 2017 Fedora Release Engineering <releng@fedoraproject.org> - 5.3.28-17
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Thu Dec 08 2016 Petr Kubat <pkubat@redhat.com> 5.3.28-16
+- Add man pages for libdb-utils
+
+* Mon Nov 14 2016 Petr Kubat <pkubat@redhat.com> 5.3.28-15
+- Fix mutexes not being released properly (#1272680)
+
+* Thu Feb 04 2016 Fedora Release Engineering <releng@fedoraproject.org> - 5.3.28-14
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Wed Jun 17 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.3.28-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Tue May 19 2015 Jan Stanek <jstanek@redhat.com> - 5.3.28-12
+- Add upstream patch for a memp_stat issue.
+- Resolves: rhbz#1211871
+
+* Sat May 02 2015 Kalev Lember <kalevlember@gmail.com> - 5.3.28-11
+- Rebuilt for GCC 5 C++11 ABI change
+
+* Sat Feb 21 2015 Till Maas <opensource@till.name> - 5.3.28-10
+- Rebuilt for Fedora 23 Change
+  https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code
+
+* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.3.28-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Thu Jul 17 2014 Tom Callaway <spot@fedoraproject.org> - 5.3.28-8
+- fix license handling
+
+* Mon Jul 14 2014 Jakub Čajka <jcajka@redhat.com> - 5.3.28-7
+- Fixed build with Java 8
+
+* Tue Jun 10 2014 Jan Stanek <jstanek@redhat.com> - 5.3.28-6
+- Fixed search path for new tcl, new BuildRequires for zlib
+
+* Sat Jun 07 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.3.28-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Sat Feb 22 2014 Peter Robinson <pbrobinson@fedoraproject.org> 5.3.28-4
+- Add some of the previous aarch64 bits back as the sub configure don't use the macro
+
+* Sun Jan 26 2014 Peter Robinson <pbrobinson@fedoraproject.org> 5.3.28-3
+- Fix configure macro usage for better aarch64 build fix
+
+* Wed Nov 06 2013 Jan Stanek <jstanek@redhat.com> - 5.3.28-2
+- Updated config files to allow build on aarch64 (#1022970)
+
+* Tue Oct 08 2013 Jan Stanek <jstanek@redhat.com> - 5.3.28-1
+- Added Sleepycat to the license list (#1013841)
+- Updated to 5.3.28 (#1013233)
+
+* Sat Aug 03 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.3.21-13
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
+
+* Tue May 28 2013 Tom Callaway <spot@fedoraproject.org> - 5.3.21-12
+- add copy of lgpl-2.1.txt
+
+* Thu May 16 2013 Jan Stanek <jstanek@redhat.com> - 5.3.21-11
+- Fix missing debuginfo issue for utils subpackage
+
+* Thu May  9 2013 Tom Callaway <spot@fedoraproject.org> - 5.3.21-10
+- add license clarification fix
+
+* Wed Apr 03 2013 Jan Stanek <jstanek@redhat.com> 5.3.21-9
+- Added sqlite compability CFLAGS (#788496)
+
+* Wed Mar 27 2013 Jan Stanek <jstanek@redhat.com> 5.3.21-8
+- Cleaning the specfile - removed gcc-java dependecy other way
+
+* Wed Mar 27 2013 Jan Stanek <jstanek@redhat.com> 5.3.21-7
+- Removed dependency on obsolete gcc-java package (#927742)
+
+* Thu Mar  7 2013 Jindrich Novy <jnovy@redhat.com> 5.3.21-6
+- add LGPLv2+ and remove Sleepycat in license tag (#886838)
+
+* Thu Feb 14 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.3.21-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Tue Nov 27 2012 Tom Callaway <spot@fedoraproject.org> - 5.3.21-4
+- fix license tag
+
+* Thu Jul 19 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.3.21-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Sat Jul 14 2012 Peter Robinson <pbrobinson@fedoraproject.org> - 5.3.21-2
+- Specify tag for libtool (fixes FTBFS # 838334 )
+
+* Thu Jul  5 2012 Jindrich Novy <jnovy@redhat.com> 5.3.21-1
+- update to 5.3.21
+http://download.oracle.com/otndocs/products/berkeleydb/html/changelog_5_3.html
+
+* Tue Jul  3 2012 Jindrich Novy <jnovy@redhat.com> 5.3.15-5
+- move C++ header files to cxx-devel
+
+* Tue Jul  3 2012 Jindrich Novy <jnovy@redhat.com> 5.3.15-4
+- fix -devel packages dependencies yet more (#832225)
+
+* Sun May  6 2012 Jindrich Novy <jnovy@redhat.com> 5.3.15-3
+- package -devel packages correctly
+
+* Sat Apr 21 2012 Jindrich Novy <jnovy@redhat.com> 5.3.15-2
+- fix multiarch conflict in libdb-devel (#812901)
+- remove unneeded dos2unix BR
+
+* Thu Mar 15 2012 Jindrich Novy <jnovy@redhat.com> 5.3.15-1
+- update to 5.3.15
+  http://download.oracle.com/otndocs/products/berkeleydb/html/changelog_5_3.html
+
+* Fri Feb 17 2012 Deepak Bhole <dbhole@redhat.com> 5.2.36-5
+- Resolves rhbz#794472
+- Patch from Omair Majid <omajid@redhat.com> to remove explicit Java 6 req.
+
+* Wed Jan 25 2012 Harald Hoyer <harald@redhat.com> 5.2.36-4
+- add filesystem guard
+
+* Wed Jan 25 2012 Harald Hoyer <harald@redhat.com> 5.2.36-3
+- install everything in /usr
+  https://fedoraproject.org/wiki/Features/UsrMove
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.2.36-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Wed Jun 15 2011 Jindrich Novy <jnovy@redhat.com> 5.2.36-1
+- update to 5.2.36,
+  http://download.oracle.com/otndocs/products/berkeleydb/html/changelog_5_2.html#id3647664
+
+* Wed Jun 15 2011 Jindrich Novy <jnovy@redhat.com> 5.2.28-2
+- move development documentation to devel-doc subpackage (#705386)
+
+* Tue Jun 14 2011 Jindrich Novy <jnovy@redhat.com> 5.2.28-1
+- update to 5.2.28
+
+* Mon Feb 07 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 5.1.25-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Thu Feb  3 2011 Jindrich Novy <jnovy@redhat.com> 5.1.25-1
+- update to 5.1.25
+
+* Wed Sep 29 2010 jkeating - 5.1.19-2
+- Rebuilt for gcc bug 634757
+
+* Fri Sep 10 2010 Jindrich Novy <jnovy@redhat.com> 5.1.19-1
+- update to 5.1.19
+- rename -devel-static to -static subpackage (#617800)
+- build java on all arches
+
+* Wed Jul  7 2010 Jindrich Novy <jnovy@redhat.com> 5.0.26-1
+- update to 5.0.26
+- drop BR: ed
+
+* Thu Jun 17 2010 Jindrich Novy <jnovy@redhat.com> 5.0.21-2
+- add Requires: libdb-cxx to libdb-devel
+
+* Wed Apr 21 2010 Jindrich Novy <jnovy@redhat.com> 5.0.21-1
+- initial build
+
+* Thu Apr 15 2010 Jindrich Novy <jnovy@redhat.com> 5.0.21-0.2
+- remove C# documentation
+- disable/remove rpath
+- fix description
+- tighten dependencies
+- run ldconfig for cxx and sql subpackages
+
+* Fri Apr  9 2010 Jindrich Novy <jnovy@redhat.com> 5.0.21-0.1
+- enable sql
+- package 5.0.21