(Finally) implemented "max open files" as a global smb.conf parameter.
authorJeremy Allison <jra@samba.org>
Wed, 30 Sep 1998 01:49:24 +0000 (01:49 +0000)
committerJeremy Allison <jra@samba.org>
Wed, 30 Sep 1998 01:49:24 +0000 (01:49 +0000)
Sets up the files array correctly - limited by the smb.conf parameter
and by the max fd's per process as found by getrlimit().
Jeremy.

source/include/local.h
source/include/proto.h
source/param/loadparm.c
source/rpc_server/srv_pipe_hnd.c
source/smbd/files.c

index 6903e5854f640715d26f852b9e0b361bbd01d78a..a31c5c35b4e59587cfe4d3023389af83d5693ce7 100644 (file)
 #define SHMEM_SIZE (1024*1024)
 #endif
 
+/* 
+ * Default number of maximum open files per smbd. This is
+ * also limited by the maximum available file descriptors
+ * per process and can also be set in smb.conf as "max open files"
+ * in the [global] section.
+ */
+
+#ifndef MAX_OPEN_FILES
+#define MAX_OPEN_FILES 4096
+#endif
 /* the max number of simultanous connections to the server by all clients */
 #define MAXSTATUS 100000
 
index 4f29b3ae20cf15b891ca71adefbc0aefd7a5139d..c706cbd2c592e9409e2d770fe3a8cfefed5bab5b 100644 (file)
@@ -958,12 +958,12 @@ BOOL lp_passwd_chat_debug(void);
 BOOL lp_ole_locking_compat(void);
 BOOL lp_nt_smb_support(void);
 BOOL lp_stat_cache(void);
-BOOL lp_kernel_oplocks(void);
 int lp_os_level(void);
 int lp_max_ttl(void);
 int lp_max_wins_ttl(void);
 int lp_min_wins_ttl(void);
 int lp_max_log_size(void);
+int lp_max_open_files(void);
 int lp_maxxmit(void);
 int lp_maxmux(void);
 int lp_passwordlevel(void);
@@ -1086,6 +1086,7 @@ int lp_major_announce_version(void);
 int lp_minor_announce_version(void);
 void lp_set_name_resolve_order(char *new_order);
 void lp_set_kernel_oplocks(BOOL val);
+BOOL lp_kernel_oplocks(void);
 
 /*The following definitions come from  param/params.c  */
 
@@ -1733,6 +1734,7 @@ BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data);
 
 /*The following definitions come from  rpc_server/srv_pipe_hnd.c  */
 
+void set_pipe_handle_offset(int max_open_files);
 void reset_chain_p(void);
 void init_rpc_pipe_hnd(void);
 pipes_struct *open_rpc_pipe_p(char *pipe_name, 
index 5cba2c95d567f6b0a198178d3bdfdfedbf122815..a0e43150b997f4af270dd1a0c2be56f68937de80 100644 (file)
@@ -160,6 +160,7 @@ typedef struct
   int mangled_stack;
   int max_xmit;
   int max_mux;
+  int max_open_files;
   int max_packet;
   int pwordlevel;
   int unamelevel;
@@ -597,6 +598,7 @@ static struct parm_struct parm_table[] =
   {"lpq cache time",   P_INTEGER, P_GLOBAL, &Globals.lpqcachetime,      NULL,   NULL,  0},
   {"max connections",  P_INTEGER, P_LOCAL,  &sDefault.iMaxConnections,  NULL,   NULL,  0},
   {"max disk size",    P_INTEGER, P_GLOBAL, &Globals.maxdisksize,       NULL,   NULL,  0},
+  {"max open files",   P_INTEGER, P_GLOBAL, &Globals.max_open_files,    NULL,   NULL,  0},
   {"min print space",  P_INTEGER, P_LOCAL,  &sDefault.iMinPrintSpace,   NULL,   NULL,  0},
   {"read prediction",  P_BOOL,    P_GLOBAL, &Globals.bReadPrediction,   NULL,   NULL,  0},
   {"read size",        P_INTEGER, P_GLOBAL, &Globals.ReadSize,          NULL,   NULL,  0},
@@ -824,6 +826,7 @@ static void init_globals(void)
   Globals.unamelevel = 0;
   Globals.deadtime = 0;
   Globals.max_log_size = 5000;
+  Globals.max_open_files = MAX_OPEN_FILES;
   Globals.maxprotocol = PROTOCOL_NT1;
   Globals.security = SEC_USER;
   Globals.bEncryptPasswords = False;
@@ -1169,6 +1172,7 @@ FN_GLOBAL_INTEGER(lp_max_ttl,&Globals.max_ttl)
 FN_GLOBAL_INTEGER(lp_max_wins_ttl,&Globals.max_wins_ttl)
 FN_GLOBAL_INTEGER(lp_min_wins_ttl,&Globals.max_wins_ttl)
 FN_GLOBAL_INTEGER(lp_max_log_size,&Globals.max_log_size)
+FN_GLOBAL_INTEGER(lp_max_open_files,&Globals.max_open_files)
 FN_GLOBAL_INTEGER(lp_maxxmit,&Globals.max_xmit)
 FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux)
 FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel)
index 301510730b8c7f1203171be72fcc1eac7ab5249a..cb1ec963d933154f4b46079451486ce544c60a3d 100644 (file)
@@ -28,9 +28,6 @@
 #define        PIPE            "\\PIPE\\"
 #define        PIPELEN         strlen(PIPE)
 
-/* this must be larger than the sum of the open files and directories */
-#define PIPE_HANDLE_OFFSET 0x7000
-
 extern int DEBUGLEVEL;
 static pipes_struct *chain_p;
 static int pipes_open;
@@ -42,6 +39,21 @@ static int pipes_open;
 static pipes_struct *Pipes;
 static struct bitmap *bmap;
 
+/* this must be larger than the sum of the open files and directories */
+static int pipe_handle_offset;
+
+/****************************************************************************
+ Set the pipe_handle_offset. Called from smbd/files.c
+****************************************************************************/
+
+void set_pipe_handle_offset(int max_open_files)
+{
+  if(max_open_files < 0x7000)
+    pipe_handle_offset = 0x7000;
+  else
+    pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
+}
+
 /****************************************************************************
   reset pipe chain handle number
 ****************************************************************************/
@@ -103,7 +115,7 @@ pipes_struct *open_rpc_pipe_p(char *pipe_name,
        DLIST_ADD(Pipes, p);
 
        bitmap_set(bmap, i);
-       i += PIPE_HANDLE_OFFSET;
+       i += pipe_handle_offset;
 
        pipes_open++;
 
@@ -283,7 +295,7 @@ BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
        mem_buf_free(&(p->rdata.data));
        mem_buf_free(&(p->rhdr .data));
 
-       bitmap_clear(bmap, p->pnum - PIPE_HANDLE_OFFSET);
+       bitmap_clear(bmap, p->pnum - pipe_handle_offset);
 
        pipes_open--;
 
index e8b391d117530d16c2c42f0f443c549597d0c1d9..9b58ef5b316a9756c36f47f9262f6d8a0a48de10 100644 (file)
 
 extern int DEBUGLEVEL;
 
-/* the only restriction is that this must be less than PIPE_HANDLE_OFFSET */
-#define MAX_FNUMS 4096
+static int real_max_open_files;
 
-#define VALID_FNUM(fnum)   (((fnum) >= 0) && ((fnum) < MAX_FNUMS))
+#define VALID_FNUM(fnum)   (((fnum) >= 0) && ((fnum) < real_max_open_files))
 
 #define FILE_HANDLE_OFFSET 0x1000
 
 static struct bitmap *file_bmap;
 
 #ifdef USE_FILES_ARRAY
-static files_struct *Files[MAX_FNUMS];
+static files_struct **Files;
 #else
 static files_struct *Files;
 #endif
@@ -66,7 +65,7 @@ files_struct *file_new(void )
           increases the chance that the errant client will get an error rather
           than causing corruption */
        if (first_file == 0) {
-               first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS;
+               first_file = (getpid() ^ (int)time(NULL)) % real_max_open_files;
        }
 
        i = bitmap_find(file_bmap, first_file);
@@ -81,7 +80,7 @@ files_struct *file_new(void )
                 * after they have finished with them.
                 */
 #ifdef USE_FILES_ARRAY
-                for(i = 0; i < MAX_FNUMS; i++) {
+                for(i = 0; i < real_max_open_files; i++) {
                   if((fsp = Files[i]) == NULL)
                     continue;
                   if (attempt_close_oplocked_file(fsp)) 
@@ -105,7 +104,7 @@ files_struct *file_new(void )
 
        ZERO_STRUCTP(fsp);
 
-       first_file = (i+1) % MAX_FNUMS;
+       first_file = (i+1) % real_max_open_files;
 
        bitmap_set(file_bmap, i);
        files_used++;
@@ -203,7 +202,7 @@ void file_close_conn(connection_struct *conn)
        
 #ifdef USE_FILES_ARRAY
         int i;
-        for (i = 0; i < MAX_FNUMS; i++) {
+        for (i = 0; i < real_max_open_files; i++) {
           if((fsp = Files[i]) == NULL)
             continue;
           if(fsp->conn == conn && fsp->open) {
@@ -229,30 +228,53 @@ void file_close_conn(connection_struct *conn)
 /****************************************************************************
 initialise file structures
 ****************************************************************************/
+
+#define MAX_OPEN_FUDGEFACTOR 10
+
 void file_init(void)
 {
-       file_bmap = bitmap_allocate(MAX_FNUMS);
-
-       if (!file_bmap) {
-               exit_server("out of memory in file_init");
-       }
+    real_max_open_files = lp_max_open_files();
 
 #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE))
        {
                struct rlimit rlp;
                getrlimit(RLIMIT_NOFILE, &rlp);
-               /* Set the fd limit to be MAX_FNUMS + 10 to
+               /* Set the fd limit to be real_max_open_files + MAX_OPEN_FUDGEFACTOR to
                 * account for the extra fd we need 
                 * as well as the log files and standard
                 * handles etc.  */
-               rlp.rlim_cur = (MAX_FNUMS+10>rlp.rlim_max)? 
-                       rlp.rlim_max:MAX_FNUMS+10;
+               rlp.rlim_cur = (real_max_open_files+MAX_OPEN_FUDGEFACTOR>rlp.rlim_max)? 
+                       rlp.rlim_max:real_max_open_files+MAX_OPEN_FUDGEFACTOR;
                setrlimit(RLIMIT_NOFILE, &rlp);
                getrlimit(RLIMIT_NOFILE, &rlp);
-               DEBUG(3,("Maximum number of open files per session is %d\n",
-                        (int)rlp.rlim_cur));
+        if(rlp.rlim_cur != (real_max_open_files + MAX_OPEN_FUDGEFACTOR))
+          DEBUG(0,("file_init: Maximum number of open files requested per session \
+was %d, actual files available  per session = %d\n", 
+                real_max_open_files, (int)rlp.rlim_cur - MAX_OPEN_FUDGEFACTOR ));
+
+        DEBUG(2,("Maximum number of open files per session is %d\n", 
+              (int)rlp.rlim_cur - MAX_OPEN_FUDGEFACTOR));
+
+        real_max_open_files = (int)rlp.rlim_cur - MAX_OPEN_FUDGEFACTOR;
        }
 #endif
+
+       file_bmap = bitmap_allocate(real_max_open_files);
+
+       if (!file_bmap) {
+               exit_server("out of memory in file_init");
+       }
+
+#ifdef USE_FILES_ARRAY
+    Files = (files_struct **)malloc( sizeof(files_struct *) * real_max_open_files);
+    if(Files == NULL)
+      exit_server("out of memory for file array in file_init");
+#endif
+
+    /*
+     * Ensure that pipe_handle_oppset is set correctly.
+     */
+    set_pipe_handle_offset(real_max_open_files);
 }
 
 
@@ -265,7 +287,7 @@ void file_close_user(int vuid)
 
 #ifdef USE_FILES_ARRAY
         int i;
-        for(i = 0; i < MAX_FNUMS; i++) {
+        for(i = 0; i < real_max_open_files; i++) {
           if((fsp = Files[i]) == NULL)
             continue;
           if((fsp->vuid == vuid) && fsp->open) {
@@ -300,7 +322,7 @@ files_struct *file_find_dit(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval
        files_struct *fsp;
 
 #ifdef USE_FILES_ARRAY
-       for(count = 0; count < MAX_FNUMS; count++) {
+       for(count = 0; count < real_max_open_files; count++) {
                if((fsp = Files[count]) == NULL)
                        continue;
                if (fsp->open &&
@@ -338,7 +360,7 @@ files_struct *file_find_print(void)
 
 #ifdef USE_FILES_ARRAY
         int i;
-        for(i = 0; i < MAX_FNUMS; i++) {
+        for(i = 0; i < real_max_open_files; i++) {
           if((fsp = Files[i]) == NULL)
             continue;
           if (fsp->open && fsp->print_file) return fsp;
@@ -362,7 +384,7 @@ void file_sync_all(connection_struct *conn)
 
 #ifdef USE_FILES_ARRAY
         int i;
-        for(i = 0; i < MAX_FNUMS; i++) {
+        for(i = 0; i < real_max_open_files; i++) {
           if((fsp = Files[i]) == NULL)
             continue;
           if (fsp->open && conn == fsp->conn)