-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

The attached patch addresses ticket #84.

The implementation is unfortunately Linux-specific as it uses the
prctl(2) syscall. Ideas how to accomplish this in a cross-platform
manner are welcome.

        Jakub
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAkp2xRwACgkQHsardTLnvCXTywCfasymEPbxk4Bxw0E0QHOD2lam
f2wAoNL9Kwu/OgenxPSAeKnQ5TypGStx
=LgoS
-----END PGP SIGNATURE-----
>From 203e015bb9222ca971f0defb6631465cd572a842 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Mon, 3 Aug 2009 11:55:36 +0200
Subject: [PATCH] Make child processes exit when parent dies

The child processes call prctl() and when their parent process is
killed, they are sent SIGTERM. The implementation is currently
Linux-specific.
---
 server/providers/data_provider.c    |    6 ++++++
 server/providers/data_provider_be.c |    6 ++++++
 server/responder/nss/nsssrv.c       |    6 ++++++
 server/responder/pam/pamsrv.c       |    6 ++++++
 server/util/server.c                |   22 ++++++++++++++++++++++
 server/util/signal.m4               |    4 ++++
 server/util/util.h                  |    1 +
 7 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/server/providers/data_provider.c b/server/providers/data_provider.c
index 4dc9dfa..dafa00c 100644
--- a/server/providers/data_provider.c
+++ b/server/providers/data_provider.c
@@ -1115,6 +1115,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 2e0c1cf..8a2f51a 100644
--- a/server/providers/data_provider_be.c
+++ b/server/providers/data_provider_be.c
@@ -1125,6 +1125,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 9a3d3c4..fb9e03c 100644
--- a/server/responder/nss/nsssrv.c
+++ b/server/responder/nss/nsssrv.c
@@ -366,6 +366,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 ef01e97..9a092e6 100644
--- a/server/responder/pam/pamsrv.c
+++ b/server/responder/pam/pamsrv.c
@@ -229,6 +229,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_methods = register_pam_dp_methods();
     sss_cmds = register_sss_cmds();
     ret = sss_process_init(main_ctx,
diff --git a/server/util/server.c b/server/util/server.c
index fd6e4cd..0cdbff1 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.
 ********************************************************************/
@@ -244,6 +248,24 @@ 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;
+    }
+    return EOK;
+#endif
+    return ENOSYS;
+}
+
 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 a778020..f9aec3a 100644
--- a/server/util/signal.m4
+++ b/server/util/signal.m4
@@ -1 +1,5 @@
 AC_CHECK_FUNCS(sigprocmask sigblock sigaction getpgrp)
+
+AC_CHECK_FUNC([prctl],
+              AC_DEFINE([HAVE_PRCTL], [1],
+                        [Define if prctl() exists]))
diff --git a/server/util/util.h b/server/util/util.h
index 02916c1..290dd6d 100644
--- a/server/util/util.h
+++ b/server/util/util.h
@@ -90,6 +90,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);
-- 
1.6.2.5

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to