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 b9529254..f0ecd30b 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 c93c4531..49885edc 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 248d5384..418e2f9f 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 92fa4aec..bff2f7cc 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 fd6e4cdc..d20a823c 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 a778020e..747c7dbf 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 e11bc51c..87965292 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);