summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/local.h11
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/param/loadparm.c4
-rw-r--r--source3/rpc_server/srv_pipe_hnd.c22
-rw-r--r--source3/smbd/files.c66
5 files changed, 79 insertions, 28 deletions
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)