summaryrefslogtreecommitdiff
path: root/source4/smbd
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-09-18 18:05:55 -0700
committerAndrew Tridgell <tridge@samba.org>2009-09-18 18:05:55 -0700
commite9a589feac531379e569bc39d803b16179002cfa (patch)
tree81fcaf840fa0ed4513e4d17d6e20f47434ca5ac5 /source4/smbd
parentade5d43c5ceb915dd2210a735a21fd9bed531dd3 (diff)
downloadsamba-e9a589feac531379e569bc39d803b16179002cfa.tar.gz
samba-e9a589feac531379e569bc39d803b16179002cfa.tar.bz2
samba-e9a589feac531379e569bc39d803b16179002cfa.zip
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.
Diffstat (limited to 'source4/smbd')
-rw-r--r--source4/smbd/process_single.c4
-rw-r--r--source4/smbd/server.c46
-rw-r--r--source4/smbd/service_named_pipe.c2
-rw-r--r--source4/smbd/service_task.c18
4 files changed, 67 insertions, 3 deletions
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;
}