⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tdbtorture.c

📁 samba服务器!
💻 C
字号:
/* this tests tdb by doing lots of ops from several simultaneous   writers - that stresses the locking code. */#include "replace.h"#include "tdb.h"#include "system/time.h"#include "system/wait.h"#include "system/filesys.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 100static struct tdb_context *db;static int in_transaction;static int error_count;#ifdef PRINTF_ATTRIBUTEstatic void tdb_log(struct tdb_context *tdb, enum tdb_debug_level level, const char *format, ...) PRINTF_ATTRIBUTE(3,4);#endifstatic 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 = 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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -