Hello community, here is the log from the commit of package sbd for openSUSE:Factory checked in at 2019-11-06 13:56:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/sbd (Old) and /work/SRC/openSUSE:Factory/.sbd.new.2990 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "sbd" Wed Nov 6 13:56:40 2019 rev:32 rq:745168 version:1.4.0+20191029.695f9ca Changes: -------- --- /work/SRC/openSUSE:Factory/sbd/sbd.changes 2019-10-30 14:44:28.845969360 +0100 +++ /work/SRC/openSUSE:Factory/.sbd.new.2990/sbd.changes 2019-11-06 13:56:45.640199024 +0100 @@ -1,0 +2,23 @@ +Wed Oct 30 16:16:31 UTC 2019 - Yan Gao <[email protected]> + +- Update to version 1.4.0+20191029.695f9ca: +- tests: add regression-tests using preload-library +- tests: added preload-library for reboot interception + +------------------------------------------------------------------- +Wed Oct 30 16:14:40 UTC 2019 - Yan Gao <[email protected]> + +- Update to version 1.4.0+20191028.3f01a1d: +- spec: add devel package + +------------------------------------------------------------------- +Wed Oct 30 14:30:59 UTC 2019 - Yan Gao <[email protected]> + +- Update to version 1.4.0+20191028.d937f9d: +- sbd-inquisitor: use crashdump timeout +- Build: switch back to serial test-harness +- Doc: mention crashdump message in usage note +- defaults: make 15s timeout default for s390 consistently +- cmdline: just use SBD_DEVICE if no devs from cmdline + +------------------------------------------------------------------- Old: ---- sbd-1.4.0+20190919.2758632.tar.xz New: ---- sbd-1.4.0+20191029.695f9ca.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ sbd.spec ++++++ --- /var/tmp/diff_new_pack.tkjQut/_old 2019-11-06 13:56:46.884200333 +0100 +++ /var/tmp/diff_new_pack.tkjQut/_new 2019-11-06 13:56:46.888200337 +0100 @@ -23,7 +23,7 @@ %endif Name: sbd -Version: 1.4.0+20190919.2758632 +Version: 1.4.0+20191029.695f9ca Release: 0 Summary: Storage-based death License: GPL-2.0-or-later @@ -52,17 +52,33 @@ %description This package contains the storage-based death functionality. +%package devel +Summary: Storage-based death environment for regression tests +Group: Productivity/Clustering/HA +Requires: %{name} = %{version}-%{release} + +%description devel +This package provides an environment + testscripts for +regression-testing sbd. + %prep %autosetup -n %{name}-%{version} -p1 +%ifarch s390x s390 +sed -i src/sbd.sysconfig -e "s/Default: 5/Default: 15/" +sed -i src/sbd.sysconfig -e "s/SBD_WATCHDOG_TIMEOUT=5/SBD_WATCHDOG_TIMEOUT=15/" +%endif + %build -autoreconf -fvi +./autogen.sh + %configure make %{?_smp_mflags} %install %make_install LIBDIR=%{_libdir} install -D -m 0755 src/sbd.sh %{buildroot}%{_datadir}/sbd/sbd.sh +install -D -m 0755 tests/regressions.sh %{buildroot}%{_datadir}/sbd/regressions.sh install -D -m 0644 src/sbd.service %{buildroot}/%{_unitdir}/sbd.service install -D -m 0644 src/sbd_remote.service %{buildroot}/%{_unitdir}/sbd_remote.service ln -s service %{buildroot}%{_sbindir}/rcsbd @@ -70,6 +86,10 @@ mkdir -p %{buildroot}%{_fillupdir} install -m 0644 src/sbd.sysconfig %{buildroot}%{_fillupdir}/sysconfig.sbd +# Don't package static libs +find %{buildroot} -type f -name "*.a" -delete -print +find %{buildroot} -type f -name "*.la" -delete -print + %post %service_add_post sbd.service sbd_remote.service @@ -86,6 +106,9 @@ %postun %service_del_postun -n sbd.service sbd_remote.service +%post devel -p /sbin/ldconfig +%postun devel -p /sbin/ldconfig + %files %defattr(-,root,root) %{_libdir}/stonith/ @@ -93,10 +116,18 @@ %{_sbindir}/rcsbd %{_sbindir}/rcsbd_remote %{_datadir}/sbd +%exclude %{_datadir}/sbd/regressions.sh %{_mandir}/man8/sbd* %{_unitdir}/sbd.service %{_unitdir}/sbd_remote.service %{_fillupdir}/sysconfig.sbd %doc COPYING +%files devel +%defattr(-,root,root) +%dir %{_datadir}/sbd +%{_datadir}/sbd/regressions.sh +%{_libdir}/libsbdtestbed* +%doc COPYING + %changelog ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.tkjQut/_old 2019-11-06 13:56:46.928200379 +0100 +++ /var/tmp/diff_new_pack.tkjQut/_new 2019-11-06 13:56:46.928200379 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/ClusterLabs/sbd.git</param> - <param name="changesrevision">275863252c88b89ed6181c6bf44640b95458448b</param> + <param name="changesrevision">c4dc05841157dd42496d3643617c31383410e51f</param> </service> </servicedata> \ No newline at end of file ++++++ sbd-1.4.0+20190919.2758632.tar.xz -> sbd-1.4.0+20191029.695f9ca.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/.travis.yml new/sbd-1.4.0+20191029.695f9ca/.travis.yml --- old/sbd-1.4.0+20190919.2758632/.travis.yml 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/.travis.yml 2019-10-29 23:38:48.000000000 +0100 @@ -40,7 +40,7 @@ - docker run --privileged -v ${PWD}:/rpms ${BUILD_OS_TYPE}:${BUILD_OS_DIST}${BUILD_OS_VERSION} /bin/bash -c "dnf install -y mock dnf-utils && if test $OS_VERSION = rawhide; then sed -i /etc/mock/${OS_MOCK}-${OS_VERSION}-${OS_ARCH}.cfg -e s/gpgcheck.*/gpgcheck=0/g; fi && mock --no-clean -r ${OS_MOCK}-${OS_VERSION}-${OS_ARCH} --resultdir=/rpms --disable-plugin=yum_cache --disable-plugin=selinux --no-bootstrap-chroot --old-chroot /rpms/sbd*.src.rpm" - ls ${PWD}/${PACKAGE}*.${OS_ARCH}.rpm - docker pull ${OS_TYPE}:${OS_DIST}${OS_VERSION} - - docker run --privileged -v ${PWD}:/rpms -v ${PWD}/tests:/tests ${OS_TYPE}:${OS_DIST}${OS_VERSION} /bin/bash -c "if test $OS_VERSION = rawhide; then yum update -y --nogpgcheck; fi && yum install -y device-mapper /rpms/${PACKAGE}*.${OS_ARCH}.rpm && /tests/regressions.sh && touch /rpms/regressions.sh.SUCCESS" + - docker run --privileged -v ${PWD}:/rpms ${OS_TYPE}:${OS_DIST}${OS_VERSION} /bin/bash -c "if test $OS_VERSION = rawhide; then yum update -y --nogpgcheck; fi && yum install -y device-mapper /rpms/${PACKAGE}*.${OS_ARCH}.rpm && /usr/share/sbd/regressions.sh && touch /rpms/regressions.sh.SUCCESS" - ls ${PWD}/regressions.sh.SUCCESS addons: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/Makefile.am new/sbd-1.4.0+20191029.695f9ca/Makefile.am --- old/sbd-1.4.0+20190919.2758632/Makefile.am 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/Makefile.am 2019-10-29 23:38:48.000000000 +0100 @@ -1,4 +1,4 @@ -SUBDIRS = src agent man +SUBDIRS = src agent man tests # .gz because github doesn't support .xz yet :-( # this is modified @@ -28,6 +28,9 @@ TESTS = tests/regressions.sh export SBD_BINARY := src/sbd +export SBD_PRELOAD := tests/.libs/libsbdtestbed.so +export SBD_USE_DM := no + EXTRA_DIST = sbd.spec tests/regressions.sh export: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/autogen.sh new/sbd-1.4.0+20191029.695f9ca/autogen.sh --- old/sbd-1.4.0+20190919.2758632/autogen.sh 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/autogen.sh 2019-10-29 23:38:48.000000000 +0100 @@ -1,4 +1,10 @@ #!/bin/sh +am_ver=`automake --version | sed -n 1p` +case $am_ver in + *\ 1.11*|*\ 1.12*) echo 'm4_define([TESTS_OPTION], [])';; + *) echo 'm4_define([TESTS_OPTION], [serial-tests])';; +esac > tests-opt.m4 +cat tests-opt.m4 # Run this to generate all the initial makefiles, etc. autoreconf -i -v && echo Now run ./configure and make diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/configure.ac new/sbd-1.4.0+20191029.695f9ca/configure.ac --- old/sbd-1.4.0+20190919.2758632/configure.ac 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/configure.ac 2019-10-29 23:38:48.000000000 +0100 @@ -22,15 +22,16 @@ AC_INIT([sbd], [1.4.0], [[email protected]]) +m4_include([tests-opt.m4]) AC_CANONICAL_HOST AC_CONFIG_AUX_DIR(.) AC_CONFIG_HEADERS(config.h) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([no])]) -AM_INIT_AUTOMAKE +AM_INIT_AUTOMAKE(1.11.1 foreign TESTS_OPTION) AM_PROG_CC_C_O PKG_CHECK_MODULES(glib, [glib-2.0]) -dnl PKG_CHECK_MODULES(libcoroipcc, [libcoroipcc]) +PKG_CHECK_MODULES(libxml, [libxml-2.0]) PKG_CHECK_MODULES(cmap, [libcmap], HAVE_cmap=1, HAVE_cmap=0) PKG_CHECK_MODULES(votequorum, [libvotequorum], HAVE_votequorum=1, HAVE_votequorum=0) @@ -40,9 +41,12 @@ dnl pacemaker <= 1.1.8 PKG_CHECK_MODULES(pcmk, [pcmk, pcmk-cib], HAVE_pcmk=1, HAVE_pcmk=0) + PKG_CHECK_MODULES(libqb, [libqb]) -CPPFLAGS="$CPPFLAGS -Werror" +CPPFLAGS="$CPPFLAGS -Werror $glib_CFLAGS $libxml_CFLAGS" +LIBS="$LIBS $glib_LIBS $libxml_LIBS" + if test $HAVE_pacemaker = 0 -a $HAVE_pcmk = 0; then AC_MSG_ERROR(No package 'pacemaker' found) elif test $HAVE_pacemaker = 1; then @@ -61,11 +65,12 @@ fi fi -PKG_CHECK_MODULES(libxml, [libxml-2.0]) -CPPFLAGS="$CPPFLAGS $libxml_CFLAGS $libqb_CFLAGS $pacemaker_CFLAGS $pcmk_CFLAGS" -LIBS="$LIBS $libxml_LIBS $libqb_LIBS $pacemaker_LIBS $pcmk_LIBS" +CPPFLAGS="$CPPFLAGS $libqb_CFLAGS $pacemaker_CFLAGS $pcmk_CFLAGS" +LIBS="$LIBS $libqb_LIBS $pacemaker_LIBS $pcmk_LIBS" dnl checks for libraries +AC_CHECK_LIB(c, dlopen) dnl if dlopen is in libc... +AC_CHECK_LIB(dl, dlopen) dnl -ldl (for Linux) AC_CHECK_LIB(aio, io_setup, , missing="yes") AC_CHECK_LIB(qb, qb_ipcs_connection_auth_set, , missing="yes") AC_CHECK_LIB(cib, cib_new, , missing="yes") @@ -127,6 +132,18 @@ [ CONFIGDIR="$withval" ] ) +# +# Where is dlopen? +# +if test "$ac_cv_lib_c_dlopen" = yes; then + LIBADD_DL="" +elif test "$ac_cv_lib_dl_dlopen" = yes; then + LIBADD_DL=-ldl +else + LIBADD_DL=${lt_cv_dlopen_libs} +fi + + dnl ********************************************************************** dnl Check for various argv[] replacing functions on various OSs dnl @@ -240,6 +257,8 @@ eval infodir="`eval echo ${infodir}`" eval mandir="`eval echo ${mandir}`" +AC_SUBST(LIBADD_DL) dnl extra flags for dynamic linking libraries + if test x"${CONFIGDIR}" = x""; then CONFIGDIR="${sysconfdir}/sysconfig" fi @@ -248,6 +267,8 @@ dnl The Makefiles and shell scripts we output AC_CONFIG_FILES([Makefile src/Makefile agent/Makefile man/Makefile agent/sbd src/sbd.service src/sbd_remote.service src/sbd.sh]) +AC_CONFIG_SUBDIRS([tests]) + dnl Now process the entire list of files added by previous dnl calls to AC_CONFIG_FILES() AC_OUTPUT() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/man/sbd.8.pod new/sbd-1.4.0+20191029.695f9ca/man/sbd.8.pod --- old/sbd-1.4.0+20190919.2758632/man/sbd.8.pod 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/man/sbd.8.pod 2019-10-29 23:38:48.000000000 +0100 @@ -331,7 +331,7 @@ setting before triggering the dump. Otherwise, the watchdog might trigger and prevent a successful crashdump from ever being written. -Defaults to 240 seconds. Set to zero to disable. +Set to zero (= default) to disable. =item B<-r> I<N> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/sbd.spec new/sbd-1.4.0+20191029.695f9ca/sbd.spec --- old/sbd-1.4.0+20190919.2758632/sbd.spec 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/sbd.spec 2019-10-29 23:38:48.000000000 +0100 @@ -35,7 +35,7 @@ BuildRequires: libuuid-devel BuildRequires: glib2-devel BuildRequires: libaio-devel -BuildRequires: corosynclib-devel +BuildRequires: corosync-devel %if 0%{?suse_version} BuildRequires: libpacemaker-devel %else @@ -60,14 +60,27 @@ This package contains the storage-based death functionality. +%package tests +Summary: Storage-based death environment for regression tests +License: GPLv2+ +Group: System Environment/Daemons + +%description tests +This package provides an environment + testscripts for +regression-testing sbd. + %prep ########################################################### # %setup -n sbd-%{version} -q %setup -q -n %{name}-%{commit} +%ifarch s390x s390 +sed -i src/sbd.sysconfig -e "s/Default: 5/Default: 15/" +sed -i src/sbd.sysconfig -e "s/SBD_WATCHDOG_TIMEOUT=5/SBD_WATCHDOG_TIMEOUT=15/" +%endif ########################################################### %build -autoreconf -i +./autogen.sh export CFLAGS="$RPM_OPT_FLAGS -Wall -Werror" %configure make %{?_smp_mflags} @@ -80,6 +93,7 @@ rm -rf ${RPM_BUILD_ROOT}%{_libdir}/stonith install -D -m 0755 src/sbd.sh $RPM_BUILD_ROOT/usr/share/sbd/sbd.sh +install -D -m 0755 tests/regressions.sh $RPM_BUILD_ROOT/usr/share/sbd/regressions.sh %if %{defined _unitdir} install -D -m 0644 src/sbd.service $RPM_BUILD_ROOT/%{_unitdir}/sbd.service install -D -m 0644 src/sbd_remote.service $RPM_BUILD_ROOT/%{_unitdir}/sbd_remote.service @@ -88,6 +102,10 @@ mkdir -p ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig install -m 644 src/sbd.sysconfig ${RPM_BUILD_ROOT}%{_sysconfdir}/sysconfig/sbd +# Don't package static libs +find %{buildroot} -name '*.a' -type f -print0 | xargs -0 rm -f +find %{buildroot} -name '*.la' -type f -print0 | xargs -0 rm -f + %clean rm -rf %{buildroot} @@ -111,6 +129,7 @@ %config(noreplace) %{_sysconfdir}/sysconfig/sbd %{_sbindir}/sbd %{_datadir}/sbd +%exclude %{_datadir}/sbd/regressions.sh %doc %{_mandir}/man8/sbd* %if %{defined _unitdir} %{_unitdir}/sbd.service @@ -118,6 +137,12 @@ %endif %doc COPYING +%files tests +%defattr(-,root,root) +%dir %{_datadir}/sbd +%{_datadir}/sbd/regressions.sh +%{_libdir}/libsbdtestbed* + %changelog * Mon Jan 14 2019 <[email protected]> - 1.4.0-0.1.2d595fdd.git - updated travis-CI (ppc64le-build, fedora29, remove need for diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/src/Makefile.am new/sbd-1.4.0+20191029.695f9ca/src/Makefile.am --- old/sbd-1.4.0+20190919.2758632/src/Makefile.am 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/src/Makefile.am 2019-10-29 23:38:48.000000000 +0100 @@ -11,5 +11,3 @@ sbd_SOURCES += sbd-md.c endif -sbd_LDADD = $(glib_LIBS) $(libcoroipcc_LIBS) - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/src/sbd-common.c new/sbd-1.4.0+20191029.695f9ca/src/sbd-common.c --- old/sbd-1.4.0+20190919.2758632/src/sbd-common.c 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/src/sbd-common.c 2019-10-29 23:38:48.000000000 +0100 @@ -47,7 +47,7 @@ int watchdog_use = 1; int watchdog_set_timeout = 1; -unsigned long timeout_watchdog_crashdump = 240; +unsigned long timeout_watchdog_crashdump = 0; int skip_rt = 0; int debug = 0; int debug_mode = 0; @@ -89,7 +89,8 @@ "-4 <N> Set msgwait timeout to N seconds (optional, create only)\n" "-5 <N> Warn if loop latency exceeds threshold (optional, watch only)\n" " (default is 3, set to 0 to disable)\n" -"-C <N> Watchdog timeout to set before crashdumping (def: 240s, optional)\n" +"-C <N> Watchdog timeout to set before crashdumping\n" +" (def: 0s = disable gracefully, optional)\n" "-I <N> Async IO read timeout (defaults to 3 * loop timeout, optional)\n" "-s <N> Timeout to wait for devices to become available (def: 120s)\n" "-t <N> Dampening delay before faulty servants are restarted (optional)\n" @@ -107,7 +108,7 @@ "dump Dump meta-data header from device.\n" "allocate <node>\n" " Allocate a slot for node (optional)\n" -"message <node> (test|reset|off|clear|exit)\n" +"message <node> (test|reset|off|crashdump|clear|exit)\n" " Writes the specified message to node's slot.\n" #endif "watch Loop forever, monitoring own slot\n" @@ -930,10 +931,17 @@ sync(); } - if(kind == 'c') { - watchdog_close(true); + if (kind == 'c') { + if (timeout_watchdog_crashdump) { + if (timeout_watchdog != timeout_watchdog_crashdump) { + timeout_watchdog = timeout_watchdog_crashdump; + watchdog_init_interval(); + } + watchdog_close(false); + } else { + watchdog_close(true); + } sysrq_trigger(kind); - } else { watchdog_close(false); sysrq_trigger(kind); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/src/sbd-inquisitor.c new/sbd-1.4.0+20191029.695f9ca/src/sbd-inquisitor.c --- old/sbd-1.4.0+20190919.2758632/src/sbd-inquisitor.c 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/src/sbd-inquisitor.c 2019-10-29 23:38:48.000000000 +0100 @@ -886,22 +886,6 @@ sbd_get_uname(); - value = getenv("SBD_DEVICE"); - if(value) { -#if SUPPORT_SHARED_DISK - int devices = parse_device_line(value); - if(devices < 1) { - fprintf(stderr, "Invalid device line: %s\n", value); - exit_status = -2; - goto out; - } -#else - fprintf(stderr, "Shared disk functionality not supported\n"); - exit_status = -2; - goto out; -#endif - } - value = getenv("SBD_PACEMAKER"); if(value) { check_pcmk = crm_is_true(value); @@ -1112,6 +1096,28 @@ } } + if (disk_count == 0) { + /* if we already have disks from commandline + then it is probably undesirable to add those + from environment (general rule cmdline has precedence) + */ + value = getenv("SBD_DEVICE"); + if ((value) && strlen(value)) { +#if SUPPORT_SHARED_DISK + int devices = parse_device_line(value); + if(devices < 1) { + fprintf(stderr, "Invalid device line: %s\n", value); + exit_status = -2; + goto out; + } +#else + fprintf(stderr, "Shared disk functionality not supported\n"); + exit_status = -2; + goto out; +#endif + } + } + if (watchdogdev == NULL || strcmp(watchdogdev, "/dev/null") == 0) { watchdog_use = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/tests/Makefile.am new/sbd-1.4.0+20191029.695f9ca/tests/Makefile.am --- old/sbd-1.4.0+20190919.2758632/tests/Makefile.am 1970-01-01 01:00:00.000000000 +0100 +++ new/sbd-1.4.0+20191029.695f9ca/tests/Makefile.am 2019-10-29 23:38:48.000000000 +0100 @@ -0,0 +1,4 @@ +lib_LTLIBRARIES = libsbdtestbed.la +libsbdtestbed_la_SOURCES = sbd-testbed.c +libsbdtestbed_la_LDFLAGS = +libsbdtestbed_la_LIBADD = @LIBADD_DL@ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/tests/configure.ac new/sbd-1.4.0+20191029.695f9ca/tests/configure.ac --- old/sbd-1.4.0+20190919.2758632/tests/configure.ac 1970-01-01 01:00:00.000000000 +0100 +++ new/sbd-1.4.0+20191029.695f9ca/tests/configure.ac 2019-10-29 23:38:48.000000000 +0100 @@ -0,0 +1,183 @@ +dnl +dnl autoconf for Agents +dnl +dnl License: GNU General Public License (GPL) + +dnl =============================================== +dnl Bootstrap +dnl =============================================== +AC_PREREQ(2.63) + +dnl Suggested structure: +dnl information on the package +dnl checks for programs +dnl checks for libraries +dnl checks for header files +dnl checks for types +dnl checks for structures +dnl checks for compiler characteristics +dnl checks for library functions +dnl checks for system services + +AC_INIT([sbd], + [1.4.0], + [[email protected]]) +m4_include([../tests-opt.m4]) +AC_CANONICAL_HOST +AC_CONFIG_AUX_DIR(.) +AC_CONFIG_HEADERS(config.h) +m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([no])]) +AM_INIT_AUTOMAKE(1.11.1 foreign TESTS_OPTION) +LT_INIT([dlopen],[disable-static]) +AM_PROG_CC_C_O + +PKG_CHECK_MODULES(glib, [glib-2.0]) + +CPPFLAGS="$CPPFLAGS -Werror $glib_CFLAGS" +LIBS="$LIBS $glib_LIBS" + +dnl checks for libraries +AC_CHECK_LIB(c, dlopen) dnl if dlopen is in libc... +AC_CHECK_LIB(dl, dlopen) dnl -ldl (for Linux) + + +CONFIGDIR="" +AC_ARG_WITH(configdir, + [ --with-configdir=DIR + Directory for SBD configuration file [${CONFIGDIR}]], + [ CONFIGDIR="$withval" ] +) + +# +# Where is dlopen? +# +if test "$ac_cv_lib_c_dlopen" = yes; then + LIBADD_DL="" +elif test "$ac_cv_lib_dl_dlopen" = yes; then + LIBADD_DL=-ldl +else + LIBADD_DL=${lt_cv_dlopen_libs} +fi + + +dnl ********************************************************************** +dnl Check for various argv[] replacing functions on various OSs +dnl +dnl Borrowed from Proftpd +dnl Proftpd is Licenced under the terms of the GNU General Public Licence +dnl and is available from http://www.proftpd.org/ +dnl + +AC_CHECK_FUNCS(setproctitle) +AC_CHECK_HEADERS(libutil.h) +AC_CHECK_LIB(util, setproctitle, + [AC_DEFINE(HAVE_SETPROCTITLE,1,[ ]) + ac_cv_func_setproctitle="yes" ; LIBS="$LIBS -lutil"]) + +if test "$ac_cv_func_setproctitle" = "yes"; then + pf_argv_set="PF_ARGV_NONE" +fi + +if test "$pf_argv_set" = ""; then + AC_CHECK_HEADERS(sys/pstat.h) + if test "$ac_cv_header_pstat_h" = "yes"; then + AC_CHECK_FUNCS(pstat) + + if test "$ac_cv_func_pstat" = "yes"; then + pf_argv_set="PF_ARGV_PSTAT" + else + pf_argv_set="PF_ARGV_WRITEABLE" + fi + fi + + if test "$pf_argv_set" = ""; then + AC_EGREP_HEADER([#define.*PS_STRINGS.*],sys/exec.h, + have_psstrings="yes",have_psstrings="no") + if test "$have_psstrings" = "yes"; then + pf_argv_set="PF_ARGV_PSSTRINGS" + fi + fi + + if test "$pf_argv_set" = ""; then + AC_CACHE_CHECK(whether __progname and __progname_full are available, + pf_cv_var_progname, + AC_TRY_LINK([extern char *__progname, *__progname_full;], + [__progname = "foo"; __progname_full = "foo bar";], + pf_cv_var_progname="yes", pf_cv_var_progname="no")) + + if test "$pf_cv_var_progname" = "yes"; then + AC_DEFINE(HAVE___PROGNAME,1,[ ]) + fi + + AC_CACHE_CHECK(which argv replacement method to use, + pf_cv_argv_type, + AC_EGREP_CPP(yes,[ +#if defined(__GNU_HURD__) + yes +#endif + ],pf_cv_argv_type="new", pf_cv_argv_type="writeable")) + + if test "$pf_cv_argv_type" = "new"; then + pf_argv_set="PF_ARGV_NEW" + fi + + if test "$pf_argv_set" = ""; then + pf_argv_set="PF_ARGV_WRITEABLE" + fi + fi +fi +AC_DEFINE_UNQUOTED(PF_ARGV_TYPE, $pf_argv_set, + mechanism to pretty-print ps output: setproctitle-equivalent) + +dnl End of tests borrowed from Proftpd + +AC_MSG_NOTICE(Sanitizing prefix: ${prefix}) +case $prefix in + NONE) + prefix=/usr + dnl Fix default variables - "prefix" variable if not specified + if test "$localstatedir" = "\${prefix}/var"; then + localstatedir="/var" + fi + if test "$sysconfdir" = "\${prefix}/etc"; then + sysconfdir="/etc" + fi + ;; +esac + +AC_MSG_NOTICE(Sanitizing exec_prefix: ${exec_prefix}) +case $exec_prefix in + dnl For consistency with Heartbeat, map NONE->$prefix + NONE) exec_prefix=$prefix;; + prefix) exec_prefix=$prefix;; +esac + +dnl Expand autoconf variables so that we dont end up with '${prefix}' +dnl in #defines and python scripts +dnl NOTE: Autoconf deliberately leaves them unexpanded to allow +dnl make exec_prefix=/foo install +dnl No longer being able to do this seems like no great loss to me... + +eval prefix="`eval echo ${prefix}`" +eval exec_prefix="`eval echo ${exec_prefix}`" +eval bindir="`eval echo ${bindir}`" +eval sbindir="`eval echo ${sbindir}`" +eval libexecdir="`eval echo ${libexecdir}`" +eval datadir="`eval echo ${datadir}`" +eval sysconfdir="`eval echo ${sysconfdir}`" +eval sharedstatedir="`eval echo ${sharedstatedir}`" +eval localstatedir="`eval echo ${localstatedir}`" +eval libdir="`eval echo ${libdir}`" +eval includedir="`eval echo ${includedir}`" +eval oldincludedir="`eval echo ${oldincludedir}`" +eval infodir="`eval echo ${infodir}`" +eval mandir="`eval echo ${mandir}`" + +AC_SUBST(LIBADD_DL) dnl extra flags for dynamic linking libraries + +dnl The Makefiles and shell scripts we output +AC_CONFIG_FILES([Makefile]) + +dnl Now process the entire list of files added by previous +dnl calls to AC_CONFIG_FILES() +AC_OUTPUT() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/tests/regressions.sh new/sbd-1.4.0+20191029.695f9ca/tests/regressions.sh --- old/sbd-1.4.0+20190919.2758632/tests/regressions.sh 2019-09-19 17:40:55.000000000 +0200 +++ new/sbd-1.4.0+20191029.695f9ca/tests/regressions.sh 2019-10-29 23:38:48.000000000 +0100 @@ -28,41 +28,78 @@ # - Can the unit/service file be tested? or at least the wrapper? : ${SBD_BINARY:="/usr/sbin/sbd"} +: ${SBD_PRELOAD="libsbdtestbed.so"} +: ${SBD_USE_DM:="yes"} sbd() { - ${SBD_BINARY} $* + LD_PRELOAD=${SBD_PRELOAD} SBD_WATCHDOG_TIMEOUT=5 SBD_DEVICE="${SBD_DEVICE}" SBD_PRELOAD_LOG=${SBD_PRELOAD_LOG} SBD_WATCHDOG_DEV=/dev/watchdog setsid ${SBD_BINARY} -p ${SBD_PIDFILE} $* +} + +sbd_wipe_disk() { + dd if=/dev/zero of=$1 count=2048 2>/dev/null } sbd_setup() { trap sbd_teardown EXIT for N in $(seq 3) ; do F[$N]=$(mktemp /tmp/sbd.device.$N.XXXXXX) - R[$N]=$(echo ${F[$N]}|cut -f4 -d.) - dd if=/dev/zero of=${F[$N]} count=2048 - L[$N]=$(losetup -f) - losetup ${L[$N]} ${F[$N]} - D[$N]="/dev/mapper/sbd_${N}_${R[$N]}" - dmsetup create sbd_${N}_${R[$N]} --table "0 2048 linear ${L[$N]} 0" - dmsetup mknodes sbd_${N}_${R[$N]} + sbd_wipe_disk ${F[$N]} + if [[ "${SBD_USE_DM}" == "yes" ]]; then + R[$N]=$(echo ${F[$N]}|cut -f4 -d.) + L[$N]=$(losetup -f) + losetup ${L[$N]} ${F[$N]} + D[$N]="/dev/mapper/sbd_${N}_${R[$N]}" + dmsetup create sbd_${N}_${R[$N]} --table "0 2048 linear ${L[$N]} 0" + dmsetup mknodes sbd_${N}_${R[$N]} + else + D[$N]=${F[$N]} + fi done + if [[ "${SBD_USE_DM}" != "yes" ]]; then + SBD_DEVICE="${F[1]};${F[2]};${F[3]}" + fi + SBD_PIDFILE=$(mktemp /tmp/sbd.pidfile.XXXXXX) + SBD_PRELOAD_LOG=$(mktemp /tmp/sbd.logfile.XXXXXX) } sbd_teardown() { for N in $(seq 3) ; do - dmsetup remove sbd_${N}_${R[$N]} - losetup -d ${L[$N]} + if [[ "${SBD_USE_DM}" == "yes" ]]; then + dmsetup remove sbd_${N}_${R[$N]} + losetup -d ${L[$N]} + fi rm -f ${F[$N]} + sbd_daemon_cleanup + rm -f ${SBD_PIDFILE} + rm -f ${SBD_PRELOAD_LOG} done } sbd_dev_fail() { - dmsetup wipe_table sbd_${1}_${R[$1]} + if [[ "${SBD_USE_DM}" == "yes" ]]; then + dmsetup wipe_table sbd_${1}_${R[$1]} + else + D[$1]=/tmp/fail123456789 + fi } sbd_dev_resume() { - dmsetup suspend sbd_${1}_${R[$1]} - dmsetup load sbd_${1}_${R[$1]} --table "0 2048 linear ${L[$1]} 0" - dmsetup resume sbd_${1}_${R[$1]} + if [[ "${SBD_USE_DM}" == "yes" ]]; then + dmsetup suspend sbd_${1}_${R[$1]} + dmsetup load sbd_${1}_${R[$1]} --table "0 2048 linear ${L[$1]} 0" + dmsetup resume sbd_${1}_${R[$1]} + else + D[$1]=${F[$1]} + fi +} + +sbd_daemon_cleanup() { + echo > ${SBD_PRELOAD_LOG} + pkill -TERM --pidfile ${SBD_PIDFILE} 2>/dev/null + sleep 5 + pkill -KILL --pidfile ${SBD_PIDFILE} 2>/dev/null + pkill -KILL --parent $(cat ${SBD_PIDFILE} 2>/dev/null) 2>/dev/null + echo > ${SBD_PIDFILE} } _ok() { @@ -86,6 +123,16 @@ return 0 } +_in_log() { + grep "$@" ${SBD_PRELOAD_LOG} >/dev/null + if [ $? -ne 0 ]; then + echo "didn't find '$@' in log:" + cat ${SBD_PRELOAD_LOG} + sbd_daemon_cleanup + exit 1 + fi +} + test_1() { echo "Creating three devices" _ok sbd -d ${D[1]} -d ${D[2]} -d ${D[3]} create @@ -168,9 +215,112 @@ _ok sbd -h } +test_watchdog() { + echo "Basic watchdog test" + echo > ${SBD_PRELOAD_LOG} + sbd test-watchdog < /dev/null + _in_log "watchdog fired" +} + +test_stall_inquisitor() { + echo "Stall inquisitor test" + sbd_daemon_cleanup + sbd -d ${D[1]} -d ${D[2]} -d ${D[3]} -n test-1 watch + sleep 10 + _ok kill -0 $(cat ${SBD_PIDFILE}) + kill -STOP $(cat ${SBD_PIDFILE}) + sleep 10 + kill -CONT $(cat ${SBD_PIDFILE}) 2>/dev/null + _in_log "watchdog fired" +} + +test_wipe_slots1() { + echo "Wipe slots test (with watchdog)" + sbd_daemon_cleanup + sbd -d ${D[1]} -n test-1 watch + sleep 2 + sbd_wipe_disk ${D[1]} + sleep 15 + _in_log "watchdog fired" +} + +test_wipe_slots2() { + echo "Wipe slots test (without watchdog)" + sbd_daemon_cleanup + sbd -d ${D[1]} create + sbd -d ${D[1]} -w /dev/null -n test-1 watch + sleep 2 + sbd_wipe_disk ${D[1]} + sleep 15 + _in_log "sysrq-trigger ('b')" + _in_log "reboot (reboot)" +} + +test_message1() { + echo "Message test (reset)" + sbd_daemon_cleanup + sbd -d ${D[1]} create + sbd -d ${D[1]} -w /dev/null -n test-1 watch + sleep 2 + sbd -d ${D[1]} message test-1 reset + sleep 2 + _in_log "sysrq-trigger ('b')" + _in_log "reboot (reboot)" +} + +test_message2() { + echo "Message test (off)" + sbd_daemon_cleanup + sbd -d ${D[1]} create + sbd -d ${D[1]} -w /dev/null -n test-1 watch + sleep 2 + sbd -d ${D[1]} message test-1 off + sleep 2 + _in_log "sysrq-trigger ('o')" + _in_log "reboot (poweroff)" +} + +test_message3() { + echo "Message test (crashdump)" + sbd_daemon_cleanup + sbd -d ${D[1]} create + sbd -d ${D[1]} -w /dev/null -n test-1 watch + sleep 2 + sbd -d ${D[1]} message test-1 crashdump + sleep 2 + _in_log "sysrq-trigger ('c')" +} + +test_timeout_action1() { + echo "Timeout action test (off)" + sbd_daemon_cleanup + sbd -d ${D[1]} create + SBD_TIMEOUT_ACTION=off sbd -d ${D[1]} -w /dev/null -n test-1 watch + sleep 2 + sbd_wipe_disk ${D[1]} + sleep 10 + _in_log "sysrq-trigger ('o')" + _in_log "reboot (poweroff)" +} + +test_timeout_action2() { + echo "Timeout action test (crashdump)" + sbd_daemon_cleanup + sbd -d ${D[1]} create + SBD_TIMEOUT_ACTION=crashdump sbd -d ${D[1]} -w /dev/null -n test-1 watch + sleep 2 + sbd_wipe_disk ${D[1]} + sleep 10 + _in_log "sysrq-trigger ('c')" +} + sbd_setup -for T in $(seq 9); do +if [[ "${SBD_PRELOAD}" != "" ]]; then + SBD_DAEMON_TESTS="watchdog stall_inquisitor wipe_slots1 wipe_slots2 message1 message2 message3 timeout_action1 timeout_action2" +fi + +for T in $(seq 9) ${SBD_DAEMON_TESTS}; do if ! test_$T ; then echo "FAILURE: Test $T" break diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.4.0+20190919.2758632/tests/sbd-testbed.c new/sbd-1.4.0+20191029.695f9ca/tests/sbd-testbed.c --- old/sbd-1.4.0+20190919.2758632/tests/sbd-testbed.c 1970-01-01 01:00:00.000000000 +0100 +++ new/sbd-1.4.0+20191029.695f9ca/tests/sbd-testbed.c 2019-10-29 23:38:48.000000000 +0100 @@ -0,0 +1,729 @@ +#define _GNU_SOURCE +#include <stdlib.h> +#include <dlfcn.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/reboot.h> +#include <stdarg.h> +#include <stddef.h> +#include <fcntl.h> +#include <libaio.h> +#include <linux/watchdog.h> +#include <linux/fs.h> +#include <stdio.h> +#include <signal.h> +#include <unistd.h> +#include <glib.h> +#include <errno.h> + +#if __GLIBC_PREREQ(2,36) +#include <glib-unix.h> +#else +#include <glib/giochannel.h> + +typedef gboolean (*GUnixFDSourceFunc) (gint fd, + GIOCondition condition, + gpointer user_data); + +static gboolean +GIOFunc2GUnixFDSourceFunc(GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + return ((GUnixFDSourceFunc) data) ( + g_io_channel_unix_get_fd(source), + condition, NULL); +} + +static guint +g_unix_fd_add(gint fd, + GIOCondition condition, + GUnixFDSourceFunc function, + gpointer user_data) +{ + GIOChannel *chan = g_io_channel_unix_new (fd); + + if (chan == NULL) { + return 0; + } else { + return g_io_add_watch(chan, + condition, + GIOFunc2GUnixFDSourceFunc, + (gpointer) function); + } +} +#endif + +typedef int (*orig_open_f_type)(const char *pathname, int flags, ...); +typedef int (*orig_ioctl_f_type)(int fd, unsigned long int request, ...); +typedef ssize_t (*orig_write_f_type)(int fd, const void *buf, size_t count); +typedef int (*orig_close_f_type)(int fd); +typedef FILE *(*orig_fopen_f_type)(const char *pathname, const char *mode); +typedef int (*orig_fclose_f_type)(FILE *fp); +typedef int (*orig_io_setup_f_type)(int nr_events, io_context_t *ctx_idp); +typedef int (*orig_io_submit_f_type)(io_context_t ctx_id, long nr, struct iocb *ios[]); +typedef int (*orig_io_getevents_f_type)(io_context_t ctx_id, long min_nr, long nr, + struct io_event *events, struct timespec *timeout); +typedef int (*orig_io_cancel_f_type)(io_context_t ctx_id, struct iocb *iocb, + struct io_event *result); + +static int is_init = 0; +static FILE *log_fp = NULL; + +static char *sbd_device[3] = {NULL, NULL, NULL}; +static int sbd_device_fd[3] = {-1, -1, -1}; + +static FILE *sysrq_fp = NULL; +static FILE *sysrq_trigger_fp = NULL; + +static char *watchdog_device = NULL; +static int watchdog_device_fd = -1; +static int watchdog_timeout = -1; +static pid_t watchdog_pid = -1; +static int watchdog_pipe[2] = {-1, -1}; +static guint watchdog_source_id = 0; +static int watchdog_timer_id = 0; + +static orig_open_f_type orig_open = NULL; +static orig_ioctl_f_type orig_ioctl = NULL; +static orig_write_f_type orig_write = NULL; +static orig_close_f_type orig_close = NULL; +static orig_fopen_f_type orig_fopen = NULL; +static orig_fclose_f_type orig_fclose = NULL; +static orig_io_setup_f_type orig_io_setup = NULL; +static orig_io_submit_f_type orig_io_submit = NULL; +static orig_io_getevents_f_type orig_io_getevents = NULL; +static orig_io_cancel_f_type orig_io_cancel = NULL; + +/* fprintf is inlined as __fprintf_chk or + * we have vfprintf. + * For fscanf we have vfscanf. + * For reboot we anyway don't want that to be + * called in any case. + */ + +static struct iocb *pending_iocb = NULL; +struct io_context { int context_num; }; +static struct io_context our_io_context = {.context_num = 1}; +static int translate_aio = 0; + +static GMainLoop *mainloop = NULL; + +#if 0 +static void +watchdog_shutdown(int nsig) +{ + if (watchdog_timer_id > 0) { + fprintf(log_fp, "exiting with watchdog-timer armed\n"); + } +} +#endif + +static void* +dlsym_fatal(void *handle, const char *symbol) +{ + void *rv = dlsym(handle, symbol); + + if (!rv) { + fprintf(stderr, "Failed looking up symbol %s\n", symbol); + exit(1); + } + return rv; +} + +static void +init (void) +{ + void *handle; + + if (!is_init) { + const char *value; + int i; + char *token, *str, *str_orig; + + is_init = 1; + + orig_open = (orig_open_f_type)dlsym_fatal(RTLD_NEXT,"open"); + orig_ioctl = (orig_ioctl_f_type)dlsym_fatal(RTLD_NEXT,"ioctl"); + orig_close = (orig_close_f_type)dlsym_fatal(RTLD_NEXT,"close"); + orig_write = (orig_write_f_type)dlsym_fatal(RTLD_NEXT,"write"); + orig_fopen = (orig_fopen_f_type)dlsym_fatal(RTLD_NEXT,"fopen"); + orig_fclose = (orig_fclose_f_type)dlsym_fatal(RTLD_NEXT,"fclose"); + + handle = dlopen("libaio.so.1", RTLD_NOW); + if (!handle) { + fprintf(stderr, "Failed opening libaio.so.1\n"); + exit(1); + } + orig_io_setup = (orig_io_setup_f_type)dlsym_fatal(handle,"io_setup"); + orig_io_submit = (orig_io_submit_f_type)dlsym_fatal(handle,"io_submit"); + orig_io_getevents = (orig_io_getevents_f_type)dlsym_fatal(handle,"io_getevents"); + orig_io_cancel = (orig_io_cancel_f_type)dlsym_fatal(handle,"io_cancel"); + dlclose(handle); + + value = getenv("SBD_PRELOAD_LOG"); + if (value) { + log_fp = fopen(value, "a"); + } else { + int fd = dup(fileno(stderr)); + if (fd >= 0) { + log_fp = fdopen(fd, "w"); + } + } + if (log_fp == NULL) { + fprintf(stderr, "couldn't open log-file\n"); + } + + value = getenv("SBD_WATCHDOG_DEV"); + if (value) { + watchdog_device = strdup(value); + } + + value = getenv("SBD_DEVICE"); + if ((value) && (str = str_orig = strdup(value))) { + for (i = 0; i < 3; i++, str = NULL) { + token = strtok(str, ";"); + if (token == NULL) { + break; + } + sbd_device[i] = strdup(token); + } + free(str_orig); + } + + value = getenv("SBD_TRANSLATE_AIO"); + if ((value) && !strcmp(value, "yes")) { + translate_aio = 1; + } + } +} + +// ***** end - handling of watchdog & block-devices **** + +static gboolean +watchdog_timeout_notify(gpointer data) +{ + fprintf(log_fp, "watchdog fired after %ds - killing process group\n", + watchdog_timeout); + fclose(log_fp); + log_fp = NULL; + killpg(0, SIGKILL); + exit(1); +} + +static gboolean +watchdog_dispatch_callback (gint fd, + GIOCondition condition, + gpointer user_data) +{ + char buf[256]; + int i = 0; + + if (condition & G_IO_HUP) { + return FALSE; + } + if (watchdog_timer_id > 0) { + g_source_remove(watchdog_timer_id); + } + watchdog_timer_id = 0; + for (i = 0; i < sizeof(buf)-1; i++) { + ssize_t len; + + do { + len = read(watchdog_pipe[0], &buf[i], 1); + } while ((len == -1) && (errno == EINTR)); + if (len <= 0) { + if (len == -1) { + fprintf(log_fp, "Couldn't read from watchdog-pipe\n"); + } + buf[i] = '\0'; + break; + } + if (buf[i] == '\n') { + buf[i] = '\0'; + break; + } + } + buf[sizeof(buf)-1] = '\0'; + if (sscanf(buf, "trigger %ds", &watchdog_timeout) == 1) { + watchdog_timer_id = g_timeout_add(watchdog_timeout * 1000, watchdog_timeout_notify, NULL); + } else if (strcmp(buf, "disarm") == 0) { + // timer is stopped already + } else { + fprintf(log_fp, "unknown watchdog command\n"); + } + return TRUE; +} + +static void +watchdog_arm (void) { + char buf[256]; + + if ((watchdog_timeout > 0) && (watchdog_pipe[1] >= 0)) { + sprintf(buf, "trigger %ds\n", watchdog_timeout); + if (write(watchdog_pipe[1], buf, strlen(buf)) != strlen(buf)) { + fprintf(log_fp, "Failed tickling watchdog via pipe\n"); + } + } +} + +static void +watchdog_disarm (void) { + char buf[256]; + + watchdog_timeout = -1; + if (watchdog_pipe[1] >= 0) { + sprintf(buf, "disarm\n"); + if (write(watchdog_pipe[1], buf, strlen(buf)) != strlen(buf)) { + fprintf(log_fp, "Failed disarming watchdog via pipe\n"); + } + } +} + +int +open(const char *pathname, int flags, ...) +{ + int i, fd; + int devnum = -1; + int is_wd_dev = 0; + va_list ap; + + init(); + + for (i=0; i < 3; i++) { + if (sbd_device[i]) { + if (strcmp(sbd_device[i], pathname) == 0) { + devnum = i; + flags &= ~O_DIRECT; + break; + } + } + } + if (watchdog_device) { + if (strcmp(watchdog_device, pathname) == 0) { + is_wd_dev = 1; + if (watchdog_pipe[1] == -1) { + if (pipe(watchdog_pipe) == -1) { + fprintf(log_fp, "Creating pipe for watchdog failed\n"); + } else { + int i; + + watchdog_pid = fork(); + switch (watchdog_pid) { + case -1: + fprintf(log_fp, "Forking watchdog-child failed\n"); + break; + case 0: + free(watchdog_device); + watchdog_device = NULL; + for (i = 0; i < 3; i++) { + free(sbd_device[i]); + sbd_device[i] = NULL; + } + close(watchdog_pipe[1]); + if (fcntl(watchdog_pipe[0], F_SETFL, O_NONBLOCK) == -1) { + // don't block on read for timer to be handled + fprintf(log_fp, + "Failed setting watchdog-pipe-read to non-blocking"); + } + mainloop = g_main_loop_new(NULL, FALSE); + // mainloop_add_signal(SIGTERM, watchdog_shutdown); + // mainloop_add_signal(SIGINT, watchdog_shutdown); + watchdog_source_id = g_unix_fd_add(watchdog_pipe[0], + G_IO_IN, + watchdog_dispatch_callback, + NULL); + if (watchdog_source_id == 0) { + fprintf(log_fp, "Failed creating source for watchdog-pipe\n"); + exit(1); + } + g_main_loop_run(mainloop); + g_main_loop_unref(mainloop); + exit(0); + default: + close(watchdog_pipe[0]); + if (fcntl(watchdog_pipe[1], F_SETFL, O_NONBLOCK) == -1) { + fprintf(log_fp, + "Failed setting watchdog-pipe-write to non-blocking"); + } + } + } + } + pathname = "/dev/null"; + } + } + + va_start (ap, flags); + fd = (flags & (O_CREAT +#ifdef O_TMPFILE + | O_TMPFILE +#endif + ))? + orig_open(pathname, flags, va_arg(ap, mode_t)): + orig_open(pathname, flags); + va_end (ap); + + if (devnum >= 0) { + sbd_device_fd[devnum] = fd; + } else if (is_wd_dev) { + watchdog_device_fd = fd; + } + + return fd; +} + +ssize_t +write(int fd, const void *buf, size_t count) +{ + init(); + + if ((fd == watchdog_device_fd) && (count >= 1)) { + if (*(const char *)buf == 'V') { + watchdog_disarm(); + } else { + watchdog_arm(); + } + } + + return orig_write(fd, buf, count); +} + +int +ioctl(int fd, unsigned long int request, ...) +{ + int rv = -1; + va_list ap; + int i; + + init(); + + va_start(ap, request); + switch (request) { + case BLKSSZGET: + for (i=0; i < 3; i++) { + if (sbd_device_fd[i] == fd) { + rv = 0; + *(va_arg(ap, int *)) = 512; + break; + } + if (i == 2) { + rv = orig_ioctl(fd, request, va_arg(ap, int *)); + } + } + break; + case WDIOC_SETTIMEOUT: + if (fd == watchdog_device_fd) { + watchdog_timeout = *va_arg(ap, int *); + + watchdog_arm(); + rv = 0; + break; + } + rv = orig_ioctl(fd, request, va_arg(ap, int *)); + break; + case WDIOC_SETOPTIONS: + if (fd == watchdog_device_fd) { + int flags = *va_arg(ap, int *); + + if (flags & WDIOS_DISABLECARD) { + watchdog_disarm(); + } + rv = 0; + break; + } + rv = orig_ioctl(fd, request, va_arg(ap, int *)); + break; + case WDIOC_GETSUPPORT: + rv = orig_ioctl(fd, request, va_arg(ap, struct watchdog_info *)); + break; + default: + fprintf(log_fp, "ioctl using unknown request = 0x%08lx", request); + rv = orig_ioctl(fd, request, va_arg(ap, void *)); + } + va_end(ap); + + return rv; +} + +int +close(int fd) +{ + int i; + + init(); + + if (fd == watchdog_device_fd) { + watchdog_device_fd = -1; + } else { + for (i = 0; i < 3; i++) { + if (sbd_device_fd[i] == fd) { + sbd_device_fd[i] = -1; + break; + } + } + } + return orig_close(fd); +} + +// ***** end - handling of watchdog & block-devices **** + +// ***** handling of sysrq, sysrq-trigger & reboot **** + +FILE * +fopen(const char *pathname, const char *mode) +{ + int is_sysrq = 0; + int is_sysrq_trigger = 0; + FILE *fp; + + init(); + + if ((strcmp("/proc/sys/kernel/sysrq", pathname) == 0) && + strcmp("w", mode)) { + pathname = "/dev/null"; + is_sysrq = 1; + } else if (strcmp("/proc/sysrq-trigger", pathname) == 0) { + pathname = "/dev/null"; + is_sysrq_trigger = 1; + } + fp = orig_fopen(pathname, mode); + if (is_sysrq) { + sysrq_fp = fp; + } else if (is_sysrq_trigger) { + sysrq_trigger_fp = fp; + } + return fp; +} + +int +fclose(FILE *fp) +{ + init(); + + if (fp == sysrq_fp) { + sysrq_fp = NULL; + } else if (fp == sysrq_trigger_fp) { + sysrq_trigger_fp = NULL; + } + return orig_fclose(fp); +} + +#if defined(__USE_FORTIFY_LEVEL) && (__USE_FORTIFY_LEVEL > 1) +int +__fprintf_chk(FILE *stream, int flag, const char *format, ...) +#else +int +fprintf(FILE *stream, const char *format, ...) +#endif +{ + va_list ap; + int rv; + + init(); + va_start (ap, format); + if (stream == sysrq_trigger_fp) { + char buf[256]; + + rv = vsnprintf(buf, sizeof(buf), format, ap); + if (rv >= 1) { + fprintf(log_fp, "sysrq-trigger ('%c') - %s\n", buf[0], + (buf[0] == 'c')?"killing process group":"don't kill but wait for reboot-call"); + if (buf[0] == 'c') { + fclose(log_fp); + log_fp = NULL; + killpg(0, SIGKILL); + exit(1); + } + } + } else { + rv = vfprintf(stream, format, ap); + } + va_end (ap); + return rv; +} + +int +fscanf(FILE *stream, const char *format, ...) +{ + va_list ap; + int rv; + + init(); + va_start (ap, format); + rv = vfscanf(stream, format, ap); + va_end (ap); + return rv; +} + +int +reboot (int __howto) +{ + fprintf(log_fp, "reboot (%s) - exiting inquisitor process\n", + (__howto == RB_POWER_OFF)?"poweroff":"reboot"); + fclose(log_fp); + log_fp = NULL; + killpg(0, SIGKILL); + exit(1); +} + +// ***** end - handling of sysrq, sysrq-trigger & reboot **** + +// ***** aio translate **** + +#if 0 +struct iocb { + void *data; + unsigned key; + short aio_lio_opcode; + short aio_reqprio; + int aio_fildes; +}; + +static inline void io_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset) +{ + memset(iocb, 0, sizeof(*iocb)); + iocb->aio_fildes = fd; + iocb->aio_lio_opcode = IO_CMD_PREAD; + iocb->aio_reqprio = 0; + iocb->u.c.buf = buf; + iocb->u.c.nbytes = count; + iocb->u.c.offset = offset; +} + +static inline void io_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset) +{ + memset(iocb, 0, sizeof(*iocb)); + iocb->aio_fildes = fd; + iocb->aio_lio_opcode = IO_CMD_PWRITE; + iocb->aio_reqprio = 0; + iocb->u.c.buf = buf; + iocb->u.c.nbytes = count; + iocb->u.c.offset = offset; +} +#endif + +int io_setup(int nr_events, io_context_t *ctx_idp) +{ + init(); + + if (!translate_aio) { + return orig_io_setup(nr_events, ctx_idp); + } + + if (nr_events == 0) { + return EINVAL; + } + if (nr_events > 1) { + return EAGAIN; + } + if (ctx_idp == NULL) { + return EFAULT; + } + *ctx_idp = &our_io_context; + return 0; +} + + +int io_submit(io_context_t ctx_id, long nr, struct iocb *ios[]) +{ + init(); + + if (!translate_aio) { + return orig_io_submit(ctx_id, nr, ios); + } + + if ((pending_iocb != NULL) || + (nr > 1)) { + return EAGAIN; + } + if ((nr == 1) && ((ios == NULL) || (ios[0] == NULL))) { + return EFAULT; + } + if ((ctx_id != &our_io_context) || + (nr < 0) || + ((nr == 1) && + (ios[0]->aio_lio_opcode != IO_CMD_PREAD) && + (ios[0]->aio_lio_opcode != IO_CMD_PWRITE))) { + return EINVAL; + } + if ((fcntl(ios[0]->aio_fildes, F_GETFD) == -1) && (errno == EBADF)) { + return EBADF; + } + if (nr == 1) { + pending_iocb = ios[0]; + } + return nr; +} + +int io_getevents(io_context_t ctx_id, long min_nr, long nr, + struct io_event *events, struct timespec *timeout) +{ + init(); + + if (!translate_aio) { + return orig_io_getevents(ctx_id, min_nr, nr, events, timeout); + } + + if ((ctx_id != &our_io_context) || + (min_nr != 1) || + (nr != 1)) { + return EINVAL; + } + if (pending_iocb == NULL) { + return 0; + } + + switch (pending_iocb->aio_lio_opcode) { + case IO_CMD_PWRITE: + events->res = pwrite(pending_iocb->aio_fildes, + pending_iocb->u.c.buf, + pending_iocb->u.c.nbytes, + pending_iocb->u.c.offset); + break; + case IO_CMD_PREAD: + events->res = pread(pending_iocb->aio_fildes, + pending_iocb->u.c.buf, + pending_iocb->u.c.nbytes, + pending_iocb->u.c.offset); + break; + default: + events->res = 0; + } + + events->data = pending_iocb->data; + events->obj = pending_iocb; + + events->res2 = 0; + pending_iocb = NULL; + return 1; +} + +int io_cancel(io_context_t ctx_id, struct iocb *iocb, + struct io_event *result) +{ + init(); + + if (!translate_aio) { + return orig_io_cancel(ctx_id, iocb, result); + } + + if (ctx_id != &our_io_context) { + return EINVAL; + } + if ((iocb == NULL) || (result == NULL)) { + return EFAULT; + } + if (pending_iocb != iocb) { + return EAGAIN; + } + result->data = iocb->data; + result->obj = iocb; + result->res = 0; + result->res2 = 0; + pending_iocb = NULL; + return 0; +} + +// ***** end - aio translate ****
