return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_DOMAIN_PDC:
case ROLE_DOMAIN_BDC:
- task_server_terminate(task, "Cannot start KDC as a 'classic Samba' DC", true);
+ task_server_terminate(
+ task, "Cannot start KDC as a 'classic Samba' DC", false);
return NT_STATUS_INVALID_DOMAIN_ROLE;
case ROLE_ACTIVE_DIRECTORY_DC:
/* Yes, we want a KDC */
const struct service_details*,
const int);
- /* function to terminate a connection or task */
- void (*terminate)(struct tevent_context *,
- struct loadparm_context *lp_ctx,
- const char *reason,
- bool fatal,
- void *process_context);
+ /* function to terminate a task */
+ void (*terminate_task)(struct tevent_context *,
+ struct loadparm_context *lp_ctx,
+ const char *reason,
+ bool fatal,
+ void *process_context);
+ /* function to terminate a connection */
+ void (*terminate_connection)(struct tevent_context *,
+ struct loadparm_context *lp_ctx,
+ const char *reason,
+ void *process_context);
/* function to set a title for the connection or task */
void (*set_title)(struct tevent_context *, const char *title);
exit(0);
}
+static void prefork_restart(struct tevent_context *ev,
+ struct restart_context *rc)
+{
+ if (rc->master != NULL) {
+ DBG_ERR("Restarting [%s] pre-fork master\n", rc->service_name);
+ prefork_new_task(ev,
+ rc->master->lp_ctx,
+ rc->service_name,
+ rc->master->new_task_fn,
+ rc->master->private_data,
+ rc->service_details,
+ rc->from_parent_fd);
+ } else if (rc->worker != NULL) {
+ struct process_details pd = initial_process_details;
+ DBG_ERR("Restarting [%s] pre-fork worker(%d)\n",
+ rc->service_name,
+ rc->worker->instance);
+ pd.instances = rc->worker->instance;
+ prefork_fork_worker(rc->worker->task,
+ ev,
+ rc->worker->ev2,
+ rc->service_details,
+ rc->service_name,
+ rc->worker->control_pipe,
+ &pd);
+ }
+}
/*
handle EOF on the child pipe in the parent, so we know when a
process terminates without using SIGCHLD or waiting on all possible pids.
DBG_ERR("Parent %d, Child %d terminated, "
"unable to get status code from tfork\n",
getpid(), pid);
+ prefork_restart(ev, rc);
} else if (WIFEXITED(status)) {
status = WEXITSTATUS(status);
DBG_ERR("Parent %d, Child %d exited with status %d\n",
getpid(), pid, status);
+ if (status != 0) {
+ prefork_restart(ev, rc);
+ }
} else if (WIFSIGNALED(status)) {
status = WTERMSIG(status);
DBG_ERR("Parent %d, Child %d terminated with signal %d\n",
getpid(), pid, status);
if (status == SIGABRT || status == SIGBUS || status == SIGFPE ||
- status == SIGILL || status == SIGSYS) {
- /*
- * Lets restart the process.
- *
- */
- tfork_destroy(&rc->t);
- if (rc->master != NULL) {
- DBG_ERR("Restarting [%s] pre-fork master\n",
- rc->service_name);
- prefork_new_task(ev,
- rc->master->lp_ctx,
- rc->service_name,
- rc->master->new_task_fn,
- rc->master->private_data,
- rc->service_details,
- rc->from_parent_fd);
- } else if (rc->worker != NULL) {
- struct process_details pd =
- initial_process_details;
- DBG_ERR("Restarting [%s] pre-fork worker(%d)\n",
- rc->service_name,
- rc->worker->instance);
- pd.instances = rc->worker->instance;
- prefork_fork_worker(rc->worker->task,
- ev,
- rc->worker->ev2,
- rc->service_details,
- rc->service_name,
- rc->worker->control_pipe,
- &pd);
- }
+ status == SIGILL || status == SIGSYS || status == SIGSEGV) {
+
+ prefork_restart(ev, rc);
}
}
/* tfork allocates tfork structures with malloc */
+ tfork_destroy(&rc->t);
free(rc->t);
TALLOC_FREE(rc);
return;
}
-
-/* called when a task goes down */
-static void prefork_terminate(struct tevent_context *ev,
- struct loadparm_context *lp_ctx,
- const char *reason,
- bool fatal,
- void *process_context)
+/*
+ * called when a task terminates
+ */
+static void prefork_terminate_task(struct tevent_context *ev,
+ struct loadparm_context *lp_ctx,
+ const char *reason,
+ bool fatal,
+ void *process_context)
{
DBG_DEBUG("called with reason[%s]\n", reason);
+ if (fatal == true) {
+ exit(127);
+ } else {
+ exit(0);
+ }
+}
+
+/*
+ * called when a connection completes
+ */
+static void prefork_terminate_connection(struct tevent_context *ev,
+ struct loadparm_context *lp_ctx,
+ const char *reason,
+ void *process_context)
+{
}
/* called to set a title of a task or connection */
.model_init = prefork_model_init,
.accept_connection = prefork_accept_connection,
.new_task = prefork_new_task,
- .terminate = prefork_terminate,
+ .terminate_task = prefork_terminate_task,
+ .terminate_connection = prefork_terminate_connection,
.set_title = prefork_set_title,
};
}
}
-
-/* called when a task goes down */
-static void single_terminate(struct tevent_context *ev,
- struct loadparm_context *lp_ctx,
- const char *reason,
- bool fatal,
- void *process_context)
+/*
+ * Called when a task goes down
+ */
+static void single_terminate_task(struct tevent_context *ev,
+ struct loadparm_context *lp_ctx,
+ const char *reason,
+ bool fatal,
+ void *process_context)
{
DBG_NOTICE("single_terminate: reason[%s]\n",reason);
}
+/*
+ * Called when a connection has ended
+ */
+static void single_terminate_connection(struct tevent_context *ev,
+ struct loadparm_context *lp_ctx,
+ const char *reason,
+ void *process_context)
+{
+}
+
/* called to set a title of a task or connection */
static void single_set_title(struct tevent_context *ev, const char *title)
{
const struct model_ops single_ops = {
.name = "single",
.model_init = single_model_init,
- .new_task = single_new_task,
+ .new_task = single_new_task,
.accept_connection = single_accept_connection,
- .terminate = single_terminate,
+ .terminate_task = single_terminate_task,
+ .terminate_connection = single_terminate_connection,
.set_title = single_set_title,
};
/* called when a task goes down */
-static void standard_terminate(struct tevent_context *ev,
- struct loadparm_context *lp_ctx,
- const char *reason,
- bool fatal,
- void *process_context)
+static void standard_terminate_task(struct tevent_context *ev,
+ struct loadparm_context *lp_ctx,
+ const char *reason,
+ bool fatal,
+ void *process_context)
+{
+ if (fatal == true) {
+ exit(127);
+ }
+ exit(0);
+}
+
+/* called when a connection terminates*/
+static void standard_terminate_connection(struct tevent_context *ev,
+ struct loadparm_context *lp_ctx,
+ const char *reason,
+ void *process_context)
{
struct process_context *proc_ctx = NULL;
- DBG_DEBUG("process terminating reason[%s]\n", reason);
+ DBG_DEBUG("connection terminating reason[%s]\n", reason);
if (process_context == NULL) {
smb_panic("Panicking process_context is NULL");
}
/* terminate this process */
exit(0);
}
-
/* called to set a title of a task or connection */
static void standard_set_title(struct tevent_context *ev, const char *title)
{
.name = "standard",
.model_init = standard_model_init,
.accept_connection = standard_accept_connection,
- .new_task = standard_new_task,
- .terminate = standard_terminate,
- .set_title = standard_set_title,
+ .new_task = standard_new_task,
+ .terminate_task = standard_terminate_task,
+ .terminate_connection = standard_terminate_connection,
+ .set_title = standard_set_title,
};
/*
const struct model_ops *model_ops = srv_conn->model_ops;
struct loadparm_context *lp_ctx = srv_conn->lp_ctx;
void *process_context = srv_conn->process_context;
- bool fatal = true;
TALLOC_CTX *frame = NULL;
if (!reason) reason = "unknown reason";
srv_conn->event.fde = NULL;
imessaging_cleanup(srv_conn->msg_ctx);
TALLOC_FREE(srv_conn);
- model_ops->terminate(event_ctx, lp_ctx, reason, fatal, process_context);
+ model_ops->terminate_connection(
+ event_ctx, lp_ctx, reason, process_context);
TALLOC_FREE(frame);
}
imessaging_cleanup(task->msg_ctx);
- model_ops->terminate(
+ model_ops->terminate_task(
event_ctx, task->lp_ctx, reason, fatal, task->process_context);
/* don't free this above, it might contain the 'reason' being printed */
talloc_free(task);