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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "libcli/raw/libcliraw.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/torture.h"
34 #include "torture/util.h"
35 #include "libcli/smb_composite/smb_composite.h"
36 #include "libcli/composite/composite.h"
38 extern struct cli_credentials
*cmdline_credentials
;
39 void benchrw_callback(struct smbcli_request
*req
);
60 struct smbcli_tree
*cli
;
67 enum benchrw_stage mode
;
73 const char *workgroup
;
75 unsigned int writeblocks
;
76 unsigned int blocksize
;
77 unsigned int writeratio
;
81 static BOOL
wait_lock(struct smbcli_state
*c
, int fnum
, uint32_t offset
, uint32_t len
)
83 while (NT_STATUS_IS_ERR(smbcli_lock(c
->tree
, fnum
, offset
, len
, -1, WRITE_LOCK
))) {
84 if (!check_error(__location__
, c
, ERRDOS
, ERRlock
, NT_STATUS_LOCK_NOT_GRANTED
)) return False
;
90 static BOOL
rw_torture(struct smbcli_state
*c
)
92 const char *lockfname
= "\\torture.lck";
96 pid_t pid2
, pid
= getpid();
101 fnum2
= smbcli_open(c
->tree
, lockfname
, O_RDWR
| O_CREAT
| O_EXCL
,
104 fnum2
= smbcli_open(c
->tree
, lockfname
, O_RDWR
, DENY_NONE
);
106 printf("open of %s failed (%s)\n", lockfname
, smbcli_errstr(c
->tree
));
111 for (i
=0;i
<torture_numops
;i
++) {
112 uint_t n
= (uint_t
)random()%10;
114 printf("%d\r", i
); fflush(stdout
);
116 asprintf(&fname
, "\\torture.%u", n
);
118 if (!wait_lock(c
, fnum2
, n
*sizeof(int), sizeof(int))) {
122 fnum
= smbcli_open(c
->tree
, fname
, O_RDWR
| O_CREAT
| O_TRUNC
, DENY_ALL
);
124 printf("open failed (%s)\n", smbcli_errstr(c
->tree
));
129 if (smbcli_write(c
->tree
, fnum
, 0, &pid
, 0, sizeof(pid
)) != sizeof(pid
)) {
130 printf("write failed (%s)\n", smbcli_errstr(c
->tree
));
135 if (smbcli_write(c
->tree
, fnum
, 0, buf
,
136 sizeof(pid
)+(j
*sizeof(buf
)),
137 sizeof(buf
)) != sizeof(buf
)) {
138 printf("write failed (%s)\n", smbcli_errstr(c
->tree
));
145 if (smbcli_read(c
->tree
, fnum
, &pid2
, 0, sizeof(pid
)) != sizeof(pid
)) {
146 printf("read failed (%s)\n", smbcli_errstr(c
->tree
));
151 printf("data corruption!\n");
155 if (NT_STATUS_IS_ERR(smbcli_close(c
->tree
, fnum
))) {
156 printf("close failed (%s)\n", smbcli_errstr(c
->tree
));
160 if (NT_STATUS_IS_ERR(smbcli_unlink(c
->tree
, fname
))) {
161 printf("unlink failed (%s)\n", smbcli_errstr(c
->tree
));
165 if (NT_STATUS_IS_ERR(smbcli_unlock(c
->tree
, fnum2
, n
*sizeof(int), sizeof(int)))) {
166 printf("unlock failed (%s)\n", smbcli_errstr(c
->tree
));
172 smbcli_close(c
->tree
, fnum2
);
173 smbcli_unlink(c
->tree
, lockfname
);
180 static BOOL
run_torture(struct smbcli_state
*cli
, int dummy
)
184 ret
= rw_torture(cli
);
186 if (!torture_close_connection(cli
)) {
195 see how many RPC pipes we can open at once
197 static BOOL
run_pipe_number(struct torture_context
*torture
)
199 struct smbcli_state
*cli1
;
200 const char *pipe_name
= "\\WKSSVC";
204 printf("starting pipenumber test\n");
205 if (!torture_open_connection(&cli1
, 0)) {
210 fnum
= smbcli_nt_create_full(cli1
->tree
, pipe_name
, 0, SEC_FILE_READ_DATA
, FILE_ATTRIBUTE_NORMAL
,
211 NTCREATEX_SHARE_ACCESS_READ
|NTCREATEX_SHARE_ACCESS_WRITE
, NTCREATEX_DISP_OPEN_IF
, 0, 0);
214 printf("Open of pipe %s failed with error (%s)\n", pipe_name
, smbcli_errstr(cli1
->tree
));
218 printf("%d\r", num_pipes
);
222 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes
, pipe_name
);
223 torture_close_connection(cli1
);
231 open N connections to the server and just hold them open
232 used for testing performance when there are N idle users
235 static BOOL
torture_holdcon(struct torture_context
*torture
)
238 struct smbcli_state
**cli
;
241 printf("Opening %d connections\n", torture_numops
);
243 cli
= malloc_array_p(struct smbcli_state
*, torture_numops
);
245 for (i
=0;i
<torture_numops
;i
++) {
246 if (!torture_open_connection(&cli
[i
], i
)) {
249 printf("opened %d connections\r", i
);
253 printf("\nStarting pings\n");
256 for (i
=0;i
<torture_numops
;i
++) {
259 status
= smbcli_chkpath(cli
[i
]->tree
, "\\");
260 if (!NT_STATUS_IS_OK(status
)) {
261 printf("Connection %d is dead\n", i
);
269 if (num_dead
== torture_numops
) {
270 printf("All connections dead - finishing\n");
282 test how many open files this server supports on the one socket
284 static BOOL
run_maxfidtest(struct smbcli_state
*cli
, int dummy
)
286 #define MAXFID_TEMPLATE "\\maxfid\\fid%d\\maxfid.%d.%d"
288 int fnums
[0x11000], i
;
289 int retries
=4, maxfid
;
293 printf("failed to connect\n");
297 if (smbcli_deltree(cli
->tree
, "\\maxfid") == -1) {
298 printf("Failed to deltree \\maxfid - %s\n",
299 smbcli_errstr(cli
->tree
));
302 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, "\\maxfid"))) {
303 printf("Failed to mkdir \\maxfid, error=%s\n",
304 smbcli_errstr(cli
->tree
));
308 printf("Testing maximum number of open files\n");
310 for (i
=0; i
<0x11000; i
++) {
312 asprintf(&fname
, "\\maxfid\\fid%d", i
/1000);
313 if (NT_STATUS_IS_ERR(smbcli_mkdir(cli
->tree
, fname
))) {
314 printf("Failed to mkdir %s, error=%s\n",
315 fname
, smbcli_errstr(cli
->tree
));
320 asprintf(&fname
, MAXFID_TEMPLATE
, i
/1000, i
,(int)getpid());
321 if ((fnums
[i
] = smbcli_open(cli
->tree
, fname
,
322 O_RDWR
|O_CREAT
|O_TRUNC
, DENY_NONE
)) ==
324 printf("open of %s failed (%s)\n",
325 fname
, smbcli_errstr(cli
->tree
));
326 printf("maximum fnum is %d\n", i
);
337 printf("cleaning up\n");
338 for (i
=0;i
<maxfid
/2;i
++) {
339 asprintf(&fname
, MAXFID_TEMPLATE
, i
/1000, i
,(int)getpid());
340 if (NT_STATUS_IS_ERR(smbcli_close(cli
->tree
, fnums
[i
]))) {
341 printf("Close of fnum %d failed - %s\n", fnums
[i
], smbcli_errstr(cli
->tree
));
343 if (NT_STATUS_IS_ERR(smbcli_unlink(cli
->tree
, fname
))) {
344 printf("unlink of %s failed (%s)\n",
345 fname
, smbcli_errstr(cli
->tree
));
350 asprintf(&fname
, MAXFID_TEMPLATE
, (maxfid
-i
)/1000, maxfid
-i
,(int)getpid());
351 if (NT_STATUS_IS_ERR(smbcli_close(cli
->tree
, fnums
[maxfid
-i
]))) {
352 printf("Close of fnum %d failed - %s\n", fnums
[maxfid
-i
], smbcli_errstr(cli
->tree
));
354 if (NT_STATUS_IS_ERR(smbcli_unlink(cli
->tree
, fname
))) {
355 printf("unlink of %s failed (%s)\n",
356 fname
, smbcli_errstr(cli
->tree
));
361 printf("%6d %6d\r", i
, maxfid
-i
);
365 if (smbcli_deltree(cli
->tree
, "\\maxfid") == -1) {
366 printf("Failed to deltree \\maxfid - %s\n",
367 smbcli_errstr(cli
->tree
));
371 printf("maxfid test finished\n");
372 if (!torture_close_connection(cli
)) {
376 #undef MAXFID_TEMPLATE
382 sees what IOCTLs are supported
384 static BOOL
torture_ioctl_test(struct torture_context
*torture
)
386 struct smbcli_state
*cli
;
387 uint16_t device
, function
;
389 const char *fname
= "\\ioctl.dat";
391 union smb_ioctl parms
;
394 if (!torture_open_connection(&cli
, 0)) {
398 mem_ctx
= talloc_named_const(torture
, 0, "ioctl_test");
400 printf("starting ioctl test\n");
402 smbcli_unlink(cli
->tree
, fname
);
404 fnum
= smbcli_open(cli
->tree
, fname
, O_RDWR
|O_CREAT
|O_EXCL
, DENY_NONE
);
406 printf("open of %s failed (%s)\n", fname
, smbcli_errstr(cli
->tree
));
410 parms
.ioctl
.level
= RAW_IOCTL_IOCTL
;
411 parms
.ioctl
.in
.file
.fnum
= fnum
;
412 parms
.ioctl
.in
.request
= IOCTL_QUERY_JOB_INFO
;
413 status
= smb_raw_ioctl(cli
->tree
, mem_ctx
, &parms
);
414 printf("ioctl job info: %s\n", smbcli_errstr(cli
->tree
));
416 for (device
=0;device
<0x100;device
++) {
417 printf("testing device=0x%x\n", device
);
418 for (function
=0;function
<0x100;function
++) {
419 parms
.ioctl
.in
.request
= (device
<< 16) | function
;
420 status
= smb_raw_ioctl(cli
->tree
, mem_ctx
, &parms
);
422 if (NT_STATUS_IS_OK(status
)) {
423 printf("ioctl device=0x%x function=0x%x OK : %d bytes\n",
424 device
, function
, (int)parms
.ioctl
.out
.blob
.length
);
429 if (!torture_close_connection(cli
)) {
437 init params using lp_parm_xxx
438 return number of unclist entries
440 int init_benchrw_params(TALLOC_CTX
*mem_ctx
,struct params
*lpar
)
442 char **unc_list
= NULL
;
443 int num_unc_names
= 0, conn_index
=0, empty_lines
=0;
445 lpar
->retry
= lp_parm_int(-1, "torture", "retry",3);
446 lpar
->blocksize
= lp_parm_int(-1, "torture", "blocksize",65535);
447 lpar
->writeblocks
= lp_parm_int(-1, "torture", "writeblocks",15);
448 lpar
->writeratio
= lp_parm_int(-1, "torture", "writeratio",5);
449 lpar
->workgroup
= lp_workgroup();
451 p
= lp_parm_string(-1, "torture", "unclist");
454 unc_list
= file_lines_load(p
, &num_unc_names
, NULL
);
455 if (!unc_list
|| num_unc_names
<= 0) {
456 printf("Failed to load unc names list from '%s'\n", p
);
460 lpar
->unc
= talloc_array(mem_ctx
, struct unclist
*, (num_unc_names
-empty_lines
));
461 for(conn_index
= 0; conn_index
< num_unc_names
; conn_index
++) {
462 /* ignore empty lines */
463 if(strlen(unc_list
[conn_index
% num_unc_names
])==0){
467 if (!smbcli_parse_unc(unc_list
[conn_index
% num_unc_names
],
469 printf("Failed to parse UNC name %s\n",
470 unc_list
[conn_index
% num_unc_names
]);
473 lpar
->unc
[conn_index
-empty_lines
] = talloc(mem_ctx
,struct unclist
);
474 lpar
->unc
[conn_index
-empty_lines
]->host
= h
;
475 lpar
->unc
[conn_index
-empty_lines
]->share
= s
;
477 return num_unc_names
-empty_lines
;
479 lpar
->unc
= talloc_array(mem_ctx
, struct unclist
*, 1);
480 lpar
->unc
[0] = talloc(mem_ctx
,struct unclist
);
481 lpar
->unc
[0]->host
= lp_parm_string(-1, "torture", "host");
482 lpar
->unc
[0]->share
= lp_parm_string(-1, "torture", "share");
488 Called when the reads & writes are finished. closes the file.
490 NTSTATUS
benchrw_close(struct smbcli_request
*req
,
491 struct benchrw_state
*state
)
493 union smb_close close_parms
;
495 NT_STATUS_NOT_OK_RETURN(req
->status
);
497 printf("Close file %d (%d)\n",state
->nr
,state
->fnum
);
498 close_parms
.close
.level
= RAW_CLOSE_CLOSE
;
499 close_parms
.close
.in
.file
.fnum
= state
->fnum
;
500 close_parms
.close
.in
.write_time
= 0;
501 state
->mode
=CLOSE_FILE
;
503 req
= smb_raw_close_send(state
->cli
, &close_parms
);
504 NT_STATUS_HAVE_NO_MEMORY(req
);
505 /*register the callback function!*/
506 req
->async
.fn
= benchrw_callback
;
507 req
->async
.private = state
;
513 Called when the initial write is completed is done. write or read a file.
515 NTSTATUS
benchrw_readwrite(struct smbcli_request
*req
,
516 struct benchrw_state
*state
)
521 NT_STATUS_NOT_OK_RETURN(req
->status
);
524 /*rotate between writes and reads*/
525 if( state
->completed
% state
->lp_params
->writeratio
== 0){
526 printf("Callback WRITE file:%d (%d/%d)\n",
527 state
->nr
,state
->completed
,torture_numops
);
528 wr
.generic
.level
= RAW_WRITE_WRITEX
;
529 wr
.writex
.in
.file
.fnum
= state
->fnum
;
530 wr
.writex
.in
.offset
= 0;
531 wr
.writex
.in
.wmode
= 0 ;
532 wr
.writex
.in
.remaining
= 0;
533 wr
.writex
.in
.count
= state
->lp_params
->blocksize
;
534 wr
.writex
.in
.data
= state
->buffer
;
536 req
= smb_raw_write_send(state
->cli
,&wr
);
538 printf("Callback READ file:%d (%d/%d) Offset:%d\n",
539 state
->nr
,state
->completed
,torture_numops
,
540 (state
->readcnt
*state
->lp_params
->blocksize
));
541 rd
.generic
.level
= RAW_READ_READ
;
542 rd
.read
.in
.file
.fnum
= state
->fnum
;
543 rd
.read
.in
.offset
= state
->readcnt
*
544 state
->lp_params
->blocksize
;
545 rd
.read
.in
.count
= state
->lp_params
->blocksize
;
546 rd
.read
.in
.remaining
= 0 ;
547 rd
.read
.out
.data
= state
->buffer
;
548 if(state
->readcnt
< state
->lp_params
->writeblocks
){
551 /*start reading from beginn of file*/
554 req
= smb_raw_read_send(state
->cli
,&rd
);
556 NT_STATUS_HAVE_NO_MEMORY(req
);
557 /*register the callback function!*/
558 req
->async
.fn
= benchrw_callback
;
559 req
->async
.private = state
;
565 Called when the open is done. writes to the file.
567 NTSTATUS
benchrw_open(struct smbcli_request
*req
,
568 struct benchrw_state
*state
)
571 if(state
->mode
== OPEN_FILE
){
573 status
= smb_raw_open_recv(req
,state
->mem_ctx
,(
574 union smb_open
*)state
->req_params
);
575 NT_STATUS_NOT_OK_RETURN(status
);
577 state
->fnum
= ((union smb_open
*)state
->req_params
)
578 ->openx
.out
.file
.fnum
;
579 printf("File opened (%d)\n",state
->fnum
);
580 state
->mode
=INITIAL_WRITE
;
583 printf("Write initial test file:%d (%d/%d)\n",state
->nr
,
584 (state
->writecnt
+1)*state
->lp_params
->blocksize
,
585 (state
->lp_params
->writeblocks
*state
->lp_params
->blocksize
));
586 wr
.generic
.level
= RAW_WRITE_WRITEX
;
587 wr
.writex
.in
.file
.fnum
= state
->fnum
;
588 wr
.writex
.in
.offset
= state
->writecnt
*
589 state
->lp_params
->blocksize
;
590 wr
.writex
.in
.wmode
= 0 ;
591 wr
.writex
.in
.remaining
= (state
->lp_params
->writeblocks
*
592 state
->lp_params
->blocksize
)-
593 ((state
->writecnt
+1)*state
->
594 lp_params
->blocksize
);
595 wr
.writex
.in
.count
= state
->lp_params
->blocksize
;
596 wr
.writex
.in
.data
= state
->buffer
;
598 if(state
->writecnt
== state
->lp_params
->writeblocks
){
599 state
->mode
=READ_WRITE_DATA
;
601 req
= smb_raw_write_send(state
->cli
,&wr
);
602 NT_STATUS_HAVE_NO_MEMORY(req
);
604 /*register the callback function!*/
605 req
->async
.fn
= benchrw_callback
;
606 req
->async
.private = state
;
611 Called when the mkdir is done. Opens a file.
613 NTSTATUS
benchrw_mkdir(struct smbcli_request
*req
,
614 struct benchrw_state
*state
)
616 union smb_open
*open_parms
;
619 NT_STATUS_NOT_OK_RETURN(req
->status
);
621 /* open/create the files */
622 printf("Open File %d/%d\n",state
->nr
+1,torture_nprocs
);
623 open_parms
=talloc_zero(state
->mem_ctx
, union smb_open
);
624 NT_STATUS_HAVE_NO_MEMORY(open_parms
);
625 open_parms
->openx
.level
= RAW_OPEN_OPENX
;
626 open_parms
->openx
.in
.flags
= 0;
627 open_parms
->openx
.in
.open_mode
= OPENX_MODE_ACCESS_RDWR
;
628 open_parms
->openx
.in
.search_attrs
=
629 FILE_ATTRIBUTE_SYSTEM
| FILE_ATTRIBUTE_HIDDEN
;
630 open_parms
->openx
.in
.file_attrs
= 0;
631 open_parms
->openx
.in
.write_time
= 0;
632 open_parms
->openx
.in
.open_func
= OPENX_OPEN_FUNC_CREATE
;
633 open_parms
->openx
.in
.size
= 0;
634 open_parms
->openx
.in
.timeout
= 0;
635 open_parms
->openx
.in
.fname
= state
->fname
;
637 writedata
= talloc_size(state
->mem_ctx
,state
->lp_params
->blocksize
);
638 NT_STATUS_HAVE_NO_MEMORY(writedata
);
639 generate_random_buffer(writedata
,state
->lp_params
->blocksize
);
640 state
->buffer
=writedata
;
643 state
->req_params
=open_parms
;
644 state
->mode
=OPEN_FILE
;
646 req
= smb_raw_open_send(state
->cli
,open_parms
);
647 NT_STATUS_HAVE_NO_MEMORY(req
);
649 /*register the callback function!*/
650 req
->async
.fn
= benchrw_callback
;
651 req
->async
.private = state
;
657 handler for completion of a sub-request of the bench-rw test
659 void benchrw_callback(struct smbcli_request
*req
)
661 struct benchrw_state
*state
= req
->async
.private;
663 /*dont send new requests when torture_numops is reached*/
664 if(state
->completed
>= torture_numops
){
666 state
->mode
=MAX_OPS_REACHED
;
669 switch (state
->mode
) {
672 if (!NT_STATUS_IS_OK(benchrw_mkdir(req
,state
))) {
673 printf("Failed to create the test directory - %s\n",
674 nt_errstr(req
->status
));
681 if (!NT_STATUS_IS_OK(benchrw_open(req
,state
))){
682 printf("Failed to open/write the file - %s\n",
683 nt_errstr(req
->status
));
688 case READ_WRITE_DATA
:
689 if (!NT_STATUS_IS_OK(benchrw_readwrite(req
,state
))){
690 printf("Failed to read/write the file - %s\n",
691 nt_errstr(req
->status
));
696 case MAX_OPS_REACHED
:
697 if (!NT_STATUS_IS_OK(benchrw_close(req
,state
))){
698 printf("Failed to read/write/close the file - %s\n",
699 nt_errstr(req
->status
));
705 printf("File %d closed\n",state
->nr
);
706 if (!NT_STATUS_IS_OK(req
->status
)) {
707 printf("Failed to close the file - %s\n",
708 nt_errstr(req
->status
));
720 /* open connection async callback function*/
721 void async_open_callback(struct composite_context
*con
)
723 struct benchrw_state
*state
= con
->async
.private_data
;
724 int retry
= state
->lp_params
->retry
;
726 if (NT_STATUS_IS_OK(con
->status
)) {
727 state
->cli
=((struct smb_composite_connect
*)
728 state
->req_params
)->out
.tree
;
729 state
->mode
=CLEANUP_TESTDIR
;
731 if(state
->writecnt
< retry
){
732 printf("Failed to open connection:%d, Retry (%d/%d)\n",
733 state
->nr
,state
->writecnt
,retry
);
738 printf("Failed to open connection (%d) - %s\n",
739 state
->nr
, nt_errstr(con
->status
));
747 establishs a smbcli_tree from scratch (async)
749 struct composite_context
*torture_connect_async(
750 struct smb_composite_connect
*smb
,
752 struct event_context
*ev
,
755 const char *workgroup
)
757 printf("Open Connection to %s/%s\n",host
,share
);
758 smb
->in
.dest_host
=talloc_strdup(mem_ctx
,host
);
759 smb
->in
.service
=talloc_strdup(mem_ctx
,share
);
761 smb
->in
.called_name
= strupper_talloc(mem_ctx
, host
);
762 smb
->in
.service_type
=NULL
;
763 smb
->in
.credentials
=cmdline_credentials
;
764 smb
->in
.fallback_to_anonymous
=False
;
765 smb
->in
.workgroup
=workgroup
;
767 return smb_composite_connect_send(smb
,mem_ctx
,ev
);
770 static BOOL
run_benchrw(struct torture_context
*torture
)
772 struct smb_composite_connect
*smb_con
;
773 const char *fname
= "\\rwtest.dat";
774 struct smbcli_request
*req
;
775 struct benchrw_state
**state
;
776 int i
, num_unc_names
;
778 struct event_context
*ev
;
779 struct composite_context
*req1
;
780 struct params lpparams
;
781 union smb_mkdir parms
;
785 printf("Start BENCH-READWRITE num_ops=%d num_nprocs=%d\n",
786 torture_numops
,torture_nprocs
);
788 /*init talloc context*/
789 mem_ctx
= talloc_named_const(torture
, 0, "bench-readwrite");
790 ev
= event_context_init(mem_ctx
);
791 state
= talloc_array(mem_ctx
, struct benchrw_state
*, torture_nprocs
);
793 /* init params using lp_parm_xxx */
794 num_unc_names
= init_benchrw_params(mem_ctx
,&lpparams
);
796 /* init private data structs*/
797 for(i
= 0; i
<torture_nprocs
;i
++){
798 state
[i
]=talloc(mem_ctx
,struct benchrw_state
);
799 state
[i
]->completed
=0;
800 state
[i
]->lp_params
=&lpparams
;
802 state
[i
]->dname
=talloc_asprintf(mem_ctx
,"benchrw%d",i
);
803 state
[i
]->fname
=talloc_asprintf(mem_ctx
,"%s%s",
804 state
[i
]->dname
,fname
);
805 state
[i
]->mode
=START
;
806 state
[i
]->writecnt
=0;
809 printf("Starting async requests\n");
810 while(finished
!= torture_nprocs
){
812 for(i
= 0; i
<torture_nprocs
;i
++){
813 switch (state
[i
]->mode
){
814 /*open multiple connections with the same userid */
816 smb_con
= talloc(mem_ctx
,struct smb_composite_connect
) ;
817 state
[i
]->req_params
=smb_con
;
818 state
[i
]->mode
=OPEN_CONNECTION
;
819 req1
= torture_connect_async(smb_con
,
821 lpparams
.unc
[i
% num_unc_names
]->host
,
822 lpparams
.unc
[i
% num_unc_names
]->share
,
824 /* register callback fn + private data */
825 req1
->async
.fn
= async_open_callback
;
826 req1
->async
.private_data
=state
[i
];
828 /*setup test dirs (sync)*/
829 case CLEANUP_TESTDIR
:
830 printf("Setup test dir %d\n",i
);
831 smb_raw_exit(state
[i
]->cli
->session
);
832 if (smbcli_deltree(state
[i
]->cli
,
833 state
[i
]->dname
) == -1) {
834 printf("Unable to delete %s - %s\n",
836 smbcli_errstr(state
[i
]->cli
));
837 state
[i
]->mode
=ERROR
;
840 state
[i
]->mode
=MK_TESTDIR
;
841 parms
.mkdir
.level
= RAW_MKDIR_MKDIR
;
842 parms
.mkdir
.in
.path
= state
[i
]->dname
;
843 req
= smb_raw_mkdir_send(state
[i
]->cli
,&parms
);
844 /* register callback fn + private data */
845 req
->async
.fn
= benchrw_callback
;
846 req
->async
.private=state
[i
];
848 /* error occured , finish */
853 /* cleanup , close connection */
855 printf("Deleting test dir %s %d/%d\n",state
[i
]->dname
,
857 smbcli_deltree(state
[i
]->cli
,state
[i
]->dname
);
858 if (NT_STATUS_IS_ERR(smb_tree_disconnect(
860 printf("ERROR: Tree disconnect failed");
861 state
[i
]->mode
=ERROR
;
864 state
[i
]->mode
=FINISHED
;
874 printf("BENCH-READWRITE done. Closing connections.\n");
876 /*free all allocated memory*/
877 talloc_free(mem_ctx
);
883 NTSTATUS
torture_misc_init(void)
885 register_torture_op("BENCH-HOLDCON", torture_holdcon
);
886 register_torture_op("SCAN-PIPE_NUMBER", run_pipe_number
);
887 register_torture_op("SCAN-IOCTL", torture_ioctl_test
);
888 register_torture_op("BENCH-READWRITE", run_benchrw
);
889 register_torture_multi_op("BENCH-TORTURE", run_torture
);
890 register_torture_multi_op("SCAN-MAXFID", run_maxfidtest
);