📄 misc.c
字号:
} lpar->unc[conn_index-empty_lines] = talloc(tctx, struct unclist); lpar->unc[conn_index-empty_lines]->host = h; lpar->unc[conn_index-empty_lines]->share = s; } return num_unc_names-empty_lines; }else{ lpar->unc = talloc_array(tctx, struct unclist *, 1); lpar->unc[0] = talloc(tctx,struct unclist); lpar->unc[0]->host = torture_setting_string(tctx, "host", NULL); lpar->unc[0]->share = torture_setting_string(tctx, "share", NULL); return 1; }}/* Called when the reads & writes are finished. closes the file.*/static NTSTATUS benchrw_close(struct torture_context *tctx, struct smbcli_request *req, struct benchrw_state *state){ union smb_close close_parms; NT_STATUS_NOT_OK_RETURN(req->status); torture_comment(tctx, "Close file %d (%d)\n",state->nr,state->fnum); close_parms.close.level = RAW_CLOSE_CLOSE; close_parms.close.in.file.fnum = state->fnum ; close_parms.close.in.write_time = 0; state->mode=CLOSE_FILE; req = smb_raw_close_send(state->cli, &close_parms); NT_STATUS_HAVE_NO_MEMORY(req); /*register the callback function!*/ req->async.fn = benchrw_callback; req->async.private = state; return NT_STATUS_OK;}static NTSTATUS benchrw_readwrite(struct torture_context *tctx, struct benchrw_state *state);static void benchrw_callback(struct smbcli_request *req);static void benchrw_rw_callback(struct smbcli_request *req){ struct benchrw_state *state = req->async.private; struct torture_context *tctx = state->tctx; if (!NT_STATUS_IS_OK(req->status)) { state->mode = ERROR; return; } state->completed++; state->num_parallel_requests--; if ((state->completed >= torture_numops) && (state->num_parallel_requests == 0)) { benchrw_callback(req); talloc_free(req); return; } talloc_free(req); if (state->completed + state->num_parallel_requests < torture_numops) { benchrw_readwrite(tctx, state); }}/* Called when the initial write is completed is done. write or read a file.*/static NTSTATUS benchrw_readwrite(struct torture_context *tctx, struct benchrw_state *state){ struct smbcli_request *req; union smb_read rd; union smb_write wr; /* randomize between writes and reads*/ if (random() % state->lp_params->writeratio == 0) { torture_comment(tctx, "Callback WRITE file:%d (%d/%d)\n", state->nr,state->completed,torture_numops); wr.generic.level = RAW_WRITE_WRITEX ; wr.writex.in.file.fnum = state->fnum ; wr.writex.in.offset = 0; wr.writex.in.wmode = 0 ; wr.writex.in.remaining = 0; wr.writex.in.count = state->lp_params->blocksize; wr.writex.in.data = state->buffer; state->readcnt=0; req = smb_raw_write_send(state->cli,&wr); } else { torture_comment(tctx, "Callback READ file:%d (%d/%d) Offset:%d\n", state->nr,state->completed,torture_numops, (state->readcnt*state->lp_params->blocksize)); rd.generic.level = RAW_READ_READX; rd.readx.in.file.fnum = state->fnum ; rd.readx.in.offset = state->readcnt*state->lp_params->blocksize; rd.readx.in.mincnt = state->lp_params->blocksize; rd.readx.in.maxcnt = rd.readx.in.mincnt; rd.readx.in.remaining = 0 ; rd.readx.out.data = state->buffer; rd.readx.in.read_for_execute = false; if(state->readcnt < state->lp_params->writeblocks){ state->readcnt++; }else{ /*start reading from beginn of file*/ state->readcnt=0; } req = smb_raw_read_send(state->cli,&rd); } state->num_parallel_requests += 1; NT_STATUS_HAVE_NO_MEMORY(req); /*register the callback function!*/ req->async.fn = benchrw_rw_callback; req->async.private = state; return NT_STATUS_OK;}/* Called when the open is done. writes to the file.*/static NTSTATUS benchrw_open(struct torture_context *tctx, struct smbcli_request *req, struct benchrw_state *state){ union smb_write wr; if(state->mode == OPEN_FILE){ NTSTATUS status; status = smb_raw_open_recv(req,tctx,( union smb_open*)state->req_params); NT_STATUS_NOT_OK_RETURN(status); state->fnum = ((union smb_open*)state->req_params) ->openx.out.file.fnum; torture_comment(tctx, "File opened (%d)\n",state->fnum); state->mode=INITIAL_WRITE; } torture_comment(tctx, "Write initial test file:%d (%d/%d)\n",state->nr, (state->writecnt+1)*state->lp_params->blocksize, (state->lp_params->writeblocks*state->lp_params->blocksize)); wr.generic.level = RAW_WRITE_WRITEX ; wr.writex.in.file.fnum = state->fnum ; wr.writex.in.offset = state->writecnt * state->lp_params->blocksize; wr.writex.in.wmode = 0 ; wr.writex.in.remaining = (state->lp_params->writeblocks * state->lp_params->blocksize)- ((state->writecnt+1)*state-> lp_params->blocksize); wr.writex.in.count = state->lp_params->blocksize; wr.writex.in.data = state->buffer; state->writecnt++; if(state->writecnt == state->lp_params->writeblocks){ state->mode=READ_WRITE_DATA; } req = smb_raw_write_send(state->cli,&wr); NT_STATUS_HAVE_NO_MEMORY(req); /*register the callback function!*/ req->async.fn = benchrw_callback; req->async.private = state; return NT_STATUS_OK;} /* Called when the mkdir is done. Opens a file.*/static NTSTATUS benchrw_mkdir(struct torture_context *tctx, struct smbcli_request *req, struct benchrw_state *state){ union smb_open *open_parms; uint8_t *writedata; NT_STATUS_NOT_OK_RETURN(req->status); /* open/create the files */ torture_comment(tctx, "Open File %d/%d\n",state->nr+1, torture_setting_int(tctx, "nprocs", 4)); open_parms=talloc_zero(tctx, union smb_open); NT_STATUS_HAVE_NO_MEMORY(open_parms); open_parms->openx.level = RAW_OPEN_OPENX; open_parms->openx.in.flags = 0; open_parms->openx.in.open_mode = OPENX_MODE_ACCESS_RDWR; open_parms->openx.in.search_attrs = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN; open_parms->openx.in.file_attrs = 0; open_parms->openx.in.write_time = 0; open_parms->openx.in.open_func = OPENX_OPEN_FUNC_CREATE; open_parms->openx.in.size = 0; open_parms->openx.in.timeout = 0; open_parms->openx.in.fname = state->fname; writedata = talloc_size(tctx,state->lp_params->blocksize); NT_STATUS_HAVE_NO_MEMORY(writedata); generate_random_buffer(writedata,state->lp_params->blocksize); state->buffer=writedata; state->writecnt=1; state->readcnt=0; state->req_params=open_parms; state->mode=OPEN_FILE; req = smb_raw_open_send(state->cli,open_parms); NT_STATUS_HAVE_NO_MEMORY(req); /*register the callback function!*/ req->async.fn = benchrw_callback; req->async.private = state; return NT_STATUS_OK;}/* handler for completion of a sub-request of the bench-rw test*/static void benchrw_callback(struct smbcli_request *req){ struct benchrw_state *state = req->async.private; struct torture_context *tctx = state->tctx; /*dont send new requests when torture_numops is reached*/ if ((state->mode == READ_WRITE_DATA) && (state->completed >= torture_numops)) { state->mode=MAX_OPS_REACHED; } switch (state->mode) { case MK_TESTDIR: if (!NT_STATUS_IS_OK(benchrw_mkdir(tctx, req,state))) { torture_comment(tctx, "Failed to create the test " "directory - %s\n", nt_errstr(req->status)); state->mode=ERROR; return; } break; case OPEN_FILE: case INITIAL_WRITE: if (!NT_STATUS_IS_OK(benchrw_open(tctx, req,state))){ torture_comment(tctx, "Failed to open/write the " "file - %s\n", nt_errstr(req->status)); state->mode=ERROR; state->readcnt=0; return; } break; case READ_WRITE_DATA: while (state->num_parallel_requests < state->lp_params->num_parallel_requests) { NTSTATUS status; status = benchrw_readwrite(tctx,state); if (!NT_STATUS_IS_OK(status)){ torture_comment(tctx, "Failed to read/write " "the file - %s\n", nt_errstr(req->status)); state->mode=ERROR; return; } } break; case MAX_OPS_REACHED: if (!NT_STATUS_IS_OK(benchrw_close(tctx,req,state))){ torture_comment(tctx, "Failed to read/write/close " "the file - %s\n", nt_errstr(req->status)); state->mode=ERROR; return; } break; case CLOSE_FILE: torture_comment(tctx, "File %d closed\n",state->nr); if (!NT_STATUS_IS_OK(req->status)) { torture_comment(tctx, "Failed to close the " "file - %s\n", nt_errstr(req->status)); state->mode=ERROR; return; } state->mode=CLEANUP; return; default: break; } }/* open connection async callback function*/static void async_open_callback(struct composite_context *con){ struct benchrw_state *state = con->async.private_data; struct torture_context *tctx = state->tctx; int retry = state->lp_params->retry; if (NT_STATUS_IS_OK(con->status)) { state->cli=((struct smb_composite_connect*) state->req_params)->out.tree; state->mode=CLEANUP_TESTDIR; }else{ if(state->writecnt < retry){ torture_comment(tctx, "Failed to open connection: " "%d, Retry (%d/%d)\n", state->nr,state->writecnt,retry); state->writecnt++; state->mode=START; usleep(1000); }else{ torture_comment(tctx, "Failed to open connection " "(%d) - %s\n", state->nr, nt_errstr(con->status)); state->mode=ERROR; } return; } }/* establishs a smbcli_tree from scratch (async)*/static struct composite_context *torture_connect_async( struct torture_context *tctx, struct smb_composite_connect *smb, TALLOC_CTX *mem_ctx, struct event_context *ev, const char *host, const char *share, const char *workgroup){ torture_comment(tctx, "Open Connection to %s/%s\n",host,share); smb->in.dest_host=talloc_strdup(mem_ctx,host); smb->in.service=talloc_strdup(mem_ctx,share); smb->in.dest_ports=lp_smb_ports(tctx->lp_ctx); smb->in.called_name = strupper_talloc(mem_ctx, host); smb->in.service_type=NULL; smb->in.credentials=cmdline_credentials; smb->in.fallback_to_anonymous=false; smb->in.workgroup=workgroup; lp_smbcli_options(tctx->lp_ctx, &smb->in.options); return smb_composite_connect_send(smb,mem_ctx, lp_resolve_context(tctx->lp_ctx),ev);}bool run_benchrw(struct torture_context *tctx){ struct smb_composite_connect *smb_con; const char *fname = "\\rwtest.dat"; struct smbcli_request *req; struct benchrw_state **state; int i , num_unc_names; struct event_context *ev ; struct composite_context *req1; struct params lpparams; union smb_mkdir parms; int finished = 0; bool success=true; int torture_nprocs = torture_setting_int(tctx, "nprocs", 4); torture_comment(tctx, "Start BENCH-READWRITE num_ops=%d " "num_nprocs=%d\n", torture_numops, torture_nprocs); /*init talloc context*/ ev = tctx->ev; state = talloc_array(tctx, struct benchrw_state *, torture_nprocs); /* init params using lp_parm_xxx */ num_unc_names = init_benchrw_params(tctx,&lpparams); /* init private data structs*/ for(i = 0; i<torture_nprocs;i++){ state[i]=talloc(tctx,struct benchrw_state); state[i]->tctx = tctx; state[i]->completed=0; state[i]->num_parallel_requests=0; state[i]->lp_params=&lpparams; state[i]->nr=i; state[i]->dname=talloc_asprintf(tctx,"benchrw%d",i); state[i]->fname=talloc_asprintf(tctx,"%s%s", state[i]->dname,fname); state[i]->mode=START; state[i]->writecnt=0; } torture_comment(tctx, "Starting async requests\n"); while(finished != torture_nprocs){ finished=0; for(i = 0; i<torture_nprocs;i++){ switch (state[i]->mode){ /*open multiple connections with the same userid */ case START: smb_con = talloc( tctx,struct smb_composite_connect) ; state[i]->req_params=smb_con; state[i]->mode=OPEN_CONNECTION; req1 = torture_connect_async( tctx, smb_con, tctx,ev, lpparams.unc[i % num_unc_names]->host, lpparams.unc[i % num_unc_names]->share, lpparams.workgroup); /* register callback fn + private data */ req1->async.fn = async_open_callback; req1->async.private_data=state[i]; break; /*setup test dirs (sync)*/ case CLEANUP_TESTDIR: torture_comment(tctx, "Setup test dir %d\n",i); smb_raw_exit(state[i]->cli->session); if (smbcli_deltree(state[i]->cli, state[i]->dname) == -1) { torture_comment( tctx, "Unable to delete %s - %s\n", state[i]->dname, smbcli_errstr(state[i]->cli)); state[i]->mode=ERROR; break; } state[i]->mode=MK_TESTDIR; parms.mkdir.level = RAW_MKDIR_MKDIR; parms.mkdir.in.path = state[i]->dname; req = smb_raw_mkdir_send(state[i]->cli,&parms); /* register callback fn + private data */ req->async.fn = benchrw_callback; req->async.private=state[i]; break; /* error occured , finish */ case ERROR: finished++; success=false; break; /* cleanup , close connection */ case CLEANUP: torture_comment(tctx, "Deleting test dir %s " "%d/%d\n",state[i]->dname, i+1,torture_nprocs); smbcli_deltree(state[i]->cli,state[i]->dname); if (NT_STATUS_IS_ERR(smb_tree_disconnect( state[i]->cli))) { torture_comment(tctx, "ERROR: Tree " "disconnect failed"); state[i]->mode=ERROR; break; } state[i]->mode=FINISHED; case FINISHED: finished++; break; default: event_loop_once(ev); } } } return success; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -