diff -Nur pacemaker.orig/configure.ac pacemaker.mark/configure.ac --- pacemaker.orig/configure.ac 2009-06-04 08:04:24.000000000 -0500 +++ pacemaker.mark/configure.ac 2009-06-08 13:53:13.000000000 -0500 @@ -1341,6 +1341,18 @@ AC_SUBST(QUIET_MAKE_OPTS) AC_SUBST(QUIET_LIBTOOL_OPTS) +dnl Check if servicelog development package is installed +SERVICELOG=servicelog-1 +if + $PKGCONFIG --exists $SERVICELOG +then + SERVICELOG_EXISTS="yes" + AC_MSG_RESULT($SERVICELOG found) +else + SERVICELOG_EXISTS="no" +fi +AM_CONDITIONAL(BUILD_SERVICELOG, test $SERVICELOG_EXISTS = "yes") + dnl The Makefiles and shell scripts we output AC_CONFIG_FILES(Makefile \ README \ diff -Nur pacemaker.orig/extra/resources/Makefile.am pacemaker.mark/extra/resources/Makefile.am --- pacemaker.orig/extra/resources/Makefile.am 2009-06-04 08:04:24.000000000 -0500 +++ pacemaker.mark/extra/resources/Makefile.am 2009-06-08 09:46:27.000000000 -0500 @@ -27,5 +27,6 @@ Stateful \ SysInfo \ pingd \ - controld + controld \ + SystemHealth diff -Nur pacemaker.orig/extra/resources/SystemHealth pacemaker.mark/extra/resources/SystemHealth --- pacemaker.orig/extra/resources/SystemHealth 1969-12-31 18:00:00.000000000 -0600 +++ pacemaker.mark/extra/resources/SystemHealth 2009-06-08 10:44:50.000000000 -0500 @@ -0,0 +1,237 @@ +#!/bin/sh +# +# SystemHealth OCF RA. +# +# Copyright (c) 2009 International Business Machines (IBM), Mark Hamzy +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Further, this software is distributed without any warranty that it is +# free of the rightful claim of any third person regarding infringement +# or the like. Any license provided herein, whether implied or +# otherwise, applies only to this software file. Patent licenses, if +# any, provided herein do not apply to combinations of this program with +# other software, or any other product whatsoever. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# + +####################################################################### +# Initialization: + +. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs + +####################################################################### + +meta_data() { + cat < + + +0.1 + + +This is a SystemHealth Resource Agent. It is used to monitor +the health of a system via IPMI. + +SystemHealth resource agent + + + + + + + + + + + + + +END +} + +####################################################################### + +SystemHealth_usage() { + cat < /dev/null 2>&1 + RC=$? + + if [ $RC != 0 ]; then + ocf_log err "servicelog_notify not found!" + return $RC + fi + + which ipmiservicelogd > /dev/null 2>&1 + RC=$? + + if [ $RC != 0 ]; then + ocf_log err "ipmiservicelogd not found!" + return $RC + fi +} + +SystemHealth_start() { + SystemHealth_monitor + RC=$? + + if [ $RC = $OCF_ERR_GENERIC ]; then + return $OCF_ERR_GENERIC + elif [ $RC = $OCF_SUCCESS ]; then + ocf_log warn "starting an already started SystemHealth" + return $OCF_SUCCESS + fi + + service ipmi start > /dev/null 2>&1 + RC=$? + + if [ $RC != 0 ]; then + ocf_log err "Could not start service IPMI!" + return $OCF_ERR_GENERIC + fi + + ipmiservicelogd -I open sel daemon > /dev/null 2>&1 + RC=$? + + if [ $RC != 0 ]; then + ocf_log err "Could not start ipmiservicelogd!" + return $OCF_ERR_GENERIC + fi + + servicelog_notify --add --type=EVENT --command="$OCF_RESKEY_program" --method=num_arg --match='type=4' > /dev/null 2>&1 + RC=$? + + if [ $RC != 0 ]; then + ocf_log err "servicelog_notify register handler failed!" + return $OCF_ERR_GENERIC + fi + + return $OCF_SUCCESS +} + +SystemHealth_stop() { + SystemHealth_monitor + RC=$? + + if [ $RC = $OCF_ERR_GENERIC ]; then + return $OCF_ERR_GENERIC + elif [ $RC = $OCF_SUCCESS ]; then + killall ipmiservicelogd + RC1=$? + + if [ $RC1 != 0 ]; then + ocf_log err "Could not stop ipmiservicelogd!" + fi + + servicelog_notify --remove --command="$OCF_RESKEY_program" > /dev/null 2>&1 + RC2=$? + + if [ $RC2 != 0 ]; then + ocf_log err "servicelog_notify remove handler failed!" + fi + + if [ $RC1 = 0 -a $RC2 = 0 ]; then + return $OCF_SUCCESS + else + return $OCF_ERR_GENERIC + fi + elif [ $RC = $OCF_NOT_RUNNING ]; then + ocf_log warn "stopping an already stopped SystemHealth" + return $OCF_SUCCESS + else + ocf_log err "SystemHealth_stop: should not be here!" + return $OCF_ERR_GENERIC + fi +} + +SystemHealth_monitor() { + # Monitor _MUST!_ differentiate correctly between running + # (SUCCESS), failed (ERROR) or _cleanly_ stopped (NOT RUNNING). + # That is THREE states, not just yes/no. + + SystemHealth_check_tools + RC=$? + + if [ $RC != 0 ]; then + return $OCF_ERR_GENERIC + fi + + if [ ! -f /var/run/ipmiservicelogd.pid0 ]; then + ocf_log debug "ipmiservicelogd is not running!" + return $OCF_NOT_RUNNING + fi + + ps -p `cat /var/run/ipmiservicelogd.pid0` > /dev/null 2>&1 + RC=$? + + if [ $RC != 0 ]; then + ocf_log debug "ipmiservicelogd's pid `cat /var/run/ipmiservicelogd.pid0` is not running!" + + rm /var/run/ipmiservicelogd.pid0 + + return $OCF_ERR_GENERIC + fi + + servicelog_notify --list --command="$OCF_RESKEY_program" > /dev/null 2>&1 + RC=$? + + if [ $RC = 0 ]; then + return $OCF_SUCCESS + else + return $OCF_NOT_RUNNING + fi +} + +SystemHealth_validate() { + + SystemHealth_check_tools + RC=$? + + if [ $RC != 0 ]; then + return $OCF_ERR_ARGS + fi + + return $OCF_SUCCESS +} + +# @TBD - figure out where heartbeat's library path is +: ${OCF_RESKEY_program=/usr/lib64/heartbeat/notifyServicelogEvent} + +case $__OCF_ACTION in +meta-data) meta_data + exit $OCF_SUCCESS + ;; +start) SystemHealth_start;; +stop) SystemHealth_stop;; +monitor) SystemHealth_monitor;; +reload) ocf_log err "Reloading..." + SystemHealth_start + ;; +validate-all) SystemHealth_validate;; +usage|help) SystemHealth_usage + exit $OCF_SUCCESS + ;; +*) SystemHealth_usage + exit $OCF_ERR_UNIMPLEMENTED + ;; +esac +rc=$? +ocf_log debug "${OCF_RESOURCE_INSTANCE} $__OCF_ACTION : $rc" +exit $rc diff -Nur pacemaker.orig/tools/Makefile.am pacemaker.mark/tools/Makefile.am --- pacemaker.orig/tools/Makefile.am 2009-06-04 08:04:24.000000000 -0500 +++ pacemaker.mark/tools/Makefile.am 2009-06-09 11:28:12.000000000 -0500 @@ -34,7 +34,11 @@ halibdir = $(CRM_DAEMON_DIR) halib_SCRIPTS = haresources2cib.py hb2openais.sh +if BUILD_SERVICELOG +halib_PROGRAMS = attrd pingd notifyServicelogEvent +else halib_PROGRAMS = attrd pingd +endif halib_PYTHON = crm_primitive.py hb2openais-helper.py sbin_PROGRAMS = crmadmin cibadmin crm_node crm_attribute crm_resource crm_verify \ @@ -111,6 +115,12 @@ attrd_updater_SOURCES = attrd_updater.c attrd_updater_LDADD = $(COMMONLIBS) +if BUILD_SERVICELOG +notifyServicelogEvent_SOURCES = notifyServicelogEvent.c +notifyServicelogEvent_CFLAGS = `pkg-config --cflags servicelog-1` +notifyServicelogEvent_LDFLAGS = `pkg-config --libs servicelog-1` -lcrmcommon +endif + clean-generic: rm -f *.log *.debug *.xml *~ diff -Nur pacemaker.orig/tools/notifyServicelogEvent.c pacemaker.mark/tools/notifyServicelogEvent.c --- pacemaker.orig/tools/notifyServicelogEvent.c 1969-12-31 18:00:00.000000000 -0600 +++ pacemaker.mark/tools/notifyServicelogEvent.c 2009-06-09 14:08:50.000000000 -0500 @@ -0,0 +1,182 @@ +/* + * Copyright (C) 2009 International Business Machines, IBM, Mark Hamzy + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* gcc -o notifyServicelogEvent `pkg-config --cflags servicelog-1` `pkg-config --libs servicelog-1` notifyServicelogEvent.c +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum {STATUS_GREEN = 1, STATUS_YELLOW, STATUS_RED} STATUS; + +const char * status2char (STATUS status); +STATUS event2status (struct sl_event *event); + +const char * +status2char (STATUS status) +{ + switch (status) + { + default: + case STATUS_GREEN: + return "green"; + case STATUS_YELLOW: + return "yellow"; + case STATUS_RED: + return "red"; + } +} + +STATUS +event2status (struct sl_event *event) +{ + STATUS status = STATUS_GREEN; + + syslog (LOG_DEBUG, "Severity = %d, Disposition = %d\n", event->severity, event->disposition); + + /* @TBD */ + if (event->severity == SL_SEV_WARNING) + { + status = STATUS_YELLOW; + } + + if (event->disposition == SL_DISP_UNRECOVERABLE) + { + status = STATUS_RED; + } + + return status; +} + +int +main (int argc, char *argv[]) +{ + int rc = 0; + servicelog *slog = NULL; + struct sl_event *event = NULL; + uint64_t event_id = 0; + + openlog ("notifyServicelogEvent", LOG_NDELAY, LOG_USER); + + if (argc != 2) + { + syslog (LOG_ERR, "Error: #args (%d) is not 2!\n", argc); + + rc = 1; + goto cleanup; + } + + if (sscanf (argv[1], U64T, &event_id) != 1) + { + syslog (LOG_ERR, "Error: could not read event_id from stdin!\n"); + + rc = 1; + goto cleanup; + } + + if (event_id == 0) + { + syslog (LOG_ERR, "Error: event_id is 0!\n"); + + rc = 1; + goto cleanup; + } + + rc = servicelog_open (&slog, 0); /* flags is one of SL_FLAG_xxx */ + + if (!slog) + { + syslog (LOG_ERR, "Error: servicelog_open failed, rc = %d\n", rc); + + rc = 1; + goto cleanup; + } + + if (slog) + { + rc = servicelog_event_get (slog, event_id, &event); + } + + if (rc == 0) + { + STATUS status = STATUS_GREEN; + const char *health_component = "#health-ipmi"; + const char *health_status = NULL; + + syslog (LOG_INFO, + "Event id = "U64T", Log timestamp = %s, Event timestamp = %s\n", + event_id, + ctime (&(event->time_logged)), + ctime (&(event->time_event))); + + status = event2status (event); + + health_status = status2char (status); + + if (health_status) + { + gboolean rc; + + rc = attrd_update_no_mainloop (NULL, + 'v', + NULL, + health_component, + health_status, + NULL, + NULL, + NULL); + + syslog (LOG_DEBUG, "attrd_update_no_mainloop ('%s', '%s') = %d\n", + health_component, + health_status, + rc); + } + else + { + syslog (LOG_ERR, "Error: status2char failed, status = %d\n", status); + rc = 1; + } + } + else + { + syslog (LOG_ERR, "Error: servicelog_event_get failed, rc = %d\n", rc); + } + +cleanup: + if (event) + { + servicelog_event_free (event); + } + + if (slog) + { + servicelog_close (slog); + } + + closelog (); + + return rc; +}