1
/* $Id: tdbtorture.c 18843 2005-11-14 14:25:58Z benny $ */
3
* Copyright (c) 1999-2004 Andrew Tridgell <tridge@linuxcare.com>
4
* Copyright (c) 2005 Benedikt Meurer <benny@xfce.org>
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Library General Public
8
* License as published by the Free Software Foundation; either
9
* version 2 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Library General Public License for more details.
16
* You should have received a copy of the GNU Library General Public
17
* License along with this library; if not, write to the
18
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19
* Boston, MA 02111-1307, USA.
21
* This file was originally part of the tdb library, which in turn is
22
* part of the Samba suite, a Unix SMB/CIFS implementation.
29
#ifdef HAVE_SYS_TYPES_H
30
#include <sys/types.h>
32
#ifdef HAVE_SYS_MMAN_h
35
#ifdef HAVE_SYS_STAT_H
38
#ifdef HAVE_SYS_TIME_H
41
#ifdef HAVE_SYS_WAIT_H
67
/* this tests tdb by doing lots of ops from several simultaneous
68
writers - that stresses the locking code. Build with TDB_DEBUG=1
73
#define REOPEN_PROB 30
77
#define LOCKSTORE_PROB 0
78
#define TRAVERSE_PROB 20
84
static TDB_CONTEXT *db;
86
static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
91
vfprintf(stdout, format, ap);
97
asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
104
static void fatal(char *why)
110
static char *randbuf(int len)
114
buf = (char *)malloc(len+1);
116
for (i=0;i<len;i++) {
117
buf[i] = 'a' + (rand() % 26);
123
static int cull_traverse(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf,
126
if (random() % CULL_PROB == 0) {
127
tdb_delete(tdb, key);
132
static void addrec_db(void)
134
int klen, dlen, slen;
136
TDB_DATA key, data, lockkey;
138
klen = 1 + (rand() % KEYLEN);
139
dlen = 1 + (rand() % DATALEN);
140
slen = 1 + (rand() % LOCKLEN);
153
lockkey.dsize = slen+1;
156
if (random() % REOPEN_PROB == 0) {
163
if (random() % DELETE_PROB == 0) {
170
if (random() % STORE_PROB == 0) {
171
if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
172
fatal("tdb_store failed");
179
if (random() % APPEND_PROB == 0) {
180
if (tdb_append(db, key, data) != 0) {
181
fatal("tdb_append failed");
188
if (random() % LOCKSTORE_PROB == 0) {
189
tdb_chainlock(db, lockkey);
190
data = tdb_fetch(db, key);
191
if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
192
fatal("tdb_store failed");
194
if (data.dptr) free(data.dptr);
195
tdb_chainunlock(db, lockkey);
201
if (random() % TRAVERSE_PROB == 0) {
202
tdb_traverse(db, cull_traverse, NULL);
207
data = tdb_fetch(db, key);
208
if (data.dptr) free(data.dptr);
216
static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf,
219
tdb_delete(tdb, key);
228
#define NLOOPS 200000
231
int main(int argc, char *argv[])
239
for (i=0;i<NPROC-1;i++) {
240
if ((pids[i+1]=fork()) == 0) break;
243
db = tdb_open("torture.tdb", 2, TDB_CLEAR_IF_FIRST,
244
O_RDWR | O_CREAT, 0600);
246
fatal("db open failed");
248
tdb_logging_function(db, tdb_log);
250
srand(seed + getpid());
251
srandom(seed + getpid() + time(NULL));
252
for (i=0;i<loops;i++) addrec_db();
254
tdb_traverse(db, NULL, NULL);
255
tdb_traverse(db, traverse_fn, NULL);
256
tdb_traverse(db, traverse_fn, NULL);
260
if (getpid() == pids[0]) {
261
for (i=0;i<NPROC-1;i++) {
263
if (waitpid(pids[i+1], &status, 0) != pids[i+1]) {
264
printf("failed to wait for %d\n",
268
if (WEXITSTATUS(status) != 0) {
269
printf("child %d exited with status %d\n",
270
(int)pids[i+1], WEXITSTATUS(status));