summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2009-08-03 11:55:36 +0200
committerStephen Gallagher <sgallagh@redhat.com>2009-08-11 12:29:35 -0400
commitdd8aaf74198c084fd0aa712d56c4511978f04ebe (patch)
tree32b5b07a2781ffe2381265f3ffeb8202cd216e91 /server
parentb3b55f167063417c285524ba35bd9298965b834a (diff)
Make child processes exit when parent dies
The child processes call prctl() and when their parent process is killed, they are sent SIGTERM using prctl. This is currently Linux-specific, for non-Linuxes, a similar effect is achieved by catching a set of common termination signals and sending SIGTERM to the process group.
Diffstat (limited to 'server')
-rw-r--r--server/providers/data_provider.c6
-rw-r--r--server/providers/data_provider_be.c6
-rw-r--r--server/responder/nss/nsssrv.c6
-rw-r--r--server/responder/pam/pamsrv.c6
-rw-r--r--server/util/server.c44
-rw-r--r--server/util/signal.m42
-rw-r--r--server/util/util.h1
7 files changed, 70 insertions, 1 deletions
diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c
index b95292546..f0ecd30bb 100644
--- a/server/providers/data_provider.c
+++ b/server/providers/data_provider.c
@@ -1088,6 +1088,12 @@ int main(int argc, const char *argv[])
ret = server_setup("sssd[dp]", 0, DP_CONF_ENTRY, &main_ctx);
if (ret != EOK) return 2;
+ ret = die_if_parent_died();
+ if (ret != EOK) {
+ /* This is not fatal, don't return */
+ DEBUG(2, ("Could not set up to exit when parent process does\n"));
+ }
+
ret = dp_process_init(main_ctx,
main_ctx->event_ctx,
main_ctx->confdb_ctx);
diff --git a/server/providers/data_provider_be.c b/server/providers/data_provider_be.c
index c93c4531e..49885edc6 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -1109,6 +1109,12 @@ int main(int argc, const char *argv[])
return 2;
}
+ ret = die_if_parent_died();
+ if (ret != EOK) {
+ /* This is not fatal, don't return */
+ DEBUG(2, ("Could not set up to exit when parent process does\n"));
+ }
+
ret = be_process_init(main_ctx,
be_name, be_domain,
main_ctx->event_ctx,
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index 248d53843..418e2f9f6 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -365,6 +365,12 @@ int main(int argc, const char *argv[])
ret = server_setup("sssd[nss]", 0, NSS_SRV_CONFIG, &main_ctx);
if (ret != EOK) return 2;
+ ret = die_if_parent_died();
+ if (ret != EOK) {
+ /* This is not fatal, don't return */
+ DEBUG(2, ("Could not set up to exit when parent process does\n"));
+ }
+
ret = nss_process_init(main_ctx,
main_ctx->event_ctx,
main_ctx->confdb_ctx);
diff --git a/server/responder/pam/pamsrv.c b/server/responder/pam/pamsrv.c
index 92fa4aecb..bff2f7cc9 100644
--- a/server/responder/pam/pamsrv.c
+++ b/server/responder/pam/pamsrv.c
@@ -227,6 +227,12 @@ int main(int argc, const char *argv[])
ret = server_setup("sssd[pam]", 0, PAM_SRV_CONFIG, &main_ctx);
if (ret != EOK) return 2;
+ ret = die_if_parent_died();
+ if (ret != EOK) {
+ /* This is not fatal, don't return */
+ DEBUG(2, ("Could not set up to exit when parent process does\n"));
+ }
+
pam_dp_interface = get_pam_dp_interface();
sss_cmds = register_sss_cmds();
ret = sss_process_init(main_ctx,
diff --git a/server/util/server.c b/server/util/server.c
index fd6e4cdc4..d20a823c7 100644
--- a/server/util/server.c
+++ b/server/util/server.c
@@ -33,6 +33,10 @@
#include "ldb.h"
#include "confdb/confdb.h"
+#ifdef HAVE_PRCTL
+#include <sys/prctl.h>
+#endif
+
/*******************************************************************
Close the low 3 fd's and open dev/null in their place.
********************************************************************/
@@ -191,6 +195,21 @@ static void sig_term(int sig)
exit(0);
}
+#ifndef HAVE_PRCTL
+static void sig_segv_abrt(int sig)
+{
+#if HAVE_GETPGRP
+ static int done;
+ if (done == 0 && getpgrp() == getpid()) {
+ DEBUG(0,("%s: killing children\n", strsignal(sig)));
+ done = 1;
+ kill(-getpgrp(), SIGTERM);
+ }
+#endif /* HAVE_GETPGRP */
+ exit(1);
+}
+#endif /* HAVE_PRCTL */
+
/*
setup signal masks
*/
@@ -219,6 +238,14 @@ static void setup_signals(void)
CatchSignal(SIGHUP, sig_hup);
CatchSignal(SIGTERM, sig_term);
+
+#ifndef HAVE_PRCTL
+ /* If prctl is not defined on the system, try to handle
+ * some common termination signals gracefully */
+ CatchSignal(SIGSEGV, sig_segv_abrt);
+ CatchSignal(SIGABRT, sig_segv_abrt);
+#endif
+
}
/*
@@ -244,6 +271,23 @@ static void server_stdin_handler(struct tevent_context *event_ctx,
/*
main server helpers.
*/
+
+int die_if_parent_died(void)
+{
+#ifdef HAVE_PRCTL
+ int ret;
+
+ errno = 0;
+ ret = prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0);
+ if (ret != 0) {
+ ret = errno;
+ DEBUG(2, ("prctl failed [%d]: %s", ret, strerror(ret)));
+ return ret;
+ }
+#endif
+ return EOK;
+}
+
int server_setup(const char *name, int flags,
const char *conf_entry,
struct main_context **main_ctx)
diff --git a/server/util/signal.m4 b/server/util/signal.m4
index a778020e7..747c7dbf3 100644
--- a/server/util/signal.m4
+++ b/server/util/signal.m4
@@ -1 +1 @@
-AC_CHECK_FUNCS(sigprocmask sigblock sigaction getpgrp)
+AC_CHECK_FUNCS(sigprocmask sigblock sigaction getpgrp prctl)
diff --git a/server/util/util.h b/server/util/util.h
index e11bc51cf..879652924 100644
--- a/server/util/util.h
+++ b/server/util/util.h
@@ -107,6 +107,7 @@ struct main_context {
struct confdb_ctx *confdb_ctx;
};
+int die_if_parent_died(void);
int server_setup(const char *name, int flags,
const char *conf_entry,
struct main_context **main_ctx);