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

📄 nbio.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  TODO: add splitting of writes for servers with signing*//*    Unix SMB/CIFS implementation.   SMB torture tester   Copyright (C) Andrew Tridgell 1997-1998      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 "includes.h"#include "system/time.h"#include "system/filesys.h"#include "lib/util/dlinklist.h"#include "libcli/libcli.h"#include "libcli/raw/libcliraw.h"#include "torture/torture.h"#include "libcli/libcli.h"#include "torture/util.h"#include "torture/nbench/proto.h"extern int nbench_line_count;static int nbio_id = -1;static int nprocs;static bool bypass_io;static struct timeval tv_start, tv_end;static int warmup, timelimit;static int in_cleanup;struct lock_info {	struct lock_info *next, *prev;	off_t offset;	int size;};struct createx_params {	char *fname;	uint_t create_options;	uint_t create_disposition;	int handle;};struct ftable {	struct ftable *next, *prev;	int fd;     /* the fd that we got back from the server */	int handle; /* the handle in the load file */	struct createx_params cp;	struct lock_info *locks;};static struct ftable *ftable;static struct {	double bytes, warmup_bytes;	int line;	int done;	bool connected;	double max_latency;	struct timeval starttime;} *children;static bool nb_do_createx(struct ftable *f,			  const char *fname,			  uint_t create_options,			  uint_t create_disposition,			  int handle,			  NTSTATUS status,			  bool retry);static bool nb_do_lockx(bool relock, int handle, off_t offset, int size, NTSTATUS status);static void nb_set_createx_params(struct ftable *f,				  const char *fname,				  uint_t create_options,				  uint_t create_disposition,				  int handle){	struct createx_params *cp = &f->cp;	if (fname != NULL) {		cp->fname = talloc_strdup(f, fname);		if (cp->fname == NULL) {			perror("nb_set_createx_params: strdup");			nb_exit(1);		}	} else {		cp->fname = NULL;	}	cp->create_options = create_options;	cp->create_disposition = create_disposition;	cp->handle = handle;}static bool nb_reestablish_locks(struct ftable *f){	struct lock_info *linfo = f->locks;	while (linfo != NULL) {		DEBUG(1,("nb_reestablish_locks: lock for file %d at %lu\n",			 f->handle, (unsigned long) linfo->offset));		if (!nb_do_lockx(true, f->handle, linfo->offset, linfo->size, NT_STATUS_OK)) {			printf("nb_reestablish_locks: failed to get lock for file %s at %lu\n",			       f->cp.fname, (unsigned long) linfo->offset);			return false;		}		linfo = linfo->next;	}	return true;}static bool nb_reopen_all_files(void){	struct ftable *f = ftable;	while (f != NULL) {		DEBUG(1,("-- nb_reopen_all_files: opening %s (handle %d)\n",			 f->cp.fname, f->cp.handle));		if (!nb_do_createx(f,				   f->cp.fname,				   f->cp.create_options,				   f->cp.create_disposition,				   f->cp.handle,				   NT_STATUS_OK,				   true))		{			printf("-- nb_reopen_all_files: failed to open file %s\n", f->cp.fname);			return false;		}		if (!nb_reestablish_locks(f)) {			printf("--nb_reopen_all_files: failed to reestablish locks\n");			return false;		}		f = f->next;	}	return true;}bool nb_reconnect(struct smbcli_state **cli, struct torture_context *tctx, int client){	children[client].connected = false;	if (*cli != NULL) {		talloc_free(*cli);	}	if (!torture_open_connection(cli, tctx, client)) {		printf("nb_reconnect: failed to connect\n");		*cli = NULL;		return false;	}	nb_setup(*cli, client);	if (!nb_reopen_all_files()) {		printf("nb_reconnect: failed to reopen files in client %d\n", client);		return false;	}	return true;}void nbio_target_rate(double rate){	static double last_bytes;	static struct timeval last_time;	double tdelay;	if (last_bytes == 0) {		last_bytes = children[nbio_id].bytes;		last_time = timeval_current();		return;	}	tdelay = (children[nbio_id].bytes - last_bytes)/(1.0e6*rate) - timeval_elapsed(&last_time);	if (tdelay > 0) {		msleep(tdelay*1000);	} else {		children[nbio_id].max_latency = MAX(children[nbio_id].max_latency, -tdelay);	}	last_time = timeval_current();	last_bytes = children[nbio_id].bytes;}void nbio_time_reset(void){	children[nbio_id].starttime = timeval_current();	}void nbio_time_delay(double targett){	double elapsed = timeval_elapsed(&children[nbio_id].starttime);	if (targett > elapsed) {		msleep(1000*(targett - elapsed));	} else if (elapsed - targett > children[nbio_id].max_latency) {		children[nbio_id].max_latency = MAX(elapsed - targett, children[nbio_id].max_latency);	}}double nbio_result(void){	int i;	double total = 0;	for (i=0;i<nprocs;i++) {		total += children[i].bytes - children[i].warmup_bytes;	}	return 1.0e-6 * total / timeval_elapsed2(&tv_start, &tv_end);}double nbio_latency(void){	int i;	double max_latency = 0;	for (i=0;i<nprocs;i++) {		if (children[i].max_latency > max_latency) {			max_latency = children[i].max_latency;			children[i].max_latency = 0;		}	}	return max_latency;}bool nb_tick(void){	return children[nbio_id].done;}void nb_alarm(int sig){	int i;	int lines=0;	double t;	int in_warmup = 0;	int num_connected = 0;	if (nbio_id != -1) return;	for (i=0;i<nprocs;i++) {		if (children[i].connected) {			num_connected++;		}		if (children[i].bytes == 0) {			in_warmup = 1;		}		lines += children[i].line;	}	t = timeval_elapsed(&tv_start);	if (!in_warmup && warmup>0 && t > warmup) {		tv_start = timeval_current();		warmup = 0;		for (i=0;i<nprocs;i++) {			children[i].warmup_bytes = children[i].bytes;		}		goto next;	}	if (t < warmup) {		in_warmup = 1;	} else if (!in_warmup && !in_cleanup && t > timelimit) {		for (i=0;i<nprocs;i++) {			children[i].done = 1;		}		tv_end = timeval_current();		in_cleanup = 1;	}	if (t < 1) {		goto next;	}	if (!in_cleanup) {		tv_end = timeval_current();	}	if (in_warmup) {		printf("%4d  %8d  %.2f MB/sec  warmup %.0f sec   \n", 		       num_connected, lines/nprocs, 		       nbio_result(), t);	} else if (in_cleanup) {		printf("%4d  %8d  %.2f MB/sec  cleanup %.0f sec   \n", 		       num_connected, lines/nprocs, 		       nbio_result(), t);	} else {		printf("%4d  %8d  %.2f MB/sec  execute %.0f sec  latency %.2f msec \n", 		       num_connected, lines/nprocs, 		       nbio_result(), t, nbio_latency() * 1.0e3);	}	fflush(stdout);next:	signal(SIGALRM, nb_alarm);	alarm(1);	}void nbio_shmem(int n, int t_timelimit, int t_warmup){	nprocs = n;	children = shm_setup(sizeof(*children) * nprocs);	if (!children) {		printf("Failed to setup shared memory!\n");		nb_exit(1);	}	memset(children, 0, sizeof(*children) * nprocs);	timelimit = t_timelimit;	warmup = t_warmup;	in_cleanup = 0;	tv_start = timeval_current();}static struct lock_info* find_lock(struct lock_info *linfo, off_t offset, int size){	while (linfo != NULL) {		if (linfo->offset == offset &&		    linfo->size == size)		{			return linfo;		}		linfo = linfo->next;	}	return NULL;}static struct ftable *find_ftable(int handle){	struct ftable *f;	for (f=ftable;f;f=f->next) {		if (f->handle == handle) return f;	}	return NULL;}static int find_handle(int handle, struct ftable **f_ret){	struct ftable *f;	if (f_ret != NULL)		*f_ret = NULL;	children[nbio_id].line = nbench_line_count;	f = find_ftable(handle);	if (f) {		if (f_ret != NULL)			*f_ret = f;		return f->fd;	}	printf("(%d) ERROR: handle %d was not found\n", 	       nbench_line_count, handle);	nb_exit(1);	return -1;		/* Not reached */}static struct smbcli_state *c;/*  a handler function for oplock break requests*/static bool oplock_handler(struct smbcli_transport *transport, uint16_t tid, 			   uint16_t fnum, uint8_t level, void *private){	struct smbcli_tree *tree = (struct smbcli_tree *)private;	return smbcli_oplock_ack(tree, fnum, OPLOCK_BREAK_TO_NONE);}void nb_setup(struct smbcli_state *cli, int id){	nbio_id = id;	c = cli;	if (bypass_io)		printf("skipping I/O\n");	if (cli) {		smbcli_oplock_handler(cli->transport, oplock_handler, cli->tree);	}	children[id].connected = true;}static bool check_status(const char *op, NTSTATUS status, NTSTATUS ret){	if ((NT_STATUS_EQUAL(ret, NT_STATUS_END_OF_FILE) ||	     NT_STATUS_EQUAL(ret, NT_STATUS_NET_WRITE_FAULT) ||	     NT_STATUS_EQUAL(ret, NT_STATUS_CONNECTION_RESET)) 		&& !NT_STATUS_EQUAL (status, ret))	{		return false;	}	if (!NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(ret)) {		printf("[%d] Error: %s should have failed with %s\n", 		       nbench_line_count, op, nt_errstr(status));		nb_exit(1);	}	if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(ret)) {		printf("[%d] Error: %s should have succeeded - %s\n", 		       nbench_line_count, op, nt_errstr(ret));		nb_exit(1);	}	if (!NT_STATUS_EQUAL(status, ret)) {		printf("[%d] Warning: got status %s but expected %s\n",		       nbench_line_count, nt_errstr(ret), nt_errstr(status));	}	return true;}bool nb_unlink(const char *fname, int attr, NTSTATUS status, bool retry){	union smb_unlink io;	NTSTATUS ret;	io.unlink.in.pattern = fname;	io.unlink.in.attrib = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;	if (strchr(fname, '*') == 0) {		io.unlink.in.attrib |= FILE_ATTRIBUTE_DIRECTORY;	}	ret = smb_raw_unlink(c->tree, &io);	if (!retry)		return check_status("Unlink", status, ret);	return true;}static bool nb_do_createx(struct ftable *f,			  const char *fname,			  uint_t create_options,			  uint_t create_disposition,			  int handle,			  NTSTATUS status,			  bool retry){	union smb_open io;		uint32_t desired_access;	NTSTATUS ret;	TALLOC_CTX *mem_ctx;	uint_t flags = 0;	mem_ctx = talloc_init("raw_open");	if (create_options & NTCREATEX_OPTIONS_DIRECTORY) {		desired_access = SEC_FILE_READ_DATA;	} else {		desired_access = 			SEC_FILE_READ_DATA | 			SEC_FILE_WRITE_DATA |			SEC_FILE_READ_ATTRIBUTE |			SEC_FILE_WRITE_ATTRIBUTE;		flags = NTCREATEX_FLAGS_EXTENDED |			NTCREATEX_FLAGS_REQUEST_OPLOCK | 			NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;	}	io.ntcreatex.level = RAW_OPEN_NTCREATEX;	io.ntcreatex.in.flags = flags;	io.ntcreatex.in.root_fid = 0;	io.ntcreatex.in.access_mask = desired_access;	io.ntcreatex.in.file_attr = 0;	io.ntcreatex.in.alloc_size = 0;	io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE;	io.ntcreatex.in.open_disposition = create_disposition;	io.ntcreatex.in.create_options = create_options;	io.ntcreatex.in.impersonation = 0;	io.ntcreatex.in.security_flags = 0;	io.ntcreatex.in.fname = fname;

⌨️ 快捷键说明

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