From e9a589feac531379e569bc39d803b16179002cfa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 18 Sep 2009 18:05:55 -0700 Subject: s4-server: kill main daemon if a task fails to initialise When one of our core tasks fails to initialise it can now ask for the server as a whole to die, rather than limping along in a degraded state. --- source4/smbd/process_single.c | 4 +++- source4/smbd/server.c | 46 +++++++++++++++++++++++++++++++++++++++ source4/smbd/service_named_pipe.c | 2 ++ source4/smbd/service_task.c | 18 +++++++++++++-- 4 files changed, 67 insertions(+), 3 deletions(-) (limited to 'source4/smbd') diff --git a/source4/smbd/process_single.c b/source4/smbd/process_single.c index 738ace95c7..ff57a0bc34 100644 --- a/source4/smbd/process_single.c +++ b/source4/smbd/process_single.c @@ -84,7 +84,9 @@ static void single_new_task(struct tevent_context *ev, void (*new_task)(struct tevent_context *, struct loadparm_context *, struct server_id, void *), void *private_data) { - static uint32_t taskid = 0; + /* start our taskids at 1, zero is reserved for the top + level samba task */ + static uint32_t taskid = 1; /* We use 1 so we cannot collide in with cluster ids generated * in the accept connection above, and unlikly to collide with diff --git a/source4/smbd/server.c b/source4/smbd/server.c index 73dbec0120..d150161e05 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -40,6 +40,9 @@ #include "param/param.h" #include "dsdb/samdb/samdb.h" #include "auth/session.h" +#include "lib/messaging/irpc.h" +#include "librpc/gen_ndr/ndr_irpc.h" +#include "cluster/cluster.h" /* recursively delete a directory tree @@ -192,6 +195,43 @@ static void prime_samdb_schema(struct tevent_context *event_ctx) talloc_free(samdb_context); } + +/* + called when a fatal condition occurs in a child task + */ +static NTSTATUS samba_terminate(struct irpc_message *msg, + struct samba_terminate *r) +{ + DEBUG(0,("samba_terminate: %s\n", r->in.reason)); + exit(1); +} + +/* + setup messaging for the top level samba (parent) task + */ +static NTSTATUS setup_parent_messaging(struct tevent_context *event_ctx, + struct loadparm_context *lp_ctx) +{ + struct messaging_context *msg; + NTSTATUS status; + + msg = messaging_init(talloc_autofree_context(), + lp_messaging_path(event_ctx, lp_ctx), + cluster_id(0, SAMBA_PARENT_TASKID), + lp_iconv_convenience(lp_ctx), + event_ctx); + NT_STATUS_HAVE_NO_MEMORY(msg); + + irpc_add_name(msg, "samba"); + + status = IRPC_REGISTER(msg, irpc, SAMBA_TERMINATE, + samba_terminate, NULL); + + return status; +} + + + /* main server. */ @@ -363,6 +403,12 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ prime_samdb_schema(event_ctx); + status = setup_parent_messaging(event_ctx, cmdline_lp_ctx); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Failed to setup parent messaging - %s\n", nt_errstr(status))); + return 1; + } + DEBUG(0,("%s: using '%s' process model\n", binary_name, model)); status = server_service_startup(event_ctx, cmdline_lp_ctx, model, lp_server_services(cmdline_lp_ctx)); diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c index 940edf2cb5..96d572e813 100644 --- a/source4/smbd/service_named_pipe.c +++ b/source4/smbd/service_named_pipe.c @@ -477,6 +477,8 @@ NTSTATUS stream_setup_named_pipe(struct tevent_context *event_context, if (!directory_create_or_exist(dirname, geteuid(), 0700)) { status = map_nt_error_from_unix(errno); + DEBUG(0,(__location__ ": Failed to create stream pipe directory %s - %s\n", + dirname, nt_errstr(status))); goto fail; } diff --git a/source4/smbd/service_task.c b/source4/smbd/service_task.c index c4fd3d4e98..5db8995764 100644 --- a/source4/smbd/service_task.c +++ b/source4/smbd/service_task.c @@ -25,15 +25,29 @@ #include "smbd/service_task.h" #include "lib/messaging/irpc.h" #include "param/param.h" +#include "librpc/gen_ndr/ndr_irpc.h" /* terminate a task service */ -void task_server_terminate(struct task_server *task, const char *reason) +void task_server_terminate(struct task_server *task, const char *reason, bool fatal) { struct tevent_context *event_ctx = task->event_ctx; const struct model_ops *model_ops = task->model_ops; DEBUG(0,("task_server_terminate: [%s]\n", reason)); + + if (fatal) { + struct samba_terminate r; + struct server_id *sid; + + sid = irpc_servers_byname(task->msg_ctx, task, "samba"); + + r.in.reason = reason; + IRPC_CALL(task->msg_ctx, sid[0], + irpc, SAMBA_TERMINATE, + &r, NULL); + } + model_ops->terminate(event_ctx, task->lp_ctx, reason); /* don't free this above, it might contain the 'reason' being printed */ @@ -72,7 +86,7 @@ static void task_server_callback(struct tevent_context *event_ctx, lp_iconv_convenience(task->lp_ctx), task->event_ctx); if (!task->msg_ctx) { - task_server_terminate(task, "messaging_init() failed"); + task_server_terminate(task, "messaging_init() failed", true); return; } -- cgit