monitor.c revision 157223dce84e1fb8aa1edbb02dce02a0e4f76f2b
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber Service monitor
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber Copyright (C) Simo Sorce 2008
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber This program is free software; you can redistribute it and/or modify
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber it under the terms of the GNU General Public License as published by
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber the Free Software Foundation; either version 3 of the License, or
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber (at your option) any later version.
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber This program is distributed in the hope that it will be useful,
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber but WITHOUT ANY WARRANTY; without even the implied warranty of
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber GNU General Public License for more details.
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber You should have received a copy of the GNU General Public License
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber along with this program. If not, see <http://www.gnu.org/licenses/>.
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber/* Needed for res_init() */
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber/* ping time cannot be less then once every few seconds or the
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber * monitor will get crazy hammering children with messages */
e339d6b9c1b85e6341c0d230ac68c5958f28cf08KATOH Yasufumi/* terminate the child after this interval by default if it
e339d6b9c1b85e6341c0d230ac68c5958f28cf08KATOH Yasufumi * doesn't shutdown on receiving SIGTERM */
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber/* name of the monitor server instance */
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber#define SSSD_PIDFILE_PATH PID_PATH"/"MONITOR_NAME".pid"
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber/* Special value to leave the Kerberos Replay Cache set to use
9c631ea7c2906f41b23f5c8dcc9f6045078879dbDwight Engen * the libkrb5 defaults
1bc07a5b8dbaef4b6eb6d30a260e9c2153ed368bKATOH Yasufumi#define KRB5_RCACHE_DIR_DISABLE "__LIBKRB5_DEFAULTS__"
b9d957c316c3827898b91cc69788d90be3260935Dwight Engen TALLOC_CTX *domain_ctx; /* Memory context for domain list */
b9d957c316c3827898b91cc69788d90be3260935Dwight Engen TALLOC_CTX *service_ctx; /* Memory context for services */
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graberstatic int start_service(struct mt_svc *mt_svc);
b9d957c316c3827898b91cc69788d90be3260935Dwight Engenstatic int monitor_service_init(struct sbus_connection *conn, void *data);
b9d957c316c3827898b91cc69788d90be3260935Dwight Engenstatic int service_send_ping(struct mt_svc *svc);
b9d957c316c3827898b91cc69788d90be3260935Dwight Engenstatic int service_signal_reset_offline(struct mt_svc *svc);
b9d957c316c3827898b91cc69788d90be3260935Dwight Engenstatic void ping_check(DBusPendingCall *pending, void *data);
b9d957c316c3827898b91cc69788d90be3260935Dwight Engenstatic void set_tasks_checker(struct mt_svc *srv);
b9d957c316c3827898b91cc69788d90be3260935Dwight Engenstatic int monitor_kill_service (struct mt_svc *svc);
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graberstatic int get_service_config(struct mt_ctx *ctx, const char *name,
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graberstatic int get_provider_config(struct mt_ctx *ctx, const char *name,
9c631ea7c2906f41b23f5c8dcc9f6045078879dbDwight Engen const char *name,
9c631ea7c2906f41b23f5c8dcc9f6045078879dbDwight Engen const char *name,
9c631ea7c2906f41b23f5c8dcc9f6045078879dbDwight Engenstatic int mark_service_as_started(struct mt_svc *svc);
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graberstatic int monitor_cleanup(void);
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graberstatic void network_status_change_cb(void *cb_data)
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber struct mt_ctx *ctx = (struct mt_ctx *) cb_data;
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber DEBUG(SSSDBG_TRACE_INTERNAL, ("A networking status change detected "
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber "signaling providers to reset offline status\n"));
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber for (iter = ctx->svc_list; iter; iter = iter->next) {
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber /* Don't signal services, only providers */
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber/* dbus_get_monitor_version
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graber * Return the monitor version over D-BUS */
4019712d198a7d50b08b326ade17f5ff1666efbbStéphane Graberstatic int get_monitor_version(DBusMessage *message,
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;
goto done;
errno = 0;
if (ret != 0) {
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;
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 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)
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;
} 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,
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,
bool ignore_missing);
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 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;
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 */
monitor_update_resolv,true);
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