[Debian-ha-commits] [sbd] 01/09: New upstream version 1.3.1
Valentin Vidic
vvidic-guest at moszumanska.debian.org
Thu Nov 9 10:41:26 UTC 2017
This is an automated email from the git hooks/post-receive script.
vvidic-guest pushed a commit to branch master
in repository sbd.
commit 0c55a699f0dfed929568d947b7dbf1f29494cea7
Author: Valentin Vidic <Valentin.Vidic at CARNet.hr>
Date: Wed Nov 8 21:16:08 2017 +0100
New upstream version 1.3.1
---
.travis.yml | 25 ++++
agent/{sbd => sbd.in} | 6 +-
configure.ac | 27 +++-
man/sbd.8.pod | 7 +-
sbd.spec | 14 +-
src/sbd-cluster.c | 166 ++++++++++++++++++++--
src/sbd-common.c | 346 +++++++++++++++++++++++++++++++++++++++++-----
src/sbd-inquisitor.c | 122 ++++++++++------
src/sbd-md.c | 58 +++-----
src/sbd.h | 14 +-
src/sbd.service.in | 4 +-
src/{sbd.sh => sbd.sh.in} | 2 +-
src/sbd_remote.service.in | 8 +-
tests/regressions.sh | 5 +-
14 files changed, 653 insertions(+), 151 deletions(-)
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..bae79a9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,25 @@
+sudo: required
+language: c
+
+env:
+ global:
+ - DOCKER_BUILD_IMAGE=alectolytic/rpmbuilder
+ - OS_ARCH=x86_64
+ - PACKAGE=sbd
+ matrix:
+ - OS_TYPE=centos OS_DIST=epel OS_VERSION=7
+ - OS_TYPE=centos OS_DIST=epel OS_VERSION=6
+
+services:
+ - docker
+
+install: true
+
+script:
+ - make -f Makefile.am spec export PACKAGE=${PACKAGE}
+ - docker pull ${DOCKER_BUILD_IMAGE}:${OS_TYPE}-${OS_VERSION}
+ - docker run -v ${PWD}:/sources -v ${PWD}:/output ${DOCKER_BUILD_IMAGE}:${OS_TYPE}-${OS_VERSION}
+ - ls ${PWD}/sbd*.${OS_ARCH}.rpm
+ - docker pull ${OS_TYPE}:${OS_TYPE}${OS_VERSION}
+ - docker run --privileged -v ${PWD}:/rpms -v ${PWD}/tests:/tests ${OS_TYPE}:${OS_TYPE}${OS_VERSION} /bin/bash -c "yum install -y device-mapper /rpms/${PACKAGE}*.${OS_ARCH}.rpm && /tests/regressions.sh && touch /rpms/regressions.sh.SUCCESS"
+ - ls ${PWD}/regressions.sh.SUCCESS
diff --git a/agent/sbd b/agent/sbd.in
similarity index 97%
rename from agent/sbd
rename to agent/sbd.in
index 5645213..4bc0245 100644
--- a/agent/sbd
+++ b/agent/sbd.in
@@ -22,8 +22,8 @@
# Main code
if [ -z "$sbd_device" ]; then
- if [ -f /etc/sysconfig/sbd ]; then
- source /etc/sysconfig/sbd
+ if [ -f @CONFIGDIR@/sbd ]; then
+ source @CONFIGDIR@/sbd
sbd_device=$SBD_DEVICE
fi
fi
@@ -150,7 +150,7 @@ The block device used for the SBD partition. Up to three
can be specified if separated by a semicolon. (Please check
the documentation if specifying two.)
-If not specified, will default to the value from /etc/sysconfig/sbd.
+If not specified, will default to the value from @CONFIGDIR@/sbd.
</longdesc>
</parameter>
diff --git a/configure.ac b/configure.ac
index a7e3e70..1eb8758 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,7 +20,7 @@ dnl checks for library functions
dnl checks for system services
AC_INIT([sbd],
- [1.3.0],
+ [1.3.1],
[lmb at suse.com])
AC_CANONICAL_HOST
AC_CONFIG_AUX_DIR(.)
@@ -32,6 +32,8 @@ AM_PROG_CC_C_O
PKG_CHECK_MODULES(glib, [glib-2.0])
dnl PKG_CHECK_MODULES(libcoroipcc, [libcoroipcc])
+PKG_CHECK_MODULES(cmap, [libcmap], HAVE_cmap=1, HAVE_cmap=0)
+
dnl pacemaker > 1.1.8
PKG_CHECK_MODULES(pacemaker, [pacemaker, pacemaker-cib], HAVE_pacemaker=1, HAVE_pacemaker=0)
@@ -44,6 +46,11 @@ if test $HAVE_pacemaker = 0 -a $HAVE_pcmk = 0; then
AC_MSG_ERROR(No package 'pacemaker' found)
elif test $HAVE_pacemaker = 1; then
CPPFLAGS="$CPPFLAGS $glib_CFLAGS $pacemaker_CFLAGS"
+ if test $HAVE_cmap = 0; then
+ AC_MSG_NOTICE(No package 'cmap' found)
+ else
+ CPPFLAGS="$CPPFLAGS $cmap_CFLAGS"
+ fi
fi
PKG_CHECK_MODULES(libxml, [libxml-2.0])
@@ -58,6 +65,7 @@ AC_CHECK_LIB(pe_status, pe_find_node, , missing="yes")
AC_CHECK_LIB(pe_rules, test_rule, , missing="yes")
AC_CHECK_LIB(crmcluster, crm_peer_init, , missing="yes")
AC_CHECK_LIB(uuid, uuid_unparse, , missing="yes")
+AC_CHECK_LIB(cmap, cmap_initialize, , HAVE_cmap=0)
dnl pacemaker >= 1.1.8
AC_CHECK_HEADERS(pacemaker/crm/cluster.h)
@@ -89,6 +97,16 @@ then
AC_DEFINE_UNQUOTED(HAVE_PROC_PID, 1, Define to 1 if /proc/{pid} is supported.)
fi
+AC_DEFINE_UNQUOTED(CHECK_TWO_NODE, $HAVE_cmap, Turn on checking for 2-node cluster)
+AM_CONDITIONAL(CHECK_TWO_NODE, test "$HAVE_cmap" = "1")
+
+CONFIGDIR=""
+AC_ARG_WITH(configdir,
+ [ --with-configdir=DIR
+ Directory for SBD configuration file [${CONFIGDIR}]],
+ [ CONFIGDIR="$withval" ]
+)
+
dnl **********************************************************************
dnl Check for various argv[] replacing functions on various OSs
dnl
@@ -202,8 +220,13 @@ eval oldincludedir="`eval echo ${oldincludedir}`"
eval infodir="`eval echo ${infodir}`"
eval mandir="`eval echo ${mandir}`"
+if test x"${CONFIGDIR}" = x""; then
+ CONFIGDIR="${sysconfdir}/sysconfig"
+fi
+AC_SUBST(CONFIGDIR)
+
dnl The Makefiles and shell scripts we output
-AC_CONFIG_FILES([Makefile src/Makefile agent/Makefile man/Makefile src/sbd.service src/sbd_remote.service])
+AC_CONFIG_FILES([Makefile src/Makefile agent/Makefile man/Makefile agent/sbd src/sbd.service src/sbd_remote.service src/sbd.sh])
dnl Now process the entire list of files added by previous
dnl calls to AC_CONFIG_FILES()
diff --git a/man/sbd.8.pod b/man/sbd.8.pod
index b410a27..c1bf67a 100644
--- a/man/sbd.8.pod
+++ b/man/sbd.8.pod
@@ -62,7 +62,7 @@ Enable some verbose debug logging.
Display a concise summary of C<sbd> options.
-=item B<-c> I<node>
+=item B<-n> I<node>
Set local node name; defaults to C<uname -n>. This should not need to be
set.
@@ -267,7 +267,10 @@ If set to zero, processes will be restarted indefinitely and immediately.
=item B<-P>
-Check Pacemaker quorum and node health.
+Enable Pacemaker integration which checks Pacemaker quorum and node health.
+Specify this once to enable, twice to disable.
+
+Defaults to I<enabled>.
=item B<-S> I<N>
diff --git a/sbd.spec b/sbd.spec
index e643c53..e016579 100644
--- a/sbd.spec
+++ b/sbd.spec
@@ -15,7 +15,7 @@
# Please submit bugfixes or comments via http://bugs.opensuse.org/
#
-%global commit 4ee36fa33b57a1ad95678363911cfb02a92e1edb
+%global commit a180176c23e57ee904ebb08ab449cfb3d90a0383
%global shortcommit %(c=%{commit}; echo ${c:0:7})
%global github_owner beekhof
%global buildnum 1
@@ -24,7 +24,7 @@ Name: sbd
Summary: Storage-based death
License: GPLv2+
Group: System Environment/Daemons
-Version: 1.3.0
+Version: 1.3.1
Release: 0.%{buildnum}.%{shortcommit}.git%{?dist}
Url: https://github.com/%{github_owner}/%{name}
Source0: https://github.com/%{github_owner}/%{name}/archive/%{commit}/%{name}-%{commit}.tar.gz
@@ -41,6 +41,7 @@ BuildRequires: libuuid-devel
BuildRequires: libxml2-devel
BuildRequires: pkgconfig
BuildRequires: python-devel
+BuildRequires: make
%if 0%{?rhel} > 0
ExclusiveArch: i686 x86_64 s390x
@@ -113,6 +114,15 @@ rm -rf %{buildroot}
%doc COPYING
%changelog
+* Fri Nov 3 2017 <klaus.wenninger at aon.at> - 1.3.1-0.1.a180176c.git
+- Add commands to test/query watchdogs
+- Allow 2-node-operation with a single shared-disk
+- Overhaul of the command-line options & config-file
+- Proper handling of off instead of reboot
+- Refactored disk-servant for more robust communication with parent
+- Fix config for Debian + configurable location of config
+- Fixes in sbd.sh - multiple SBD devices and others
+
* Sun Mar 26 2016 <klaus.wenninger at aon.at> - 1.3.0-0.1.4ee36fa3.git
- Changes since v1.2.0 like adding the possibility to have a
watchdog-only setup without shared-block-devices
diff --git a/src/sbd-cluster.c b/src/sbd-cluster.c
index 0ed56e7..de99d0c 100644
--- a/src/sbd-cluster.c
+++ b/src/sbd-cluster.c
@@ -33,6 +33,10 @@
#include <crm/cluster.h>
#include <crm/common/mainloop.h>
+#if CHECK_TWO_NODE
+#include <glib-unix.h>
+#endif
+
#include "sbd.h"
//undef SUPPORT_PLUGIN
@@ -48,6 +52,7 @@ static gboolean sbd_remote_check(gpointer user_data);
static long unsigned int find_pacemaker_remote(void);
static void sbd_membership_destroy(gpointer user_data);
+
#if SUPPORT_PLUGIN
static void
sbd_plugin_membership_dispatch(cpg_handle_t handle,
@@ -67,6 +72,55 @@ sbd_plugin_membership_dispatch(cpg_handle_t handle,
#endif
#if SUPPORT_COROSYNC
+
+static bool two_node = false;
+static bool ever_seen_both = false;
+static int cpg_membership_entries = -1;
+
+#if CHECK_TWO_NODE
+#include <corosync/cmap.h>
+
+static cmap_handle_t cmap_handle = 0;
+static cmap_track_handle_t track_handle = 0;
+static GSource *cmap_source = NULL;
+#endif
+
+void
+sbd_cpg_membership_health_update()
+{
+ if(cpg_membership_entries > 0) {
+ bool quorum_is_suspect =
+ (two_node && ever_seen_both && cpg_membership_entries == 1);
+
+ if (!quorum_is_suspect) {
+ set_servant_health(pcmk_health_online, LOG_INFO,
+ "Connected to %s (%u members)",
+ name_for_cluster_type(get_cluster_type()),
+ cpg_membership_entries
+ );
+ } else {
+ /* Alternative would be asking votequorum for number of votes.
+ * Using pacemaker's cpg as source for number of active nodes
+ * avoids binding to an additional library, is definitely
+ * less code to write and we wouldn't have to combine data
+ * from 3 sources (cmap, cpq & votequorum) in a potentially
+ * racy environment.
+ */
+ set_servant_health(pcmk_health_noquorum, LOG_WARNING,
+ "Connected to %s but requires both nodes present",
+ name_for_cluster_type(get_cluster_type())
+ );
+ }
+
+ if (cpg_membership_entries > 1) {
+ ever_seen_both = true;
+ }
+ } else {
+ set_servant_health(pcmk_health_unclean, LOG_WARNING,
+ "Empty %s membership", name_for_cluster_type(get_cluster_type()));
+ }
+}
+
void
sbd_cpg_membership_dispatch(cpg_handle_t handle,
const struct cpg_name *groupName,
@@ -74,16 +128,104 @@ sbd_cpg_membership_dispatch(cpg_handle_t handle,
const struct cpg_address *left_list, size_t left_list_entries,
const struct cpg_address *joined_list, size_t joined_list_entries)
{
- if(member_list_entries > 0) {
- set_servant_health(pcmk_health_online, LOG_INFO,
- "Connected to %s", name_for_cluster_type(get_cluster_type()));
+ cpg_membership_entries = member_list_entries;
+ sbd_cpg_membership_health_update();
+ notify_parent();
+}
+
+#if CHECK_TWO_NODE
+static void sbd_cmap_notify_fn(
+ cmap_handle_t cmap_handle,
+ cmap_track_handle_t cmap_track_handle,
+ int32_t event,
+ const char *key_name,
+ struct cmap_notify_value new_val,
+ struct cmap_notify_value old_val,
+ void *user_data)
+{
+ if (new_val.type == CMAP_VALUETYPE_UINT8) {
+ switch (event) {
+ case CMAP_TRACK_ADD:
+ case CMAP_TRACK_MODIFY:
+ two_node = *((uint8_t *) new_val.data);
+ break;
+ case CMAP_TRACK_DELETE:
+ two_node = false;
+ break;
+ default:
+ return;
+ }
+ sbd_cpg_membership_health_update();
+ notify_parent();
+ }
+}
+
+static gboolean
+cmap_dispatch_callback (gpointer user_data)
+{
+ cmap_dispatch(cmap_handle, CS_DISPATCH_ALL);
+ return TRUE;
+}
+
+static gboolean
+sbd_get_two_node(void)
+{
+ uint8_t two_node_u8 = 0;
+ int cmap_fd;
+
+ if (!track_handle) {
+ if (cmap_initialize(&cmap_handle) != CS_OK) {
+ cl_log(LOG_WARNING, "Cannot initialize CMAP service\n");
+ goto out;
+ }
+
+ if (cmap_track_add(cmap_handle, "quorum.two_node",
+ CMAP_TRACK_DELETE|CMAP_TRACK_MODIFY|CMAP_TRACK_ADD,
+ sbd_cmap_notify_fn, NULL, &track_handle) != CS_OK) {
+ cl_log(LOG_WARNING, "Failed adding CMAP tracker for 2Node-mode\n");
+ goto out;
+ }
+
+ /* add the tracker to mainloop */
+ if (cmap_fd_get(cmap_handle, &cmap_fd) != CS_OK) {
+ cl_log(LOG_WARNING, "Failed to get a file handle for cmap\n");
+ goto out;
+ }
+
+ if (!(cmap_source = g_unix_fd_source_new (cmap_fd, G_IO_IN))) {
+ cl_log(LOG_WARNING, "Couldn't create source for cmap\n");
+ goto out;
+ }
+ g_source_set_callback(cmap_source, cmap_dispatch_callback, NULL, NULL);
+ g_source_attach(cmap_source, NULL);
+ }
+
+ if (cmap_get_uint8(cmap_handle, "quorum.two_node", &two_node_u8) == CS_OK) {
+ cl_log(LOG_NOTICE, "Corosync is%s in 2Node-mode", two_node_u8?"":" not");
+ two_node = two_node_u8;
} else {
- set_servant_health(pcmk_health_unclean, LOG_WARNING,
- "Empty %s membership", name_for_cluster_type(get_cluster_type()));
+ cl_log(LOG_NOTICE, "quorum.two_node present in cmap\n");
}
- notify_parent();
+ return TRUE;
+
+out:
+ if (cmap_source) {
+ g_source_destroy(cmap_source);
+ cmap_source = NULL;
+ }
+ if (track_handle) {
+ cmap_track_delete(cmap_handle, track_handle);
+ track_handle = 0;
+ }
+ if (cmap_handle) {
+ cmap_finalize(cmap_handle);
+ cmap_handle = 0;
+ }
+
+ return FALSE;
}
#endif
+#endif
static gboolean
notify_timer_cb(gpointer data)
@@ -143,9 +285,17 @@ sbd_membership_connect(void)
} else {
cl_log(LOG_INFO, "Attempting connection to %s", name_for_cluster_type(stack));
- if(crm_cluster_connect(&cluster)) {
- connected = true;
+#if SUPPORT_COROSYNC && CHECK_TWO_NODE
+ if (sbd_get_two_node()) {
+#endif
+
+ if(crm_cluster_connect(&cluster)) {
+ connected = true;
+ }
+
+#if SUPPORT_COROSYNC && CHECK_TWO_NODE
}
+#endif
}
if(connected == false) {
diff --git a/src/sbd-common.c b/src/sbd-common.c
index 0f3fd62..803bc3a 100644
--- a/src/sbd-common.c
+++ b/src/sbd-common.c
@@ -19,7 +19,10 @@
#include "sbd.h"
#include <sys/reboot.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <pwd.h>
+#include <unistd.h>
+#include <dirent.h>
#ifdef _POSIX_MEMLOCK
# include <sys/mman.h>
@@ -46,6 +49,7 @@ int skip_rt = 0;
int debug = 0;
int debug_mode = 0;
char *watchdogdev = NULL;
+bool watchdogdev_is_default = false;
char * local_uname;
/* Global, non-tunable variables: */
@@ -102,35 +106,53 @@ usage(void)
" Writes the specified message to node's slot.\n"
#endif
"watch Loop forever, monitoring own slot\n"
+"query-watchdog Check for available watchdog-devices and print some info\n"
+"test-watchdog Test the watchdog-device selected.\n"
+" Attention: This will arm the watchdog and have your system reset\n"
+" in case your watchdog is working properly!\n"
, cmdname);
}
+static int
+watchdog_init_interval_fd(int wdfd, int timeout)
+{
+ if (ioctl(wdfd, WDIOC_SETTIMEOUT, &timeout) < 0) {
+ cl_perror( "WDIOC_SETTIMEOUT"
+ ": Failed to set watchdog timer to %u seconds.",
+ timeout);
+ cl_log(LOG_CRIT, "Please validate your watchdog configuration!");
+ cl_log(LOG_CRIT, "Choose a different watchdog driver or specify -T to skip this if you are completely sure.");
+ return -1;
+ }
+ return 0;
+}
+
int
watchdog_init_interval(void)
{
- int timeout = timeout_watchdog;
-
if (watchdogfd < 0) {
return 0;
}
-
if (watchdog_set_timeout == 0) {
cl_log(LOG_INFO, "NOT setting watchdog timeout on explicit user request!");
return 0;
}
- if (ioctl(watchdogfd, WDIOC_SETTIMEOUT, &timeout) < 0) {
- cl_perror( "WDIOC_SETTIMEOUT"
- ": Failed to set watchdog timer to %u seconds.",
- timeout);
- cl_log(LOG_CRIT, "Please validate your watchdog configuration!");
- cl_log(LOG_CRIT, "Choose a different watchdog driver or specify -T to skip this if you are completely sure.");
+ if (watchdog_init_interval_fd(watchdogfd, timeout_watchdog) < 0) {
return -1;
- } else {
- cl_log(LOG_INFO, "Set watchdog timeout to %u seconds.",
- timeout);
}
+ cl_log(LOG_INFO, "Set watchdog timeout to %u seconds.", (int) timeout_watchdog);
+ return 0;
+}
+
+static int
+watchdog_tickle_fd(int wdfd, char *wddev)
+{
+ if (write(wdfd, "", 1) != 1) {
+ cl_perror("Watchdog write failure: %s!", wddev);
+ return -1;
+ }
return 0;
}
@@ -138,67 +160,284 @@ int
watchdog_tickle(void)
{
if (watchdogfd >= 0) {
- if (write(watchdogfd, "", 1) != 1) {
- cl_perror("Watchdog write failure: %s!",
- watchdogdev);
+ return watchdog_tickle_fd(watchdogfd, watchdogdev);
+ }
+ return 0;
+}
+
+static int
+watchdog_init_fd(char *wddev, int timeout)
+{
+ int wdfd;
+
+ wdfd = open(wddev, O_WRONLY);
+ if (wdfd >= 0) {
+ if (((timeout >= 0) && (watchdog_init_interval_fd(wdfd, timeout) < 0))
+ || (watchdog_tickle_fd(wdfd, wddev) < 0)) {
+ close(wdfd);
return -1;
}
+ } else {
+ cl_perror("Cannot open watchdog device '%s'", wddev);
+ return -1;
}
- return 0;
+ return wdfd;
}
int
watchdog_init(void)
{
if (watchdogfd < 0 && watchdogdev != NULL) {
- watchdogfd = open(watchdogdev, O_WRONLY);
+ int timeout = timeout_watchdog;
+
+ if (watchdog_set_timeout == 0) {
+ cl_log(LOG_INFO, "NOT setting watchdog timeout on explicit user request!");
+ timeout = -1;
+ }
+ watchdogfd = watchdog_init_fd(watchdogdev, timeout);
if (watchdogfd >= 0) {
cl_log(LOG_NOTICE, "Using watchdog device '%s'", watchdogdev);
- if ((watchdog_init_interval() < 0)
- || (watchdog_tickle() < 0)) {
- return -1;
+ if (watchdog_set_timeout) {
+ cl_log(LOG_INFO, "Set watchdog timeout to %u seconds.", (int) timeout_watchdog);
}
- }else{
- cl_perror("Cannot open watchdog device '%s'", watchdogdev);
+ } else {
return -1;
}
}
return 0;
}
-void
-watchdog_close(bool disarm)
+static void
+watchdog_close_fd(int wdfd, char *wddev, bool disarm)
{
- if (watchdogfd < 0) {
- return;
- }
-
if (disarm) {
int r;
int flags = WDIOS_DISABLECARD;;
/* Explicitly disarm it */
- r = ioctl(watchdogfd, WDIOC_SETOPTIONS, &flags);
+ r = ioctl(wdfd, WDIOC_SETOPTIONS, &flags);
if (r < 0) {
- cl_perror("Failed to disable hardware watchdog %s", watchdogdev);
+ cl_perror("Failed to disable hardware watchdog %s", wddev);
}
/* To be sure, use magic close logic, too */
for (;;) {
- if (write(watchdogfd, "V", 1) > 0) {
+ if (write(wdfd, "V", 1) > 0) {
break;
}
- cl_perror("Cannot disable watchdog device %s", watchdogdev);
+ cl_perror("Cannot disable watchdog device %s", wddev);
}
}
- if (close(watchdogfd) < 0) {
- cl_perror("Watchdog close(%d) failed", watchdogfd);
+ if (close(wdfd) < 0) {
+ cl_perror("Watchdog close(%d) failed", wdfd);
}
+}
+void
+watchdog_close(bool disarm)
+{
+ if (watchdogfd < 0) {
+ return;
+ }
+
+ watchdog_close_fd(watchdogfd, watchdogdev, disarm);
watchdogfd = -1;
}
+#define MAX_WATCHDOGS 64
+#define SYS_CLASS_WATCHDOG "/sys/class/watchdog"
+#define SYS_CHAR_DEV_DIR "/sys/dev/char"
+#define WATCHDOG_NODEDIR "/dev"
+
+struct watchdog_list_item {
+ dev_t dev;
+ char *dev_node;
+ char *dev_ident;
+ char *dev_driver;
+ struct watchdog_list_item *next;
+};
+
+static struct watchdog_list_item *watchdog_list = NULL;
+static int watchdog_list_items = 0;
+
+static void
+watchdog_populate_list(void)
+{
+ dev_t watchdogs[MAX_WATCHDOGS + 1] =
+ {makedev(10,130), 0};
+ int num_watchdogs = 1;
+ struct dirent *entry;
+ char entry_name[64];
+ DIR *dp;
+ char buf[256] = "";
+
+ if (watchdog_list != NULL) {
+ return;
+ }
+
+ /* get additional devices from /sys/class/watchdog */
+ dp = opendir(SYS_CLASS_WATCHDOG);
+ if (dp) {
+ while ((entry = readdir(dp))) {
+ if (entry->d_type == DT_LNK) {
+ FILE *file;
+
+ snprintf(entry_name, sizeof(entry_name),
+ SYS_CLASS_WATCHDOG "/%s/dev", entry->d_name);
+ file = fopen(entry_name, "r");
+ if (file) {
+ int major, minor;
+
+ if (fscanf(file, "%d:%d", &major, &minor) == 2) {
+ watchdogs[num_watchdogs++] = makedev(major, minor);
+ }
+ fclose(file);
+ if (num_watchdogs == MAX_WATCHDOGS) {
+ break;
+ }
+ }
+ }
+ }
+ closedir(dp);
+ }
+
+ /* search for watchdog nodes in /dev */
+ dp = opendir(WATCHDOG_NODEDIR);
+ if (dp) {
+ while ((entry = readdir(dp))) {
+ if ((entry->d_type == DT_CHR) || (entry->d_type == DT_LNK)) {
+ struct stat statbuf;
+
+ snprintf(entry_name, sizeof(entry_name),
+ WATCHDOG_NODEDIR "/%s", entry->d_name);
+ if(!stat(entry_name, &statbuf) && S_ISCHR(statbuf.st_mode)) {
+ int i;
+
+ for (i=0; i<num_watchdogs; i++) {
+ if (statbuf.st_rdev == watchdogs[i]) {
+ int wdfd = watchdog_init_fd(entry_name, -1);
+ struct watchdog_list_item *wdg =
+ calloc(1, sizeof(struct watchdog_list_item));
+
+ wdg->dev = watchdogs[i];
+ wdg->dev_node = strdup(entry_name);
+ wdg->next = watchdog_list;
+ watchdog_list = wdg;
+ watchdog_list_items++;
+
+ if (wdfd >= 0) {
+ struct watchdog_info ident;
+
+ ident.identity[0] = '\0';
+ ioctl(wdfd, WDIOC_GETSUPPORT, &ident);
+ watchdog_close_fd(wdfd, entry_name, true);
+ if (ident.identity[0]) {
+ wdg->dev_ident = strdup((char *) ident.identity);
+ }
+ }
+
+ snprintf(entry_name, sizeof(entry_name),
+ SYS_CHAR_DEV_DIR "/%d:%d/device/driver",
+ major(watchdogs[i]), minor(watchdogs[i]));
+ if (readlink(entry_name, buf, sizeof(buf)) > 0) {
+ wdg->dev_driver = strdup(basename(buf));
+ } else if ((wdg->dev_ident) &&
+ (strcmp(wdg->dev_ident,
+ "Software Watchdog") == 0)) {
+ wdg->dev_driver = strdup("softdog");
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ closedir(dp);
+ }
+}
+
+int watchdog_info(void)
+{
+ struct watchdog_list_item *wdg;
+ int wdg_cnt = 0;
+
+ watchdog_populate_list();
+ printf("\nDiscovered %d watchdog devices:\n", watchdog_list_items);
+ for (wdg = watchdog_list; wdg != NULL; wdg = wdg->next) {
+ wdg_cnt++;
+ printf("\n[%d] %s\nIdentity: %s\nDriver: %s\n",
+ wdg_cnt, wdg->dev_node,
+ wdg->dev_ident?wdg->dev_ident:"Error: Check if hogged by e.g. sbd-daemon!",
+ wdg->dev_driver?wdg->dev_driver:"<unknown>");
+ if ((wdg->dev_driver) && (strcmp(wdg->dev_driver, "softdog") == 0)) {
+ printf("CAUTION: Not recommended for use with sbd.\n");
+ }
+ }
+
+ return 0;
+}
+
+int watchdog_test(void)
+{
+ int i;
+
+ if ((watchdog_set_timeout == 0) || !watchdog_use) {
+ printf("\nWatchdog is disabled - aborting test!!!\n");
+ return 0;
+ }
+ if (watchdogdev_is_default) {
+ watchdog_populate_list();
+ if (watchdog_list_items > 1) {
+ printf("\nError: Multiple watchdog devices discovered.\n"
+ " Use -w <watchdog> or SBD_WATCHDOG_DEV to specify\n"
+ " which device to reset the system with\n");
+ watchdog_info();
+ return -1;
+ }
+ }
+ if ((isatty(fileno(stdin)))) {
+ char buffer[16];
+ printf("\nWARNING: This operation is expected to force-reboot this system\n"
+ " without following any shutdown procedures.\n\n"
+ "Proceed? [NO/Proceed] ");
+
+ if ((fgets(buffer, 16, stdin) == NULL) ||
+ strcmp(buffer, "Proceed\n")) {
+ printf("\nAborting watchdog test!!!\n");
+ return 0;
+ }
+ printf("\n");
+ }
+ printf("Initializing %s with a reset countdown of %d seconds ...\n",
+ watchdogdev, (int) timeout_watchdog);
+ if ((watchdog_init() < 0) || (watchdog_init_interval() < 0)) {
+ printf("Failed to initialize watchdog!!!\n");
+ return -1;
+ }
+ printf("\n");
+ printf("NOTICE: The watchdog device is expected to reset the system\n"
+ " in %d seconds. If system remains active beyond that time,\n"
+ " watchdog may not be functional.\n\n", (int) timeout_watchdog);
+ for (i=timeout_watchdog; i>1; i--) {
+ printf("Reset countdown ... %d seconds\n", i);
+ sleep(1);
+ }
+ for (i=2; i>0; i--) {
+ printf("System expected to reset any moment ...\n");
+ sleep(1);
+ }
+ for (i=5; i>0; i--) {
+ printf("System should have reset ...\n");
+ sleep(1);
+ }
+ printf("Error: The watchdog device has failed to reboot the system,\n"
+ " and it may not be suitable for usage with sbd.\n");
+
+ /* test should trigger a reboot thus returning is actually bad */
+ return -1;
+}
+
/* This duplicates some code from linux/ioprio.h since these are not included
* even in linux-kernel-headers. Sucks. See also
* /usr/src/linux/Documentation/block/ioprio.txt and ioprio_set(2) */
@@ -487,10 +726,8 @@ do_exit(char kind)
} else {
watchdog_close(false);
sysrq_trigger(kind);
- if (kind != 'o') {
- if(reboot(RB_AUTOBOOT) < 0) {
- cl_perror("Reboot failed");
- }
+ if (reboot((kind == 'o')?RB_POWER_OFF:RB_AUTOBOOT) < 0) {
+ cl_perror("%s failed", (kind == 'o')?"Poweroff":"Reboot");
}
}
@@ -696,3 +933,36 @@ set_servant_health(enum pcmk_health state, int level, char const *format, ...)
free(string);
}
}
+
+bool
+sbd_is_disk(struct servants_list_item *servant)
+{
+ if ((servant != NULL) &&
+ (servant->devname != NULL) &&
+ (servant->devname[0] == '/')) {
+ return true;
+ }
+ return false;
+}
+
+bool
+sbd_is_cluster(struct servants_list_item *servant)
+{
+ if ((servant != NULL) &&
+ (servant->devname != NULL) &&
+ (strcmp("cluster", servant->devname) == 0)) {
+ return true;
+ }
+ return false;
+}
+
+bool
+sbd_is_pcmk(struct servants_list_item *servant)
+{
+ if ((servant != NULL) &&
+ (servant->devname != NULL) &&
+ (strcmp("pcmk", servant->devname) == 0)) {
+ return true;
+ }
+ return false;
+}
diff --git a/src/sbd-inquisitor.c b/src/sbd-inquisitor.c
index 3c3a5a0..59408b3 100644
--- a/src/sbd-inquisitor.c
+++ b/src/sbd-inquisitor.c
@@ -23,8 +23,8 @@
static struct servants_list_item *servants_leader = NULL;
int disk_priority = 1;
-int check_pcmk = 0;
-int check_cluster = 0;
+int check_pcmk = 1;
+int check_cluster = 1;
int disk_count = 0;
int servant_count = 0;
int servant_restart_interval = 5;
@@ -34,17 +34,6 @@ char* pidfile = NULL;
int parse_device_line(const char *line);
-bool
-sbd_is_disk(struct servants_list_item *servant)
-{
- if (servant == NULL
- || servant->devname == NULL
- || servant->devname[0] == '/') {
- return true;
- }
- return false;
-}
-
void recruit_servant(const char *devname, pid_t pid)
{
struct servants_list_item *s = servants_leader;
@@ -162,11 +151,11 @@ void servant_start(struct servants_list_item *s)
cl_log(LOG_ERR, "Shared disk functionality not supported");
return;
#endif
- } else if(strcmp("pcmk", s->devname) == 0) {
+ } else if(sbd_is_pcmk(s)) {
DBGLOG(LOG_INFO, "Starting Pacemaker servant");
s->pid = assign_servant(s->devname, servant_pcmk, start_mode, NULL);
- } else if(strcmp("cluster", s->devname) == 0) {
+ } else if(sbd_is_cluster(s)) {
DBGLOG(LOG_INFO, "Starting Cluster servant");
s->pid = assign_servant(s->devname, servant_cluster, start_mode, NULL);
@@ -401,7 +390,7 @@ int cluster_alive(bool all)
}
for (s = servants_leader; s; s = s->next) {
- if (sbd_is_disk(s) == false) {
+ if (sbd_is_cluster(s) || sbd_is_pcmk(s)) {
if(s->outdated) {
alive = 0;
} else if(all == false) {
@@ -454,7 +443,6 @@ void inquisitor_child(void)
sigaddset(&procmask, SIG_LIVENESS);
sigaddset(&procmask, SIG_EXITREQ);
sigaddset(&procmask, SIG_TEST);
- sigaddset(&procmask, SIG_IO_FAIL);
sigaddset(&procmask, SIG_PCMK_UNHEALTHY);
sigaddset(&procmask, SIG_RESTART);
sigaddset(&procmask, SIGUSR1);
@@ -485,28 +473,44 @@ void inquisitor_child(void)
if (pid == -1 && errno == ECHILD) {
break;
} else {
+ s = lookup_servant_by_pid(pid);
+ if (sbd_is_disk(s)) {
+ if (WIFEXITED(status)) {
+ switch(WEXITSTATUS(status)) {
+ case EXIT_MD_IO_FAIL:
+ DBGLOG(LOG_INFO, "Servant for %s requests to be disowned",
+ s->devname);
+ break;
+ case EXIT_MD_REQUEST_RESET:
+ cl_log(LOG_WARNING, "%s requested a reset", s->devname);
+ do_reset();
+ break;
+ case EXIT_MD_REQUEST_SHUTOFF:
+ cl_log(LOG_WARNING, "%s requested a shutoff", s->devname);
+ do_off();
+ break;
+ case EXIT_MD_REQUEST_CRASHDUMP:
+ cl_log(LOG_WARNING, "%s requested a crashdump", s->devname);
+ do_crashdump();
+ break;
+ default:
+ break;
+ }
+ }
+ }
cleanup_servant_by_pid(pid);
}
}
} else if (sig == SIG_PCMK_UNHEALTHY) {
s = lookup_servant_by_pid(sinfo.si_pid);
- if (sbd_is_disk(s)) {
- cl_log(LOG_WARNING, "Ignoring SIG_PCMK_UNHEALTHY from unknown source");
-
- } else {
- if(s->outdated == 0) {
- cl_log(LOG_WARNING, "%s health check: UNHEALTHY", s->devname);
- }
- s->t_last.tv_sec = 1;
- }
-
- } else if (sig == SIG_IO_FAIL) {
- s = lookup_servant_by_pid(sinfo.si_pid);
- if (s) {
- DBGLOG(LOG_INFO, "Servant for %s requests to be disowned",
- s->devname);
- cleanup_servant_by_pid(sinfo.si_pid);
- }
+ if (sbd_is_cluster(s) || sbd_is_pcmk(s)) {
+ if (s->outdated == 0) {
+ cl_log(LOG_WARNING, "%s health check: UNHEALTHY", s->devname);
+ }
+ s->t_last.tv_sec = 1;
+ } else {
+ cl_log(LOG_WARNING, "Ignoring SIG_PCMK_UNHEALTHY from unknown source");
+ }
} else if (sig == SIG_LIVENESS) {
s = lookup_servant_by_pid(sinfo.si_pid);
if (s) {
@@ -799,11 +803,19 @@ parse_device_line(const char *line)
return found;
}
+int
+arg_enabled(int arg_count)
+{
+ return arg_count % 2;
+}
+
int main(int argc, char **argv, char **envp)
{
int exit_status = 0;
int c;
- int w = 0;
+ int W_count = 0;
+ int c_count = 0;
+ int P_count = 0;
int qb_facility;
const char *value = NULL;
int start_delay = 0;
@@ -815,6 +827,7 @@ int main(int argc, char **argv, char **envp)
}
watchdogdev = strdup("/dev/watchdog");
+ watchdogdev_is_default = true;
qb_facility = qb_log_facility2int("daemon");
qb_log_init(cmdname, qb_facility, LOG_WARNING);
sbd_set_format_string(QB_LOG_SYSLOG, "sbd");
@@ -860,6 +873,14 @@ int main(int argc, char **argv, char **envp)
if(value) {
free(watchdogdev);
watchdogdev = strdup(value);
+ watchdogdev_is_default = false;
+ }
+
+ /* SBD_WATCHDOG has been dropped from sbd.sysconfig example.
+ * This is for backward compatibility. */
+ value = getenv("SBD_WATCHDOG");
+ if(value) {
+ watchdog_use = crm_is_true(value);
}
value = getenv("SBD_WATCHDOG_TIMEOUT");
@@ -921,12 +942,13 @@ int main(int argc, char **argv, char **envp)
cl_log(LOG_INFO, "Setting watchdog timeout disabled; using defaults.");
break;
case 'W':
- w++;
+ W_count++;
break;
case 'w':
cl_log(LOG_NOTICE, "Using watchdog device '%s'", watchdogdev);
free(watchdogdev);
watchdogdev = strdup(optarg);
+ watchdogdev_is_default = false;
break;
case 'd':
#if SUPPORT_SHARED_DISK
@@ -938,10 +960,10 @@ int main(int argc, char **argv, char **envp)
#endif
break;
case 'c':
- check_cluster = 1;
+ c_count++;
break;
case 'P':
- check_pcmk = 1;
+ P_count++;
break;
case 'z':
disk_priority = 0;
@@ -1004,11 +1026,11 @@ int main(int argc, char **argv, char **envp)
}
}
- if (w > 0) {
- watchdog_use = w % 2;
-
- } else if(watchdogdev == NULL || strcmp(watchdogdev, "/dev/null") == 0) {
+ if (watchdogdev == NULL || strcmp(watchdogdev, "/dev/null") == 0) {
watchdog_use = 0;
+
+ } else if (W_count > 0) {
+ watchdog_use = arg_enabled(W_count);
}
if (watchdog_use) {
@@ -1017,6 +1039,14 @@ int main(int argc, char **argv, char **envp)
cl_log(LOG_INFO, "Watchdog disabled.");
}
+ if (c_count > 0) {
+ check_cluster = arg_enabled(c_count);
+ }
+
+ if (P_count > 0) {
+ check_pcmk = arg_enabled(P_count);
+ }
+
if ((disk_count > 0) && (strlen(local_uname) > SECTOR_NAME_MAX)) {
fprintf(stderr, "Node name mustn't be longer than %d chars.\n",
SECTOR_NAME_MAX);
@@ -1079,8 +1109,12 @@ int main(int argc, char **argv, char **envp)
exit_status = -2;
}
#endif
-
- if (strcmp(argv[optind], "watch") == 0) {
+
+ if (strcmp(argv[optind], "query-watchdog") == 0) {
+ exit_status = watchdog_info();
+ } else if (strcmp(argv[optind], "test-watchdog") == 0) {
+ exit_status = watchdog_test();
+ } else if (strcmp(argv[optind], "watch") == 0) {
/* sleep $(sbd $SBD_DEVICE_ARGS dump | grep -m 1 msgwait | awk '{print $4}') 2>/dev/null */
/* We only want this to have an effect during watch right now;
diff --git a/src/sbd-md.c b/src/sbd-md.c
index 10b1925..54ac580 100644
--- a/src/sbd-md.c
+++ b/src/sbd-md.c
@@ -29,7 +29,6 @@
#define MBOX_TO_SECTOR(mbox) (2+mbox*2)
extern int disk_count;
-static int servant_inform_parent = 0;
/* These have to match the values in the header of the partition */
static char sbd_magic[8] = "SBD_SBD_";
@@ -833,7 +832,7 @@ int ping_via_slots(const char *name, struct servants_list_item *servants)
break;
} else {
s = lookup_servant_by_pid(pid);
- if (s && sbd_is_disk(s)) {
+ if (sbd_is_disk(s)) {
servants_finished++;
}
}
@@ -1025,20 +1024,6 @@ static int servant_check_timeout_inconsistent(struct sector_header_s *hdr)
return 0;
}
-/* This is a bit hackish, but the easiest way to rewire all process
- * exits to send the desired signal to the parent. */
-void servant_exit(void)
-{
- pid_t ppid;
- union sigval signal_value;
-
- ppid = getppid();
- if (servant_inform_parent) {
- memset(&signal_value, 0, sizeof(signal_value));
- sigqueue(ppid, SIG_IO_FAIL, signal_value);
- }
-}
-
int servant(const char *diskname, int mode, const void* argp)
{
struct sector_mbox_s *s_mbox = NULL;
@@ -1072,24 +1057,21 @@ int servant(const char *diskname, int mode, const void* argp)
/* FIXME: check error */
sigprocmask(SIG_SETMASK, &servant_masks, NULL);
- atexit(servant_exit);
- servant_inform_parent = 1;
-
st = open_device(diskname, LOG_WARNING);
if (!st) {
- return -1;
+ exit(EXIT_MD_IO_FAIL);
}
s_header = header_get(st);
if (!s_header) {
cl_log(LOG_ERR, "Not a valid header on %s", diskname);
- return -1;
+ exit(EXIT_MD_IO_FAIL);
}
if (servant_check_timeout_inconsistent(s_header) < 0) {
cl_log(LOG_ERR, "Timeouts on %s do not match first device",
diskname);
- return -1;
+ exit(EXIT_MD_IO_FAIL);
}
if (s_header->minor_version > 0) {
@@ -1102,14 +1084,14 @@ int servant(const char *diskname, int mode, const void* argp)
cl_log(LOG_ERR,
"No slot allocated, and automatic allocation failed for disk %s.",
diskname);
- rc = -1;
+ rc = EXIT_MD_IO_FAIL;
goto out;
}
s_node = sector_alloc();
if (slot_read(st, mbox, s_node) < 0) {
cl_log(LOG_ERR, "Unable to read node entry on %s",
diskname);
- exit(1);
+ exit(EXIT_MD_IO_FAIL);
}
DBGLOG(LOG_INFO, "Monitoring slot %d on disk %s", mbox, diskname);
@@ -1125,7 +1107,7 @@ int servant(const char *diskname, int mode, const void* argp)
if (mode > 0) {
if (mbox_read(st, mbox, s_mbox) < 0) {
cl_log(LOG_ERR, "mbox read failed during start-up in servant.");
- rc = -1;
+ rc = EXIT_MD_IO_FAIL;
goto out;
}
if (s_mbox->cmd != SBD_MSG_EXIT &&
@@ -1141,7 +1123,7 @@ int servant(const char *diskname, int mode, const void* argp)
DBGLOG(LOG_INFO, "First servant start - zeroing inbox");
memset(s_mbox, 0, sizeof(*s_mbox));
if (mbox_write(st, mbox, s_mbox) < 0) {
- rc = -1;
+ rc = EXIT_MD_IO_FAIL;
goto out;
}
}
@@ -1170,28 +1152,28 @@ int servant(const char *diskname, int mode, const void* argp)
s_header_retry = header_get(st);
if (!s_header_retry) {
cl_log(LOG_ERR, "No longer found a valid header on %s", diskname);
- exit(1);
+ exit(EXIT_MD_IO_FAIL);
}
if (memcmp(s_header, s_header_retry, sizeof(*s_header)) != 0) {
cl_log(LOG_ERR, "Header on %s changed since start-up!", diskname);
- exit(1);
+ exit(EXIT_MD_IO_FAIL);
}
free(s_header_retry);
s_node_retry = sector_alloc();
if (slot_read(st, mbox, s_node_retry) < 0) {
cl_log(LOG_ERR, "slot read failed in servant.");
- exit(1);
+ exit(EXIT_MD_IO_FAIL);
}
if (memcmp(s_node, s_node_retry, sizeof(*s_node)) != 0) {
cl_log(LOG_ERR, "Node entry on %s changed since start-up!", diskname);
- exit(1);
+ exit(EXIT_MD_IO_FAIL);
}
free(s_node_retry);
if (mbox_read(st, mbox, s_mbox) < 0) {
cl_log(LOG_ERR, "mbox read failed in servant.");
- exit(1);
+ exit(EXIT_MD_IO_FAIL);
}
if (s_mbox->cmd > 0) {
@@ -1206,17 +1188,14 @@ int servant(const char *diskname, int mode, const void* argp)
sigqueue(ppid, SIG_TEST, signal_value);
break;
case SBD_MSG_RESET:
- do_reset();
- break;
+ exit(EXIT_MD_REQUEST_RESET);
case SBD_MSG_OFF:
- do_off();
- break;
+ exit(EXIT_MD_REQUEST_SHUTOFF);
case SBD_MSG_EXIT:
sigqueue(ppid, SIG_EXITREQ, signal_value);
break;
case SBD_MSG_CRASHDUMP:
- do_crashdump();
- break;
+ exit(EXIT_MD_REQUEST_CRASHDUMP);
default:
/* FIXME:
An "unknown" message might result
@@ -1247,10 +1226,7 @@ int servant(const char *diskname, int mode, const void* argp)
out:
free(s_mbox);
close_device(st);
- if (rc == 0) {
- servant_inform_parent = 0;
- }
- return rc;
+ exit(rc);
}
diff --git a/src/sbd.h b/src/sbd.h
index 07a476d..0f8847a 100644
--- a/src/sbd.h
+++ b/src/sbd.h
@@ -50,10 +50,15 @@
#define SIG_EXITREQ (SIGRTMIN + 2) /* exit request to inquisitor */
#define SIG_TEST (SIGRTMIN + 3) /* trigger self test */
#define SIG_RESTART (SIGRTMIN + 4) /* trigger restart of all failed disk */
-#define SIG_IO_FAIL (SIGRTMIN + 5) /* the IO child requests to be considered failed */
-#define SIG_PCMK_UNHEALTHY (SIGRTMIN + 6)
+#define SIG_PCMK_UNHEALTHY (SIGRTMIN + 5)
/* FIXME: should add dynamic check of SIG_XX >= SIGRTMAX */
+/* exit status for disk-servant */
+#define EXIT_MD_IO_FAIL 20
+#define EXIT_MD_REQUEST_RESET 21
+#define EXIT_MD_REQUEST_SHUTOFF 22
+#define EXIT_MD_REQUEST_CRASHDUMP 23
+
#define HOG_CHAR 0xff
#define SECTOR_NAME_MAX 63
@@ -119,6 +124,8 @@ int watchdog_tickle(void);
int watchdog_init(void);
void sysrq_init(void);
void watchdog_close(bool disarm);
+int watchdog_info(void);
+int watchdog_test(void);
void sysrq_trigger(char t);
void do_crashdump(void);
void do_reset(void);
@@ -144,6 +151,7 @@ extern int skip_rt;
extern int debug;
extern int debug_mode;
extern char *watchdogdev;
+extern bool watchdogdev_is_default;
extern char* local_uname;
/* Global, non-tunable variables: */
@@ -191,3 +199,5 @@ extern int servant_health;
void set_servant_health(enum pcmk_health state, int level, char const *format, ...) __attribute__ ((__format__ (__printf__, 3, 4)));
bool sbd_is_disk(struct servants_list_item *servant);
+bool sbd_is_pcmk(struct servants_list_item *servant);
+bool sbd_is_cluster(struct servants_list_item *servant);
diff --git a/src/sbd.service.in b/src/sbd.service.in
index a7f4e7f..ef1bd16 100644
--- a/src/sbd.service.in
+++ b/src/sbd.service.in
@@ -9,8 +9,8 @@ RefuseManualStart=true
[Service]
Type=forking
PIDFile=@localstatedir@/run/sbd.pid
-EnvironmentFile=- at sysconfdir@/sysconfig/sbd
-ExecStart=@sbindir@/sbd $SBD_OPTS -p @localstatedir@/run/sbd.pid watch
+EnvironmentFile=- at CONFIGDIR@/sbd
+ExecStart=@sbindir@/sbd $SBD_OPTS -p @localstatedir@/run/sbd.pid watch
ExecStop=@bindir@/kill -TERM $MAINPID
# Could this benefit from exit codes for restart?
diff --git a/src/sbd.sh b/src/sbd.sh.in
similarity index 98%
rename from src/sbd.sh
rename to src/sbd.sh.in
index 35b0e92..386f89b 100644
--- a/src/sbd.sh
+++ b/src/sbd.sh.in
@@ -17,7 +17,7 @@
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
-SBD_CONFIG=/etc/sysconfig/sbd
+SBD_CONFIG=@CONFIGDIR@/sbd
SBD_BIN="/usr/sbin/sbd"
test -x $SBD_BIN || exit 1
diff --git a/src/sbd_remote.service.in b/src/sbd_remote.service.in
index 73eaa89..e05f80e 100644
--- a/src/sbd_remote.service.in
+++ b/src/sbd_remote.service.in
@@ -7,10 +7,10 @@ RefuseManualStart=true
[Service]
Type=forking
-PIDFile=/var/run/sbd.pid
-EnvironmentFile=-/etc/sysconfig/sbd
-ExecStart=/usr/sbin/sbd $SBD_OPTS -p /var/run/sbd.pid watch
-ExecStop=/usr/bin/kill -TERM $MAINPID
+PIDFile=@localstatedir@/run/sbd.pid
+EnvironmentFile=- at CONFIGDIR@/sbd
+ExecStart=@sbindir@/sbd $SBD_OPTS -p @localstatedir@/run/sbd.pid watch
+ExecStop=@bindir@/kill -TERM $MAINPID
# Could this benefit from exit codes for restart?
# Does this need to be set to msgwait * 1.2?
diff --git a/tests/regressions.sh b/tests/regressions.sh
index 9db1c15..4c531ae 100755
--- a/tests/regressions.sh
+++ b/tests/regressions.sh
@@ -36,6 +36,7 @@ sbd_setup() {
losetup ${L[$N]} ${F[$N]}
D[$N]="/dev/mapper/sbd_$N"
dmsetup create sbd_$N --table "0 2048 linear ${L[$N]} 0"
+ dmsetup mknodes sbd_$N
done
}
@@ -63,7 +64,7 @@ _ok() {
rc=$?
if [ $rc -ne 0 ]; then
echo "$@ failed with $rc"
- exit
+ exit $rc
fi
}
@@ -73,7 +74,7 @@ _no() {
rc=$?
if [ $rc -eq 0 ]; then
echo "$@ did NOT fail ($rc)"
- exit
+ exit $rc
fi
return 0
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-ha/sbd.git
More information about the Debian-HA-Commits
mailing list