diff options
author | Jelmer Vernooij <jelmer@samba.org> | 2008-09-16 16:44:16 +0200 |
---|---|---|
committer | Jelmer Vernooij <jelmer@samba.org> | 2008-09-16 16:44:16 +0200 |
commit | f957aeaee64745148b815393b1fc1338104ed2e1 (patch) | |
tree | 3ab8268492918549f36f01faa6f90335b54bc789 /source4/lib/tdb/tools | |
parent | 80a5da73e9a9ed148314be3fa071181c82fc7c64 (diff) | |
parent | 8ec93160d5cf2a0f917c1e1304127625e38ec2e0 (diff) | |
download | samba-f957aeaee64745148b815393b1fc1338104ed2e1.tar.gz samba-f957aeaee64745148b815393b1fc1338104ed2e1.tar.bz2 samba-f957aeaee64745148b815393b1fc1338104ed2e1.zip |
Merge branch 'singletdb' into single
Diffstat (limited to 'source4/lib/tdb/tools')
-rw-r--r-- | source4/lib/tdb/tools/tdbbackup.c | 300 | ||||
-rw-r--r-- | source4/lib/tdb/tools/tdbdump.c | 116 | ||||
-rw-r--r-- | source4/lib/tdb/tools/tdbtest.c | 265 | ||||
-rw-r--r-- | source4/lib/tdb/tools/tdbtool.c | 659 | ||||
-rw-r--r-- | source4/lib/tdb/tools/tdbtorture.c | 318 |
5 files changed, 0 insertions, 1658 deletions
diff --git a/source4/lib/tdb/tools/tdbbackup.c b/source4/lib/tdb/tools/tdbbackup.c deleted file mode 100644 index 6f3ca48314..0000000000 --- a/source4/lib/tdb/tools/tdbbackup.c +++ /dev/null @@ -1,300 +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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -/* - - 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. - - */ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -#ifdef HAVE_GETOPT_H -#include <getopt.h> -#endif - -static int failed; - -static char *add_suffix(const char *name, const char *suffix) -{ - char *ret; - int len = strlen(name) + strlen(suffix) + 1; - ret = (char *)malloc(len); - if (!ret) { - fprintf(stderr,"Out of memory!\n"); - exit(1); - } - snprintf(ret, len, "%s%s", name, suffix); - return ret; -} - -static int copy_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - TDB_CONTEXT *tdb_new = (TDB_CONTEXT *)state; - - if (tdb_store(tdb_new, key, dbuf, TDB_INSERT) != 0) { - fprintf(stderr,"Failed to insert into %s\n", tdb_name(tdb_new)); - failed = 1; - return 1; - } - return 0; -} - - -static int test_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - return 0; -} - -/* - carefully backup a tdb, validating the contents and - only doing the backup if its OK - this function is also used for restore -*/ -static int backup_tdb(const char *old_name, const char *new_name, int hash_size) -{ - TDB_CONTEXT *tdb; - TDB_CONTEXT *tdb_new; - char *tmp_name; - struct stat st; - int count1, count2; - - tmp_name = add_suffix(new_name, ".tmp"); - - /* stat the old tdb to find its permissions */ - if (stat(old_name, &st) != 0) { - perror(old_name); - free(tmp_name); - return 1; - } - - /* open the old tdb */ - tdb = tdb_open(old_name, 0, 0, O_RDWR, 0); - if (!tdb) { - printf("Failed to open %s\n", old_name); - free(tmp_name); - return 1; - } - - /* create the new tdb */ - unlink(tmp_name); - tdb_new = tdb_open(tmp_name, - hash_size ? hash_size : tdb_hash_size(tdb), - TDB_DEFAULT, O_RDWR|O_CREAT|O_EXCL, - st.st_mode & 0777); - if (!tdb_new) { - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* lock the old tdb */ - if (tdb_lockall(tdb) != 0) { - fprintf(stderr,"Failed to lock %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - failed = 0; - - /* traverse and copy */ - count1 = tdb_traverse(tdb, copy_fn, (void *)tdb_new); - if (count1 < 0 || failed) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* close the old tdb */ - tdb_close(tdb); - - /* close the new tdb and re-open read-only */ - tdb_close(tdb_new); - tdb_new = tdb_open(tmp_name, 0, TDB_DEFAULT, O_RDONLY, 0); - if (!tdb_new) { - fprintf(stderr,"failed to reopen %s\n", tmp_name); - unlink(tmp_name); - perror(tmp_name); - free(tmp_name); - return 1; - } - - /* traverse the new tdb to confirm */ - count2 = tdb_traverse(tdb_new, test_fn, NULL); - if (count2 != count1) { - fprintf(stderr,"failed to copy %s\n", old_name); - tdb_close(tdb_new); - unlink(tmp_name); - free(tmp_name); - return 1; - } - - /* make sure the new tdb has reached stable storage */ - fsync(tdb_fd(tdb_new)); - - /* close the new tdb and rename it to .bak */ - tdb_close(tdb_new); - if (rename(tmp_name, new_name) != 0) { - perror(new_name); - free(tmp_name); - return 1; - } - - free(tmp_name); - - return 0; -} - -/* - verify a tdb and if it is corrupt then restore from *.bak -*/ -static int verify_tdb(const char *fname, const char *bak_name) -{ - TDB_CONTEXT *tdb; - int count = -1; - - /* open the tdb */ - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - - /* traverse the tdb, then close it */ - if (tdb) { - count = tdb_traverse(tdb, test_fn, NULL); - tdb_close(tdb); - } - - /* count is < 0 means an error */ - if (count < 0) { - printf("restoring %s\n", fname); - return backup_tdb(bak_name, fname, 0); - } - - printf("%s : %d records\n", fname, count); - - return 0; -} - -/* - 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"); - printf(" -n hashsize set the new hash size for the backup\n"); -} - - - int main(int argc, char *argv[]) -{ - int i; - int ret = 0; - int c; - int verify = 0; - int hashsize = 0; - const char *suffix = ".bak"; - - while ((c = getopt(argc, argv, "vhs:n:")) != -1) { - switch (c) { - case 'h': - usage(); - exit(0); - case 'v': - verify = 1; - break; - case 's': - suffix = optarg; - break; - case 'n': - hashsize = atoi(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, hashsize) != 0) { - ret = 1; - } - } - - free(bak_name); - } - - return ret; -} diff --git a/source4/lib/tdb/tools/tdbdump.c b/source4/lib/tdb/tools/tdbdump.c deleted file mode 100644 index 8d930383b0..0000000000 --- a/source4/lib/tdb/tools/tdbdump.c +++ /dev/null @@ -1,116 +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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -static void print_data(TDB_DATA d) -{ - unsigned char *p = (unsigned char *)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(%d) = \"", (int)key.dsize); - print_data(key); - printf("\"\n"); - printf("data(%d) = \"", (int)dbuf.dsize); - print_data(dbuf); - printf("\"\n"); - printf("}\n"); - return 0; -} - -static int dump_tdb(const char *fname, const char *keyname) -{ - TDB_CONTEXT *tdb; - TDB_DATA key, value; - - tdb = tdb_open(fname, 0, 0, O_RDONLY, 0); - if (!tdb) { - printf("Failed to open %s\n", fname); - return 1; - } - - if (!keyname) { - tdb_traverse(tdb, traverse_fn, NULL); - } else { - key.dptr = discard_const_p(uint8_t,keyname); - key.dsize = strlen( keyname); - value = tdb_fetch(tdb, key); - if (!value.dptr) { - return 1; - } else { - print_data(value); - free(value.dptr); - } - } - - return 0; -} - -static void usage( void) -{ - printf( "Usage: tdbdump [options] <filename>\n\n"); - printf( " -h this help message\n"); - printf( " -k keyname dumps value of keyname\n"); -} - - int main(int argc, char *argv[]) -{ - char *fname, *keyname=NULL; - int c; - - if (argc < 2) { - printf("Usage: tdbdump <fname>\n"); - exit(1); - } - - while ((c = getopt( argc, argv, "hk:")) != -1) { - switch (c) { - case 'h': - usage(); - exit( 0); - case 'k': - keyname = optarg; - break; - default: - usage(); - exit( 1); - } - } - - fname = argv[optind]; - - return dump_tdb(fname, keyname); -} diff --git a/source4/lib/tdb/tools/tdbtest.c b/source4/lib/tdb/tools/tdbtest.c deleted file mode 100644 index 416bc50a5b..0000000000 --- a/source4/lib/tdb/tools/tdbtest.c +++ /dev/null @@ -1,265 +0,0 @@ -/* a test program for tdb - the trivial database */ - -#include "replace.h" -#include "tdb.h" -#include "system/filesys.h" -#include "system/time.h" - -#include <gdbm.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); -} - - int main(int argc, const char *argv[]) -{ - int i, seed=0; - int loops = 10000; - int num_entries; - char test_gdbm[] = "test.gdbm"; - - 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); - - return 0; -} diff --git a/source4/lib/tdb/tools/tdbtool.c b/source4/lib/tdb/tools/tdbtool.c deleted file mode 100644 index d104ccd7c4..0000000000 --- a/source4/lib/tdb/tools/tdbtool.c +++ /dev/null @@ -1,659 +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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "replace.h" -#include "system/locale.h" -#include "system/time.h" -#include "system/filesys.h" -#include "system/wait.h" -#include "tdb.h" - -static int do_command(void); -const char *cmdname; -char *arg1, *arg2; -size_t arg1len, arg2len; -int bIterate = 0; -char *line; -TDB_DATA iterate_kbuf; -char cmdline[1024]; -static int disable_mmap; - -enum commands { - CMD_CREATE_TDB, - CMD_OPEN_TDB, - CMD_ERASE, - CMD_DUMP, - CMD_INSERT, - CMD_MOVE, - CMD_STORE, - CMD_SHOW, - CMD_KEYS, - CMD_HEXKEYS, - CMD_DELETE, - CMD_LIST_HASH_FREE, - CMD_LIST_FREE, - CMD_INFO, - CMD_MMAP, - CMD_SPEED, - CMD_FIRST, - CMD_NEXT, - CMD_SYSTEM, - CMD_QUIT, - CMD_HELP -}; - -typedef struct { - const char *name; - enum commands cmd; -} COMMAND_TABLE; - -COMMAND_TABLE cmd_table[] = { - {"create", CMD_CREATE_TDB}, - {"open", CMD_OPEN_TDB}, - {"erase", CMD_ERASE}, - {"dump", CMD_DUMP}, - {"insert", CMD_INSERT}, - {"move", CMD_MOVE}, - {"store", CMD_STORE}, - {"show", CMD_SHOW}, - {"keys", CMD_KEYS}, - {"hexkeys", CMD_HEXKEYS}, - {"delete", CMD_DELETE}, - {"list", CMD_LIST_HASH_FREE}, - {"free", CMD_LIST_FREE}, - {"info", CMD_INFO}, - {"speed", CMD_SPEED}, - {"mmap", CMD_MMAP}, - {"first", CMD_FIRST}, - {"1", CMD_FIRST}, - {"next", CMD_NEXT}, - {"n", CMD_NEXT}, - {"quit", CMD_QUIT}, - {"q", CMD_QUIT}, - {"!", CMD_SYSTEM}, - {NULL, CMD_HELP} -}; - -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); -} - -/* a tdb tool for manipulating a tdb database */ - -static TDB_CONTEXT *tdb; - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); -static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); -static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state); - -static void print_asc(const 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(const char *buf,int len) -{ - int i=0; - if (len<=0) return; - printf("[%03X] ",i); - for (i=0;i<len;) { - printf("%02X ",(int)((unsigned char)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" -" keys : dump the database keys as strings\n" -" hexkeys : dump the database keys as hex values\n" -" info : print summary info about the database\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" -" ! command : execute system command\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(const char *why) -{ - printf("%s\n", why); -} - -static void create_tdb(const char *tdbname) -{ - if (tdb) tdb_close(tdb); - tdb = tdb_open(tdbname, 0, TDB_CLEAR_IF_FIRST | (disable_mmap?TDB_NOMMAP:0), - O_RDWR | O_CREAT | O_TRUNC, 0600); - if (!tdb) { - printf("Could not create %s: %s\n", tdbname, strerror(errno)); - } -} - -static void open_tdb(const char *tdbname) -{ - if (tdb) tdb_close(tdb); - tdb = tdb_open(tdbname, 0, disable_mmap?TDB_NOMMAP:0, O_RDWR, 0600); - if (!tdb) { - printf("Could not open %s: %s\n", tdbname, strerror(errno)); - } -} - -static void insert_tdb(char *keyname, size_t keylen, char* data, size_t datalen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - dbuf.dptr = (unsigned char *)data; - dbuf.dsize = datalen; - - if (tdb_store(tdb, key, dbuf, TDB_INSERT) == -1) { - terror("insert failed"); - } -} - -static void store_tdb(char *keyname, size_t keylen, char* data, size_t datalen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - if ((data == NULL) || (datalen == 0)) { - terror("need data"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - dbuf.dptr = (unsigned char *)data; - dbuf.dsize = datalen; - - 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(char *keyname, size_t keylen) -{ - TDB_DATA key, dbuf; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - terror("fetch failed"); - return; - } - - print_rec(tdb, key, dbuf, NULL); - - free( dbuf.dptr ); - - return; -} - -static void delete_tdb(char *keyname, size_t keylen) -{ - TDB_DATA key; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - - if (tdb_delete(tdb, key) != 0) { - terror("delete failed"); - } -} - -static void move_rec(char *keyname, size_t keylen, char* tdbname) -{ - TDB_DATA key, dbuf; - TDB_CONTEXT *dst_tdb; - - if ((keyname == NULL) || (keylen == 0)) { - terror("need key"); - return; - } - - if ( !tdbname ) { - terror("need destination tdb name"); - return; - } - - key.dptr = (unsigned char *)keyname; - key.dsize = keylen; - - dbuf = tdb_fetch(tdb, key); - if (!dbuf.dptr) { - terror("fetch failed"); - return; - } - - print_rec(tdb, key, dbuf, NULL); - - dst_tdb = tdb_open(tdbname, 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; -} - -static int print_rec(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("\nkey %d bytes\n", (int)key.dsize); - print_asc((const char *)key.dptr, key.dsize); - printf("\ndata %d bytes\n", (int)dbuf.dsize); - print_data((const char *)dbuf.dptr, dbuf.dsize); - return 0; -} - -static int print_key(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("key %d bytes: ", (int)key.dsize); - print_asc((const char *)key.dptr, key.dsize); - printf("\n"); - return 0; -} - -static int print_hexkey(TDB_CONTEXT *the_tdb, TDB_DATA key, TDB_DATA dbuf, void *state) -{ - printf("key %d bytes\n", (int)key.dsize); - print_data((const char *)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 void speed_tdb(const char *tlimit) -{ - unsigned timelimit = tlimit?atoi(tlimit):0; - double t; - int ops=0; - if (timelimit == 0) timelimit = 10; - printf("Testing traverse speed for %u seconds\n", timelimit); - _start_timer(); - while ((t=_end_timer()) < timelimit) { - tdb_traverse(tdb, traverse_fn, NULL); - printf("%10.3f ops/sec\r", (++ops)/t); - } - printf("\n"); -} - -static void toggle_mmap(void) -{ - disable_mmap = !disable_mmap; - if (disable_mmap) { - printf("mmap is disabled\n"); - } else { - printf("mmap is enabled\n"); - } -} - -static char *tdb_getline(const char *prompt) -{ - static char thisline[1024]; - char *p; - fputs(prompt, stdout); - thisline[0] = 0; - p = fgets(thisline, sizeof(thisline)-1, stdin); - if (p) p = strchr(p, '\n'); - if (p) *p = 0; - return p?thisline: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 { - 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 - print_rec(the_tdb, *pkey, dbuf, NULL); -} - -static int do_command(void) -{ - COMMAND_TABLE *ctp = cmd_table; - enum commands mycmd = CMD_HELP; - int cmd_len; - - if (cmdname && strlen(cmdname) == 0) { - mycmd = CMD_NEXT; - } else { - while (ctp->name) { - cmd_len = strlen(ctp->name); - if (strncmp(ctp->name,cmdname,cmd_len) == 0) { - mycmd = ctp->cmd; - break; - } - ctp++; - } - } - - switch (mycmd) { - case CMD_CREATE_TDB: - bIterate = 0; - create_tdb(arg1); - return 0; - case CMD_OPEN_TDB: - bIterate = 0; - open_tdb(arg1); - return 0; - case CMD_SYSTEM: - /* Shell command */ - system(arg1); - return 0; - case CMD_QUIT: - return 1; - default: - /* all the rest require a open database */ - if (!tdb) { - bIterate = 0; - terror("database not open"); - help(); - return 0; - } - switch (mycmd) { - case CMD_ERASE: - bIterate = 0; - tdb_traverse(tdb, do_delete_fn, NULL); - return 0; - case CMD_DUMP: - bIterate = 0; - tdb_traverse(tdb, print_rec, NULL); - return 0; - case CMD_INSERT: - bIterate = 0; - insert_tdb(arg1, arg1len,arg2,arg2len); - return 0; - case CMD_MOVE: - bIterate = 0; - move_rec(arg1,arg1len,arg2); - return 0; - case CMD_STORE: - bIterate = 0; - store_tdb(arg1,arg1len,arg2,arg2len); - return 0; - case CMD_SHOW: - bIterate = 0; - show_tdb(arg1, arg1len); - return 0; - case CMD_KEYS: - tdb_traverse(tdb, print_key, NULL); - return 0; - case CMD_HEXKEYS: - tdb_traverse(tdb, print_hexkey, NULL); - return 0; - case CMD_DELETE: - bIterate = 0; - delete_tdb(arg1,arg1len); - return 0; - case CMD_LIST_HASH_FREE: - tdb_dump_all(tdb); - return 0; - case CMD_LIST_FREE: - tdb_printfreelist(tdb); - return 0; - case CMD_INFO: - info_tdb(); - return 0; - case CMD_SPEED: - speed_tdb(arg1); - return 0; - case CMD_MMAP: - toggle_mmap(); - return 0; - case CMD_FIRST: - bIterate = 1; - first_record(tdb, &iterate_kbuf); - return 0; - case CMD_NEXT: - if (bIterate) - next_record(tdb, &iterate_kbuf); - return 0; - case CMD_HELP: - help(); - return 0; - case CMD_CREATE_TDB: - case CMD_OPEN_TDB: - case CMD_SYSTEM: - case CMD_QUIT: - /* - * unhandled commands. cases included here to avoid compiler - * warnings. - */ - return 0; - } - } - - return 0; -} - -static char *convert_string(char *instring, size_t *sizep) -{ - size_t length = 0; - char *outp, *inp; - char temp[3]; - - - outp = inp = instring; - - while (*inp) { - if (*inp == '\\') { - inp++; - if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { - temp[0] = *inp++; - temp[1] = '\0'; - if (*inp && strchr("0123456789abcdefABCDEF",(int)*inp)) { - temp[1] = *inp++; - temp[2] = '\0'; - } - *outp++ = (char)strtol((const char *)temp,NULL,16); - } else { - *outp++ = *inp++; - } - } else { - *outp++ = *inp++; - } - length++; - } - *sizep = length; - return instring; -} - -int main(int argc, char *argv[]) -{ - cmdname = ""; - arg1 = NULL; - arg1len = 0; - arg2 = NULL; - arg2len = 0; - - if (argv[1]) { - cmdname = "open"; - arg1 = argv[1]; - do_command(); - cmdname = ""; - arg1 = NULL; - } - - switch (argc) { - case 1: - case 2: - /* Interactive mode */ - while ((cmdname = tdb_getline("tdb> "))) { - arg2 = arg1 = NULL; - if ((arg1 = strchr((const char *)cmdname,' ')) != NULL) { - arg1++; - arg2 = arg1; - while (*arg2) { - if (*arg2 == ' ') { - *arg2++ = '\0'; - break; - } - if ((*arg2++ == '\\') && (*arg2 == ' ')) { - arg2++; - } - } - } - if (arg1) arg1 = convert_string(arg1,&arg1len); - if (arg2) arg2 = convert_string(arg2,&arg2len); - if (do_command()) break; - } - break; - case 5: - arg2 = convert_string(argv[4],&arg2len); - case 4: - arg1 = convert_string(argv[3],&arg1len); - case 3: - cmdname = argv[2]; - default: - do_command(); - break; - } - - if (tdb) tdb_close(tdb); - - return 0; -} diff --git a/source4/lib/tdb/tools/tdbtorture.c b/source4/lib/tdb/tools/tdbtorture.c deleted file mode 100644 index 9265cf07aa..0000000000 --- a/source4/lib/tdb/tools/tdbtorture.c +++ /dev/null @@ -1,318 +0,0 @@ -/* this tests tdb by doing lots of ops from several simultaneous - writers - that stresses the locking code. -*/ - -#include "replace.h" -#include "system/time.h" -#include "system/wait.h" -#include "system/filesys.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 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; - -#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; - - error_count++; - - 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(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 TRANSACTION_PROB - if (in_transaction == 0 && 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 (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 REOPEN_PROB - if (in_transaction == 0 && random() % REOPEN_PROB == 0) { - tdb_reopen_all(0); - 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 [-n NUM_PROCS] [-l NUM_LOOPS] [-s SEED] [-H HASH_SIZE]\n"); - exit(0); -} - - int main(int argc, char * const *argv) -{ - int i, seed = -1; - int num_procs = 3; - int num_loops = 5000; - int hash_size = 2; - int c; - extern char *optarg; - pid_t *pids; - - struct tdb_logging_context log_ctx; - log_ctx.log_fn = tdb_log; - - while ((c = getopt(argc, argv, "n:l:s:H:h")) != -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; - default: - usage(); - } - } - - unlink("torture.tdb"); - - pids = (pid_t *)calloc(sizeof(pid_t), num_procs); - pids[0] = getpid(); - - for (i=0;i<num_procs-1;i++) { - if ((pids[i+1]=fork()) == 0) break; - } - - db = tdb_open_ex("torture.tdb", hash_size, TDB_CLEAR_IF_FIRST, - O_RDWR | O_CREAT, 0600, &log_ctx, NULL); - if (!db) { - fatal("db open failed"); - } - - if (seed == -1) { - seed = (getpid() + time(NULL)) & 0x7FFFFFFF; - } - - if (i == 0) { - printf("testing with %d processes, %d loops, %d hash_size, seed=%d\n", - num_procs, num_loops, hash_size, seed); - } - - srand(seed + i); - srandom(seed + i); - - for (i=0;i<num_loops && error_count == 0;i++) { - addrec_db(); - } - - if (error_count == 0) { - tdb_traverse_read(db, NULL, NULL); - tdb_traverse(db, traverse_fn, NULL); - tdb_traverse(db, traverse_fn, NULL); - } - - tdb_close(db); - - if (getpid() != pids[0]) { - return error_count; - } - - for (i=1;i<num_procs;i++) { - int status, j; - pid_t pid; - if (error_count != 0) { - /* try and stop the test on any failure */ - for (j=1;j<num_procs;j++) { - if (pids[j] != 0) { - kill(pids[j], SIGTERM); - } - } - } - pid = waitpid(-1, &status, 0); - if (pid == -1) { - perror("failed to wait for child\n"); - exit(1); - } - for (j=1;j<num_procs;j++) { - if (pids[j] == pid) break; - } - if (j == num_procs) { - printf("unknown child %d exited!?\n", (int)pid); - exit(1); - } - if (WEXITSTATUS(status) != 0) { - printf("child %d exited with status %d\n", - (int)pid, WEXITSTATUS(status)); - error_count++; - } - pids[j] = 0; - } - - if (error_count == 0) { - printf("OK\n"); - } - - return error_count; -} |