LCOV - code coverage report
Current view: top level - source4/torture/smb2 - maxfid.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 60 67 89.6 %
Date: 2024-04-21 15:09:00 Functions: 1 1 100.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    SMB2 maxfid test
       5             : 
       6             :    Copyright (C) Christof Schmitt 2016
       7             : 
       8             :    This program is free software; you can redistribute it and/or modify
       9             :    it under the terms of the GNU General Public License as published by
      10             :    the Free Software Foundation; either version 3 of the License, or
      11             :    (at your option) any later version.
      12             : 
      13             :    This program is distributed in the hope that it will be useful,
      14             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :    GNU General Public License for more details.
      17             : 
      18             :    You should have received a copy of the GNU General Public License
      19             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      20             : */
      21             : 
      22             : #include "includes.h"
      23             : #include "libcli/smb2/smb2.h"
      24             : #include "libcli/smb2/smb2_calls.h"
      25             : 
      26             : #include "torture/torture.h"
      27             : #include "torture/smb2/proto.h"
      28             : 
      29           5 : bool torture_smb2_maxfid(struct torture_context *tctx)
      30             : {
      31           5 :         bool ret = true;
      32           0 :         NTSTATUS status;
      33           5 :         struct smb2_tree *tree = NULL;
      34           5 :         const char *dname = "smb2_maxfid";
      35           0 :         size_t i, maxfid;
      36           5 :         struct smb2_handle *handles,  dir_handle = { };
      37           0 :         size_t max_handles;
      38             : 
      39             :         /*
      40             :          * We limited this to 65520 as socket_wrapper has a limit of
      41             :          * 65535 (0xfff0) open sockets.
      42             :          *
      43             :          * It could be increased by setting the following env variable:
      44             :          *
      45             :          * SOCKET_WRAPPER_MAX_SOCKETS=100000
      46             :          */
      47           5 :         max_handles = torture_setting_int(tctx, "maxopenfiles", 65520);
      48             : 
      49           5 :         if (!torture_smb2_connection(tctx, &tree)) {
      50           0 :                 return false;
      51             :         }
      52             : 
      53           5 :         handles = talloc_array(tctx, struct smb2_handle, max_handles);
      54           5 :         if (handles == 0) {
      55           0 :                 torture_fail(tctx, "Could not allocate handles array.\n");
      56             :                 return false;
      57             :         }
      58             : 
      59           5 :         smb2_deltree(tree, dname);
      60             : 
      61           5 :         status = torture_smb2_testdir(tree, dname, &dir_handle);
      62           5 :         torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
      63             :                                         "torture_smb2_testdir failed");
      64           5 :         smb2_util_close(tree, dir_handle);
      65             : 
      66           5 :         torture_comment(tctx, "Creating subdirectories\n");
      67             : 
      68         335 :         for (i = 0; i < max_handles; i += 1000) {
      69           0 :                 char *name;
      70         330 :                 struct smb2_create create = { };
      71         330 :                 struct smb2_close close = { };
      72             : 
      73         330 :                 name = talloc_asprintf(tctx, "%s\\%zu", dname, i / 1000);
      74         330 :                 torture_assert_goto(tctx, (name != NULL), ret, done,
      75             :                                     "no memory for directory name\n");
      76             : 
      77         330 :                 create.in.desired_access = SEC_RIGHTS_DIR_ALL;
      78         330 :                 create.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
      79         330 :                 create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
      80         330 :                 create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
      81             :                         NTCREATEX_SHARE_ACCESS_WRITE |
      82             :                         NTCREATEX_SHARE_ACCESS_DELETE;
      83         330 :                 create.in.create_disposition = NTCREATEX_DISP_CREATE;
      84         330 :                 create.in.fname = name;
      85             : 
      86         330 :                 status = smb2_create(tree, tctx, &create);
      87         330 :                 talloc_free(name);
      88             : 
      89         330 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
      90             :                                                 "CREATE directory failed\n");
      91             : 
      92         330 :                 close.in.file.handle = create.out.file.handle;
      93         330 :                 status = smb2_close(tree, &close);
      94         330 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
      95             :                                                 "CLOSE directory failed\n");
      96             :         }
      97             : 
      98           5 :         torture_comment(tctx, "Testing maximum number of open files\n");
      99             : 
     100      131155 :         for (i = 0; i < max_handles; i++) {
     101           0 :                 char *name;
     102      131154 :                 struct smb2_create create = { };
     103             : 
     104      131154 :                 name = talloc_asprintf(tctx, "%s\\%zu\\%zu", dname, i / 1000, i);
     105      131154 :                 torture_assert_goto(tctx, (name != NULL), ret, done,
     106             :                                     "no memory for file name\n");
     107             : 
     108      131154 :                 create.in.desired_access = SEC_RIGHTS_DIR_ALL;
     109      131154 :                 create.in.create_options = 0;
     110      131154 :                 create.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
     111      131154 :                 create.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
     112             :                         NTCREATEX_SHARE_ACCESS_WRITE |
     113             :                         NTCREATEX_SHARE_ACCESS_DELETE;
     114      131154 :                 create.in.create_disposition = NTCREATEX_DISP_CREATE;
     115      131154 :                 create.in.fname = name;
     116             : 
     117      131154 :                 status = smb2_create(tree, tctx, &create);
     118      131154 :                 if (!NT_STATUS_IS_OK(status)) {
     119           4 :                         torture_comment(tctx, "create of %s failed: %s\n",
     120             :                                         name, nt_errstr(status));
     121           4 :                         talloc_free(name);
     122           4 :                         break;
     123             :                 }
     124      131150 :                 talloc_free(name);
     125             : 
     126      131150 :                 handles[i] = create.out.file.handle;
     127             :         }
     128             : 
     129           5 :         maxfid = i;
     130           5 :         if (maxfid == max_handles) {
     131           1 :                 torture_comment(tctx, "Reached test limit of %zu open files. "
     132             :                                 "Adjust to higher test with "
     133             :                                 "--option=torture:maxopenfiles=NNN\n", maxfid);
     134             :         }
     135             : 
     136           5 :         torture_comment(tctx, "Cleanup open files\n");
     137             : 
     138      131155 :         for (i = 0; i < maxfid; i++) {
     139      131150 :                 status = smb2_util_close(tree, handles[i]);
     140      131150 :                 torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
     141             :                                                 "CLOSE failed\n");
     142             :         }
     143             : 
     144           5 : done:
     145           5 :         smb2_deltree(tree, dname);
     146           5 :         talloc_free(handles);
     147             : 
     148           5 :         return ret;
     149             : }

Generated by: LCOV version 1.14