monitor.c revision 9657c178fb22bcbd3755db6d6fc2ec5f2e114841
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen Service monitor
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen Copyright (C) Simo Sorce 2008
9de5eb9e1ac3a07c4197a60fdefd412d6cc78eb2Timo Sirainen This program is free software; you can redistribute it and/or modify
9de5eb9e1ac3a07c4197a60fdefd412d6cc78eb2Timo Sirainen it under the terms of the GNU General Public License as published by
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen the Free Software Foundation; either version 3 of the License, or
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen (at your option) any later version.
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen This program is distributed in the hope that it will be useful,
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen but WITHOUT ANY WARRANTY; without even the implied warranty of
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2670cd577aa57eb9f915a4f4220ae48c9b4fc5fbTimo Sirainen GNU General Public License for more details.
along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "util/child_common.h"
#include <time.h>
#include <string.h>
#ifdef HAVE_SYS_INOTIFY_H
#include <unistd.h>
#include <fcntl.h>
#include <popt.h>
#include <tevent.h>
#include <resolv.h>
#include "confdb/confdb_setup.h"
#include "sbus/sssd_dbus.h"
#include "monitor/monitor_interfaces.h"
#include "responder/common/responder_sbus.h"
#ifdef USE_KEYRING
#include <keyutils.h>
#ifdef HAVE_SYSTEMD
int cmdline_debug_level;
struct svc_spy;
struct mt_svc {
char *provider;
char *command;
char *name;
char *identity;
int kill_time;
bool svc_started;
int restarts;
int debug_level;
struct config_file_callback {
int wd;
int retries;
char *filename;
struct config_file_ctx {
bool needs_update;
struct mt_ctx {
char **services;
int num_services;
int started_services;
int inotify_fd;
int service_id_timeout;
bool check_children;
bool services_started;
const char *conf_path;
bool pid_file_created;
bool is_daemon;
const char *name,
int restarts);
const char *name,
int restarts);
static int monitor_cleanup(void);
struct mon_init_conn {
return ENOENT;
#ifdef HAVE_SYSTEMD
char *svc_name,
bool is_provider,
int ret;
if (is_provider) {
return EINVAL;
svc_name);
return ret;
return EOK;
char *svc_name,
bool is_provider,
return EOK;
#ifdef HAVE_SYSTEMD
_svc);
char *svc_name;
int ret;
if (!mini) {
return EINVAL;
if (!dbret) {
goto done;
&svc);
goto done;
return ret;
if (ret) {
goto done;
done:
return EOK;
struct svc_spy {
if (!svc) {
if (!spy) {
return EOK;
int ret;
if (ret) {
goto done;
if (iter) {
goto done;
goto done;
#ifdef HAVE_SYSTEMD
if (ret < 0) {
goto done;
errno = 0;
if (ret != 0) {
done:
return ret;
if (!to) {
return ENOMEM;
return EOK;
{ &mon_srv_iface_meta, 0 },
char *monitor_address;
int ret;
return ret;
return ret;
if (!reply) {
const char *filename)
int ret;
if(ret != 0) {
return EIO;
return EOK;
int ret;
return EOK;
return EIO;
return ENOMEM;
return ret;
while (dom) {
return EINVAL;
while (other) {
return EOK;
while (dom) {
count++;
return EINVAL;
return EOK;
char ***_services)
int ret;
char **domain_names;
size_t c;
char *conf_path;
char *id_provider;
bool add_pac = false;
return ENOMEM;
&domain_names);
goto done;
domain_names[c]);
goto done;
add_pac = true;
domain_names[c]);
goto done;
done:
return ret;
return service;
return NULL;
return NULL;
for (int i = 0; services[i]; i++) {
return services[i];
return NULL;
char *user_str;
return ret;
return ret;
return EOK;
int ret;
int timeout_seconds;
return ret;
#ifdef HAVE_SYSTEMD
return EINVAL;
return EINVAL;
return EINVAL;
return ret;
return ret;
return ret;
return ret;
return EOK;
int ret;
char *path;
if (!svc) {
return ENOMEM;
return ENOMEM;
return ENOMEM;
if (!path) {
return ENOMEM;
return ret;
return ENOMEM;
return ENOMEM;
return ENOMEM;
return ENOMEM;
return ENOMEM;
if (debug_to_file) {
return ENOMEM;
return ENOMEM;
return EOK;
const char *name,
int restarts)
int ret;
return ret;
return ret;
int ret;
char *path;
if (!svc) {
return ENOMEM;
return ENOMEM;
return ENOMEM;
if (!path) {
return ENOMEM;
return ret;
return ret;
return EIO;
return ENOMEM;
return ENOMEM;
return ENOMEM;
return ENOMEM;
return ENOMEM;
if (debug_to_file) {
return ENOMEM;
return ENOMEM;
return EOK;
const char *name,
int restarts)
int ret;
name);
return ret;
return ENOENT;
return ret;
int signum,
int count,
void *siginfo,
void *private_data)
static int monitor_cleanup(void)
int ret;
errno = 0;
return ret;
return EOK;
int status;
int kret;
bool killed;
killed = false;
errno = 0;
if (kret < 0) {
error = 0;
errno = 0;
killed = true;
} else if (pid != 0) {
error = 0;
killed = true;
if (!killed) {
} while (!killed);
#if HAVE_GETPGRP
error = 0;
errno = 0;
int signum,
int count,
void *siginfo,
void *private_data)
int ret;
if (ret == 0) {
int signum,
int count,
void *siginfo,
void *private_data)
int signum,
int count,
void *siginfo,
void *private_data)
const char *config_file,
const char *config_dir,
if(!ctx) {
return ENOMEM;
goto done;
goto done;
goto done;
if (ret != 0) {
goto done;
done:
return ret;
const char *file,
bool ignore_missing);
#ifdef HAVE_INOTIFY
if (!te) {
struct rewatch_ctx {
char *name;
if (!tmp_ctx) return;
if (!in_event) {
goto done;
errno = 0;
sizeof(struct inotify_event));
goto done;
if (!name) {
goto done;
errno = 0;
goto done;
if (!cb) {
goto done;
if(!rw_ctx) {
goto done;
goto done;
done:
int err;
if (ret < 0) {
#ifdef HAVE_INOTIFY
return err;
if (fd_args < 0) {
return EINVAL;
if (ret < 0) {
return EINVAL;
file_ctx);
if (!tfd) {
return EIO;
if(!cb) {
return ENOMEM;
return ENOMEM;
return err;
return EOK;
return EINVAL;
const char *file,
bool ignore_missing)
bool use_inotify;
if (ret < 0) {
return EOK;
return err;
true, &use_inotify);
return ret;
if (use_inotify) {
use_inotify = false;
if (!use_inotify) {
return ret;
const char *file,
bool ignore_missing)
if (ret < 0) {
return EOK;
return err;
if (!cb) {
return ENOMEM;
return ENOMEM;
return EIO;
return EOK;
int ret;
monitor_update_resolv, false);
"tevent_add_timer failed. resolv.conf will be ignored.\n");
"Monitor_config_file failed. resolv.conf will be ignored.\n");
const char *config_file)
char *rcachedir;
int num_providers;
int ret;
int error;
bool disable_netlink;
&rcachedir);
return ret;
errno = 0;
if (ret < 0) {
return EIO;
return EIO;
return EIO;
return EIO;
return EIO;
return ret;
/* Watch for changes to the DNS resolv.conf */
monitor_update_resolv, false);
return ret;
if (!tmp_ctx) {
return ENOMEM;
return ret;
return ret;
false, &disable_netlink);
return ret;
if (disable_netlink == false) {
return ret;
num_providers = 0;
return ret;
if (num_providers > 0) {
return ret;
return EOK;
if (!mini) {
return ENOMEM;
return ENOMEM;
return ENOMEM;
return EOK;
char **args;
int restart_delay;
int opt;
int opt_daemon = 0;
int opt_interactive = 0;
int opt_genconf = 0;
int opt_version = 0;
int opt_netlinkoff = 0;
int flags = 0;
int ret;
&opt_netlinkoff, 0, \
NULL}, \
switch(opt) {
if (opt_version) {
return EXIT_SUCCESS;
if (uid != 0) {
if (!tmp_ctx) {
if (opt_interactive) {
if (opt_genconf) {
if (opt_config_file) {
if (opt_netlinkoff) {
"replaced as a monitor option in sssd.conf\n");
"disable_netlink available as replacement(man sssd.conf)");
if (!config_file) {
if (debug_to_file) {
if (ret) {
#ifdef USE_KEYRING
switch (ret) {
case ENOENT:
case EEXIST:
case EOK:
&monitor);
switch (ret) {
case ERR_MISSING_CONF:
case EPERM:
case EACCES:
if (opt_genconf) return 0;