summaryrefslogtreecommitdiffstats
path: root/src/monitor
diff options
context:
space:
mode:
authorOndrej Kos <okos@redhat.com>2013-06-19 14:05:00 +0200
committerJakub Hrozek <jhrozek@redhat.com>2013-06-25 10:42:36 +0200
commit1554077521ea202bc886d6483b72e5ebdc10c520 (patch)
treedae1a3e2d542da0cb0a1c10965b2d7fac7505fbf /src/monitor
parent8adef6fcff7db7b40efa242b147641ffa2981fb0 (diff)
downloadsssd-1554077521ea202bc886d6483b72e5ebdc10c520.tar.gz
sssd-1554077521ea202bc886d6483b72e5ebdc10c520.tar.xz
sssd-1554077521ea202bc886d6483b72e5ebdc10c520.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.
Diffstat (limited to 'src/monitor')
-rw-r--r--src/monitor/monitor.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index ea600ba3a..8f1be95af 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -142,6 +142,8 @@ struct mt_ctx {
struct sss_domain_info *domains;
TALLOC_CTX *service_ctx; /* Memory context for services */
char **services;
+ int num_services;
+ int started_services;
struct mt_svc *svc_list;
struct sbus_connection *sbus_srv;
struct config_file_ctx *file_ctx;
@@ -151,6 +153,8 @@ struct mt_ctx {
bool services_started;
struct netlink_ctx *nlctx;
struct sss_sigchild_ctx *sigchld_ctx;
+ bool is_daemon;
+ pid_t parent_pid;
};
static int start_service(struct mt_svc *mt_svc);
@@ -422,6 +426,34 @@ static int mark_service_as_started(struct mt_svc *svc)
}
}
+ if (svc->type == MT_SVC_SERVICE) {
+ ctx->started_services++;
+ }
+
+ if (ctx->started_services == ctx->num_services) {
+ /* 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:
return ret;
}
@@ -783,6 +815,7 @@ int get_monitor_config(struct mt_ctx *ctx)
int ret;
int timeout_seconds;
char *badsrv = NULL;
+ int i;
ret = confdb_get_int(ctx->cdb, ctx,
CONFDB_MONITOR_CONF_ENTRY,
@@ -813,6 +846,12 @@ int get_monitor_config(struct mt_ctx *ctx)
return EINVAL;
}
+ ctx->started_services = 0;
+ ctx->num_services = 0;
+ for (i = 0; ctx->services[i] != NULL; i++) {
+ ctx->num_services++;
+ }
+
ctx->domain_ctx = talloc_new(ctx);
if(!ctx->domain_ctx) {
return ENOMEM;
@@ -2460,6 +2499,8 @@ int main(int argc, const char *argv[])
ret = server_setup("sssd", flags, CONFDB_MONITOR_CONF_ENTRY, &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);