~ubuntu-branches/debian/experimental/thunar/experimental

« back to all changes in this revision

Viewing changes to tdb/tdbtorture.c

  • Committer: Bazaar Package Importer
  • Author(s): Yves-Alexis Perez
  • Date: 2006-01-02 23:42:32 UTC
  • Revision ID: james.westby@ubuntu.com-20060102234232-8xeq0lqhyn70syr0
Tags: upstream-0.1.4svn+r18850
ImportĀ upstreamĀ versionĀ 0.1.4svn+r18850

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Id: tdbtorture.c 18843 2005-11-14 14:25:58Z benny $ */
 
2
/*-
 
3
 * Copyright (c) 1999-2004 Andrew Tridgell <tridge@linuxcare.com>
 
4
 * Copyright (c) 2005      Benedikt Meurer <benny@xfce.org>
 
5
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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.
 
20
 *
 
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.
 
23
 */
 
24
 
 
25
#ifdef HAVE_CONFIG_H
 
26
#include <config.h>
 
27
#endif
 
28
 
 
29
#ifdef HAVE_SYS_TYPES_H
 
30
#include <sys/types.h>
 
31
#endif
 
32
#ifdef HAVE_SYS_MMAN_h
 
33
#include <sys/mman.h>
 
34
#endif
 
35
#ifdef HAVE_SYS_STAT_H
 
36
#include <sys/stat.h>
 
37
#endif
 
38
#ifdef HAVE_SYS_TIME_H
 
39
#include <sys/time.h>
 
40
#endif
 
41
#ifdef HAVE_SYS_WAIT_H
 
42
#include <sys/wait.h>
 
43
#endif
 
44
 
 
45
#ifdef HAVE_FCNTL_H
 
46
#include <fcntl.h>
 
47
#endif
 
48
#ifdef HAVE_STDARG_H
 
49
#include <stdarg.h>
 
50
#endif
 
51
#include <stdio.h>
 
52
#ifdef HAVE_STDLIB_H
 
53
#include <stdlib.h>
 
54
#endif
 
55
#ifdef HAVE_STRING_H
 
56
#include <string.h>
 
57
#endif
 
58
#ifdef HAVE_TIME_H
 
59
#include <time.h>
 
60
#endif
 
61
#ifdef HAVE_UNISTD_H
 
62
#include <unistd.h>
 
63
#endif
 
64
 
 
65
#include <tdb/tdb.h>
 
66
 
 
67
/* this tests tdb by doing lots of ops from several simultaneous
 
68
   writers - that stresses the locking code. Build with TDB_DEBUG=1
 
69
   for best effect */
 
70
 
 
71
 
 
72
 
 
73
#define REOPEN_PROB 30
 
74
#define DELETE_PROB 8
 
75
#define STORE_PROB 4
 
76
#define APPEND_PROB 6
 
77
#define LOCKSTORE_PROB 0
 
78
#define TRAVERSE_PROB 20
 
79
#define CULL_PROB 100
 
80
#define KEYLEN 3
 
81
#define DATALEN 100
 
82
#define LOCKLEN 20
 
83
 
 
84
static TDB_CONTEXT *db;
 
85
 
 
86
static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...)
 
87
{
 
88
        va_list ap;
 
89
    
 
90
        va_start(ap, format);
 
91
        vfprintf(stdout, format, ap);
 
92
        va_end(ap);
 
93
        fflush(stdout);
 
94
#if 0
 
95
        {
 
96
                char *ptr;
 
97
                asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid());
 
98
                system(ptr);
 
99
                free(ptr);
 
100
        }
 
101
#endif  
 
102
}
 
103
 
 
104
static void fatal(char *why)
 
105
{
 
106
        perror(why);
 
107
        exit(1);
 
108
}
 
109
 
 
110
static char *randbuf(int len)
 
111
{
 
112
        char *buf;
 
113
        int i;
 
114
        buf = (char *)malloc(len+1);
 
115
 
 
116
        for (i=0;i<len;i++) {
 
117
                buf[i] = 'a' + (rand() % 26);
 
118
        }
 
119
        buf[i] = 0;
 
120
        return buf;
 
121
}
 
122
 
 
123
static int cull_traverse(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf,
 
124
                         void *state)
 
125
{
 
126
        if (random() % CULL_PROB == 0) {
 
127
                tdb_delete(tdb, key);
 
128
        }
 
129
        return 0;
 
130
}
 
131
 
 
132
static void addrec_db(void)
 
133
{
 
134
        int klen, dlen, slen;
 
135
        char *k, *d, *s;
 
136
        TDB_DATA key, data, lockkey;
 
137
 
 
138
        klen = 1 + (rand() % KEYLEN);
 
139
        dlen = 1 + (rand() % DATALEN);
 
140
        slen = 1 + (rand() % LOCKLEN);
 
141
 
 
142
        k = randbuf(klen);
 
143
        d = randbuf(dlen);
 
144
        s = randbuf(slen);
 
145
 
 
146
        key.dptr = k;
 
147
        key.dsize = klen+1;
 
148
 
 
149
        data.dptr = d;
 
150
        data.dsize = dlen+1;
 
151
 
 
152
        lockkey.dptr = s;
 
153
        lockkey.dsize = slen+1;
 
154
 
 
155
#if REOPEN_PROB
 
156
        if (random() % REOPEN_PROB == 0) {
 
157
                tdb_reopen_all();
 
158
                goto next;
 
159
        } 
 
160
#endif
 
161
 
 
162
#if DELETE_PROB
 
163
        if (random() % DELETE_PROB == 0) {
 
164
                tdb_delete(db, key);
 
165
                goto next;
 
166
        }
 
167
#endif
 
168
 
 
169
#if STORE_PROB
 
170
        if (random() % STORE_PROB == 0) {
 
171
                if (tdb_store(db, key, data, TDB_REPLACE) != 0) {
 
172
                        fatal("tdb_store failed");
 
173
                }
 
174
                goto next;
 
175
        }
 
176
#endif
 
177
 
 
178
#if APPEND_PROB
 
179
        if (random() % APPEND_PROB == 0) {
 
180
                if (tdb_append(db, key, data) != 0) {
 
181
                        fatal("tdb_append failed");
 
182
                }
 
183
                goto next;
 
184
        }
 
185
#endif
 
186
 
 
187
#if LOCKSTORE_PROB
 
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");
 
193
                }
 
194
                if (data.dptr) free(data.dptr);
 
195
                tdb_chainunlock(db, lockkey);
 
196
                goto next;
 
197
        } 
 
198
#endif
 
199
 
 
200
#if TRAVERSE_PROB
 
201
        if (random() % TRAVERSE_PROB == 0) {
 
202
                tdb_traverse(db, cull_traverse, NULL);
 
203
                goto next;
 
204
        }
 
205
#endif
 
206
 
 
207
        data = tdb_fetch(db, key);
 
208
        if (data.dptr) free(data.dptr);
 
209
 
 
210
next:
 
211
        free(k);
 
212
        free(d);
 
213
        free(s);
 
214
}
 
215
 
 
216
static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf,
 
217
                       void *state)
 
218
{
 
219
        tdb_delete(tdb, key);
 
220
        return 0;
 
221
}
 
222
 
 
223
#ifndef NPROC
 
224
#define NPROC 6
 
225
#endif
 
226
 
 
227
#ifndef NLOOPS
 
228
#define NLOOPS 200000
 
229
#endif
 
230
 
 
231
int main(int argc, char *argv[])
 
232
{
 
233
        int i, seed=0;
 
234
        int loops = NLOOPS;
 
235
        pid_t pids[NPROC];
 
236
 
 
237
        pids[0] = getpid();
 
238
 
 
239
        for (i=0;i<NPROC-1;i++) {
 
240
                if ((pids[i+1]=fork()) == 0) break;
 
241
        }
 
242
 
 
243
        db = tdb_open("torture.tdb", 2, TDB_CLEAR_IF_FIRST, 
 
244
                      O_RDWR | O_CREAT, 0600);
 
245
        if (!db) {
 
246
                fatal("db open failed");
 
247
        }
 
248
        tdb_logging_function(db, tdb_log);
 
249
 
 
250
        srand(seed + getpid());
 
251
        srandom(seed + getpid() + time(NULL));
 
252
        for (i=0;i<loops;i++) addrec_db();
 
253
 
 
254
        tdb_traverse(db, NULL, NULL);
 
255
        tdb_traverse(db, traverse_fn, NULL);
 
256
        tdb_traverse(db, traverse_fn, NULL);
 
257
 
 
258
        tdb_close(db);
 
259
 
 
260
        if (getpid() == pids[0]) {
 
261
                for (i=0;i<NPROC-1;i++) {
 
262
                        int status;
 
263
                        if (waitpid(pids[i+1], &status, 0) != pids[i+1]) {
 
264
                                printf("failed to wait for %d\n",
 
265
                                       (int)pids[i+1]);
 
266
                                exit(1);
 
267
                        }
 
268
                        if (WEXITSTATUS(status) != 0) {
 
269
                                printf("child %d exited with status %d\n",
 
270
                                       (int)pids[i+1], WEXITSTATUS(status));
 
271
                                exit(1);
 
272
                        }
 
273
                }
 
274
                printf("OK\n");
 
275
        }
 
276
 
 
277
        return 0;
 
278
}