Compare commits

...

No commits in common. "c8" and "c9s" have entirely different histories.
c8 ... c9s

12 changed files with 959 additions and 58 deletions

41
.gitignore vendored
View File

@ -1,2 +1,39 @@
SOURCES/tdb-1.4.9.tar.gz
SOURCES/tdb.keyring
/tdb-1.2.9.tar.gz
/tdb-1.2.10.tar.gz
/tdb-1.2.11.tar.gz
/tdb-1.2.12.tar.gz
/tdb-1.2.13.tar.gz
/tdb-1.3.0.tar.gz
/tdb-1.3.1.tar.gz
/tdb-1.3.3.tar.gz
/tdb-1.3.4.tar.gz
/tdb-1.3.5.tar.gz
/tdb-1.3.6.tar.gz
/tdb-1.3.7.tar.gz
/tdb-1.3.8.tar.gz
/tdb-1.3.9.tar.gz
/tdb-1.3.10.tar.gz
/tdb-1.3.11.tar.gz
/tdb-1.3.12.tar.gz
/tdb-1.3.13.tar.gz
/tdb-1.3.14.tar.gz
/tdb-1.3.15.tar.gz
/tdb-1.3.16.tar.gz
/tdb-1.3.17.tar.gz
/tdb-1.3.18.tar.gz
/tdb-1.4.2.tar.gz
/tdb.keyring
/tdb-1.4.3.tar.asc
/tdb-1.4.3.tar.gz
/tdb-1.4.4.tar.asc
/tdb-1.4.4.tar.gz
/tdb-1.4.6.tar.asc
/tdb-1.4.6.tar.gz
/tdb-1.4.7.tar.asc
/tdb-1.4.7.tar.gz
/tdb-1.4.8.tar.asc
/tdb-1.4.8.tar.gz
/tdb-1.4.9.tar.gz
/tdb-1.4.9.tar.asc
/tdb-1.4.10.tar.asc
/tdb-1.4.10.tar.gz

2
.libtdb.metadata Normal file
View File

@ -0,0 +1,2 @@
36f3fde462949b3581a379ab6a6d1ccd78f6b717 tdb-1.4.10.tar.asc
284c7927ca381502cda87631945808f69833c582 tdb-1.4.10.tar.gz

View File

@ -1,11 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQEzBAABCgAdFiEEkUejOXGVGO6QEby1R5ORYRMIQCUFAmS5EQcACgkQR5ORYRMI
QCVEJAf/fs1Nzq/ipbjmD7O4bOJ8QOWtbg3sJ5UeD7hRAtSWs0DuNlWQOXMYSXS3
kA3bjU896uWqEnkSQWdedWkOVe4TKMRYB464UMfRF4o+7mv8kf04auExMW0jQizt
ORXUID1edICT39mcXF5tWzMpdMZGYrnstd2VOKlVEDavJ3eq4EHaQrxHf+cKVvog
+9LdXUDYDjppyLjNoY8TimSmOPA7cN5O/yGorpOUsRrie9n1q6G65ZgnlYRIIKmy
FCyn9JKNGVgLeqmuANt62b0ENI0DM29pEauqIIsSEgbwDiMLu88l+jkt1n5kPKLm
p3ASZafnW7MncjtjpIzCcv5bBAfC5Q==
=UUVZ
-----END PGP SIGNATURE-----

6
gating.yaml Normal file
View File

@ -0,0 +1,6 @@
--- !Policy
product_versions:
- rhel-9
decision_context: osci_compose_gate
rules:
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}

View File

@ -1,10 +1,6 @@
%if 0%{?fedora} || 0%{?rhel} > 7
%global with_python3 1
%endif
Name: libtdb
Version: 1.4.9
Release: 0%{?dist}
Version: 1.4.10
Release: 1%{?dist}
Summary: The tdb library
License: LGPL-3.0-or-later
URL: http://tdb.samba.org/
@ -13,16 +9,12 @@ Source1: http://samba.org/ftp/tdb/tdb-%{version}.tar.asc
# gpg2 --no-default-keyring --keyring ./tdb.keyring --recv-keys 9147A339719518EE9011BCB54793916113084025
Source2: tdb.keyring
# Patches
BuildRequires: make
BuildRequires: gcc
BuildRequires: gnupg2
BuildRequires: libxslt
BuildRequires: docbook-style-xsl
%if 0%{?with_python3}
BuildRequires: python3-devel
%endif
Provides: bundled(libreplace)
Obsoletes: python2-tdb < 1.4.2-1
@ -44,7 +36,6 @@ Requires: libtdb = %{version}-%{release}
%description -n tdb-tools
Tools to manage Tdb files
%if 0%{?with_python3}
%package -n python3-tdb
Summary: Python3 bindings for the Tdb library
Requires: libtdb = %{version}-%{release}
@ -52,7 +43,6 @@ Requires: libtdb = %{version}-%{release}
%description -n python3-tdb
Python3 bindings for libtdb
%endif
%prep
%autosetup -n tdb-%{version} -p1
@ -69,7 +59,7 @@ zcat %{SOURCE0} | gpgv2 --quiet --keyring %{SOURCE2} %{SOURCE1} -
%make_build check
%install
make install DESTDIR=$RPM_BUILD_ROOT
%make_install
%files
%{_libdir}/libtdb.so.*
@ -90,62 +80,103 @@ make install DESTDIR=$RPM_BUILD_ROOT
%{_mandir}/man8/tdbtool.8*
%{_mandir}/man8/tdbrestore.8*
%if 0%{?with_python3}
%files -n python3-tdb
%{python3_sitearch}/__pycache__/_tdb_text.cpython*.py[co]
%{python3_sitearch}/tdb.cpython*.so
%{python3_sitearch}/_tdb_text.py
%endif
%ldconfig_scriptlets
%changelog
* Fri Nov 17 2023 Pavel Filipenský <pfilipen@redhat.com> - 1.4.9-0
- resolves: RHEL-16507 - Update to version libtdb-1.4.9
* Wed Apr 24 2024 Pavel Filipenský <pfilipen@redhat.com> - 1.4.10-1
- resolves: RHEL-33756 - Rebase to version 1.4.10
* Tue Jun 06 2023 Pavel Filipenský <pfilipen@redhat.com> - 1.4.8-3
- resolves: rhbz#2190421 - Rebuild to trigger distrobaker sync
* Mon Dec 04 2023 Andreas Schneider <asn@redhat.com> - 1.4.9-1
- resolves: RHEL-16480 - Rebase to version 1.4.9
* Wed May 24 2023 Pavel Filipenský <pfilipen@redhat.com> - 1.4.8-2
- resolves: rhbz#2190421 - Add missing tests to fix osci.brew-build.tier0.functional
* Mon Jun 05 2023 Pavel Filipenský <pfilipen@redhat.com> - 1.4.8-2
- resolves: rhbz#2190420 - Rebuilt to retrigger brew build
* Thu May 18 2023 Pavel Filipenský <pfilipen@redhat.com> - 1.4.8-1
- resolves: rhbz#2190421 - Update to version 1.4.8
* Tue May 16 2023 Pavel Filipenský <pfilipen@redhat.com> - 1.4.8-1
- resolves: rhbz#2190420 - Rebase to version 1.4.8
* Mon Oct 24 2022 Andreas Schneider <asn@redhat.com> - 1.4.7-1
- resolves: rhbz#2132054 - Rebase to version 1.4.7
* Fri Oct 21 2022 Andreas Schneider <asn@redhat.com> - 1.4.7-1
- resolves: rhbz#2131998 - Rebase to version 1.4.7
* Mon May 02 2022 Pavel Filipenský <pfilipen@redhat.com> - 1.4.6-1
- resolves: rhbz#2077482 - Rebase to version 1.4.6
- resolves: rhbz#2077489 - Rebase libtdb to the version (1.4.6) required by Samba
* Thu Nov 25 2021 Pavel Filipenský <pfilipen@redhat.com> - 1.4.4-1
* resolves: rhbz#2013604 - Rebase to version 1.4.4
* Mon Nov 29 2021 Pavel Filipenský <pfilipen@redhat.com> - 1.4.4-1
- resolves: rhbz#2013584 - Rebase to version 1.4.4
* Tue Jun 2 2020 Isaac Boukris <iboukris@redhat.com> - 1.4.3-1
- Resolves: rhbz#1817565 - Rebase libtdb 1.4.3 for samba
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1.4.3-10
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Tue Nov 26 2019 Isaac Boukris <iboukris@redhat.com> - 1.4.2-2
- Resolves: rhbz#1754420 - Rebase libtdb 1.4.2 for samba
- Related: rhbz#1754420 - Fix sssd tests (tdb)
* Fri Jul 23 2021 Andreas Schneider <asn@redhat.com> - 1.4.3-9
- resolves: rhbz#1938798 - Fix memory leak on transaction error
* Tue Apr 30 2019 Jakub Hrozek <jhrozek@redhat.com> - 1.3.18.2
- Obsolete the python2 packages on upgrade
- Resolves: rhbz#1567138 - libtdb: Drop Python 2 subpackage from RHEL 8
* Mon May 31 2021 Andreas Schneider <asn@redhat.com> - 1.4.3-8
- related: rhbz#1962774 - Rebuilt for running gating tests
* Wed Apr 24 2019 Jakub Hrozek <jhrozek@redhat.com> - 1.3.18.1
- Resolves: rhbz#1684579 - Rebase libtdb to version 1.3.18 for Samba
- Resolves: rhbz#1597319 - libtdb uses Python 2 to build
- Resolves: rhbz#1567138 - libtdb: Drop Python 2 subpackage from RHEL 8
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.4.3-7
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Thu Sep 20 2018 Jakub Hrozek <jhrozek@redhat.com> - 1.3.16-3
- Resolves: rhbz#1624137 - Review annocheck distro flag failures in libtdb
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1.4.3-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Thu Jul 12 2018 Jakub Hrozek <jhrozek@redhat.com> - 1.3.16-2
- Use pathfix.py to select python2 instead of pytho
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.4.3-5
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Mon Jul 13 2020 Tom Stellard <tstellar@redhat.com> - 1.4.3-4
- Use make macros
- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
* Tue May 26 2020 Miro Hrončok <mhroncok@redhat.com> - 1.4.3-3
- Rebuilt for Python 3.9
* Wed Jan 29 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.4.3-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Wed Jan 22 2020 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.4.3-1
- rhbz#1783927 - libtdb-1.4.3 is available
* Thu Oct 03 2019 Miro Hrončok <mhroncok@redhat.com> - 1.4.2-2
- Rebuilt for Python 3.8.0rc1 (#1748018)
* Mon Aug 26 2019 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.4.2-1
- rhbz#1691299 - libtdb-1.4.2 is available
- rhbz#1737644 - libldb, libtalloc, libtevent, libtdb: Remove Python 2 subpackages from Fedora 31+
* Mon Aug 19 2019 Miro Hrončok <mhroncok@redhat.com> - 1.3.18-5
- Rebuilt for Python 3.8
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.18-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Fri Jun 14 2019 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.3.18-3
- rhbz#1718113 - samba fail to build with Python 3.8
AttributeError: module 'time' has no attribute 'clock'
* Mon Jun 03 2019 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.3.18-2
- rhbz#1711638 - fails to build with Python 3.8.0a4
* Tue Feb 26 2019 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.3.18-1
- rhbz#1683185 - libtdb-1.3.18 is available
* Fri Feb 01 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1.3.17-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
* Thu Jan 17 2019 Lukas Slebodnik <lslebodn@fedoraproject.org> - 1.3.17-1
- rhbz#1667472 - libtdb-1.3.17 is available
* Fri Jul 13 2018 Jakub Hrozek <jhrozek@redhat.com> - 1.3.16-2
- Drop the unneeded ABI hide patch
- Use pathfix.py instead of a local patch to munge the python path
* Thu Jul 12 2018 Jakub Hrozek <jhrozek@redhat.com> - 1.3.16-1
- New upstream release 1.3.16
- Use RHEL_ALLOW_PYTHON2_FOR_BUILD=1 until libtalloc uses waf3
- Apply a patch to hide local ABI symbols to avoid issues with new binutils
- Patch the waf script to explicitly call python2 as "env python" doesn't
yield py2 anymore

2
sources Normal file
View File

@ -0,0 +1,2 @@
SHA512 (tdb-1.4.10.tar.asc) = 7bc9616aa6a3badba33e508777eec307de51c2abb494836677356e432036970641b53f3b7c0c207efe909194343d3554af7932412d163f59db0ec8877fd19848
SHA512 (tdb-1.4.10.tar.gz) = b5147d811617d90a025d1070abf16c42744b3fc3cac1042fbff03b1e635af2eaf9c957a7bffdb3f56b4a0c775b44f8027def9f23deb1b3ede817b95bbece2ce9

BIN
tdb.keyring Normal file

Binary file not shown.

15
tests/sanity/Makefile Normal file
View File

@ -0,0 +1,15 @@
tdbtorture: tdbtorture.c
gcc tdbtorture.c -g -ltdb -o tdbtorture
tdbtest: tdbtest.c
gcc tdbtest.c -ltdb -lgdbm -g -o tdbtest
run: tdbtorture tdbtest
@echo "Running tdbtorture"
./tdbtorture
@echo "Running tdbtest"
./tdbtest
clean:
rm -f tdbtorture tdbtest *.tdb *.gdbm

297
tests/sanity/tdbtest.c Normal file
View File

@ -0,0 +1,297 @@
/* a test program for tdb - the trivial database */
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gdbm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#include <tdb.h>
#define DELETE_PROB 7
#define STORE_PROB 5
static struct tdb_context *db;
static GDBM_FILE gdbm;
struct timeval tp1,tp2;
static void _start_timer(void)
{
gettimeofday(&tp1,NULL);
}
static double _end_timer(void)
{
gettimeofday(&tp2,NULL);
return((tp2.tv_sec - tp1.tv_sec) +
(tp2.tv_usec - tp1.tv_usec)*1.0e-6);
}
static void fatal(const char *why)
{
perror(why);
exit(1);
}
#ifdef PRINTF_ATTRIBUTE
static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
#endif
static void tdb_log(struct tdb_context *tdb, int level, const char *format, ...)
{
va_list ap;
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
fflush(stdout);
}
static void compare_db(void)
{
TDB_DATA d, key, nextkey;
datum gd, gkey, gnextkey;
key = tdb_firstkey(db);
while (key.dptr) {
d = tdb_fetch(db, key);
gkey.dptr = key.dptr;
gkey.dsize = key.dsize;
gd = gdbm_fetch(gdbm, gkey);
if (!gd.dptr) fatal("key not in gdbm");
if (gd.dsize != d.dsize) fatal("data sizes differ");
if (memcmp(gd.dptr, d.dptr, d.dsize)) {
fatal("data differs");
}
nextkey = tdb_nextkey(db, key);
free(key.dptr);
free(d.dptr);
free(gd.dptr);
key = nextkey;
}
gkey = gdbm_firstkey(gdbm);
while (gkey.dptr) {
gd = gdbm_fetch(gdbm, gkey);
key.dptr = gkey.dptr;
key.dsize = gkey.dsize;
d = tdb_fetch(db, key);
if (!d.dptr) fatal("key not in db");
if (d.dsize != gd.dsize) fatal("data sizes differ");
if (memcmp(d.dptr, gd.dptr, gd.dsize)) {
fatal("data differs");
}
gnextkey = gdbm_nextkey(gdbm, gkey);
free(gkey.dptr);
free(gd.dptr);
free(d.dptr);
gkey = gnextkey;
}
}
static char *randbuf(int len)
{
char *buf;
int i;
buf = (char *)malloc(len+1);
for (i=0;i<len;i++) {
buf[i] = 'a' + (rand() % 26);
}
buf[i] = 0;
return buf;
}
static void addrec_db(void)
{
int klen, dlen;
char *k, *d;
TDB_DATA key, data;
klen = 1 + (rand() % 4);
dlen = 1 + (rand() % 100);
k = randbuf(klen);
d = randbuf(dlen);
key.dptr = k;
key.dsize = klen+1;
data.dptr = d;
data.dsize = dlen+1;
if (rand() % DELETE_PROB == 0) {
tdb_delete(db, key);
} else if (rand() % STORE_PROB == 0) {
if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
fatal("tdb_store failed");
}
} else {
data = tdb_fetch(db, key);
if (data.dptr) free(data.dptr);
}
free(k);
free(d);
}
static void addrec_gdbm(void)
{
int klen, dlen;
char *k, *d;
datum key, data;
klen = 1 + (rand() % 4);
dlen = 1 + (rand() % 100);
k = randbuf(klen);
d = randbuf(dlen);
key.dptr = k;
key.dsize = klen+1;
data.dptr = d;
data.dsize = dlen+1;
if (rand() % DELETE_PROB == 0) {
gdbm_delete(gdbm, key);
} else if (rand() % STORE_PROB == 0) {
if (gdbm_store(gdbm, key, data, GDBM_REPLACE) != 0) {
fatal("gdbm_store failed");
}
} else {
data = gdbm_fetch(gdbm, key);
if (data.dptr) free(data.dptr);
}
free(k);
free(d);
}
static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *state)
{
#if 0
printf("[%s] [%s]\n", key.dptr, dbuf.dptr);
#endif
tdb_delete(tdb, key);
return 0;
}
static void merge_test(void)
{
int i;
char keys[5][2];
char tdata[] = "test";
TDB_DATA key, data;
for (i = 0; i < 5; i++) {
snprintf(keys[i],2, "%d", i);
key.dptr = keys[i];
key.dsize = 2;
data.dptr = tdata;
data.dsize = 4;
if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
fatal("tdb_store failed");
}
}
key.dptr = keys[0];
tdb_delete(db, key);
key.dptr = keys[4];
tdb_delete(db, key);
key.dptr = keys[2];
tdb_delete(db, key);
key.dptr = keys[1];
tdb_delete(db, key);
key.dptr = keys[3];
tdb_delete(db, key);
}
static char *test_path(const char *filename)
{
const char *prefix = getenv("TEST_DATA_PREFIX");
if (prefix) {
char *path = NULL;
int ret;
ret = asprintf(&path, "%s/%s", prefix, filename);
if (ret == -1) {
return NULL;
}
return path;
}
return strdup(filename);
}
int main(int argc, const char *argv[])
{
int i, seed=0;
int loops = 10000;
int num_entries;
char *test_gdbm;
char *test_tdb;
test_gdbm = test_path("test.gdbm");
test_tdb = test_path("test.tdb");
unlink(test_gdbm);
db = tdb_open(test_tdb, 0, TDB_CLEAR_IF_FIRST,
O_RDWR | O_CREAT | O_TRUNC, 0600);
gdbm = gdbm_open(test_gdbm, 512, GDBM_WRITER|GDBM_NEWDB|GDBM_FAST,
0600, NULL);
if (!db || !gdbm) {
fatal("db open failed");
}
#if 1
srand(seed);
_start_timer();
for (i=0;i<loops;i++) addrec_gdbm();
printf("gdbm got %.2f ops/sec\n", i/_end_timer());
#endif
merge_test();
srand(seed);
_start_timer();
for (i=0;i<loops;i++) addrec_db();
printf("tdb got %.2f ops/sec\n", i/_end_timer());
if (tdb_validate_freelist(db, &num_entries) == -1) {
printf("tdb freelist is corrupt\n");
} else {
printf("tdb freelist is good (%d entries)\n", num_entries);
}
compare_db();
printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
printf("traversed %d records\n", tdb_traverse(db, traverse_fn, NULL));
tdb_close(db);
gdbm_close(gdbm);
free(test_tdb);
free(test_gdbm);
return 0;
}

4
tests/sanity/tdbtest.sh Executable file
View File

@ -0,0 +1,4 @@
#/bin/bash
make run || exit 1
make clean || exit 2

501
tests/sanity/tdbtorture.c Normal file
View File

@ -0,0 +1,501 @@
/* this tests tdb by doing lots of ops from several simultaneous
writers - that stresses the locking code.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <tdb.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
#define REOPEN_PROB 30
#define DELETE_PROB 8
#define STORE_PROB 4
#define APPEND_PROB 6
#define TRANSACTION_PROB 10
#define TRANSACTION_PREPARE_PROB 2
#define LOCKSTORE_PROB 5
#define TRAVERSE_PROB 20
#define TRAVERSE_READ_PROB 20
#define CULL_PROB 100
#define KEYLEN 3
#define DATALEN 100
static struct tdb_context *db;
static int in_transaction;
static int error_count;
static int always_transaction = 0;
static int hash_size = 2;
static int loopnum;
static int count_pipe;
static bool mutex = false;
static struct tdb_logging_context log_ctx;
#ifdef PRINTF_ATTRIBUTE
static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4);
#endif
static void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...)
{
va_list ap;
/* trace level messages do not indicate an error */
if (level != TDB_DEBUG_TRACE) {
error_count++;
}
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
fflush(stdout);
#if 0
if (level != TDB_DEBUG_TRACE) {
char *ptr;
signal(SIGUSR1, SIG_IGN);
asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
system(ptr);
free(ptr);
}
#endif
}
static void fatal(const char *why)
{
perror(why);
error_count++;
}
static char *randbuf(int len)
{
char *buf;
int i;
buf = (char *)malloc(len+1);
for (i=0;i<len;i++) {
buf[i] = 'a' + (rand() % 26);
}
buf[i] = 0;
return buf;
}
static int cull_traverse(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf,
void *state)
{
#if CULL_PROB
if (random() % CULL_PROB == 0) {
tdb_delete(tdb, key);
}
#endif
return 0;
}
static void addrec_db(void)
{
int klen, dlen;
char *k, *d;
TDB_DATA key, data;
klen = 1 + (rand() % KEYLEN);
dlen = 1 + (rand() % DATALEN);
k = randbuf(klen);
d = randbuf(dlen);
key.dptr = (unsigned char *)k;
key.dsize = klen+1;
data.dptr = (unsigned char *)d;
data.dsize = dlen+1;
#if REOPEN_PROB
if (in_transaction == 0 && random() % REOPEN_PROB == 0) {
tdb_reopen_all(0);
goto next;
}
#endif
#if TRANSACTION_PROB
if (in_transaction == 0 &&
(always_transaction || random() % TRANSACTION_PROB == 0)) {
if (tdb_transaction_start(db) != 0) {
fatal("tdb_transaction_start failed");
}
in_transaction++;
goto next;
}
if (in_transaction && random() % TRANSACTION_PROB == 0) {
if (random() % TRANSACTION_PREPARE_PROB == 0) {
if (tdb_transaction_prepare_commit(db) != 0) {
fatal("tdb_transaction_prepare_commit failed");
}
}
if (tdb_transaction_commit(db) != 0) {
fatal("tdb_transaction_commit failed");
}
in_transaction--;
goto next;
}
if (in_transaction && random() % TRANSACTION_PROB == 0) {
if (tdb_transaction_cancel(db) != 0) {
fatal("tdb_transaction_cancel failed");
}
in_transaction--;
goto next;
}
#endif
#if DELETE_PROB
if (random() % DELETE_PROB == 0) {
tdb_delete(db, key);
goto next;
}
#endif
#if STORE_PROB
if (random() % STORE_PROB == 0) {
if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
fatal("tdb_store failed");
}
goto next;
}
#endif
#if APPEND_PROB
if (random() % APPEND_PROB == 0) {
if (tdb_append(db, key, data) != 0) {
fatal("tdb_append failed");
}
goto next;
}
#endif
#if LOCKSTORE_PROB
if (random() % LOCKSTORE_PROB == 0) {
tdb_chainlock(db, key);
data = tdb_fetch(db, key);
if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
fatal("tdb_store failed");
}
if (data.dptr) free(data.dptr);
tdb_chainunlock(db, key);
goto next;
}
#endif
#if TRAVERSE_PROB
if (random() % TRAVERSE_PROB == 0) {
tdb_traverse(db, cull_traverse, NULL);
goto next;
}
#endif
#if TRAVERSE_READ_PROB
if (random() % TRAVERSE_READ_PROB == 0) {
tdb_traverse_read(db, NULL, NULL);
goto next;
}
#endif
data = tdb_fetch(db, key);
if (data.dptr) free(data.dptr);
next:
free(k);
free(d);
}
static int traverse_fn(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf,
void *state)
{
tdb_delete(tdb, key);
return 0;
}
static void usage(void)
{
printf("Usage: tdbtorture [-t] [-k] [-m] [-n NUM_PROCS] [-l NUM_LOOPS] [-s SEED] [-H HASH_SIZE]\n");
exit(0);
}
static void send_count_and_suicide(int sig)
{
ssize_t ret;
/* This ensures our successor can continue where we left off. */
do {
ret = write(count_pipe, &loopnum, sizeof(loopnum));
} while (ret == -1 && errno == EINTR);
/* This gives a unique signature. */
kill(getpid(), SIGUSR2);
}
static int run_child(const char *filename, int i, int seed, unsigned num_loops, unsigned start)
{
int tdb_flags = TDB_DEFAULT|TDB_CLEAR_IF_FIRST|TDB_INCOMPATIBLE_HASH;
if (mutex) {
tdb_flags |= TDB_MUTEX_LOCKING;
}
db = tdb_open_ex(filename, hash_size, tdb_flags,
O_RDWR | O_CREAT, 0600, &log_ctx, NULL);
if (!db) {
fatal("db open failed");
}
srand(seed + i);
srandom(seed + i);
/* Set global, then we're ready to handle being killed. */
loopnum = start;
signal(SIGUSR1, send_count_and_suicide);
for (;loopnum<num_loops && error_count == 0;loopnum++) {
addrec_db();
}
if (error_count == 0) {
tdb_traverse_read(db, NULL, NULL);
if (always_transaction) {
while (in_transaction) {
tdb_transaction_cancel(db);
in_transaction--;
}
if (tdb_transaction_start(db) != 0)
fatal("tdb_transaction_start failed");
}
tdb_traverse(db, traverse_fn, NULL);
tdb_traverse(db, traverse_fn, NULL);
if (always_transaction) {
if (tdb_transaction_commit(db) != 0)
fatal("tdb_transaction_commit failed");
}
}
tdb_close(db);
return (error_count < 100 ? error_count : 100);
}
static char *test_path(const char *filename)
{
const char *prefix = getenv("TEST_DATA_PREFIX");
if (prefix) {
char *path = NULL;
int ret;
ret = asprintf(&path, "%s/%s", prefix, filename);
if (ret == -1) {
return NULL;
}
return path;
}
return strdup(filename);
}
int main(int argc, char * const *argv)
{
int i, seed = -1;
int num_loops = 5000;
int num_procs = 3;
int c, pfds[2];
extern char *optarg;
pid_t *pids;
int kill_random = 0;
int *done;
char *test_tdb;
log_ctx.log_fn = tdb_log;
while ((c = getopt(argc, argv, "n:l:s:H:thkm")) != -1) {
switch (c) {
case 'n':
num_procs = strtol(optarg, NULL, 0);
break;
case 'l':
num_loops = strtol(optarg, NULL, 0);
break;
case 'H':
hash_size = strtol(optarg, NULL, 0);
break;
case 's':
seed = strtol(optarg, NULL, 0);
break;
case 't':
always_transaction = 1;
break;
case 'k':
kill_random = 1;
break;
case 'm':
mutex = tdb_runtime_check_for_robust_mutexes();
if (!mutex) {
printf("tdb_runtime_check_for_robust_mutexes() returned false\n");
exit(1);
}
break;
default:
usage();
}
}
test_tdb = test_path("torture.tdb");
unlink(test_tdb);
if (seed == -1) {
seed = (getpid() + time(NULL)) & 0x7FFFFFFF;
}
printf("Testing with %d processes, %d loops, %d hash_size, seed=%d%s\n",
num_procs, num_loops, hash_size, seed,
(always_transaction ? " (all within transactions)" : ""));
if (num_procs == 1 && !kill_random) {
/* Don't fork for this case, makes debugging easier. */
error_count = run_child(test_tdb, 0, seed, num_loops, 0);
goto done;
}
pids = (pid_t *)calloc(sizeof(pid_t), num_procs);
if (pids == NULL) {
perror("Unable to allocate memory for pids");
exit(1);
}
done = (int *)calloc(sizeof(int), num_procs);
if (done == NULL) {
perror("Unable to allocate memory for done");
exit(1);
}
if (pipe(pfds) != 0) {
perror("Creating pipe");
exit(1);
}
count_pipe = pfds[1];
for (i=0;i<num_procs;i++) {
if ((pids[i]=fork()) == 0) {
close(pfds[0]);
exit(run_child(test_tdb, i, seed, num_loops, 0));
}
}
while (num_procs) {
int status, j;
pid_t pid;
if (error_count != 0) {
/* try and stop the test on any failure */
for (j=0;j<num_procs;j++) {
if (pids[j] != 0) {
kill(pids[j], SIGTERM);
}
}
}
pid = waitpid(-1, &status, kill_random ? WNOHANG : 0);
if (pid == 0) {
struct timeval tv;
/* Sleep for 1/10 second. */
tv.tv_sec = 0;
tv.tv_usec = 100000;
select(0, NULL, NULL, NULL, &tv);
/* Kill someone. */
kill(pids[random() % num_procs], SIGUSR1);
continue;
}
if (pid == -1) {
perror("failed to wait for child\n");
exit(1);
}
for (j=0;j<num_procs;j++) {
if (pids[j] == pid) break;
}
if (j == num_procs) {
printf("unknown child %d exited!?\n", (int)pid);
exit(1);
}
if (WIFSIGNALED(status)) {
if (WTERMSIG(status) == SIGUSR2
|| WTERMSIG(status) == SIGUSR1) {
/* SIGUSR2 means they wrote to pipe. */
if (WTERMSIG(status) == SIGUSR2) {
ssize_t ret;
do {
ret = read(pfds[0], &done[j],
sizeof(done[j]));
} while (ret == -1 && errno == EINTR);
}
pids[j] = fork();
if (pids[j] == 0)
exit(run_child(test_tdb, j, seed,
num_loops, done[j]));
printf("Restarting child %i for %u-%u\n",
j, done[j], num_loops);
continue;
}
printf("child %d exited with signal %d\n",
(int)pid, WTERMSIG(status));
error_count++;
} else {
if (WEXITSTATUS(status) != 0) {
printf("child %d exited with status %d\n",
(int)pid, WEXITSTATUS(status));
error_count++;
}
}
memmove(&pids[j], &pids[j+1],
(num_procs - j - 1)*sizeof(pids[0]));
num_procs--;
}
free(pids);
done:
if (error_count == 0) {
int tdb_flags = TDB_DEFAULT;
if (mutex) {
tdb_flags |= TDB_NOLOCK;
}
db = tdb_open_ex(test_tdb, hash_size, tdb_flags,
O_RDWR, 0, &log_ctx, NULL);
if (!db) {
fatal("db open failed\n");
exit(1);
}
if (tdb_check(db, NULL, NULL) == -1) {
printf("db check failed\n");
exit(1);
}
tdb_close(db);
printf("OK\n");
}
free(test_tdb);
return error_count;
}

17
tests/tests.yml Normal file
View File

@ -0,0 +1,17 @@
- hosts: localhost
roles:
- role: standard-test-basic
tags:
- classic
tests:
- sanity:
dir: sanity
run: ./tdbtest.sh
required_packages:
- make
- gcc
- libtdb
- libtdb-devel
- gdbm
- gdbm-devel