diff options
author | Stefan Metzmacher <metze@samba.org> | 2004-05-24 16:27:23 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:56:02 -0500 |
commit | a3d61e0485c70ec5215c34b6caf40e2e6c6c5338 (patch) | |
tree | c6dd1cdffceadf0e88f5ddbde8507c49478f55fa /source4/utils | |
parent | 29a93d26cfc17dad96c74da9b05535b38552e4c0 (diff) | |
download | samba-a3d61e0485c70ec5215c34b6caf40e2e6c6c5338.tar.gz samba-a3d61e0485c70ec5215c34b6caf40e2e6c6c5338.tar.bz2 samba-a3d61e0485c70ec5215c34b6caf40e2e6c6c5338.zip |
r848: convert lib/tdb into the same layout as lib/ldb
metze
(This used to be commit bacab322ce89979f0ad0811cd15b73d81eceb69d)
Diffstat (limited to 'source4/utils')
-rw-r--r-- | source4/utils/tdb/Makefile | 29 | ||||
-rw-r--r-- | source4/utils/tdb/README | 167 | ||||
-rw-r--r-- | source4/utils/tdb/tdb.magic | 10 | ||||
-rw-r--r-- | source4/utils/tdb/tdbbackup.c | 149 | ||||
-rw-r--r-- | source4/utils/tdb/tdbdump.c | 89 | ||||
-rw-r--r-- | source4/utils/tdb/tdbtest.c | 263 | ||||
-rw-r--r-- | source4/utils/tdb/tdbtool.c | 547 | ||||
-rw-r--r-- | source4/utils/tdb/tdbtorture.c | 227 |
8 files changed, 0 insertions, 1481 deletions
diff --git a/source4/utils/tdb/Makefile b/source4/utils/tdb/Makefile deleted file mode 100644 index 59fbb079bd..0000000000 --- a/source4/utils/tdb/Makefile +++ /dev/null @@ -1,29 +0,0 @@ -# -# Makefile for tdb directory -# - -CFLAGS = -DSTANDALONE -DTDB_DEBUG -g -DHAVE_MMAP=1 -CC = gcc - -PROGS = tdbtest tdbtool tdbtorture -TDB_OBJ = tdb.o spinlock.o - -default: $(PROGS) - -tdbtest: tdbtest.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbtest tdbtest.o $(TDB_OBJ) -lgdbm - -tdbtool: tdbtool.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbtool tdbtool.o $(TDB_OBJ) - -tdbtorture: tdbtorture.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbtorture tdbtorture.o $(TDB_OBJ) - -tdbdump: tdbdump.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbdump tdbdump.o $(TDB_OBJ) - -tdbbackup: tdbbackup.o $(TDB_OBJ) - $(CC) $(CFLAGS) -o tdbbackup tdbbackup.o $(TDB_OBJ) - -clean: - rm -f $(PROGS) *.o *~ *% core test.db test.tdb test.gdbm diff --git a/source4/utils/tdb/README b/source4/utils/tdb/README deleted file mode 100644 index fac3eacb4d..0000000000 --- a/source4/utils/tdb/README +++ /dev/null @@ -1,167 +0,0 @@ -tdb - a trivial database system -tridge@linuxcare.com December 1999 -================================== - -This is a simple database API. It was inspired by the realisation that -in Samba we have several ad-hoc bits of code that essentially -implement small databases for sharing structures between parts of -Samba. As I was about to add another I realised that a generic -database module was called for to replace all the ad-hoc bits. - -I based the interface on gdbm. I couldn't use gdbm as we need to be -able to have multiple writers to the databases at one time. - -Compilation ------------ - -add HAVE_MMAP=1 to use mmap instead of read/write -add TDB_DEBUG=1 for verbose debug info -add NOLOCK=1 to disable locking code - -Testing -------- - -Compile tdbtest.c and link with gdbm for testing. tdbtest will perform -identical operations via tdb and gdbm then make sure the result is the -same - -Also included is tdbtool, which allows simple database manipulation -on the commandline. - -tdbtest and tdbtool are not built as part of Samba, but are included -for completeness. - -Interface ---------- - -The interface is very similar to gdbm except for the following: - -- different open interface. The tdb_open call is more similar to a - traditional open() -- no tdbm_reorganise() function -- no tdbm_sync() function. No operations are cached in the library anyway -- added a tdb_traverse() function for traversing the whole database - -A general rule for using tdb is that the caller frees any returned -TDB_DATA structures. Just call free(p.dptr) to free a TDB_DATA -return value called p. This is the same as gdbm. - -here is a full list of tdb functions with brief descriptions. - - ----------------------------------------------------------------------- -TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode) - - open the database, creating it if necessary - - The open_flags and mode are passed straight to the open call on the database - file. A flags value of O_WRONLY is invalid - - The hash size is advisory, use zero for a default value. - - return is NULL on error - - possible tdb_flags are: - TDB_CLEAR_IF_FIRST - clear database if we are the only one with it open - TDB_INTERNAL - don't use a file, instaed store the data in - memory. The filename is ignored in this case. - TDB_NOLOCK - don't do any locking - TDB_NOMMAP - don't use mmap - ----------------------------------------------------------------------- -char *tdb_error(TDB_CONTEXT *tdb); - - return a error string for the last tdb error - ----------------------------------------------------------------------- -int tdb_close(TDB_CONTEXT *tdb); - - close a database - ----------------------------------------------------------------------- -int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf); - - update an entry in place - this only works if the new data size - is <= the old data size and the key exists. - on failure return -1 - ----------------------------------------------------------------------- -TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); - - fetch an entry in the database given a key - if the return value has a null dptr then a error occurred - - caller must free the resulting data - ----------------------------------------------------------------------- -int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); - - check if an entry in the database exists - - note that 1 is returned if the key is found and 0 is returned if not found - this doesn't match the conventions in the rest of this module, but is - compatible with gdbm - ----------------------------------------------------------------------- -int tdb_traverse(TDB_CONTEXT *tdb, int (*fn)(TDB_CONTEXT *tdb, - TDB_DATA key, TDB_DATA dbuf, void *state), void *state); - - traverse the entire database - calling fn(tdb, key, data, state) on each - element. - - return -1 on error or the record count traversed - - if fn is NULL then it is not called - - a non-zero return value from fn() indicates that the traversal should stop - ----------------------------------------------------------------------- -TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); - - find the first entry in the database and return its key - - the caller must free the returned data - ----------------------------------------------------------------------- -TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); - - find the next entry in the database, returning its key - - the caller must free the returned data - ----------------------------------------------------------------------- -int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key); - - delete an entry in the database given a key - ----------------------------------------------------------------------- -int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag); - - store an element in the database, replacing any existing element - with the same key - - If flag==TDB_INSERT then don't overwrite an existing entry - If flag==TDB_MODIFY then don't create a new entry - - return 0 on success, -1 on failure - ----------------------------------------------------------------------- -int tdb_writelock(TDB_CONTEXT *tdb); - - lock the database. If we already have it locked then don't do anything - ----------------------------------------------------------------------- -int tdb_writeunlock(TDB_CONTEXT *tdb); - unlock the database - ----------------------------------------------------------------------- -int tdb_lockchain(TDB_CONTEXT *tdb, TDB_DATA key); - - lock one hash chain. This is meant to be used to reduce locking - contention - it cannot guarantee how many records will be locked - ----------------------------------------------------------------------- -int tdb_unlockchain(TDB_CONTEXT *tdb, TDB_DATA key); - - unlock one hash chain diff --git a/source4/utils/tdb/tdb.magic b/source4/utils/tdb/tdb.magic deleted file mode 100644 index f5619e7327..0000000000 --- a/source4/utils/tdb/tdb.magic +++ /dev/null @@ -1,10 +0,0 @@ -# Magic file(1) information about tdb files. -# -# Install this into /etc/magic or the corresponding location for your -# system, or pass as a -m argument to file(1). - -# You may use and redistribute this file without restriction. - -0 string TDB\ file TDB database ->32 lelong =0x2601196D version 6, little-endian ->>36 lelong x hash size %d bytes diff --git a/source4/utils/tdb/tdbbackup.c b/source4/utils/tdb/tdbbackup.c deleted file mode 100644 index 1a0e1c1588..0000000000 --- a/source4/utils/tdb/tdbbackup.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - Unix SMB/CIFS implementation. - low level tdb backup and restore utility - Copyright (C) Andrew Tridgell 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -/* - - This program is meant for backup/restore of tdb databases. Typical usage would be: - tdbbackup *.tdb - when Samba shuts down cleanly, which will make a backup of all the local databases - to *.bak files. Then on Samba startup you would use: - tdbbackup -v *.tdb - and this will check the databases for corruption and if corruption is detected then - the backup will be restored. - - You may also like to do a backup on a regular basis while Samba is - running, perhaps using cron. - - The reason this program is needed is to cope with power failures - while Samba is running. A power failure could lead to database - corruption and Samba will then not start correctly. - - Note that many of the databases in Samba are transient and thus - don't need to be backed up, so you can optimise the above a little - by only running the backup on the critical databases. - - */ - -#ifdef STANDALONE -#if HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <time.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <ctype.h> -#include <signal.h> - -#else - -#include "includes.h" - -#endif - -#include "tdb.h" -#include "tdbback.h" - -/* - see if one file is newer than another -*/ -static int file_newer(const char *fname1, const char *fname2) -{ - struct stat st1, st2; - if (stat(fname1, &st1) != 0) { - return 0; - } - if (stat(fname2, &st2) != 0) { - return 1; - } - return (st1.st_mtime > st2.st_mtime); -} - -static void usage(void) -{ - printf("Usage: tdbbackup [options] <fname...>\n\n"); - printf(" -h this help message\n"); - printf(" -s suffix set the backup suffix\n"); - printf(" -v verify mode (restore if corrupt)\n"); -} - - - int main(int argc, char *argv[]) -{ - int i; - int ret = 0; - int c; - int verify = 0; - const char *suffix = ".bak"; - extern int optind; - extern char *optarg; - - while ((c = getopt(argc, argv, "vhs:")) != -1) { - switch (c) { - case 'h': - usage(); - exit(0); - case 'v': - verify = 1; - break; - case 's': - suffix = optarg; - break; - } - } - - argc -= optind; - argv += optind; - - if (argc < 1) { - usage(); - exit(1); - } - - for (i=0; i<argc; i++) { - const char *fname = argv[i]; - char *bak_name; - - bak_name = add_suffix(fname, suffix); - - if (verify) { - if (verify_tdb(fname, bak_name) != 0) { - ret = 1; - } - } else { - if (file_newer(fname, bak_name) && - backup_tdb(fname, bak_name) != 0) { - ret = 1; - } - } - - free(bak_name); - } - - return ret; -} diff --git a/source4/utils/tdb/tdbdump.c b/source4/utils/tdb/tdbdump.c deleted file mode 100644 index 9c1dc2761b..0000000000 --- a/source4/utils/tdb/tdbdump.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - Unix SMB/CIFS implementation. - simple tdb dump util - Copyright (C) Andrew Tridgell 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <time.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <ctype.h> -#include <signal.h> -#include "tdb.h" - -static void print_data(TDB_DATA d) -{ - unsigned char *p = d.dptr; - int len = d.dsize; - while (len--) { - if (isprint(*p) && !strchr("\"\\", *p)) { - fputc(*p, stdout); - } else { - printf("\\%02X", *p); - } - p++; - } -} - -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("{\n"); - printf("key = \""); - print_data(key); - printf("\"\n"); - printf("data = \""); - print_data(dbuf); - printf("\"\n"); - printf("}\n"); - return 0; -} - -static int dump_tdb(const char *fname) -{ - TDB_CONTEXT *tdb; - - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - if (!tdb) { - printf("Failed to open %s\n", fname); - return 1; - } - - tdb_traverse(tdb, traverse_fn, NULL); - return 0; -} - - int main(int argc, char *argv[]) -{ - char *fname; - - if (argc < 2) { - printf("Usage: tdbdump <fname>\n"); - exit(1); - } - - fname = argv[1]; - - return dump_tdb(fname); -} diff --git a/source4/utils/tdb/tdbtest.c b/source4/utils/tdb/tdbtest.c deleted file mode 100644 index 89295a3291..0000000000 --- a/source4/utils/tdb/tdbtest.c +++ /dev/null @@ -1,263 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <stdarg.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <signal.h> -#include "tdb.h" -#include <gdbm.h> - -/* a test program for tdb - the trivial database */ - - - -#define DELETE_PROB 7 -#define STORE_PROB 5 - -static 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(char *why) -{ - perror(why); - exit(1); -} - -static void tdb_log(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(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]; - TDB_DATA key, data; - - for (i = 0; i < 5; i++) { - sprintf(keys[i], "%d", i); - key.dptr = keys[i]; - key.dsize = 2; - - data.dptr = "test"; - 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); -} - -int main(int argc, char *argv[]) -{ - int i, seed=0; - int loops = 10000; - - 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"); - } - - tdb_logging_function(db, tdb_log); - -#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()); - - 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); - - return 0; -} diff --git a/source4/utils/tdb/tdbtool.c b/source4/utils/tdb/tdbtool.c deleted file mode 100644 index 92009dcef4..0000000000 --- a/source4/utils/tdb/tdbtool.c +++ /dev/null @@ -1,547 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Samba database functions - Copyright (C) Andrew Tridgell 1999-2000 - Copyright (C) Paul `Rusty' Russell 2000 - Copyright (C) Jeremy Allison 2000 - Copyright (C) Andrew Esh 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <time.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <ctype.h> -#include <signal.h> -#include "tdb.h" - -/* a tdb tool for manipulating a tdb database */ - -#define FSTRING_LEN 256 -typedef char fstring[FSTRING_LEN]; - -typedef struct connections_key { - pid_t pid; - int cnum; - fstring name; -} connections_key; - -typedef struct connections_data { - int magic; - pid_t pid; - int cnum; - uid_t uid; - gid_t gid; - char name[24]; - char addr[24]; - char machine[128]; - time_t start; -} connections_data; - -static TDB_CONTEXT *tdb; - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); - -static void print_asc(unsigned char *buf,int len) -{ - int i; - - /* We're probably printing ASCII strings so don't try to display - the trailing NULL character. */ - - if (buf[len - 1] == 0) - len--; - - for (i=0;i<len;i++) - printf("%c",isprint(buf[i])?buf[i]:'.'); -} - -static void print_data(unsigned char *buf,int len) -{ - int i=0; - if (len<=0) return; - printf("[%03X] ",i); - for (i=0;i<len;) { - printf("%02X ",(int)buf[i]); - i++; - if (i%8 == 0) printf(" "); - if (i%16 == 0) { - print_asc(&buf[i-16],8); printf(" "); - print_asc(&buf[i-8],8); printf("\n"); - if (i<len) printf("[%03X] ",i); - } - } - if (i%16) { - int n; - - n = 16 - (i%16); - printf(" "); - if (n>8) printf(" "); - while (n--) printf(" "); - - n = i%16; - if (n > 8) n = 8; - print_asc(&buf[i-(i%16)],n); printf(" "); - n = (i%16) - n; - if (n>0) print_asc(&buf[i-n],n); - printf("\n"); - } -} - -static void help(void) -{ - printf("\n" -"tdbtool: \n" -" create dbname : create a database\n" -" open dbname : open an existing database\n" -" erase : erase the database\n" -" dump : dump the database as strings\n" -" insert key data : insert a record\n" -" move key file : move a record to a destination tdb\n" -" store key data : store a record (replace)\n" -" show key : show a record by key\n" -" delete key : delete a record by key\n" -" list : print the database hash table and freelist\n" -" free : print the database freelist\n" -" 1 | first : print the first record\n" -" n | next : print the next record\n" -" q | quit : terminate\n" -" \\n : repeat 'next' command\n" -"\n"); -} - -static void terror(char *why) -{ - printf("%s\n", why); -} - -static char *get_token(int startover) -{ - static char tmp[1024]; - static char *cont = NULL; - char *insert, *start; - char *k = strtok(NULL, " "); - - if (!k) - return NULL; - - if (startover) - start = tmp; - else - start = cont; - - strcpy(start, k); - insert = start + strlen(start) - 1; - while (*insert == '\\') { - *insert++ = ' '; - k = strtok(NULL, " "); - if (!k) - break; - strcpy(insert, k); - insert = start + strlen(start) - 1; - } - - /* Get ready for next call */ - cont = start + strlen(start) + 1; - return start; -} - -static void create_tdb(void) -{ - char *tok = get_token(1); - if (!tok) { - help(); - return; - } - if (tdb) tdb_close(tdb); - tdb = tdb_open(tok, 0, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT | O_TRUNC, 0600); - if (!tdb) { - printf("Could not create %s: %s\n", tok, strerror(errno)); - } -} - -static void open_tdb(void) -{ - char *tok = get_token(1); - if (!tok) { - help(); - return; - } - if (tdb) tdb_close(tdb); - tdb = tdb_open(tok, 0, 0, O_RDWR, 0600); - if (!tdb) { - printf("Could not open %s: %s\n", tok, strerror(errno)); - } -} - -static void insert_tdb(void) -{ - char *k = get_token(1); - char *d = get_token(0); - TDB_DATA key, dbuf; - - if (!k || !d) { - help(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - dbuf.dptr = d; - dbuf.dsize = strlen(d)+1; - - if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) { - terror("insert failed"); - } -} - -static void store_tdb(void) -{ - char *k = get_token(1); - char *d = get_token(0); - TDB_DATA key, dbuf; - - if (!k || !d) { - help(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - dbuf.dptr = d; - dbuf.dsize = strlen(d)+1; - - printf("Storing key:\n"); - print_rec(tdb, key, dbuf, NULL); - - if (tdb_store(tdb, key, dbuf, TDB_REPLACE) == -1) { - terror("store failed"); - } -} - -static void show_tdb(void) -{ - char *k = get_token(1); - TDB_DATA key, dbuf; - - if (!k) { - help(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - /* maybe it is non-NULL terminated key? */ - key.dsize = strlen(k); - dbuf = tdb_fetch(tdb, key); - - if ( !dbuf.dptr ) { - terror("fetch failed"); - return; - } - } - - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ - print_rec(tdb, key, dbuf, NULL); - - free( dbuf.dptr ); - - return; -} - -static void delete_tdb(void) -{ - char *k = get_token(1); - TDB_DATA key; - - if (!k) { - help(); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - - if (tdb_delete(tdb, key) != 0) { - terror("delete failed"); - } -} - -static void move_rec(void) -{ - char *k = get_token(1); - char *file = get_token(0); - TDB_DATA key, dbuf; - TDB_CONTEXT *dst_tdb; - - if (!k) { - help(); - return; - } - - if ( !file ) { - terror("need destination tdb name"); - return; - } - - key.dptr = k; - key.dsize = strlen(k)+1; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - /* maybe it is non-NULL terminated key? */ - key.dsize = strlen(k); - dbuf = tdb_fetch(tdb, key); - - if ( !dbuf.dptr ) { - terror("fetch failed"); - return; - } - } - - print_rec(tdb, key, dbuf, NULL); - - dst_tdb = tdb_open(file, 0, 0, O_RDWR, 0600); - if ( !dst_tdb ) { - terror("unable to open destination tdb"); - return; - } - - if ( tdb_store( dst_tdb, key, dbuf, TDB_REPLACE ) == -1 ) { - terror("failed to move record"); - } - else - printf("record moved\n"); - - tdb_close( dst_tdb ); - - return; -} - -#if 0 -static int print_conn_key(TDB_DATA key) -{ - printf( "pid =%5d ", ((connections_key*)key.dptr)->pid); - printf( "cnum =%10d ", ((connections_key*)key.dptr)->cnum); - printf( "name =[%s]\n", ((connections_key*)key.dptr)->name); - return 0; -} - -static int print_conn_data(TDB_DATA dbuf) -{ - printf( "pid =%5d ", ((connections_data*)dbuf.dptr)->pid); - printf( "cnum =%10d ", ((connections_data*)dbuf.dptr)->cnum); - printf( "name =[%s]\n", ((connections_data*)dbuf.dptr)->name); - - printf( "uid =%5d ", ((connections_data*)dbuf.dptr)->uid); - printf( "addr =[%s]\n", ((connections_data*)dbuf.dptr)->addr); - printf( "gid =%5d ", ((connections_data*)dbuf.dptr)->gid); - printf( "machine=[%s]\n", ((connections_data*)dbuf.dptr)->machine); - printf( "start = %s\n", ctime(&((connections_data*)dbuf.dptr)->start)); - return 0; -} -#endif - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ -#if 0 - print_conn_key(key); - print_conn_data(dbuf); - return 0; -#else - printf("\nkey %d bytes\n", key.dsize); - print_asc(key.dptr, key.dsize); - printf("\ndata %d bytes\n", dbuf.dsize); - print_data(dbuf.dptr, dbuf.dsize); - return 0; -#endif -} - -static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - print_asc(key.dptr, key.dsize); - printf("\n"); - return 0; -} - -static int total_bytes; - -static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - total_bytes += dbuf.dsize; - return 0; -} - -static void info_tdb(void) -{ - int count; - total_bytes = 0; - if ((count = tdb_traverse(tdb, traverse_fn, NULL) == -1)) - printf("Error = %s\n", tdb_errorstr(tdb)); - else - printf("%d records totalling %d bytes\n", count, total_bytes); -} - -static char *tdb_getline(char *prompt) -{ - static char line[1024]; - char *p; - fputs(prompt, stdout); - line[0] = 0; - p = fgets(line, sizeof(line)-1, stdin); - if (p) p = strchr(p, '\n'); - if (p) *p = 0; - return p?line:NULL; -} - -static int do_delete_fn(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ - return tdb_delete(the_tdb, key); -} - -static void first_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) -{ - TDB_DATA dbuf; - *pkey = tdb_firstkey(the_tdb); - - dbuf = tdb_fetch(the_tdb, *pkey); - if (!dbuf.dptr) terror("fetch failed"); - else { - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ - print_rec(the_tdb, *pkey, dbuf, NULL); - } -} - -static void next_record(TDB_CONTEXT *the_tdb, TDB_DATA *pkey) -{ - TDB_DATA dbuf; - *pkey = tdb_nextkey(the_tdb, *pkey); - - dbuf = tdb_fetch(the_tdb, *pkey); - if (!dbuf.dptr) - terror("fetch failed"); - else - /* printf("%s : %*.*s\n", k, (int)dbuf.dsize, (int)dbuf.dsize, dbuf.dptr); */ - print_rec(the_tdb, *pkey, dbuf, NULL); -} - -int main(int argc, char *argv[]) -{ - int bIterate = 0; - char *line; - char *tok; - TDB_DATA iterate_kbuf; - - if (argv[1]) { - static char tmp[1024]; - sprintf(tmp, "open %s", argv[1]); - tok=strtok(tmp," "); - open_tdb(); - } - - while ((line = tdb_getline("tdb> "))) { - - /* Shell command */ - - if (line[0] == '!') { - system(line + 1); - continue; - } - - if ((tok = strtok(line," "))==NULL) { - if (bIterate) - next_record(tdb, &iterate_kbuf); - continue; - } - if (strcmp(tok,"create") == 0) { - bIterate = 0; - create_tdb(); - continue; - } else if (strcmp(tok,"open") == 0) { - open_tdb(); - continue; - } else if ((strcmp(tok, "q") == 0) || - (strcmp(tok, "quit") == 0)) { - break; - } - - /* all the rest require a open database */ - if (!tdb) { - bIterate = 0; - terror("database not open"); - help(); - continue; - } - - if (strcmp(tok,"insert") == 0) { - bIterate = 0; - insert_tdb(); - } else if (strcmp(tok,"store") == 0) { - bIterate = 0; - store_tdb(); - } else if (strcmp(tok,"show") == 0) { - bIterate = 0; - show_tdb(); - } else if (strcmp(tok,"erase") == 0) { - bIterate = 0; - tdb_traverse(tdb, do_delete_fn, NULL); - } else if (strcmp(tok,"delete") == 0) { - bIterate = 0; - delete_tdb(); - } else if (strcmp(tok,"dump") == 0) { - bIterate = 0; - tdb_traverse(tdb, print_rec, NULL); - } else if (strcmp(tok,"move") == 0) { - bIterate = 0; - move_rec(); - } else if (strcmp(tok,"list") == 0) { - tdb_dump_all(tdb); - } else if (strcmp(tok, "free") == 0) { - tdb_printfreelist(tdb); - } else if (strcmp(tok,"info") == 0) { - info_tdb(); - } else if ( (strcmp(tok, "1") == 0) || - (strcmp(tok, "first") == 0)) { - bIterate = 1; - first_record(tdb, &iterate_kbuf); - } else if ((strcmp(tok, "n") == 0) || - (strcmp(tok, "next") == 0)) { - next_record(tdb, &iterate_kbuf); - } else if ((strcmp(tok, "keys") == 0)) { - bIterate = 0; - tdb_traverse(tdb, print_key, NULL); - } else { - help(); - } - } - - if (tdb) tdb_close(tdb); - - return 0; -} diff --git a/source4/utils/tdb/tdbtorture.c b/source4/utils/tdb/tdbtorture.c deleted file mode 100644 index 3f704e537e..0000000000 --- a/source4/utils/tdb/tdbtorture.c +++ /dev/null @@ -1,227 +0,0 @@ -#include <stdlib.h> -#include <time.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <signal.h> -#include <stdarg.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/wait.h> -#include "tdb.h" - -/* this tests tdb by doing lots of ops from several simultaneous - writers - that stresses the locking code. Build with TDB_DEBUG=1 - for best effect */ - - - -#define REOPEN_PROB 30 -#define DELETE_PROB 8 -#define STORE_PROB 4 -#define APPEND_PROB 6 -#define LOCKSTORE_PROB 0 -#define TRAVERSE_PROB 20 -#define CULL_PROB 100 -#define KEYLEN 3 -#define DATALEN 100 -#define LOCKLEN 20 - -static TDB_CONTEXT *db; - -static void tdb_log(TDB_CONTEXT *tdb, int level, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - vfprintf(stdout, format, ap); - va_end(ap); - fflush(stdout); -#if 0 - { - char *ptr; - asprintf(&ptr,"xterm -e gdb /proc/%d/exe %d", getpid(), getpid()); - system(ptr); - free(ptr); - } -#endif -} - -static void fatal(char *why) -{ - perror(why); - exit(1); -} - -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(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ - if (random() % CULL_PROB == 0) { - tdb_delete(tdb, key); - } - return 0; -} - -static void addrec_db(void) -{ - int klen, dlen, slen; - char *k, *d, *s; - TDB_DATA key, data, lockkey; - - klen = 1 + (rand() % KEYLEN); - dlen = 1 + (rand() % DATALEN); - slen = 1 + (rand() % LOCKLEN); - - k = randbuf(klen); - d = randbuf(dlen); - s = randbuf(slen); - - key.dptr = k; - key.dsize = klen+1; - - data.dptr = d; - data.dsize = dlen+1; - - lockkey.dptr = s; - lockkey.dsize = slen+1; - -#if REOPEN_PROB - if (random() % REOPEN_PROB == 0) { - tdb_reopen_all(); - 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, lockkey); - 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, lockkey); - goto next; - } -#endif - -#if TRAVERSE_PROB - if (random() % TRAVERSE_PROB == 0) { - tdb_traverse(db, cull_traverse, NULL); - goto next; - } -#endif - - data = tdb_fetch(db, key); - if (data.dptr) free(data.dptr); - -next: - free(k); - free(d); - free(s); -} - -static int traverse_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, - void *state) -{ - tdb_delete(tdb, key); - return 0; -} - -#ifndef NPROC -#define NPROC 6 -#endif - -#ifndef NLOOPS -#define NLOOPS 200000 -#endif - -int main(int argc, char *argv[]) -{ - int i, seed=0; - int loops = NLOOPS; - pid_t pids[NPROC]; - - pids[0] = getpid(); - - for (i=0;i<NPROC-1;i++) { - if ((pids[i+1]=fork()) == 0) break; - } - - db = tdb_open("torture.tdb", 2, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT, 0600); - if (!db) { - fatal("db open failed"); - } - tdb_logging_function(db, tdb_log); - - srand(seed + getpid()); - srandom(seed + getpid() + time(NULL)); - for (i=0;i<loops;i++) addrec_db(); - - tdb_traverse(db, NULL, NULL); - tdb_traverse(db, traverse_fn, NULL); - tdb_traverse(db, traverse_fn, NULL); - - tdb_close(db); - - if (getpid() == pids[0]) { - for (i=0;i<NPROC-1;i++) { - int status; - if (waitpid(pids[i+1], &status, 0) != pids[i+1]) { - printf("failed to wait for %d\n", - (int)pids[i+1]); - exit(1); - } - if (WEXITSTATUS(status) != 0) { - printf("child %d exited with status %d\n", - (int)pids[i+1], WEXITSTATUS(status)); - exit(1); - } - } - printf("OK\n"); - } - - return 0; -} |