monitor.c revision 33dd2356d5b2cadf14e912a0e9f7a8a56f6bc5f1
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano Service monitor
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano Copyright (C) Simo Sorce 2008
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano This program is free software; you can redistribute it and/or modify
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano it under the terms of the GNU General Public License as published by
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano the Free Software Foundation; either version 3 of the License, or
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano (at your option) any later version.
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano This program is distributed in the hope that it will be useful,
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano but WITHOUT ANY WARRANTY; without even the implied warranty of
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano GNU General Public License for more details.
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano You should have received a copy of the GNU General Public License
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano along with this program. If not, see <http://www.gnu.org/licenses/>.
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Needed for res_init() */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* ping time cannot be less then once every few seconds or the
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano * monitor will get crazy hammering children with messages */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* terminate the child after this interval by default if it
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano * doesn't shutdown on receiving SIGTERM */
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano/* Special value to leave the Kerberos Replay Cache set to use
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano * the libkrb5 defaults
d823d5b966f49d975a09a8512d084389d6d7ffc7dlezcano#define KRB5_RCACHE_DIR_DISABLE "__LIBKRB5_DEFAULTS__"
bool needs_update;
struct mt_ctx {
char **services;
int inotify_fd;
int service_id_timeout;
bool check_children;
bool services_started;
const char *conf_path;
const char *name,
int restarts);
const char *name,
int restarts);
static int monitor_cleanup(void);
if (!ret) {
return EIO;
return EOK;
struct mon_init_conn {
void *data;
char *svc_name;
int ret;
if (!mini) {
return EINVAL;
if (!dbret) {
goto done;
while (svc) {
if (ret == 0) {
if (!svc) {
goto done;
if (ret) {
goto done;
if (!dbret) {
return EIO;
done:
return EOK;
struct svc_spy {
if (!svc) {
if (!spy) {
return EOK;
int ret;
if (ret) {
goto done;
if (iter) {
goto done;
done:
return ret;
if (!to) {
return ENOMEM;
return EOK;
char *monitor_address;
int ret;
return ret;
return ret;
int ret;
switch (ret) {
case EOK:
case ENXIO:
int ret;
return ret;
int ret;
if (!reply) {
const char *filename)
int ret;
if(ret != 0) {
return EIO;
return EOK;
int ret;
return EOK;
return EIO;
if (!msg) {
return ENOMEM;
return ret;
while (dom) {
return EINVAL;
while (other) {
return EOK;
while (dom) {
count++;
return EINVAL;
return EOK;
int ii;
for (i = 0; services[i]; i++) {
return services[i];
return NULL;
int ret;
int timeout_seconds;
return ret;
return ENOMEM;
return EINVAL;
return EINVAL;
return ENOMEM;
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;
if (debug_to_file) {
return ENOMEM;
return ret;
return ret;
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 ret;
return EIO;
return ENOMEM;
return ENOMEM;
return ENOMEM;
return ENOMEM;
if (debug_to_file) {
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)
char *file;
int ret;
return ENOMEM;
errno = 0;
return errno;
return EOK;
int signum,
int count,
void *siginfo,
void *private_data)
int status;
int kret;
bool killed;
killed = false;
errno = 0;
if (kret < 0) {
error = 0;
errno = 0;
} else if (pid != 0) {
error = 0;
killed = true;
if (!killed) {
} while (!killed);
#if HAVE_GETPGRP
error = 0;
errno = 0;
exit(0);
int signum,
int count,
void *siginfo,
void *private_data)
int signum,
int count,
void *siginfo,
void *private_data)
const char *config_file,
if(!ctx) {
return ENOMEM;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
done:
return ret;
#ifdef HAVE_SYS_INOTIFY_H
if (!te) {
struct rewatch_ctx {
char *buf;
char *name;
if (!tmp_ctx) return;
if (!buf) {
goto done;
errno = 0;
goto done;
if (!name) {
goto done;
errno = 0;
goto done;
if (!cb) {
goto done;
if(!rw_ctx) {
goto done;
goto done;
done:
const char *file,
int err;
if (ret < 0) {
#ifdef HAVE_SYS_INOTIFY_H
return err;
if (fd_args < 0) {
return EINVAL;
if (ret < 0) {
return EINVAL;
file_ctx);
if (!tfd) {
return EIO;
if(!cb) {
return EIO;
return ENOMEM;
return err;
return EOK;
return EINVAL;
const char *file,
bool use_inotify;
if (ret < 0) {
return err;
true, &use_inotify);
return ret;
if (use_inotify) {
use_inotify = false;
if (!use_inotify) {
return ret;
const char *file,
if (ret < 0) {
return err;
if (!cb) {
return ENOMEM;
return ENOMEM;
return EIO;
return EOK;
const char *config_file)
char *rcachedir;
int num_providers;
int ret;
int error;
&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 */
return ret;
if (!tmp_ctx) {
return ENOMEM;
return ret;
return ret;
return ret;
num_providers = 0;
return ret;
if (num_providers > 0) {
return ret;
return EOK;
if (!mini) {
return ENOMEM;
return ENOMEM;
return EOK;
int ret;
return ENXIO;
if (!msg) {
return ENOMEM;
return ret;
const char *dbus_error_name;
int type;
if (!svc) {
if (!reply) {
goto done;
switch (type) {
case DBUS_MESSAGE_TYPE_ERROR:
if (!dbus_error_name) {
done:
return ENOMEM;
return EOK;
char **args;
int opt;
int opt_daemon = 0;
int opt_interactive = 0;
int opt_version = 0;
int flags = 0;
int ret;
switch(opt) {
if (opt_version) {
return EXIT_SUCCESS;
if (uid != 0) {
if (!tmp_ctx) {
if (opt_config_file)
if(!config_file)
if (debug_to_file) {
if (ret) {
#ifdef USE_KEYRING