diff --git a/ipmitool/ChangeLog b/ipmitool/ChangeLog index d1df4d2..6fe40f9 100644 --- a/ipmitool/ChangeLog +++ b/ipmitool/ChangeLog @@ -12,6 +12,7 @@ version 1.8.7 * Add support for FreeBSD OpenIPMI-compatible driver * Add support for IPMIv2 Firmware Firewall * Fix gcc4 compile warnings + * Make ipmievd generate pidfile version 1.8.6 * Fix memory corruption when sending encrypted SOL traffic diff --git a/ipmitool/doc/ipmievd.8 b/ipmitool/doc/ipmievd.8 index 2aff8dc..eb634a1 100644 --- a/ipmitool/doc/ipmievd.8 +++ b/ipmitool/doc/ipmievd.8 @@ -158,6 +158,10 @@ All messages will be sent to syslog. This is the default action. .TP \fInodaemon\fP Do NOT become a daemon, instead log all messages to stderr. +.TP +\fIpidfile\fP=<\fBfilename\fR> +Save process ID to this file when in daemon mode. Defaults to +/var/run/ipmievd.pid. .RE .TP @@ -176,6 +180,10 @@ All messages will be sent to syslog. This is the default action. .TP \fInodaemon\fP Do NOT become a daemon, instead log all messages to stderr. +.TP +\fIpidfile\fP=<\fBfilename\fR> +Save process ID to this file when in daemon mode. Defaults to +/var/run/ipmievd.pid. .TP \fItimeout\fP=<\fBseconds\fR> Time between checks for SEL polling method. Default is 10 seconds. diff --git a/ipmitool/src/ipmievd.c b/ipmitool/src/ipmievd.c index 13b8882..82dfad9 100644 --- a/ipmitool/src/ipmievd.c +++ b/ipmitool/src/ipmievd.c @@ -40,23 +40,21 @@ #include #include #include - -#ifdef __FreeBSD__ -# include -# include -#endif +#include +#include #include #ifdef IPMI_INTF_OPEN -# ifdef HAVE_OPENIPMI_H +# if defined(HAVE_OPENIPMI_H) # include # include -# include -# else /* HAVE_OPENIPMI_H */ +# elif defined(HAVE_FREEBSD_IPMI_H) +# include +# else # include "plugins/open/open.h" +# endif # include -# endif /* HAVE_OPENIPMI_H */ #endif /* IPMI_INTF_OPEN */ #include @@ -68,6 +66,9 @@ #include #include +#define DEFAULT_PIDFILE "/var/run/ipmievd.pid" +char pidfile[64]; + /* global variables */ int verbose = 0; int csv_output = 0; @@ -580,11 +581,28 @@ selwatch_wait(struct ipmi_event_intf * eintf) } /*************************************************************************/ +static void +ipmievd_cleanup(int signal) +{ + struct stat st1; + + if (lstat(pidfile, &st1) == 0) { + /* cleanup daemon pidfile */ + (void)unlink(pidfile); + } + + exit(EXIT_SUCCESS); +} + int ipmievd_main(struct ipmi_event_intf * eintf, int argc, char ** argv) { int i, rc; int daemon = 1; + struct sigaction act; + + memset(pidfile, 0, 64); + strncpy(pidfile, DEFAULT_PIDFILE, strlen(DEFAULT_PIDFILE)); for (i = 0; i < argc; i++) { if (strncasecmp(argv[i], "help", 4) == 0) { @@ -608,11 +626,41 @@ ipmievd_main(struct ipmi_event_intf * eintf, int argc, char ** argv) else if (strncasecmp(argv[i], "timeout=", 8) == 0) { selwatch_timeout = strtoul(argv[i]+8, NULL, 0); } + else if (strncasecmp(argv[i], "pidfile=", 8) == 0) { + memset(pidfile, 0, 64); + strncpy(pidfile, argv[i]+8, + __min(strlen((const char *)(argv[i]+8)), 63)); + } } - if (daemon) + if (daemon) { + FILE *fp; + struct stat st1; + ipmi_start_daemon(); + if (lstat(pidfile, &st1) == 0) { + /* already exists, erase first */ + if (unlink(pidfile) != 0) { + lprintf(LOG_WARN, "Unable to erase pidfile"); + } + } + + fp = ipmi_open_file_write(pidfile); + if (fp != NULL) { + fprintf(fp, "%d\n", (int)getpid()); + fclose(fp); + } + } + + /* register signal handler for cleanup */ + act.sa_handler = ipmievd_cleanup; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + sigaction(SIGINT, &act, NULL); + sigaction(SIGQUIT, &act, NULL); + sigaction(SIGTERM, &act, NULL); + log_halt(); log_init("ipmievd", daemon, verbose); @@ -622,6 +670,7 @@ ipmievd_main(struct ipmi_event_intf * eintf, int argc, char ** argv) lprintf(LOG_DEBUG, "Sensors cached"); /* call event handler setup routine */ + if (eintf->setup != NULL) { rc = eintf->setup(eintf); if (rc < 0) {