From 7f6e90e6b3486cbea2188cbd6eff1d01ce90b234 Mon Sep 17 00:00:00 2001 From: Olaf Rempel Date: Fri, 1 May 2009 22:57:15 +0200 Subject: [PATCH] pidfile support --- Makefile | 5 +++- pidfile.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ pidfile.h | 11 ++++++++ sammler.c | 18 ++++++++++++- sammler.conf | 1 + 5 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 pidfile.c create mode 100644 pidfile.h diff --git a/Makefile b/Makefile index 5820736..27060ef 100644 --- a/Makefile +++ b/Makefile @@ -10,13 +10,15 @@ CONFIG_DIR = /usr/local/etc PLUGIN_DIR = /usr/local/lib/sammler DATA_DIR = /var/lib/sammler LOG_DIR = /var/log +PID_DIR = /var/run WWW_DIR = /var/www WWW_CONFIG = $(WWW_DIR)/sammler_graph.conf WWW_OWNER = www-data # ############################ -SRC := sammler.c configfile.c event.c helper.c logging.c network.c plugins.c probe.c sockaddr.c +SRC := configfile.c event.c helper.c logging.c network.c pidfile.c plugins.c probe.c +SRC += sammler.c sockaddr.c CFLAGS := -O2 -Wall -MMD -fno-stack-protector -I. LDFLAGS := -ldl -rdynamic @@ -67,6 +69,7 @@ install: all install -D -m 755 -s $(TARGET) $(DESTDIR)$(BINARY_DIR)/$(TARGET) install -D -m 644 sammler.conf $(DESTDIR)$(CONFIG_DIR)/sammler.conf sed -i -e "s:^logfile .*$$:logfile $(LOG_DIR)/sammler.log:" \ + -e "s:^pidfile .*$$:pidfile $(PID_DIR)/sammler.pid:" \ -e "s:^rrd_dir .*$$:rrd_dir $(DATA_DIR):" \ -e "s:^plugin_dir .*$$:plugin_dir $(PLUGIN_DIR):" \ $(DESTDIR)$(CONFIG_DIR)/sammler.conf diff --git a/pidfile.c b/pidfile.c new file mode 100644 index 0000000..9de2d3d --- /dev/null +++ b/pidfile.c @@ -0,0 +1,71 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "logging.h" + +int pidfile_create(const char *filename) +{ + int fd = open(filename, O_CREAT | O_EXCL | O_RDWR, 0644); + if (fd < 0) + return -1; + + char buf[8]; + int len = snprintf(buf, sizeof(buf), "%d", getpid()); + write(fd, buf, len); + + close(fd); + return 0; +} + +int pidfile_remove(const char *filename) +{ + return unlink(filename); +} + +pid_t pidfile_check(const char *filename, int remove_stale) +{ + int fd = open(filename, O_RDWR); + if (fd < 0) { + if (errno == ENOENT) { + errno = 0; + return 0; + } + return -1; + } + + char buf[9]; + int len = read(fd, buf, sizeof(buf) -1); + buf[len] = '\0'; + + char *tmp; + pid_t pid = strtol(buf, &tmp, 10); + if (len == 0 || tmp == buf) + pid = -1; + + /* just return the pid */ + if (!remove_stale) + return pid; + + /* invalid pid, remove stale file */ + if (pid == -1) { + pidfile_remove(filename); + return 0; + } + + /* check if pid is still running */ + if (kill(pid, 0) == 0 || errno != ESRCH) { + errno = 0; + return pid; + } + + errno = 0; + pidfile_remove(filename); + return 0; +} diff --git a/pidfile.h b/pidfile.h new file mode 100644 index 0000000..2ba1512 --- /dev/null +++ b/pidfile.h @@ -0,0 +1,11 @@ +#ifndef _PIDFILE_H_ +#define _PIDFILE_H_ + +#include + +int pidfile_create(const char *filename); +int pidfile_remove(const char *filename); + +pid_t pidfile_check(const char *filename, int remove_stale); + +#endif // _PIDFILE_H_ diff --git a/sammler.c b/sammler.c index 1aa84db..aff6a64 100644 --- a/sammler.c +++ b/sammler.c @@ -32,11 +32,13 @@ #include "logging.h" #include "network.h" #include "rrdtool.h" +#include "pidfile.h" #include "plugins.h" #include "probe.h" #define DEFAULT_CONFIG "sammler.conf" #define DEFAULT_LOGFILE "sammler.log" +#define DEFAULT_PIDFILE "sammler.pid" static struct option opts[] = { {"config", 1, 0, 'c'}, @@ -88,12 +90,26 @@ int main(int argc, char *argv[]) /* check logfile */ const char *logfile = config_get_string("global", "logfile", DEFAULT_LOGFILE); if (logfile != NULL && debug == 0) { + /* check pidfile */ + const char *pidfile = config_get_string("global", "pidfile", DEFAULT_PIDFILE); + if (pidfile_check(pidfile, 1) != 0) { + log_print(LOG_ERROR, "sammler already running"); + exit(1); + } + /* start logging */ - if (log_init(logfile)) + const char *logfile = config_get_string("global", "logfile", DEFAULT_LOGFILE); + if (log_init(logfile) < 0) exit(1); /* zum daemon mutieren */ daemon(-1, 0); + + /* create pidfile */ + if (pidfile_create(pidfile) < 0) { + log_print(LOG_ERROR, "failed to create pidfile %s", pidfile); + exit(1); + } } log_print(LOG_EVERYTIME, "sammler (pid:%d)", getpid()); diff --git a/sammler.conf b/sammler.conf index 4fcb969..2ad0028 100644 --- a/sammler.conf +++ b/sammler.conf @@ -6,6 +6,7 @@ forward_only false logfile sammler.log +pidfile sammler.pid rrd_dir rrd