From 5b4d94e20fdb5888da1b71a7b6a30ebede6cb06a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Sep 1998 01:49:24 +0000 Subject: (Finally) implemented "max open files" as a global smb.conf parameter. 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. (This used to be commit eca24bd24352c688cdf48c1ef14adb8ac353468f) --- source3/include/local.h | 11 +++++++ source3/include/proto.h | 4 ++- source3/param/loadparm.c | 4 +++ source3/rpc_server/srv_pipe_hnd.c | 22 ++++++++++--- source3/smbd/files.c | 66 ++++++++++++++++++++++++++------------- 5 files changed, 79 insertions(+), 28 deletions(-) (limited to 'source3') diff --git a/source3/include/local.h b/source3/include/local.h index 6903e5854f..a31c5c35b4 100644 --- a/source3/include/local.h +++ b/source3/include/local.h @@ -44,6 +44,17 @@ #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 diff --git a/source3/include/proto.h b/source3/include/proto.h index 4f29b3ae20..c706cbd2c5 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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, diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 5cba2c95d5..a0e43150b9 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -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) diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 301510730b..cb1ec963d9 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -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--; diff --git a/source3/smbd/files.c b/source3/smbd/files.c index e8b391d117..9b58ef5b31 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -23,17 +23,16 @@ 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) -- cgit