blob: e6823f69231cb8e6f6d41142395196fdd16d3abe [file] [log] [blame]
/* $Header: /cvsroot/watchdog/watchdog/src/pidfile.c,v 1.2 2006/07/31 09:39:23 meskes Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <wait.h>
#include "extern.h"
#include "watch_err.h"
#if USE_SYSLOG
#include <syslog.h>
#endif
#include "watchdog_log.h"
int check_pidfile(struct list *file)
{
int fd = open(file->name, O_RDONLY), pid;
char buf[10];
if (fd == -1) {
int err = errno;
#if USE_SYSLOG
syslog(LOG_ERR, "cannot open %s (errno = %d = '%m')", file->name, err);
#else /* USE_SYSLOG */
perror(progname);
#endif /* USE_SYSLOG */
/* on error ENETDOWN|ENETUNREACH we react as if we're in ping mode
* on ENOENT we assume that the server to be monitored has exited */
if (softboot || err == ENETDOWN || err == ENETUNREACH || err == ENOENT )
return (err);
return(ENOERR);
}
/* position pointer at start of file */
if (lseek(fd, 0, SEEK_SET) < 0) {
int err = errno;
#if USE_SYSLOG
syslog(LOG_ERR, "lseek %s gave errno = %d = '%m'", file->name, err);
#else /* USE_SYSLOG */
perror(progname);
#endif /* USE_SYSLOG */
close(fd);
if (softboot)
return (err);
return (ENOERR);
}
/* just to play it safe */
memset(buf, 0, sizeof(buf));
/* read the line (there is only one) */
if (read(fd, buf, sizeof(buf)) < 0) {
int err = errno;
#if USE_SYSLOG
syslog(LOG_ERR, "read %s gave errno = %d = '%m'", file->name, err);
#else /* USE_SYSLOG */
perror(progname);
#endif /* USE_SYSLOG */
close(fd);
if (softboot)
return (err);
return (ENOERR);
}
/* we only care about integer values */
pid = atoi(buf);
if (close(fd) == -1) {
int err = errno;
#if USE_SYSLOG
syslog(LOG_ERR, "could not close %s, errno = %d = '%m'", file->name, err);
#else /* USE_SYSLOG */
perror(progname);
#endif /* USE_SYSLOG */
if (softboot)
return (err);
return (ENOERR);
}
if (kill (pid, 0) == -1) {
int err = errno;
#if USE_SYSLOG
syslog(LOG_ERR, "pinging process %d (%s) gave errno = %d = '%m'", pid, file->name, err);
#else /* USE_SYSLOG */
perror(progname);
#endif /* USE_SYSLOG */
watchdog_event_log("pinging process %d (%s): %s\n", pid, file->name, strerror(err));
if (softboot || err == ESRCH)
return (err);
return (ENOERR);
}
/*check if process becomes zombie */
char name[256];
FILE *fp;
snprintf(name, sizeof(name), "/proc/%d/stat", pid);
fp = fopen(name, "r");
if (fp) {
char status = 0;
int ret = fscanf(fp, "%*s %*s %c", &status);
if (ret == 1 && status == 'Z') {
watchdog_event_log("zombie process %d (%s)\n", pid, file->name);
return ESRCH;
}
fclose (fp);
} else {
watchdog_event_log("cannot open proc file %s", name);
return ESRCH;
}
#if USE_SYSLOG
/* do verbose logging */
if (verbose && logtick && ticker == 1)
syslog(LOG_INFO, "was able to ping process %d (%s).", pid, file->name);
#endif
return (ENOERR);
}