LCOV - code coverage report
Current view: top level - source3/torture - test_notify.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 0 340 0.0 %
Date: 2021-09-23 10:06:22 Functions: 0 26 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Scalability test for notifies
       4             :    Copyright (C) Volker Lendecke 2012
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "torture/proto.h"
      22             : #include "libsmb/libsmb.h"
      23             : #include "lib/util/tevent_ntstatus.h"
      24             : #include "libcli/security/security.h"
      25             : #include "lib/tevent_barrier.h"
      26             : 
      27             : extern int torture_nprocs, torture_numops;
      28             : 
      29             : struct wait_for_one_notify_state {
      30             :         struct tevent_context *ev;
      31             :         struct cli_state *cli;
      32             :         uint16_t dnum;
      33             :         uint32_t filter;
      34             :         bool recursive;
      35             :         unsigned *num_notifies;
      36             : };
      37             : 
      38             : static void wait_for_one_notify_opened(struct tevent_req *subreq);
      39             : static void wait_for_one_notify_chkpath_done(struct tevent_req *subreq);
      40             : static void wait_for_one_notify_done(struct tevent_req *subreq);
      41             : static void wait_for_one_notify_closed(struct tevent_req *subreq);
      42             : 
      43           0 : static struct tevent_req *wait_for_one_notify_send(TALLOC_CTX *mem_ctx,
      44             :                                                    struct tevent_context *ev,
      45             :                                                    struct cli_state *cli,
      46             :                                                    const char *path,
      47             :                                                    uint32_t filter,
      48             :                                                    bool recursive,
      49             :                                                    unsigned *num_notifies)
      50             : {
      51             :         struct tevent_req *req, *subreq;
      52             :         struct wait_for_one_notify_state *state;
      53             : 
      54           0 :         req = tevent_req_create(mem_ctx, &state,
      55             :                                 struct wait_for_one_notify_state);
      56           0 :         if (req == NULL) {
      57           0 :                 return NULL;
      58             :         }
      59           0 :         state->ev = ev;
      60           0 :         state->cli = cli;
      61           0 :         state->filter = filter;
      62           0 :         state->recursive = recursive;
      63           0 :         state->num_notifies = num_notifies;
      64             : 
      65           0 :         subreq = cli_ntcreate_send(
      66           0 :                 state, state->ev, state->cli, path, 0,
      67             :                 MAXIMUM_ALLOWED_ACCESS,
      68             :                 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
      69             :                 FILE_OPEN, FILE_DIRECTORY_FILE,
      70             :                 SMB2_IMPERSONATION_IMPERSONATION, 0);
      71           0 :         if (tevent_req_nomem(subreq, req)) {
      72           0 :                 return tevent_req_post(req, ev);
      73             :         }
      74           0 :         tevent_req_set_callback(subreq, wait_for_one_notify_opened, req);
      75           0 :         return req;
      76             : }
      77             : 
      78           0 : static void wait_for_one_notify_opened(struct tevent_req *subreq)
      79             : {
      80           0 :         struct tevent_req *req = tevent_req_callback_data(
      81             :                 subreq, struct tevent_req);
      82           0 :         struct wait_for_one_notify_state *state = tevent_req_data(
      83             :                 req, struct wait_for_one_notify_state);
      84             :         NTSTATUS status;
      85             : 
      86           0 :         status = cli_ntcreate_recv(subreq, &state->dnum, NULL);
      87           0 :         TALLOC_FREE(subreq);
      88           0 :         if (tevent_req_nterror(req, status)) {
      89           0 :                 return;
      90             :         }
      91           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->dnum,
      92           0 :                                  0xffff, state->filter, state->recursive);
      93           0 :         if (tevent_req_nomem(subreq, req)) {
      94           0 :                 return;
      95             :         }
      96           0 :         tevent_req_set_callback(subreq, wait_for_one_notify_done, req);
      97             : 
      98             :         /*
      99             :          * To make sure the notify received at the server, we do another no-op
     100             :          * that is replied to.
     101             :          */
     102           0 :         subreq = cli_chkpath_send(state, state->ev, state->cli, "\\");
     103           0 :         if (tevent_req_nomem(subreq, req)) {
     104           0 :                 return;
     105             :         }
     106           0 :         tevent_req_set_callback(subreq, wait_for_one_notify_chkpath_done, req);
     107             : }
     108             : 
     109           0 : static void wait_for_one_notify_chkpath_done(struct tevent_req *subreq)
     110             : {
     111           0 :         struct tevent_req *req = tevent_req_callback_data(
     112             :                 subreq, struct tevent_req);
     113           0 :         struct wait_for_one_notify_state *state = tevent_req_data(
     114             :                 req, struct wait_for_one_notify_state);
     115             :         NTSTATUS status;
     116             : 
     117           0 :         status = cli_chkpath_recv(subreq);
     118           0 :         TALLOC_FREE(subreq);
     119           0 :         if (tevent_req_nterror(req, status)) {
     120           0 :                 return;
     121             :         }
     122           0 :         *state->num_notifies += 1;
     123             : }
     124             : 
     125           0 : static void wait_for_one_notify_done(struct tevent_req *subreq)
     126             : {
     127           0 :         struct tevent_req *req = tevent_req_callback_data(
     128             :                 subreq, struct tevent_req);
     129           0 :         struct wait_for_one_notify_state *state = tevent_req_data(
     130             :                 req, struct wait_for_one_notify_state);
     131             :         uint32_t num_changes;
     132             :         struct notify_change *changes;
     133             :         NTSTATUS status;
     134             : 
     135           0 :         status = cli_notify_recv(subreq, state, &num_changes, &changes);
     136           0 :         TALLOC_FREE(subreq);
     137           0 :         if (tevent_req_nterror(req, status)) {
     138           0 :                 return;
     139             :         }
     140           0 :         subreq = cli_close_send(state, state->ev, state->cli, state->dnum);
     141           0 :         if (tevent_req_nomem(subreq, req)) {
     142           0 :                 return;
     143             :         }
     144           0 :         tevent_req_set_callback(subreq, wait_for_one_notify_closed, req);
     145             : }
     146             : 
     147           0 : static void wait_for_one_notify_closed(struct tevent_req *subreq)
     148             : {
     149           0 :         struct tevent_req *req = tevent_req_callback_data(
     150             :                 subreq, struct tevent_req);
     151           0 :         struct wait_for_one_notify_state *state = tevent_req_data(
     152             :                 req, struct wait_for_one_notify_state);
     153             :         NTSTATUS status;
     154             : 
     155           0 :         status = cli_close_recv(subreq);
     156           0 :         TALLOC_FREE(subreq);
     157           0 :         if (tevent_req_nterror(req, status)) {
     158           0 :                 return;
     159             :         }
     160           0 :         *state->num_notifies -= 1;
     161           0 :         tevent_req_done(req);
     162             : }
     163             : 
     164           0 : static NTSTATUS wait_for_one_notify_recv(struct tevent_req *req)
     165             : {
     166           0 :         return tevent_req_simple_recv_ntstatus(req);
     167             : }
     168             : 
     169             : static void notify_bench2_done(struct tevent_req *req);
     170             : 
     171           0 : bool run_notify_bench2(int dummy)
     172             : {
     173             :         struct cli_state *cli;
     174             :         struct cli_state **clis;
     175             :         struct tevent_context *ev;
     176           0 :         unsigned num_notifies = 0;
     177             :         NTSTATUS status;
     178             :         int i;
     179             : 
     180           0 :         if (!torture_open_connection(&cli, 0)) {
     181           0 :                 return false;
     182             :         }
     183             : 
     184           0 :         printf("starting notify bench 2 test\n");
     185             : 
     186           0 :         cli_rmdir(cli, "\\notify.dir\\subdir");
     187           0 :         cli_rmdir(cli, "\\notify.dir");
     188             : 
     189           0 :         status = cli_mkdir(cli, "\\notify.dir");
     190           0 :         if (!NT_STATUS_IS_OK(status)) {
     191           0 :                 printf("mkdir failed : %s\n", nt_errstr(status));
     192           0 :                 return false;
     193             :         }
     194             : 
     195           0 :         clis = talloc_array(talloc_tos(), struct cli_state *, torture_nprocs);
     196           0 :         if (clis == NULL) {
     197           0 :                 printf("talloc failed\n");
     198           0 :                 return false;
     199             :         }
     200             : 
     201           0 :         ev = samba_tevent_context_init(talloc_tos());
     202           0 :         if (ev == NULL) {
     203           0 :                 printf("tevent_context_create failed\n");
     204           0 :                 return false;
     205             :         }
     206             : 
     207           0 :         for (i=0; i<torture_nprocs; i++) {
     208             :                 int j;
     209           0 :                 if (!torture_open_connection(&clis[i], i)) {
     210           0 :                         return false;
     211             :                 }
     212             : 
     213           0 :                 for (j=0; j<torture_numops; j++) {
     214             :                         struct tevent_req *req;
     215           0 :                         req = wait_for_one_notify_send(
     216           0 :                                 talloc_tos(), ev, clis[i], "\\notify.dir",
     217             :                                 FILE_NOTIFY_CHANGE_ALL, true,
     218             :                                 &num_notifies);
     219           0 :                         if (req == NULL) {
     220           0 :                                 printf("wait_for_one_notify_send failed\n");
     221           0 :                                 return false;
     222             :                         }
     223           0 :                         tevent_req_set_callback(req, notify_bench2_done, NULL);
     224             :                 }
     225             :         }
     226             : 
     227           0 :         while (num_notifies < (unsigned)(torture_nprocs * torture_numops)) {
     228             :                 int ret;
     229           0 :                 ret = tevent_loop_once(ev);
     230           0 :                 if (ret != 0) {
     231           0 :                         printf("tevent_loop_once failed: %s\n",
     232           0 :                                strerror(errno));
     233           0 :                         return false;
     234             :                 }
     235             :         }
     236             : 
     237           0 :         cli_mkdir(cli, "\\notify.dir\\subdir");
     238             : 
     239           0 :         while (num_notifies > 0) {
     240             :                 int ret;
     241           0 :                 ret = tevent_loop_once(ev);
     242           0 :                 if (ret != 0) {
     243           0 :                         printf("tevent_loop_once failed: %s\n",
     244           0 :                                strerror(errno));
     245           0 :                         return false;
     246             :                 }
     247             :         }
     248             : 
     249           0 :         return true;
     250             : }
     251             : 
     252           0 : static void notify_bench2_done(struct tevent_req *req)
     253             : {
     254             :         NTSTATUS status;
     255             : 
     256           0 :         status = wait_for_one_notify_recv(req);
     257           0 :         TALLOC_FREE(req);
     258           0 :         if (!NT_STATUS_IS_OK(status)) {
     259           0 :                 printf("wait_for_one_notify returned %s\n",
     260             :                        nt_errstr(status));
     261             :         }
     262           0 : }
     263             : 
     264             : /*
     265             :  * This test creates a subdirectory. It then waits on a barrier before the
     266             :  * notify is sent. Then it creates the notify. It then waits for another
     267             :  * barrier, so that all of the notifies have gone through. It then creates
     268             :  * another subdirectory, which will trigger notifications to be sent. When the
     269             :  * notifies have been received, it waits once more before everything is
     270             :  * cleaned up.
     271             :  */
     272             : 
     273             : struct notify_bench3_state {
     274             :         struct tevent_context *ev;
     275             :         struct cli_state *cli;
     276             :         const char *dir;
     277             :         uint16_t dnum;
     278             :         const char *subdir_path;
     279             :         uint16_t subdir_dnum;
     280             :         int wait_timeout;
     281             :         struct tevent_barrier *small;
     282             :         struct tevent_barrier *large;
     283             : };
     284             : 
     285             : static void notify_bench3_mkdir1_done(struct tevent_req *subreq);
     286             : static void notify_bench3_before_notify(struct tevent_req *subreq);
     287             : static void notify_bench3_chkpath_done(struct tevent_req *subreq);
     288             : static void notify_bench3_before_mkdir2(struct tevent_req *subreq);
     289             : static void notify_bench3_notify_done(struct tevent_req *subreq);
     290             : static void notify_bench3_notifies_done(struct tevent_req *subreq);
     291             : static void notify_bench3_mksubdir_done(struct tevent_req *subreq);
     292             : static void notify_bench3_before_close_subdir(struct tevent_req *subreq);
     293             : static void notify_bench3_close_subdir_done(struct tevent_req *subreq);
     294             : static void notify_bench3_deleted_subdir(struct tevent_req *subreq);
     295             : static void notify_bench3_deleted_subdirs(struct tevent_req *subreq);
     296             : static void notify_bench3_del_on_close_set(struct tevent_req *subreq);
     297             : static void notify_bench3_closed(struct tevent_req *subreq);
     298             : 
     299           0 : static struct tevent_req *notify_bench3_send(
     300             :         TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct cli_state *cli,
     301             :         const char *dir, const char *subdir_path,
     302             :         struct tevent_barrier *small, struct tevent_barrier *large)
     303             : {
     304             :         struct tevent_req *req, *subreq;
     305             :         struct notify_bench3_state *state;
     306             : 
     307           0 :         req = tevent_req_create(mem_ctx, &state, struct notify_bench3_state);
     308           0 :         if (req == NULL) {
     309           0 :                 return NULL;
     310             :         }
     311           0 :         state->ev = ev;
     312           0 :         state->cli = cli;
     313           0 :         state->dir = dir;
     314           0 :         state->subdir_path = subdir_path;
     315           0 :         state->small = small;
     316           0 :         state->large = large;
     317             : 
     318           0 :         subreq = cli_ntcreate_send(
     319           0 :                 state, state->ev, state->cli, state->dir, 0,
     320             :                 MAXIMUM_ALLOWED_ACCESS, 0,
     321             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
     322             :                 FILE_OPEN_IF, FILE_DIRECTORY_FILE,
     323             :                 SMB2_IMPERSONATION_IMPERSONATION, 0);
     324           0 :         if (tevent_req_nomem(subreq, req)) {
     325           0 :                 return tevent_req_post(req, ev);
     326             :         }
     327           0 :         tevent_req_set_callback(subreq, notify_bench3_mkdir1_done, req);
     328           0 :         return req;
     329             : }
     330             : 
     331           0 : static void notify_bench3_mkdir1_done(struct tevent_req *subreq)
     332             : {
     333           0 :         struct tevent_req *req = tevent_req_callback_data(
     334             :                 subreq, struct tevent_req);
     335           0 :         struct notify_bench3_state *state = tevent_req_data(
     336             :                 req, struct notify_bench3_state);
     337             :         NTSTATUS status;
     338             : 
     339           0 :         status = cli_ntcreate_recv(subreq, &state->dnum, NULL);
     340           0 :         TALLOC_FREE(subreq);
     341           0 :         if (tevent_req_nterror(req, status)) {
     342           0 :                 return;
     343             :         }
     344           0 :         subreq = tevent_barrier_wait_send(state, state->ev, state->small);
     345           0 :         if (tevent_req_nomem(subreq, req)) {
     346           0 :                 return;
     347             :         }
     348           0 :         tevent_req_set_callback(subreq, notify_bench3_before_notify, req);
     349             : }
     350             : 
     351           0 : static void notify_bench3_before_notify(struct tevent_req *subreq)
     352             : {
     353           0 :         struct tevent_req *req = tevent_req_callback_data(
     354             :                 subreq, struct tevent_req);
     355           0 :         struct notify_bench3_state *state = tevent_req_data(
     356             :                 req, struct notify_bench3_state);
     357             :         int ret;
     358             : 
     359           0 :         ret = tevent_barrier_wait_recv(subreq);
     360           0 :         TALLOC_FREE(subreq);
     361           0 :         if (ret != 0) {
     362           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(ret));
     363           0 :                 return;
     364             :         }
     365           0 :         subreq = cli_notify_send(state, state->ev, state->cli, state->dnum,
     366             :                                  0xffff, FILE_NOTIFY_CHANGE_ALL, true);
     367           0 :         if (tevent_req_nomem(subreq, req)) {
     368           0 :                 return;
     369             :         }
     370           0 :         tevent_req_set_callback(subreq, notify_bench3_notify_done, req);
     371             : 
     372             :         /*
     373             :          * To make sure the notify received at the server, we do another no-op
     374             :          * that is replied to.
     375             :          */
     376           0 :         subreq = cli_chkpath_send(state, state->ev, state->cli, "\\");
     377           0 :         if (tevent_req_nomem(subreq, req)) {
     378           0 :                 return;
     379             :         }
     380           0 :         tevent_req_set_callback(subreq, notify_bench3_chkpath_done, req);
     381             : }
     382             : 
     383           0 : static void notify_bench3_notify_done(struct tevent_req *subreq)
     384             : {
     385           0 :         struct tevent_req *req = tevent_req_callback_data(
     386             :                 subreq, struct tevent_req);
     387           0 :         struct notify_bench3_state *state = tevent_req_data(
     388             :                 req, struct notify_bench3_state);
     389             :         uint32_t num_changes;
     390             :         struct notify_change *changes;
     391             :         NTSTATUS status;
     392             : 
     393           0 :         status = cli_notify_recv(subreq, state, &num_changes, &changes);
     394           0 :         TALLOC_FREE(subreq);
     395           0 :         if (tevent_req_nterror(req, status)) {
     396           0 :                 return;
     397             :         }
     398           0 :         subreq = tevent_barrier_wait_send(state, state->ev, state->large);
     399           0 :         if (tevent_req_nomem(subreq, req)) {
     400           0 :                 return;
     401             :         }
     402           0 :         tevent_req_set_callback(subreq, notify_bench3_notifies_done, req);
     403             : }
     404             : 
     405           0 : static void notify_bench3_notifies_done(struct tevent_req *subreq)
     406             : {
     407           0 :         struct tevent_req *req = tevent_req_callback_data(
     408             :                 subreq, struct tevent_req);
     409             :         int ret;
     410             : 
     411           0 :         ret = tevent_barrier_wait_recv(subreq);
     412           0 :         TALLOC_FREE(subreq);
     413           0 :         if (ret != 0) {
     414           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(ret));
     415           0 :                 return;
     416             :         }
     417             : }
     418             : 
     419           0 : static void notify_bench3_chkpath_done(struct tevent_req *subreq)
     420             : {
     421           0 :         struct tevent_req *req = tevent_req_callback_data(
     422             :                 subreq, struct tevent_req);
     423           0 :         struct notify_bench3_state *state = tevent_req_data(
     424             :                 req, struct notify_bench3_state);
     425             :         NTSTATUS status;
     426             : 
     427           0 :         status = cli_chkpath_recv(subreq);
     428           0 :         TALLOC_FREE(subreq);
     429           0 :         if (tevent_req_nterror(req, status)) {
     430           0 :                 return;
     431             :         }
     432           0 :         if (state->subdir_path == NULL) {
     433           0 :                 return;
     434             :         }
     435           0 :         subreq = tevent_barrier_wait_send(state, state->ev, state->small);
     436           0 :         if (tevent_req_nomem(subreq, req)) {
     437           0 :                 return;
     438             :         }
     439           0 :         tevent_req_set_callback(subreq, notify_bench3_before_mkdir2, req);
     440             : }
     441             : 
     442           0 : static void notify_bench3_before_mkdir2(struct tevent_req *subreq)
     443             : {
     444           0 :         struct tevent_req *req = tevent_req_callback_data(
     445             :                 subreq, struct tevent_req);
     446           0 :         struct notify_bench3_state *state = tevent_req_data(
     447             :                 req, struct notify_bench3_state);
     448             :         int ret;
     449             : 
     450           0 :         ret = tevent_barrier_wait_recv(subreq);
     451           0 :         TALLOC_FREE(subreq);
     452           0 :         if (ret != 0) {
     453           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(ret));
     454           0 :                 return;
     455             :         }
     456           0 :         subreq =  cli_ntcreate_send(
     457             :                 state, state->ev, state->cli, state->subdir_path, 0,
     458             :                 MAXIMUM_ALLOWED_ACCESS, 0,
     459             :                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
     460             :                 FILE_CREATE,
     461             :                 FILE_DIRECTORY_FILE,
     462             :                 SMB2_IMPERSONATION_IMPERSONATION, 0);
     463           0 :         if (tevent_req_nomem(subreq, req)) {
     464           0 :                 return;
     465             :         }
     466           0 :         tevent_req_set_callback(subreq, notify_bench3_mksubdir_done, req);
     467             : }
     468             : 
     469           0 : static void notify_bench3_mksubdir_done(struct tevent_req *subreq)
     470             : {
     471           0 :         struct tevent_req *req = tevent_req_callback_data(
     472             :                 subreq, struct tevent_req);
     473           0 :         struct notify_bench3_state *state = tevent_req_data(
     474             :                 req, struct notify_bench3_state);
     475             :         NTSTATUS status;
     476             : 
     477           0 :         status = cli_ntcreate_recv(subreq, &state->subdir_dnum, NULL);
     478           0 :         TALLOC_FREE(subreq);
     479           0 :         if (tevent_req_nterror(req, status)) {
     480           0 :                 return;
     481             :         }
     482           0 :         subreq = tevent_barrier_wait_send(state, state->ev, state->large);
     483           0 :         if (tevent_req_nomem(subreq, req)) {
     484           0 :                 return;
     485             :         }
     486           0 :         tevent_req_set_callback(subreq, notify_bench3_before_close_subdir,
     487             :                                 req);
     488             : }
     489             : 
     490           0 : static void notify_bench3_before_close_subdir(struct tevent_req *subreq)
     491             : {
     492           0 :         struct tevent_req *req = tevent_req_callback_data(
     493             :                 subreq, struct tevent_req);
     494           0 :         struct notify_bench3_state *state = tevent_req_data(
     495             :                 req, struct notify_bench3_state);
     496             :         int ret;
     497             : 
     498           0 :         ret = tevent_barrier_wait_recv(subreq);
     499           0 :         TALLOC_FREE(subreq);
     500           0 :         if (ret != 0) {
     501           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(ret));
     502           0 :                 return;
     503             :         }
     504           0 :         subreq = cli_close_send(state, state->ev, state->cli,
     505           0 :                                 state->subdir_dnum);
     506           0 :         if (tevent_req_nomem(subreq, req)) {
     507           0 :                 return;
     508             :         }
     509           0 :         tevent_req_set_callback(subreq, notify_bench3_close_subdir_done, req);
     510             : }
     511             : 
     512           0 : static void notify_bench3_close_subdir_done(struct tevent_req *subreq)
     513             : {
     514           0 :         struct tevent_req *req = tevent_req_callback_data(
     515             :                 subreq, struct tevent_req);
     516           0 :         struct notify_bench3_state *state = tevent_req_data(
     517             :                 req, struct notify_bench3_state);
     518             :         NTSTATUS status;
     519             : 
     520           0 :         status = cli_close_recv(subreq);
     521           0 :         TALLOC_FREE(subreq);
     522           0 :         if (tevent_req_nterror(req, status)) {
     523           0 :                 return;
     524             :         }
     525           0 :         subreq = cli_rmdir_send(state, state->ev, state->cli,
     526             :                                 state->subdir_path);
     527           0 :         if (tevent_req_nomem(subreq, req)) {
     528           0 :                 return;
     529             :         }
     530           0 :         tevent_req_set_callback(subreq, notify_bench3_deleted_subdir, req);
     531             : }
     532             : 
     533           0 : static void notify_bench3_deleted_subdir(struct tevent_req *subreq)
     534             : {
     535           0 :         struct tevent_req *req = tevent_req_callback_data(
     536             :                 subreq, struct tevent_req);
     537           0 :         struct notify_bench3_state *state = tevent_req_data(
     538             :                 req, struct notify_bench3_state);
     539             :         NTSTATUS status;
     540             : 
     541           0 :         status = cli_rmdir_recv(subreq);
     542           0 :         TALLOC_FREE(subreq);
     543           0 :         if (tevent_req_nterror(req, status)) {
     544           0 :                 return;
     545             :         }
     546           0 :         subreq = tevent_barrier_wait_send(state, state->ev, state->small);
     547           0 :         if (tevent_req_nomem(subreq, req)) {
     548           0 :                 return;
     549             :         }
     550           0 :         tevent_req_set_callback(subreq, notify_bench3_deleted_subdirs, req);
     551             : }
     552             : 
     553           0 : static void notify_bench3_deleted_subdirs(struct tevent_req *subreq)
     554             : {
     555           0 :         struct tevent_req *req = tevent_req_callback_data(
     556             :                 subreq, struct tevent_req);
     557           0 :         struct notify_bench3_state *state = tevent_req_data(
     558             :                 req, struct notify_bench3_state);
     559             :         int ret;
     560             : 
     561           0 :         ret = tevent_barrier_wait_recv(subreq);
     562           0 :         TALLOC_FREE(subreq);
     563           0 :         if (ret != 0) {
     564           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(ret));
     565           0 :                 return;
     566             :         }
     567           0 :         subreq = cli_nt_delete_on_close_send(state, state->ev, state->cli,
     568           0 :                                              state->dnum, true);
     569           0 :         if (tevent_req_nomem(subreq, req)) {
     570           0 :                 return;
     571             :         }
     572           0 :         tevent_req_set_callback(subreq, notify_bench3_del_on_close_set, req);
     573             : }
     574             : 
     575           0 : static void notify_bench3_del_on_close_set(struct tevent_req *subreq)
     576             : {
     577           0 :         struct tevent_req *req = tevent_req_callback_data(
     578             :                 subreq, struct tevent_req);
     579           0 :         struct notify_bench3_state *state = tevent_req_data(
     580             :                 req, struct notify_bench3_state);
     581             :         NTSTATUS status;
     582             : 
     583           0 :         status = cli_nt_delete_on_close_recv(subreq);
     584           0 :         TALLOC_FREE(subreq);
     585           0 :         if (tevent_req_nterror(req, status)) {
     586           0 :                 return;
     587             :         }
     588             : 
     589           0 :         subreq = cli_close_send(state, state->ev, state->cli, state->dnum);
     590           0 :         if (tevent_req_nomem(subreq, req)) {
     591           0 :                 return;
     592             :         }
     593           0 :         tevent_req_set_callback(subreq, notify_bench3_closed, req);
     594             : }
     595             : 
     596           0 : static void notify_bench3_closed(struct tevent_req *subreq)
     597             : {
     598           0 :         struct tevent_req *req = tevent_req_callback_data(
     599             :                 subreq, struct tevent_req);
     600             :         NTSTATUS status;
     601             : 
     602           0 :         status = cli_close_recv(subreq);
     603           0 :         TALLOC_FREE(subreq);
     604           0 :         if (tevent_req_nterror(req, status)) {
     605           0 :                 return;
     606             :         }
     607           0 :         tevent_req_done(req);
     608             : }
     609             : 
     610           0 : static NTSTATUS notify_bench3_recv(struct tevent_req *req)
     611             : {
     612           0 :         return tevent_req_simple_recv_ntstatus(req);
     613             : }
     614             : 
     615           0 : static void notify_bench3_done(struct tevent_req *req)
     616             : {
     617           0 :         unsigned *num_done = (unsigned *)tevent_req_callback_data_void(req);
     618             :         NTSTATUS status;
     619             : 
     620           0 :         status = notify_bench3_recv(req);
     621           0 :         TALLOC_FREE(req);
     622           0 :         if (!NT_STATUS_IS_OK(status)) {
     623           0 :                 d_printf("notify_bench3 returned %s\n", nt_errstr(status));
     624             :         }
     625           0 :         *num_done += 1;
     626           0 : }
     627             : 
     628           0 : static void notify_bench3_barrier_cb(void *private_data)
     629             : {
     630           0 :         struct timeval *ts = (struct timeval *)private_data;
     631             :         struct timeval now;
     632             : 
     633           0 :         GetTimeOfDay(&now);
     634           0 :         printf("barrier triggered: %f\n", timeval_elapsed2(ts, &now));
     635           0 :         GetTimeOfDay(ts);
     636           0 : }
     637             : 
     638           0 : bool run_notify_bench3(int dummy)
     639             : {
     640             :         struct cli_state **clis;
     641             :         struct tevent_context *ev;
     642             :         struct tevent_barrier *small;
     643             :         struct tevent_barrier *large;
     644             :         int i;
     645           0 :         unsigned num_done = 0;
     646             :         struct timeval ts, now;
     647             : 
     648           0 :         clis = talloc_array(talloc_tos(), struct cli_state *, torture_nprocs);
     649           0 :         if (clis == NULL) {
     650           0 :                 printf("talloc failed\n");
     651           0 :                 return false;
     652             :         }
     653             : 
     654           0 :         GetTimeOfDay(&ts);
     655             : 
     656           0 :         small = tevent_barrier_init(
     657           0 :                 talloc_tos(), torture_nprocs * torture_numops,
     658             :                 notify_bench3_barrier_cb, &ts);
     659           0 :         if (small == NULL) {
     660           0 :                 return false;
     661             :         }
     662             : 
     663           0 :         large = tevent_barrier_init(
     664           0 :                 talloc_tos(), 2 * torture_nprocs * torture_numops,
     665             :                 notify_bench3_barrier_cb, &ts);
     666           0 :         if (large == NULL) {
     667           0 :                 return false;
     668             :         }
     669             : 
     670           0 :         ev = samba_tevent_context_init(talloc_tos());
     671           0 :         if (ev == NULL) {
     672           0 :                 printf("tevent_context_create failed\n");
     673           0 :                 return false;
     674             :         }
     675             : 
     676           0 :         for (i=0; i<torture_nprocs; i++) {
     677           0 :                 if (!torture_open_connection(&clis[i], i)) {
     678           0 :                         return false;
     679             :                 }
     680             :         }
     681             : 
     682           0 :         for (i=0; i<torture_nprocs; i++) {
     683             :                 int j;
     684           0 :                 for (j=0; j<torture_numops; j++) {
     685           0 :                         int idx = i * torture_numops + j;
     686             :                         struct tevent_req *req;
     687             :                         char *dirname, *subdirname;
     688             : 
     689           0 :                         dirname = talloc_asprintf(
     690           0 :                                 talloc_tos(), "\\dir%.8d", idx);
     691           0 :                         if (dirname == NULL) {
     692           0 :                                 return false;
     693             :                         }
     694           0 :                         subdirname = talloc_asprintf(
     695           0 :                                 talloc_tos(), "\\dir%.8d\\subdir",
     696           0 :                                 (idx + torture_numops + 1) %
     697           0 :                                 (torture_nprocs * torture_numops));
     698           0 :                         if (subdirname == NULL) {
     699           0 :                                 return false;
     700             :                         }
     701             : 
     702           0 :                         req = notify_bench3_send(
     703           0 :                                 talloc_tos(), ev, clis[i], dirname,
     704             :                                 subdirname, small, large);
     705           0 :                         if (req == NULL) {
     706           0 :                                 return false;
     707             :                         }
     708           0 :                         tevent_req_set_callback(req, notify_bench3_done,
     709             :                                                 &num_done);
     710             :                 }
     711             :         }
     712             : 
     713           0 :         while (num_done < (unsigned)(torture_nprocs * torture_numops)) {
     714             :                 int ret;
     715           0 :                 ret = tevent_loop_once(ev);
     716           0 :                 if (ret != 0) {
     717           0 :                         printf("tevent_loop_once failed: %s\n",
     718           0 :                                strerror(errno));
     719           0 :                         return false;
     720             :                 }
     721             :         }
     722             : 
     723           0 :         GetTimeOfDay(&now);
     724           0 :         printf("turndow: %f\n", timeval_elapsed2(&ts, &now));
     725           0 :         TALLOC_FREE(small);
     726           0 :         TALLOC_FREE(large);
     727           0 :         return true;
     728             : }

Generated by: LCOV version 1.13