summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2012-10-18 10:16:06 +0200
committerJakub Hrozek <jhrozek@redhat.com>2012-11-06 12:04:47 +0100
commitd80485d2d23bec4294275f097aef3b30a551827c (patch)
treeddeb483a00b24ee7bc7015286d6a19e6f78a0c67
parent6ec69c22a7358313cbe6aa6a90318c5a4e451af1 (diff)
downloadsssd-d80485d2d23bec4294275f097aef3b30a551827c.tar.gz
sssd-d80485d2d23bec4294275f097aef3b30a551827c.tar.xz
sssd-d80485d2d23bec4294275f097aef3b30a551827c.zip
exit original process after sssd is initialized
https://fedorahosted.org/sssd/ticket/1357 Neither systemd or our init script use pid file as a notification that sssd is finished initializing. They will continue starting up next service right after the original (not daemonized) sssd process is terminated. If any of the responders fail to start, we will never terminate the original process via signal and "service sssd start" will hang. Thus we take this as an error and terminate the daemon with a non-zero value. This will also terminate the original process and init script or systemd will print failure.
-rw-r--r--src/monitor/monitor.c26
-rw-r--r--src/util/server.c31
-rw-r--r--src/util/util.h1
3 files changed, 56 insertions, 2 deletions
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index f93a8c95c..956e1d4e0 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -157,6 +157,8 @@ struct mt_ctx {
const char *conf_path;
struct sss_sigchild_ctx *sigchld_ctx;
bool pid_file_created;
+ bool is_daemon;
+ pid_t parent_pid;
};
static int start_service(struct mt_svc *mt_svc);
@@ -449,6 +451,28 @@ static int mark_service_as_started(struct mt_svc *svc)
}
ctx->pid_file_created = true;
+
+ /* Initialization is complete, terminate parent process if in daemon
+ * mode. Make sure we send the signal to the right process */
+ if (ctx->is_daemon) {
+ if (ctx->parent_pid <= 1 || ctx->parent_pid != getppid()) {
+ /* the parent process was already terminated */
+ DEBUG(SSSDBG_MINOR_FAILURE, ("Invalid parent pid: %d\n",
+ ctx->parent_pid));
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_FUNC, ("SSSD is initialized, "
+ "terminating parent process\n"));
+
+ errno = 0;
+ ret = kill(ctx->parent_pid, SIGTERM);
+ if (ret != 0) {
+ ret = errno;
+ DEBUG(SSSDBG_FATAL_FAILURE, ("Unable to terminate parent "
+ "process [%d]: %s\n", ret, strerror(ret)));
+ }
+ }
}
done:
@@ -2647,6 +2671,8 @@ int main(int argc, const char *argv[])
ret = server_setup(MONITOR_NAME, flags, monitor->conf_path, &main_ctx);
if (ret != EOK) return 2;
+ monitor->is_daemon = !opt_interactive;
+ monitor->parent_pid = main_ctx->parent_pid;
monitor->ev = main_ctx->event_ctx;
talloc_steal(main_ctx, monitor);
diff --git a/src/util/server.c b/src/util/server.c
index ccb3f3bef..3dc9bcc0b 100644
--- a/src/util/server.c
+++ b/src/util/server.c
@@ -24,6 +24,7 @@
*/
#include <sys/types.h>
+#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
@@ -67,17 +68,42 @@ static void close_low_fds(void)
#endif
}
+static void deamon_parent_sigterm(int sig)
+{
+ _exit(0);
+}
+
/**
Become a daemon, discarding the controlling terminal.
**/
void become_daemon(bool Fork)
{
+ pid_t pid;
+ int status;
int ret;
if (Fork) {
- if (fork()) {
- _exit(0);
+ pid = fork();
+ if (pid != 0) {
+ /* Terminate parent process on demand so we can hold systemd
+ * or initd from starting next service until sssd in initialized.
+ * We use signals directly here because we don't have a tevent
+ * context yet. */
+ CatchSignal(SIGTERM, deamon_parent_sigterm);
+
+ /* or exit when sssd monitor is terminated */
+ waitpid(pid, &status, 0);
+
+ /* return error if we didn't exited normally */
+ ret = 1;
+
+ if (WIFEXITED(status)) {
+ /* but return our exit code otherwise */
+ ret = WEXITSTATUS(status);
+ }
+
+ _exit(ret);
}
}
@@ -434,6 +460,7 @@ int server_setup(const char *name, int flags,
return ENOMEM;
}
+ ctx->parent_pid = getppid();
ctx->event_ctx = event_ctx;
conf_db = talloc_asprintf(ctx, "%s/%s", DB_PATH, CONFDB_FILE);
diff --git a/src/util/util.h b/src/util/util.h
index e0f153f26..e50b4f54b 100644
--- a/src/util/util.h
+++ b/src/util/util.h
@@ -359,6 +359,7 @@ void sss_log(int priority, const char *format, ...);
struct main_context {
struct tevent_context *event_ctx;
struct confdb_ctx *confdb_ctx;
+ pid_t parent_pid;
};
int die_if_parent_died(void);