summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2011-12-13 15:23:08 +0100
committerStefan Metzmacher <metze@samba.org>2011-12-14 08:15:06 +0100
commit78582da8b57120d0f1a86577d1f8df1d553769bc (patch)
tree53781560065ea0b73630505d0464cb75102f3432
parentdddaa52552d2e1288fa13f5c2206b183a4c4c032 (diff)
downloadsamba-78582da8b57120d0f1a86577d1f8df1d553769bc.tar.gz
samba-78582da8b57120d0f1a86577d1f8df1d553769bc.tar.bz2
samba-78582da8b57120d0f1a86577d1f8df1d553769bc.zip
s3:smbd/server: maintain the list of child processes under smbd_parent_context
metze
-rw-r--r--source3/include/smb.h6
-rw-r--r--source3/smbd/globals.c2
-rw-r--r--source3/smbd/globals.h3
-rw-r--r--source3/smbd/server.c86
4 files changed, 55 insertions, 42 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h
index 8c521f8a58..3451123dee 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -1359,12 +1359,6 @@ struct smb_filename {
SMB_STRUCT_STAT st;
};
-/* struct for maintaining the child processes that get spawned from smbd */
-struct child_pid {
- struct child_pid *prev, *next;
- pid_t pid;
-};
-
/* Used to keep track of deferred opens. */
struct deferred_open_record;
diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c
index 274f017b08..70ff22c6ca 100644
--- a/source3/smbd/globals.c
+++ b/source3/smbd/globals.c
@@ -101,8 +101,6 @@ struct kernel_oplocks *koplocks = NULL;
struct smbd_parent_context *am_parent = NULL;
struct memcache *smbd_memcache_ctx = NULL;
bool exit_firsttime = true;
-struct child_pid *children = 0;
-int num_children = 0;
struct smbd_server_connection *smbd_server_conn = NULL;
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 020e1bcdde..d5b2de76eb 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -117,9 +117,6 @@ struct smbd_parent_context;
extern struct smbd_parent_context *am_parent;
extern struct memcache *smbd_memcache_ctx;
extern bool exit_firsttime;
-struct child_pid;
-extern struct child_pid *children;
-extern int num_children;
struct tstream_context;
struct smbd_smb2_request;
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 38e3f87617..29456f2e8b 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -43,6 +43,7 @@
#include "lib/param/param.h"
struct smbd_open_socket;
+struct smbd_child_pid;
struct smbd_parent_context {
bool interactive;
@@ -52,6 +53,12 @@ struct smbd_parent_context {
/* the list of listening sockets */
struct smbd_open_socket *sockets;
+
+ /* the list of current child processes */
+ struct smbd_child_pid *children;
+ size_t num_children;
+
+ struct timed_event *cleanup_te;
};
struct smbd_open_socket {
@@ -61,6 +68,11 @@ struct smbd_open_socket {
struct tevent_fd *fde;
};
+struct smbd_child_pid {
+ struct smbd_child_pid *prev, *next;
+ pid_t pid;
+};
+
extern void start_epmd(struct tevent_context *ev_ctx,
struct messaging_context *msg_ctx);
@@ -183,10 +195,16 @@ NTSTATUS messaging_send_to_children(struct messaging_context *msg_ctx,
uint32_t msg_type, DATA_BLOB* data)
{
NTSTATUS status;
- struct child_pid *child;
+ struct smbd_parent_context *parent = am_parent;
+ struct smbd_child_pid *child;
+
+ if (parent == NULL) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
- for (child = children; child != NULL; child = child->next) {
- status = messaging_send(msg_ctx, pid_to_procid(child->pid),
+ for (child = parent->children; child != NULL; child = child->next) {
+ status = messaging_send(parent->msg_ctx,
+ pid_to_procid(child->pid),
msg_type, data);
if (!NT_STATUS_IS_OK(status)) {
return status;
@@ -212,18 +230,19 @@ static void smbd_msg_debug(struct messaging_context *msg_ctx,
messaging_send_to_children(msg_ctx, MSG_DEBUG, data);
}
-static void add_child_pid(pid_t pid)
+static void add_child_pid(struct smbd_parent_context *parent,
+ pid_t pid)
{
- struct child_pid *child;
+ struct smbd_child_pid *child;
- child = SMB_MALLOC_P(struct child_pid);
+ child = talloc_zero(parent, struct smbd_child_pid);
if (child == NULL) {
DEBUG(0, ("Could not add child struct -- malloc failed\n"));
return;
}
child->pid = pid;
- DLIST_ADD(children, child);
- num_children += 1;
+ DLIST_ADD(parent->children, child);
+ parent->num_children += 1;
}
/*
@@ -242,23 +261,24 @@ static void cleanup_timeout_fn(struct event_context *event_ctx,
struct timeval now,
void *private_data)
{
- struct timed_event **cleanup_te = (struct timed_event **)private_data;
- struct messaging_context *msg = smbd_messaging_context();
+ struct smbd_parent_context *parent =
+ talloc_get_type_abort(private_data,
+ struct smbd_parent_context);
+
+ parent->cleanup_te = NULL;
DEBUG(1,("Cleaning up brl and lock database after unclean shutdown\n"));
- message_send_all(msg, MSG_SMB_UNLOCK, NULL, 0, NULL);
- messaging_send_buf(msg, messaging_server_id(msg),
- MSG_SMB_BRL_VALIDATE, NULL, 0);
- /* mark the cleanup as having been done */
- (*cleanup_te) = NULL;
+ message_send_all(parent->msg_ctx, MSG_SMB_UNLOCK, NULL, 0, NULL);
+ messaging_send_buf(parent->msg_ctx,
+ messaging_server_id(parent->msg_ctx),
+ MSG_SMB_BRL_VALIDATE, NULL, 0);
}
-static void remove_child_pid(struct tevent_context *ev_ctx,
+static void remove_child_pid(struct smbd_parent_context *parent,
pid_t pid,
bool unclean_shutdown)
{
- struct child_pid *child;
- static struct timed_event *cleanup_te;
+ struct smbd_child_pid *child;
struct server_id child_id;
if (unclean_shutdown) {
@@ -268,13 +288,14 @@ static void remove_child_pid(struct tevent_context *ev_ctx,
*/
DEBUG(3,(__location__ " Unclean shutdown of pid %u\n",
(unsigned int)pid));
- if (!cleanup_te) {
+ if (parent->cleanup_te == NULL) {
/* call the cleanup timer, but not too often */
int cleanup_time = lp_parm_int(-1, "smbd", "cleanuptime", 20);
- cleanup_te = event_add_timed(ev_ctx, NULL,
+ parent->cleanup_te = tevent_add_timer(parent->ev_ctx,
+ parent,
timeval_current_ofs(cleanup_time, 0),
cleanup_timeout_fn,
- &cleanup_te);
+ parent);
DEBUG(1,("Scheduled cleanup of brl and lock database after unclean shutdown\n"));
}
}
@@ -286,12 +307,12 @@ static void remove_child_pid(struct tevent_context *ev_ctx,
(int)pid));
}
- for (child = children; child != NULL; child = child->next) {
+ for (child = parent->children; child != NULL; child = child->next) {
if (child->pid == pid) {
- struct child_pid *tmp = child;
- DLIST_REMOVE(children, child);
- SAFE_FREE(tmp);
- num_children -= 1;
+ struct smbd_child_pid *tmp = child;
+ DLIST_REMOVE(parent->children, child);
+ TALLOC_FREE(tmp);
+ parent->num_children -= 1;
return;
}
}
@@ -304,14 +325,14 @@ static void remove_child_pid(struct tevent_context *ev_ctx,
Have we reached the process limit ?
****************************************************************************/
-static bool allowable_number_of_smbd_processes(void)
+static bool allowable_number_of_smbd_processes(struct smbd_parent_context *parent)
{
int max_processes = lp_max_smbd_processes();
if (!max_processes)
return True;
- return num_children < max_processes;
+ return parent->num_children < max_processes;
}
static void smbd_sig_chld_handler(struct tevent_context *ev,
@@ -323,6 +344,9 @@ static void smbd_sig_chld_handler(struct tevent_context *ev,
{
pid_t pid;
int status;
+ struct smbd_parent_context *parent =
+ talloc_get_type_abort(private_data,
+ struct smbd_parent_context);
while ((pid = sys_waitpid(-1, &status, WNOHANG)) > 0) {
bool unclean_shutdown = False;
@@ -340,7 +364,7 @@ static void smbd_sig_chld_handler(struct tevent_context *ev,
if (WIFSIGNALED(status)) {
unclean_shutdown = True;
}
- remove_child_pid(ev, pid, unclean_shutdown);
+ remove_child_pid(parent, pid, unclean_shutdown);
}
}
@@ -399,7 +423,7 @@ static void smbd_accept_connection(struct tevent_context *ev,
return;
}
- if (!allowable_number_of_smbd_processes()) {
+ if (!allowable_number_of_smbd_processes(s->parent)) {
close(fd);
sconn->sock = -1;
return;
@@ -495,7 +519,7 @@ static void smbd_accept_connection(struct tevent_context *ev,
sconn->sock = -1;
if (pid != 0) {
- add_child_pid(pid);
+ add_child_pid(s->parent, pid);
}
/* Force parent to check log size after