2
Unix SMB/CIFS implementation.
4
Copyright (C) Andrew Tridgell 1997-2003
5
Copyright (C) Jelmer Vernooij 2006
7
This program is free software; you can redistribute it and/or modify
8
it under the terms of the GNU General Public License as published by
9
the Free Software Foundation; either version 3 of the License, or
10
(at your option) any later version.
12
This program is distributed in the hope that it will be useful,
13
but WITHOUT ANY WARRANTY; without even the implied warranty of
14
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License
18
along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include "libcli/raw/libcliraw.h"
23
#include "libcli/raw/raw_proto.h"
24
#include "system/time.h"
25
#include "system/wait.h"
26
#include "system/filesys.h"
27
#include "libcli/raw/ioctl.h"
28
#include "libcli/libcli.h"
29
#include "lib/events/events.h"
30
#include "libcli/resolve/resolve.h"
31
#include "auth/credentials/credentials.h"
32
#include "librpc/gen_ndr/ndr_nbt.h"
33
#include "torture/smbtorture.h"
34
#include "torture/util.h"
35
#include "libcli/smb_composite/smb_composite.h"
36
#include "libcli/composite/composite.h"
37
#include "param/param.h"
39
extern struct cli_credentials *cmdline_credentials;
41
static bool wait_lock(struct smbcli_state *c, int fnum, uint32_t offset, uint32_t len)
43
while (NT_STATUS_IS_ERR(smbcli_lock(c->tree, fnum, offset, len, -1, WRITE_LOCK))) {
44
if (!check_error(__location__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return false;
50
static bool rw_torture(struct torture_context *tctx, struct smbcli_state *c)
52
const char *lockfname = "\\torture.lck";
56
pid_t pid2, pid = getpid();
61
fnum2 = smbcli_open(c->tree, lockfname, O_RDWR | O_CREAT | O_EXCL,
64
fnum2 = smbcli_open(c->tree, lockfname, O_RDWR, DENY_NONE);
66
torture_comment(tctx, "open of %s failed (%s)\n", lockfname, smbcli_errstr(c->tree));
70
generate_random_buffer(buf, sizeof(buf));
72
for (i=0;i<torture_numops;i++) {
73
uint_t n = (uint_t)random()%10;
75
if (torture_setting_bool(tctx, "progress", true)) {
76
torture_comment(tctx, "%d\r", i);
80
asprintf(&fname, "\\torture.%u", n);
82
if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
86
fnum = smbcli_open(c->tree, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
88
torture_comment(tctx, "open failed (%s)\n", smbcli_errstr(c->tree));
93
if (smbcli_write(c->tree, fnum, 0, &pid, 0, sizeof(pid)) != sizeof(pid)) {
94
torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c->tree));
99
if (smbcli_write(c->tree, fnum, 0, buf,
100
sizeof(pid)+(j*sizeof(buf)),
101
sizeof(buf)) != sizeof(buf)) {
102
torture_comment(tctx, "write failed (%s)\n", smbcli_errstr(c->tree));
109
if (smbcli_read(c->tree, fnum, &pid2, 0, sizeof(pid)) != sizeof(pid)) {
110
torture_comment(tctx, "read failed (%s)\n", smbcli_errstr(c->tree));
115
torture_comment(tctx, "data corruption!\n");
119
if (NT_STATUS_IS_ERR(smbcli_close(c->tree, fnum))) {
120
torture_comment(tctx, "close failed (%s)\n", smbcli_errstr(c->tree));
124
if (NT_STATUS_IS_ERR(smbcli_unlink(c->tree, fname))) {
125
torture_comment(tctx, "unlink failed (%s)\n", smbcli_errstr(c->tree));
129
if (NT_STATUS_IS_ERR(smbcli_unlock(c->tree, fnum2, n*sizeof(int), sizeof(int)))) {
130
torture_comment(tctx, "unlock failed (%s)\n", smbcli_errstr(c->tree));
136
smbcli_close(c->tree, fnum2);
137
smbcli_unlink(c->tree, lockfname);
139
torture_comment(tctx, "%d\n", i);
144
bool run_torture(struct torture_context *tctx, struct smbcli_state *cli, int dummy)
146
return rw_torture(tctx, cli);
151
see how many RPC pipes we can open at once
153
bool run_pipe_number(struct torture_context *tctx,
154
struct smbcli_state *cli1)
156
const char *pipe_name = "\\WKSSVC";
161
fnum = smbcli_nt_create_full(cli1->tree, pipe_name, 0, SEC_FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
162
NTCREATEX_SHARE_ACCESS_READ|NTCREATEX_SHARE_ACCESS_WRITE, NTCREATEX_DISP_OPEN_IF, 0, 0);
165
torture_comment(tctx, "Open of pipe %s failed with error (%s)\n", pipe_name, smbcli_errstr(cli1->tree));
169
if (torture_setting_bool(tctx, "progress", true)) {
170
torture_comment(tctx, "%d\r", num_pipes);
175
torture_comment(tctx, "pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
183
open N connections to the server and just hold them open
184
used for testing performance when there are N idle users
187
bool torture_holdcon(struct torture_context *tctx)
190
struct smbcli_state **cli;
193
torture_comment(tctx, "Opening %d connections\n", torture_numops);
195
cli = malloc_array_p(struct smbcli_state *, torture_numops);
197
for (i=0;i<torture_numops;i++) {
198
if (!torture_open_connection(&cli[i], tctx, i)) {
201
if (torture_setting_bool(tctx, "progress", true)) {
202
torture_comment(tctx, "opened %d connections\r", i);
207
torture_comment(tctx, "\nStarting pings\n");
210
for (i=0;i<torture_numops;i++) {
213
status = smbcli_chkpath(cli[i]->tree, "\\");
214
if (!NT_STATUS_IS_OK(status)) {
215
torture_comment(tctx, "Connection %d is dead\n", i);
223
if (num_dead == torture_numops) {
224
torture_comment(tctx, "All connections dead - finishing\n");
228
torture_comment(tctx, ".");
236
test how many open files this server supports on the one socket
238
bool run_maxfidtest(struct torture_context *tctx, struct smbcli_state *cli, int dummy)
240
#define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
242
int fnums[0x11000], i;
243
int retries=4, maxfid;
247
torture_comment(tctx, "failed to connect\n");
251
if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
252
torture_comment(tctx, "Failed to deltree \\maxfid - %s\n",
253
smbcli_errstr(cli->tree));
256
if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, "\\maxfid"))) {
257
torture_comment(tctx, "Failed to mkdir \\maxfid, error=%s\n",
258
smbcli_errstr(cli->tree));
262
torture_comment(tctx, "Testing maximum number of open files\n");
264
for (i=0; i<0x11000; i++) {
266
asprintf(&fname, "\\maxfid\\fid%d", i/1000);
267
if (NT_STATUS_IS_ERR(smbcli_mkdir(cli->tree, fname))) {
268
torture_comment(tctx, "Failed to mkdir %s, error=%s\n",
269
fname, smbcli_errstr(cli->tree));
274
asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
275
if ((fnums[i] = smbcli_open(cli->tree, fname,
276
O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
278
torture_comment(tctx, "open of %s failed (%s)\n",
279
fname, smbcli_errstr(cli->tree));
280
torture_comment(tctx, "maximum fnum is %d\n", i);
284
if (torture_setting_bool(tctx, "progress", true)) {
285
torture_comment(tctx, "%6d\r", i);
289
torture_comment(tctx, "%6d\n", i);
294
torture_comment(tctx, "cleaning up\n");
295
for (i=0;i<maxfid/2;i++) {
296
asprintf(&fname, MAXFID_TEMPLATE, i/1000, i,(int)getpid());
297
if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[i]))) {
298
torture_comment(tctx, "Close of fnum %d failed - %s\n", fnums[i], smbcli_errstr(cli->tree));
300
if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
301
torture_comment(tctx, "unlink of %s failed (%s)\n",
302
fname, smbcli_errstr(cli->tree));
307
asprintf(&fname, MAXFID_TEMPLATE, (maxfid-i)/1000, maxfid-i,(int)getpid());
308
if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnums[maxfid-i]))) {
309
torture_comment(tctx, "Close of fnum %d failed - %s\n", fnums[maxfid-i], smbcli_errstr(cli->tree));
311
if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) {
312
torture_comment(tctx, "unlink of %s failed (%s)\n",
313
fname, smbcli_errstr(cli->tree));
318
if (torture_setting_bool(tctx, "progress", true)) {
319
torture_comment(tctx, "%6d %6d\r", i, maxfid-i);
323
torture_comment(tctx, "%6d\n", 0);
325
if (smbcli_deltree(cli->tree, "\\maxfid") == -1) {
326
torture_comment(tctx, "Failed to deltree \\maxfid - %s\n",
327
smbcli_errstr(cli->tree));
331
torture_comment(tctx, "maxfid test finished\n");
332
if (!torture_close_connection(cli)) {
336
#undef MAXFID_TEMPLATE
342
sees what IOCTLs are supported
344
bool torture_ioctl_test(struct torture_context *tctx,
345
struct smbcli_state *cli)
347
uint16_t device, function;
349
const char *fname = "\\ioctl.dat";
351
union smb_ioctl parms;
354
mem_ctx = talloc_named_const(tctx, 0, "ioctl_test");
356
smbcli_unlink(cli->tree, fname);
358
fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
360
torture_comment(tctx, "open of %s failed (%s)\n", fname, smbcli_errstr(cli->tree));
364
parms.ioctl.level = RAW_IOCTL_IOCTL;
365
parms.ioctl.in.file.fnum = fnum;
366
parms.ioctl.in.request = IOCTL_QUERY_JOB_INFO;
367
status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
368
torture_comment(tctx, "ioctl job info: %s\n", smbcli_errstr(cli->tree));
370
for (device=0;device<0x100;device++) {
371
torture_comment(tctx, "testing device=0x%x\n", device);
372
for (function=0;function<0x100;function++) {
373
parms.ioctl.in.request = (device << 16) | function;
374
status = smb_raw_ioctl(cli->tree, mem_ctx, &parms);
376
if (NT_STATUS_IS_OK(status)) {
377
torture_comment(tctx, "ioctl device=0x%x function=0x%x OK : %d bytes\n",
378
device, function, (int)parms.ioctl.out.blob.length);
386
static void benchrw_callback(struct smbcli_request *req);
402
struct benchrw_state {
403
struct torture_context *tctx;
408
struct smbcli_tree *cli;
413
int num_parallel_requests;
415
enum benchrw_stage mode;
421
const char *workgroup;
423
unsigned int writeblocks;
424
unsigned int blocksize;
425
unsigned int writeratio;
426
int num_parallel_requests;
431
init params using lp_parm_xxx
432
return number of unclist entries
434
static int init_benchrw_params(struct torture_context *tctx,
437
char **unc_list = NULL;
438
int num_unc_names = 0, conn_index=0, empty_lines=0;
440
lpar->retry = torture_setting_int(tctx, "retry",3);
441
lpar->blocksize = torture_setting_int(tctx, "blocksize",65535);
442
lpar->writeblocks = torture_setting_int(tctx, "writeblocks",15);
443
lpar->writeratio = torture_setting_int(tctx, "writeratio",5);
444
lpar->num_parallel_requests = torture_setting_int(
445
tctx, "parallel_requests", 5);
446
lpar->workgroup = lp_workgroup(tctx->lp_ctx);
448
p = torture_setting_string(tctx, "unclist", NULL);
451
unc_list = file_lines_load(p, &num_unc_names, 0, NULL);
452
if (!unc_list || num_unc_names <= 0) {
453
torture_comment(tctx, "Failed to load unc names list "
458
lpar->unc = talloc_array(tctx, struct unclist *,
459
(num_unc_names-empty_lines));
460
for(conn_index = 0; conn_index < num_unc_names; conn_index++) {
461
/* ignore empty lines */
462
if(strlen(unc_list[conn_index % num_unc_names])==0){
466
if (!smbcli_parse_unc(
467
unc_list[conn_index % num_unc_names],
470
tctx, "Failed to parse UNC "
472
unc_list[conn_index % num_unc_names]);
475
lpar->unc[conn_index-empty_lines] =
476
talloc(tctx, struct unclist);
477
lpar->unc[conn_index-empty_lines]->host = h;
478
lpar->unc[conn_index-empty_lines]->share = s;
480
return num_unc_names-empty_lines;
482
lpar->unc = talloc_array(tctx, struct unclist *, 1);
483
lpar->unc[0] = talloc(tctx,struct unclist);
484
lpar->unc[0]->host = torture_setting_string(tctx, "host",
486
lpar->unc[0]->share = torture_setting_string(tctx, "share",
493
Called when the reads & writes are finished. closes the file.
495
static NTSTATUS benchrw_close(struct torture_context *tctx,
496
struct smbcli_request *req,
497
struct benchrw_state *state)
499
union smb_close close_parms;
501
NT_STATUS_NOT_OK_RETURN(req->status);
503
torture_comment(tctx, "Close file %d (%d)\n",state->nr,state->fnum);
504
close_parms.close.level = RAW_CLOSE_CLOSE;
505
close_parms.close.in.file.fnum = state->fnum ;
506
close_parms.close.in.write_time = 0;
507
state->mode=CLOSE_FILE;
509
req = smb_raw_close_send(state->cli, &close_parms);
510
NT_STATUS_HAVE_NO_MEMORY(req);
511
/*register the callback function!*/
512
req->async.fn = benchrw_callback;
513
req->async.private_data = state;
518
static NTSTATUS benchrw_readwrite(struct torture_context *tctx,
519
struct benchrw_state *state);
520
static void benchrw_callback(struct smbcli_request *req);
522
static void benchrw_rw_callback(struct smbcli_request *req)
524
struct benchrw_state *state = req->async.private_data;
525
struct torture_context *tctx = state->tctx;
527
if (!NT_STATUS_IS_OK(req->status)) {
533
state->num_parallel_requests--;
535
if ((state->completed >= torture_numops)
536
&& (state->num_parallel_requests == 0)) {
537
benchrw_callback(req);
544
if (state->completed + state->num_parallel_requests
546
benchrw_readwrite(tctx, state);
551
Called when the initial write is completed is done. write or read a file.
553
static NTSTATUS benchrw_readwrite(struct torture_context *tctx,
554
struct benchrw_state *state)
556
struct smbcli_request *req;
560
/* randomize between writes and reads*/
561
if (random() % state->lp_params->writeratio == 0) {
562
torture_comment(tctx, "Callback WRITE file:%d (%d/%d)\n",
563
state->nr,state->completed,torture_numops);
564
wr.generic.level = RAW_WRITE_WRITEX ;
565
wr.writex.in.file.fnum = state->fnum ;
566
wr.writex.in.offset = 0;
567
wr.writex.in.wmode = 0 ;
568
wr.writex.in.remaining = 0;
569
wr.writex.in.count = state->lp_params->blocksize;
570
wr.writex.in.data = state->buffer;
572
req = smb_raw_write_send(state->cli,&wr);
575
torture_comment(tctx,
576
"Callback READ file:%d (%d/%d) Offset:%d\n",
577
state->nr,state->completed,torture_numops,
578
(state->readcnt*state->lp_params->blocksize));
579
rd.generic.level = RAW_READ_READX;
580
rd.readx.in.file.fnum = state->fnum ;
581
rd.readx.in.offset = state->readcnt*state->lp_params->blocksize;
582
rd.readx.in.mincnt = state->lp_params->blocksize;
583
rd.readx.in.maxcnt = rd.readx.in.mincnt;
584
rd.readx.in.remaining = 0 ;
585
rd.readx.out.data = state->buffer;
586
rd.readx.in.read_for_execute = false;
587
if(state->readcnt < state->lp_params->writeblocks){
590
/*start reading from beginn of file*/
593
req = smb_raw_read_send(state->cli,&rd);
595
state->num_parallel_requests += 1;
596
NT_STATUS_HAVE_NO_MEMORY(req);
597
/*register the callback function!*/
598
req->async.fn = benchrw_rw_callback;
599
req->async.private_data = state;
605
Called when the open is done. writes to the file.
607
static NTSTATUS benchrw_open(struct torture_context *tctx,
608
struct smbcli_request *req,
609
struct benchrw_state *state)
612
if(state->mode == OPEN_FILE){
614
status = smb_raw_open_recv(req,tctx,(
615
union smb_open*)state->req_params);
616
NT_STATUS_NOT_OK_RETURN(status);
618
state->fnum = ((union smb_open*)state->req_params)
619
->openx.out.file.fnum;
620
torture_comment(tctx, "File opened (%d)\n",state->fnum);
621
state->mode=INITIAL_WRITE;
624
torture_comment(tctx, "Write initial test file:%d (%d/%d)\n",state->nr,
625
(state->writecnt+1)*state->lp_params->blocksize,
626
(state->lp_params->writeblocks*state->lp_params->blocksize));
627
wr.generic.level = RAW_WRITE_WRITEX ;
628
wr.writex.in.file.fnum = state->fnum ;
629
wr.writex.in.offset = state->writecnt *
630
state->lp_params->blocksize;
631
wr.writex.in.wmode = 0 ;
632
wr.writex.in.remaining = (state->lp_params->writeblocks *
633
state->lp_params->blocksize)-
634
((state->writecnt+1)*state->
635
lp_params->blocksize);
636
wr.writex.in.count = state->lp_params->blocksize;
637
wr.writex.in.data = state->buffer;
639
if(state->writecnt == state->lp_params->writeblocks){
640
state->mode=READ_WRITE_DATA;
642
req = smb_raw_write_send(state->cli,&wr);
643
NT_STATUS_HAVE_NO_MEMORY(req);
645
/*register the callback function!*/
646
req->async.fn = benchrw_callback;
647
req->async.private_data = state;
652
Called when the mkdir is done. Opens a file.
654
static NTSTATUS benchrw_mkdir(struct torture_context *tctx,
655
struct smbcli_request *req,
656
struct benchrw_state *state)
658
union smb_open *open_parms;
661
NT_STATUS_NOT_OK_RETURN(req->status);
663
/* open/create the files */
664
torture_comment(tctx, "Open File %d/%d\n",state->nr+1,
665
torture_setting_int(tctx, "nprocs", 4));
666
open_parms=talloc_zero(tctx, union smb_open);
667
NT_STATUS_HAVE_NO_MEMORY(open_parms);
668
open_parms->openx.level = RAW_OPEN_OPENX;
669
open_parms->openx.in.flags = 0;
670
open_parms->openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
671
open_parms->openx.in.search_attrs =
672
FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN;
673
open_parms->openx.in.file_attrs = 0;
674
open_parms->openx.in.write_time = 0;
675
open_parms->openx.in.open_func = OPENX_OPEN_FUNC_CREATE;
676
open_parms->openx.in.size = 0;
677
open_parms->openx.in.timeout = 0;
678
open_parms->openx.in.fname = state->fname;
680
writedata = talloc_size(tctx,state->lp_params->blocksize);
681
NT_STATUS_HAVE_NO_MEMORY(writedata);
682
generate_random_buffer(writedata,state->lp_params->blocksize);
683
state->buffer=writedata;
686
state->req_params=open_parms;
687
state->mode=OPEN_FILE;
689
req = smb_raw_open_send(state->cli,open_parms);
690
NT_STATUS_HAVE_NO_MEMORY(req);
692
/*register the callback function!*/
693
req->async.fn = benchrw_callback;
694
req->async.private_data = state;
700
handler for completion of a sub-request of the bench-rw test
702
static void benchrw_callback(struct smbcli_request *req)
704
struct benchrw_state *state = req->async.private_data;
705
struct torture_context *tctx = state->tctx;
707
/*dont send new requests when torture_numops is reached*/
708
if ((state->mode == READ_WRITE_DATA)
709
&& (state->completed >= torture_numops)) {
710
state->mode=MAX_OPS_REACHED;
713
switch (state->mode) {
716
if (!NT_STATUS_IS_OK(benchrw_mkdir(tctx, req,state))) {
717
torture_comment(tctx, "Failed to create the test "
719
nt_errstr(req->status));
726
if (!NT_STATUS_IS_OK(benchrw_open(tctx, req,state))){
727
torture_comment(tctx, "Failed to open/write the "
729
nt_errstr(req->status));
735
case READ_WRITE_DATA:
736
while (state->num_parallel_requests
737
< state->lp_params->num_parallel_requests) {
739
status = benchrw_readwrite(tctx,state);
740
if (!NT_STATUS_IS_OK(status)){
741
torture_comment(tctx, "Failed to read/write "
743
nt_errstr(req->status));
749
case MAX_OPS_REACHED:
750
if (!NT_STATUS_IS_OK(benchrw_close(tctx,req,state))){
751
torture_comment(tctx, "Failed to read/write/close "
753
nt_errstr(req->status));
759
torture_comment(tctx, "File %d closed\n",state->nr);
760
if (!NT_STATUS_IS_OK(req->status)) {
761
torture_comment(tctx, "Failed to close the "
763
nt_errstr(req->status));
775
/* open connection async callback function*/
776
static void async_open_callback(struct composite_context *con)
778
struct benchrw_state *state = con->async.private_data;
779
struct torture_context *tctx = state->tctx;
780
int retry = state->lp_params->retry;
782
if (NT_STATUS_IS_OK(con->status)) {
783
state->cli=((struct smb_composite_connect*)
784
state->req_params)->out.tree;
785
state->mode=CLEANUP_TESTDIR;
787
if(state->writecnt < retry){
788
torture_comment(tctx, "Failed to open connection: "
789
"%d, Retry (%d/%d)\n",
790
state->nr,state->writecnt,retry);
795
torture_comment(tctx, "Failed to open connection "
797
state->nr, nt_errstr(con->status));
805
establishs a smbcli_tree from scratch (async)
807
static struct composite_context *torture_connect_async(
808
struct torture_context *tctx,
809
struct smb_composite_connect *smb,
811
struct tevent_context *ev,
814
const char *workgroup)
816
torture_comment(tctx, "Open Connection to %s/%s\n",host,share);
817
smb->in.dest_host=talloc_strdup(mem_ctx,host);
818
smb->in.service=talloc_strdup(mem_ctx,share);
819
smb->in.dest_ports=lp_smb_ports(tctx->lp_ctx);
820
smb->in.socket_options = lp_socket_options(tctx->lp_ctx);
821
smb->in.called_name = strupper_talloc(mem_ctx, host);
822
smb->in.service_type=NULL;
823
smb->in.credentials=cmdline_credentials;
824
smb->in.fallback_to_anonymous=false;
825
smb->in.iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
826
smb->in.gensec_settings = lp_gensec_settings(mem_ctx, tctx->lp_ctx);
827
smb->in.workgroup=workgroup;
828
lp_smbcli_options(tctx->lp_ctx, &smb->in.options);
829
lp_smbcli_session_options(tctx->lp_ctx, &smb->in.session_options);
831
return smb_composite_connect_send(smb,mem_ctx,
832
lp_resolve_context(tctx->lp_ctx),ev);
835
bool run_benchrw(struct torture_context *tctx)
837
struct smb_composite_connect *smb_con;
838
const char *fname = "\\rwtest.dat";
839
struct smbcli_request *req;
840
struct benchrw_state **state;
841
int i , num_unc_names;
842
struct tevent_context *ev ;
843
struct composite_context *req1;
844
struct params lpparams;
845
union smb_mkdir parms;
848
int torture_nprocs = torture_setting_int(tctx, "nprocs", 4);
850
torture_comment(tctx, "Start BENCH-READWRITE num_ops=%d "
852
torture_numops, torture_nprocs);
854
/*init talloc context*/
856
state = talloc_array(tctx, struct benchrw_state *, torture_nprocs);
858
/* init params using lp_parm_xxx */
859
num_unc_names = init_benchrw_params(tctx,&lpparams);
861
/* init private data structs*/
862
for(i = 0; i<torture_nprocs;i++){
863
state[i]=talloc(tctx,struct benchrw_state);
864
state[i]->tctx = tctx;
865
state[i]->completed=0;
866
state[i]->num_parallel_requests=0;
867
state[i]->lp_params=&lpparams;
869
state[i]->dname=talloc_asprintf(tctx,"benchrw%d",i);
870
state[i]->fname=talloc_asprintf(tctx,"%s%s",
871
state[i]->dname,fname);
872
state[i]->mode=START;
873
state[i]->writecnt=0;
876
torture_comment(tctx, "Starting async requests\n");
877
while(finished != torture_nprocs){
879
for(i = 0; i<torture_nprocs;i++){
880
switch (state[i]->mode){
881
/*open multiple connections with the same userid */
884
tctx,struct smb_composite_connect) ;
885
state[i]->req_params=smb_con;
886
state[i]->mode=OPEN_CONNECTION;
887
req1 = torture_connect_async(
888
tctx, smb_con, tctx,ev,
889
lpparams.unc[i % num_unc_names]->host,
890
lpparams.unc[i % num_unc_names]->share,
892
/* register callback fn + private data */
893
req1->async.fn = async_open_callback;
894
req1->async.private_data=state[i];
896
/*setup test dirs (sync)*/
897
case CLEANUP_TESTDIR:
898
torture_comment(tctx, "Setup test dir %d\n",i);
899
smb_raw_exit(state[i]->cli->session);
900
if (smbcli_deltree(state[i]->cli,
901
state[i]->dname) == -1) {
904
"Unable to delete %s - %s\n",
906
smbcli_errstr(state[i]->cli));
907
state[i]->mode=ERROR;
910
state[i]->mode=MK_TESTDIR;
911
parms.mkdir.level = RAW_MKDIR_MKDIR;
912
parms.mkdir.in.path = state[i]->dname;
913
req = smb_raw_mkdir_send(state[i]->cli,&parms);
914
/* register callback fn + private data */
915
req->async.fn = benchrw_callback;
916
req->async.private_data=state[i];
918
/* error occured , finish */
923
/* cleanup , close connection */
925
torture_comment(tctx, "Deleting test dir %s "
926
"%d/%d\n",state[i]->dname,
928
smbcli_deltree(state[i]->cli,state[i]->dname);
929
if (NT_STATUS_IS_ERR(smb_tree_disconnect(
931
torture_comment(tctx, "ERROR: Tree "
932
"disconnect failed");
933
state[i]->mode=ERROR;
936
state[i]->mode=FINISHED;