LCOV - code coverage report
Current view: top level - source3/torture - test_notify.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 386 0.0 %
Date: 2024-04-21 15:09:00 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           0 :         struct tevent_req *req, *subreq;
      52           0 :         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           0 :         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           0 :         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           0 :         uint32_t num_changes;
     132           0 :         struct notify_change *changes;
     133           0 :         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, 0);
     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           0 :         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           0 :         struct cli_state *cli;
     174           0 :         struct cli_state **clis;
     175           0 :         struct tevent_context *ev;
     176           0 :         unsigned num_notifies = 0;
     177           0 :         NTSTATUS status;
     178           0 :         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           0 :                 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           0 :                         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           0 :                 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           0 :                 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           0 :         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           0 :         struct tevent_req *req, *subreq;
     305           0 :         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           0 :         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           0 :         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           0 :         uint32_t num_changes;
     390           0 :         struct notify_change *changes;
     391           0 :         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           0 :         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           0 :         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           0 :         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           0 :         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           0 :         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,
     505             :                                 state->ev,
     506             :                                 state->cli,
     507           0 :                                 state->subdir_dnum,
     508             :                                 0);
     509           0 :         if (tevent_req_nomem(subreq, req)) {
     510           0 :                 return;
     511             :         }
     512           0 :         tevent_req_set_callback(subreq, notify_bench3_close_subdir_done, req);
     513             : }
     514             : 
     515           0 : static void notify_bench3_close_subdir_done(struct tevent_req *subreq)
     516             : {
     517           0 :         struct tevent_req *req = tevent_req_callback_data(
     518             :                 subreq, struct tevent_req);
     519           0 :         struct notify_bench3_state *state = tevent_req_data(
     520             :                 req, struct notify_bench3_state);
     521           0 :         NTSTATUS status;
     522             : 
     523           0 :         status = cli_close_recv(subreq);
     524           0 :         TALLOC_FREE(subreq);
     525           0 :         if (tevent_req_nterror(req, status)) {
     526           0 :                 return;
     527             :         }
     528           0 :         subreq = cli_rmdir_send(state, state->ev, state->cli,
     529             :                                 state->subdir_path);
     530           0 :         if (tevent_req_nomem(subreq, req)) {
     531           0 :                 return;
     532             :         }
     533           0 :         tevent_req_set_callback(subreq, notify_bench3_deleted_subdir, req);
     534             : }
     535             : 
     536           0 : static void notify_bench3_deleted_subdir(struct tevent_req *subreq)
     537             : {
     538           0 :         struct tevent_req *req = tevent_req_callback_data(
     539             :                 subreq, struct tevent_req);
     540           0 :         struct notify_bench3_state *state = tevent_req_data(
     541             :                 req, struct notify_bench3_state);
     542           0 :         NTSTATUS status;
     543             : 
     544           0 :         status = cli_rmdir_recv(subreq);
     545           0 :         TALLOC_FREE(subreq);
     546           0 :         if (tevent_req_nterror(req, status)) {
     547           0 :                 return;
     548             :         }
     549           0 :         subreq = tevent_barrier_wait_send(state, state->ev, state->small);
     550           0 :         if (tevent_req_nomem(subreq, req)) {
     551           0 :                 return;
     552             :         }
     553           0 :         tevent_req_set_callback(subreq, notify_bench3_deleted_subdirs, req);
     554             : }
     555             : 
     556           0 : static void notify_bench3_deleted_subdirs(struct tevent_req *subreq)
     557             : {
     558           0 :         struct tevent_req *req = tevent_req_callback_data(
     559             :                 subreq, struct tevent_req);
     560           0 :         struct notify_bench3_state *state = tevent_req_data(
     561             :                 req, struct notify_bench3_state);
     562           0 :         int ret;
     563             : 
     564           0 :         ret = tevent_barrier_wait_recv(subreq);
     565           0 :         TALLOC_FREE(subreq);
     566           0 :         if (ret != 0) {
     567           0 :                 tevent_req_nterror(req, map_nt_error_from_unix(ret));
     568           0 :                 return;
     569             :         }
     570           0 :         subreq = cli_nt_delete_on_close_send(state, state->ev, state->cli,
     571           0 :                                              state->dnum, true);
     572           0 :         if (tevent_req_nomem(subreq, req)) {
     573           0 :                 return;
     574             :         }
     575           0 :         tevent_req_set_callback(subreq, notify_bench3_del_on_close_set, req);
     576             : }
     577             : 
     578           0 : static void notify_bench3_del_on_close_set(struct tevent_req *subreq)
     579             : {
     580           0 :         struct tevent_req *req = tevent_req_callback_data(
     581             :                 subreq, struct tevent_req);
     582           0 :         struct notify_bench3_state *state = tevent_req_data(
     583             :                 req, struct notify_bench3_state);
     584           0 :         NTSTATUS status;
     585             : 
     586           0 :         status = cli_nt_delete_on_close_recv(subreq);
     587           0 :         TALLOC_FREE(subreq);
     588           0 :         if (tevent_req_nterror(req, status)) {
     589           0 :                 return;
     590             :         }
     591             : 
     592           0 :         subreq = cli_close_send(state, state->ev, state->cli, state->dnum, 0);
     593           0 :         if (tevent_req_nomem(subreq, req)) {
     594           0 :                 return;
     595             :         }
     596           0 :         tevent_req_set_callback(subreq, notify_bench3_closed, req);
     597             : }
     598             : 
     599           0 : static void notify_bench3_closed(struct tevent_req *subreq)
     600             : {
     601           0 :         struct tevent_req *req = tevent_req_callback_data(
     602             :                 subreq, struct tevent_req);
     603           0 :         NTSTATUS status;
     604             : 
     605           0 :         status = cli_close_recv(subreq);
     606           0 :         TALLOC_FREE(subreq);
     607           0 :         if (tevent_req_nterror(req, status)) {
     608           0 :                 return;
     609             :         }
     610           0 :         tevent_req_done(req);
     611             : }
     612             : 
     613           0 : static NTSTATUS notify_bench3_recv(struct tevent_req *req)
     614             : {
     615           0 :         return tevent_req_simple_recv_ntstatus(req);
     616             : }
     617             : 
     618           0 : static void notify_bench3_done(struct tevent_req *req)
     619             : {
     620           0 :         unsigned *num_done = (unsigned *)tevent_req_callback_data_void(req);
     621           0 :         NTSTATUS status;
     622             : 
     623           0 :         status = notify_bench3_recv(req);
     624           0 :         TALLOC_FREE(req);
     625           0 :         if (!NT_STATUS_IS_OK(status)) {
     626           0 :                 d_printf("notify_bench3 returned %s\n", nt_errstr(status));
     627             :         }
     628           0 :         *num_done += 1;
     629           0 : }
     630             : 
     631           0 : static void notify_bench3_barrier_cb(void *private_data)
     632             : {
     633           0 :         struct timeval *ts = (struct timeval *)private_data;
     634           0 :         struct timeval now;
     635             : 
     636           0 :         GetTimeOfDay(&now);
     637           0 :         printf("barrier triggered: %f\n", timeval_elapsed2(ts, &now));
     638           0 :         GetTimeOfDay(ts);
     639           0 : }
     640             : 
     641           0 : bool run_notify_bench3(int dummy)
     642             : {
     643           0 :         struct cli_state **clis;
     644           0 :         struct tevent_context *ev;
     645           0 :         struct tevent_barrier *small;
     646           0 :         struct tevent_barrier *large;
     647           0 :         int i;
     648           0 :         unsigned num_done = 0;
     649           0 :         struct timeval ts, now;
     650             : 
     651           0 :         clis = talloc_array(talloc_tos(), struct cli_state *, torture_nprocs);
     652           0 :         if (clis == NULL) {
     653           0 :                 printf("talloc failed\n");
     654           0 :                 return false;
     655             :         }
     656             : 
     657           0 :         GetTimeOfDay(&ts);
     658             : 
     659           0 :         small = tevent_barrier_init(
     660           0 :                 talloc_tos(), torture_nprocs * torture_numops,
     661             :                 notify_bench3_barrier_cb, &ts);
     662           0 :         if (small == NULL) {
     663           0 :                 return false;
     664             :         }
     665             : 
     666           0 :         large = tevent_barrier_init(
     667           0 :                 talloc_tos(), 2 * torture_nprocs * torture_numops,
     668             :                 notify_bench3_barrier_cb, &ts);
     669           0 :         if (large == NULL) {
     670           0 :                 return false;
     671             :         }
     672             : 
     673           0 :         ev = samba_tevent_context_init(talloc_tos());
     674           0 :         if (ev == NULL) {
     675           0 :                 printf("tevent_context_create failed\n");
     676           0 :                 return false;
     677             :         }
     678             : 
     679           0 :         for (i=0; i<torture_nprocs; i++) {
     680           0 :                 if (!torture_open_connection(&clis[i], i)) {
     681           0 :                         return false;
     682             :                 }
     683             :         }
     684             : 
     685           0 :         for (i=0; i<torture_nprocs; i++) {
     686             :                 int j;
     687           0 :                 for (j=0; j<torture_numops; j++) {
     688           0 :                         int idx = i * torture_numops + j;
     689           0 :                         struct tevent_req *req;
     690           0 :                         char *dirname, *subdirname;
     691             : 
     692           0 :                         dirname = talloc_asprintf(
     693           0 :                                 talloc_tos(), "\\dir%.8d", idx);
     694           0 :                         if (dirname == NULL) {
     695           0 :                                 return false;
     696             :                         }
     697           0 :                         subdirname = talloc_asprintf(
     698           0 :                                 talloc_tos(), "\\dir%.8d\\subdir",
     699           0 :                                 (idx + torture_numops + 1) %
     700           0 :                                 (torture_nprocs * torture_numops));
     701           0 :                         if (subdirname == NULL) {
     702           0 :                                 return false;
     703             :                         }
     704             : 
     705           0 :                         req = notify_bench3_send(
     706           0 :                                 talloc_tos(), ev, clis[i], dirname,
     707             :                                 subdirname, small, large);
     708           0 :                         if (req == NULL) {
     709           0 :                                 return false;
     710             :                         }
     711           0 :                         tevent_req_set_callback(req, notify_bench3_done,
     712             :                                                 &num_done);
     713             :                 }
     714             :         }
     715             : 
     716           0 :         while (num_done < (unsigned)(torture_nprocs * torture_numops)) {
     717           0 :                 int ret;
     718           0 :                 ret = tevent_loop_once(ev);
     719           0 :                 if (ret != 0) {
     720           0 :                         printf("tevent_loop_once failed: %s\n",
     721           0 :                                strerror(errno));
     722           0 :                         return false;
     723             :                 }
     724             :         }
     725             : 
     726           0 :         GetTimeOfDay(&now);
     727           0 :         printf("turndow: %f\n", timeval_elapsed2(&ts, &now));
     728           0 :         TALLOC_FREE(small);
     729           0 :         TALLOC_FREE(large);
     730           0 :         return true;
     731             : }

Generated by: LCOV version 1.14