Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package sbd for openSUSE:Factory checked in at 2022-09-12 19:08:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/sbd (Old) and /work/SRC/openSUSE:Factory/.sbd.new.2083 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "sbd" Mon Sep 12 19:08:48 2022 rev:45 rq:1002779 version:1.5.1+20220716.c43276f Changes: -------- --- /work/SRC/openSUSE:Factory/sbd/sbd.changes 2021-12-16 02:01:25.311650665 +0100 +++ /work/SRC/openSUSE:Factory/.sbd.new.2083/sbd.changes 2022-09-12 19:08:51.442639062 +0200 @@ -1,0 +2,7 @@ +Fri Sep 09 07:39:28 UTC 2022 - Yan Gao <y...@suse.com> + +- Update to version 1.5.1+20220716.c43276f: +- Be a bit more descriptive on issues opening watchdog-devices +- test: a few tweaks regarding setup of test-environment + +------------------------------------------------------------------- Old: ---- sbd-1.5.1+20211210.92ff8d8.tar.xz New: ---- sbd-1.5.1+20220716.c43276f.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ sbd.spec ++++++ --- /var/tmp/diff_new_pack.BKYJL7/_old 2022-09-12 19:08:51.866640254 +0200 +++ /var/tmp/diff_new_pack.BKYJL7/_new 2022-09-12 19:08:51.874640276 +0200 @@ -1,7 +1,7 @@ # # spec file for package sbd # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # Copyright (c) 2013 Lars Marowsky-Bree # # All modifications and additions to the file contributed by third parties @@ -47,7 +47,7 @@ %global sync_resource_startup_sysconfig "" Name: sbd -Version: 1.5.1+20211210.92ff8d8 +Version: 1.5.1+20220716.c43276f Release: 0 Summary: Storage-based death License: GPL-2.0-or-later @@ -156,13 +156,13 @@ %{_unitdir}/sbd.service %{_unitdir}/sbd_remote.service %{_fillupdir}/sysconfig.sbd -%doc COPYING +%license COPYING %files devel %defattr(-,root,root) %dir %{_datadir}/sbd %{_datadir}/sbd/regressions.sh %{_libdir}/libsbdtestbed* -%doc COPYING +%license COPYING %changelog ++++++ _service ++++++ --- /var/tmp/diff_new_pack.BKYJL7/_old 2022-09-12 19:08:51.902640355 +0200 +++ /var/tmp/diff_new_pack.BKYJL7/_new 2022-09-12 19:08:51.906640366 +0200 @@ -3,7 +3,7 @@ <param name="scm">git</param> <param name="exclude">.git</param> <param name="url">https://github.com/ClusterLabs/sbd.git</param> - <param name="revision">master</param> + <param name="revision">main</param> <param name="versionformat">1.5.1+%cd.%h</param> <param name="changesgenerate">enable</param> </service> ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.BKYJL7/_old 2022-09-12 19:08:51.926640422 +0200 +++ /var/tmp/diff_new_pack.BKYJL7/_new 2022-09-12 19:08:51.930640433 +0200 @@ -1,7 +1,7 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/ClusterLabs/sbd.git</param> - <param name="changesrevision">d9af069397d09c2695f14d1933084a9c83f8c178</param> + <param name="changesrevision">c43276f51abfff2098158728ced1838b2a1f3e9f</param> </service> </servicedata> (No newline at EOF) ++++++ sbd-1.5.1+20211210.92ff8d8.tar.xz -> sbd-1.5.1+20220716.c43276f.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.5.1+20211210.92ff8d8/.gitignore new/sbd-1.5.1+20220716.c43276f/.gitignore --- old/sbd-1.5.1+20211210.92ff8d8/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/sbd-1.5.1+20220716.c43276f/.gitignore 2022-07-16 04:38:08.000000000 +0200 @@ -0,0 +1,35 @@ +*.m4 +*.cache +compile +config.* +configure +*.list +depcomp +install-sh +libtool +ltmain.sh* +Makefile +Makefile.in +missing +stamp-* +sbd +*.8 +*.o +*.service +sbd.sh +sbd.sysconfig +*~ +*.swp +*.patch +*.diff +*.orig +*.rej +*.rpm +*.pod +*.tar.* +!.copr/Makefile +sbd-*/ +.deps +test-driver +sbd.pc +build.counter diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.5.1+20211210.92ff8d8/Makefile.am new/sbd-1.5.1+20220716.c43276f/Makefile.am --- old/sbd-1.5.1+20211210.92ff8d8/Makefile.am 2021-12-10 16:45:02.000000000 +0100 +++ new/sbd-1.5.1+20220716.c43276f/Makefile.am 2022-07-16 04:38:08.000000000 +0200 @@ -31,7 +31,8 @@ TESTS = tests/regressions.sh export SBD_BINARY := src/sbd export SBD_PRELOAD := tests/.libs/libsbdtestbed.so -export SBD_USE_DM := no +export SBD_USE_DM ?= no +export SBD_TRANSLATE_AIO ?= no EXTRA_DIST = sbd.spec tests/regressions.sh man/sbd.8.pod.in diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.5.1+20211210.92ff8d8/man/Makefile.am new/sbd-1.5.1+20220716.c43276f/man/Makefile.am --- old/sbd-1.5.1+20211210.92ff8d8/man/Makefile.am 2021-12-10 16:45:02.000000000 +0100 +++ new/sbd-1.5.1+20220716.c43276f/man/Makefile.am 2022-07-16 04:38:08.000000000 +0200 @@ -6,7 +6,7 @@ sed -r -n -e "s/^## Type: (.*)/Allows C<\1>/;t type;s/^## Default: (.*)/ defaulting to C<\1>/;t default;s/^#*(.*)=.*/=item B<\1>\n/;t variable;s/^#*//;s/^ *//;H;d;:type;h;d;:default;H;x;s/\n//;x;d;:variable;G;p" $< > $@ sbd.8.pod: sbd.8.pod.in sbd.sysconfig.pod - sed -e "s,\@runstatedir\@,$(runstatedir)," $< |sed -e "s/@environment_section@//;t insert;p;d;:insert;rsbd.sysconfig.pod" > $@ + sed -e "s,\@runstatedir\@,$(runstatedir),;s,\@configdir\@,$(CONFIGDIR)," $< |sed -e "s/@environment_section@//;t insert;p;d;:insert;rsbd.sysconfig.pod" > $@ sbd.8: sbd.8.pod @POD2MAN@ -s 8 -c "STONITH Block Device" -r "SBD" -n "SBD" $< $@ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.5.1+20211210.92ff8d8/man/sbd.8.pod.in new/sbd-1.5.1+20220716.c43276f/man/sbd.8.pod.in --- old/sbd-1.5.1+20211210.92ff8d8/man/sbd.8.pod.in 2021-12-10 16:45:02.000000000 +0100 +++ new/sbd-1.5.1+20220716.c43276f/man/sbd.8.pod.in 2022-07-16 04:38:08.000000000 +0200 @@ -28,7 +28,7 @@ To use SBD with shared storage, you must first C<create> the messaging layout on one to three block devices. Second, configure -F</etc/sysconfig/sbd> to list those devices (and possibly adjust other +F<@configdir@/sbd> to list those devices (and possibly adjust other options), and restart the cluster stack on each node to ensure that C<sbd> is started. Third, configure the C<external/sbd> fencing resource in the Pacemaker CIB. @@ -181,7 +181,7 @@ for enabling this according to your boot environment. The options for this mode are rarely specified directly on the -commandline directly, but most frequently set via F</etc/sysconfig/sbd>. +commandline directly, but most frequently set via F<@configdir@/sbd>. It also constantly monitors connectivity to the storage device, and self-fences in case the partition becomes unreachable, guaranteeing that it @@ -560,7 +560,7 @@ =head2 Configuration via sysconfig -The system instance of C<sbd> is configured via F</etc/sysconfig/sbd>. +The system instance of C<sbd> is configured via F<@configdir@/sbd>. In this file, you must specify the device(s) used, as well as any options to pass to the daemon: @@ -593,7 +593,7 @@ This confirms that SBD is indeed up and running on the node, and that it is ready to receive messages. -Make B<sure> that F</etc/sysconfig/sbd> is identical on all cluster +Make B<sure> that F<@configdir@/sbd> is identical on all cluster nodes, and that all cluster nodes are running the daemon. =head1 Pacemaker CIB integration @@ -608,7 +608,7 @@ params pcmk_delay_max=30 This will automatically use the same devices as configured in -F</etc/sysconfig/sbd>. +F<@configdir@/sbd>. While you should not configure this as a clone (as Pacemaker will register the fencing device on each node automatically), the I<pcmk_delay_max> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.5.1+20211210.92ff8d8/sbd.spec new/sbd-1.5.1+20220716.c43276f/sbd.spec --- old/sbd-1.5.1+20211210.92ff8d8/sbd.spec 2021-12-10 16:45:02.000000000 +0100 +++ new/sbd-1.5.1+20220716.c43276f/sbd.spec 2022-07-16 04:38:08.000000000 +0200 @@ -63,7 +63,11 @@ BuildRequires: libaio-devel BuildRequires: corosync-devel %if 0%{?suse_version} +%if 0%{?suse_version} > 1500 +BuildRequires: libpacemaker3-devel +%else BuildRequires: libpacemaker-devel +%endif %else BuildRequires: pacemaker-libs-devel %endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.5.1+20211210.92ff8d8/src/sbd-common.c new/sbd-1.5.1+20220716.c43276f/src/sbd-common.c --- old/sbd-1.5.1+20211210.92ff8d8/src/sbd-common.c 2021-12-10 16:45:02.000000000 +0100 +++ new/sbd-1.5.1+20220716.c43276f/src/sbd-common.c 2022-07-16 04:38:08.000000000 +0200 @@ -118,6 +118,62 @@ , cmdname); } +#define MAX_WATCHDOGS 64 +#define SYS_CLASS_WATCHDOG "/sys/class/watchdog" +#define SYS_CHAR_DEV_DIR "/sys/dev/char" +#define WATCHDOG_NODEDIR "/dev/" + +static bool +is_watchdog(dev_t device) +{ + static int num_watchdog_devs = 0; + static dev_t watchdog_devs[MAX_WATCHDOGS]; + struct dirent *entry; + int i; + + /* populate on first call */ + if (num_watchdog_devs == 0) { + DIR *dp; + + watchdog_devs[0] = makedev(10,130); + num_watchdog_devs = 1; + + /* 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; + char entry_name[NAME_MAX+sizeof(SYS_CLASS_WATCHDOG)+5]; + + 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) { + watchdog_devs[num_watchdog_devs++] = makedev(major, minor); + } + fclose(file); + if (num_watchdog_devs == MAX_WATCHDOGS) { + break; + } + } + } + } + closedir(dp); + } + } + + for (i=0; i < num_watchdog_devs; i++) { + if (device == watchdog_devs[i]) { + return true; + } + } + return false; +} + static int watchdog_init_interval_fd(int wdfd, int timeout) { @@ -173,20 +229,27 @@ static int watchdog_init_fd(char *wddev, int timeout) { - int wdfd; + 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 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 { + struct stat statbuf; + + if(!stat(wddev, &statbuf) && S_ISCHR(statbuf.st_mode) && + is_watchdog(statbuf.st_rdev)) { + cl_perror("Cannot open watchdog device '%s'", wddev); + } else { + cl_perror("Seems as if '%s' isn't a valid watchdog-device", wddev); + } + return -1; + } + return wdfd; } int @@ -250,17 +313,13 @@ 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/" -#define WATCHDOG_NODEDIR_LEN 5 - struct watchdog_list_item { dev_t dev; char *dev_node; char *dev_ident; char *dev_driver; + pid_t busy_pid; + char *busy_name; struct watchdog_list_item *next; }; @@ -276,184 +335,223 @@ 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[280]; - DIR *dp; - char buf[280] = ""; - struct link_list_item *link_list = NULL; - - 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); - } + struct dirent *entry; + char entry_name[sizeof(WATCHDOG_NODEDIR)+NAME_MAX]; + DIR *dp; + char buf[NAME_MAX+sizeof(WATCHDOG_NODEDIR)] = ""; + struct link_list_item *link_list = NULL; - /* search for watchdog nodes in /dev */ - dp = opendir(WATCHDOG_NODEDIR); - if (dp) { - /* first go for links and memorize them */ - while ((entry = readdir(dp))) { - if (entry->d_type == DT_LNK) { - int len; - - snprintf(entry_name, sizeof(entry_name), - WATCHDOG_NODEDIR "%s", entry->d_name); - - /* !realpath(entry_name, buf) unfortunately does a stat on - * target so we can't really use it to check if links stay - * within /dev without triggering e.g. AVC-logs (with - * SELinux policy that just allows stat within /dev). - * Without canonicalization that doesn't actually touch the - * filesystem easily available introduce some limitations - * for simplicity: - * - just simple path without '..' - * - just one level of symlinks (avoid e.g. loop-checking) - */ - len = readlink(entry_name, buf, sizeof(buf) - 1); - if ((len < 1) || - (len > sizeof(buf) - WATCHDOG_NODEDIR_LEN - 1)) { - continue; - } - buf[len] = '\0'; - if (buf[0] != '/') { - memmove(&buf[WATCHDOG_NODEDIR_LEN], buf, len+1); - memcpy(buf, WATCHDOG_NODEDIR, WATCHDOG_NODEDIR_LEN); - len += WATCHDOG_NODEDIR_LEN; - } - if (strstr(buf, "/../") || - strncmp(WATCHDOG_NODEDIR, buf, WATCHDOG_NODEDIR_LEN)) { - continue; - } else { - /* just memorize to avoid statting the target - SELinux */ - struct link_list_item *lli = - calloc(1, sizeof(struct link_list_item)); - - lli->dev_node = strdup(buf); - lli->link_name = strdup(entry_name); - lli->next = link_list; - link_list = lli; - } - } - } + if (watchdog_list != NULL) { + return; + } - rewinddir(dp); + /* search for watchdog nodes in /dev */ + dp = opendir(WATCHDOG_NODEDIR); + if (dp) { + /* first go for links and memorize them */ + while ((entry = readdir(dp))) { + if (entry->d_type == DT_LNK) { + int len; + + snprintf(entry_name, sizeof(entry_name), + WATCHDOG_NODEDIR "%s", entry->d_name); + + /* realpath(entry_name, buf) unfortunately does a stat on + * target so we can't really use it to check if links stay + * within /dev without triggering e.g. AVC-logs (with + * SELinux policy that just allows stat within /dev). + * Without canonicalization that doesn't actually touch the + * filesystem easily available introduce some limitations + * for simplicity: + * - just simple path without '..' + * - just one level of symlinks (avoid e.g. loop-checking) + */ + len = readlink(entry_name, buf, sizeof(buf) - 1); + if ((len < 1) || + (len > sizeof(buf) - sizeof(WATCHDOG_NODEDIR) -1 - 1)) { + continue; + } + buf[len] = '\0'; + if (buf[0] != '/') { + memmove(&buf[sizeof(WATCHDOG_NODEDIR)-1], buf, len+1); + memcpy(buf, WATCHDOG_NODEDIR, sizeof(WATCHDOG_NODEDIR)-1); + len += sizeof(WATCHDOG_NODEDIR)-1; + } + if (strstr(buf, "/../") || + strncmp(WATCHDOG_NODEDIR, buf, sizeof(WATCHDOG_NODEDIR)-1)) { + continue; + } else { + /* just memorize to avoid statting the target - SELinux */ + struct link_list_item *lli = + calloc(1, sizeof(struct link_list_item)); + + lli->dev_node = strdup(buf); + lli->link_name = strdup(entry_name); + lli->next = link_list; + link_list = lli; + } + } + } - while ((entry = readdir(dp))) { - if (entry->d_type == DT_CHR) { - 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)); - int len; - struct link_list_item *tmp_list = NULL; - - 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])); - len = readlink(entry_name, buf, sizeof(buf) - 1); - if (len > 0) { - buf[len] = '\0'; - wdg->dev_driver = strdup(basename(buf)); - } else if ((wdg->dev_ident) && - (strcmp(wdg->dev_ident, - "Software Watchdog") == 0)) { - wdg->dev_driver = strdup("softdog"); - } - - /* create dupes if we have memorized links - * to this node - */ - for (tmp_list = link_list; tmp_list; - tmp_list = tmp_list->next) { - if (!strcmp(tmp_list->dev_node, - wdg->dev_node)) { - struct watchdog_list_item *dupe_wdg = - calloc(1, sizeof(struct watchdog_list_item)); - - /* as long as we never purge watchdog_list - * there is no need to dupe strings - */ - *dupe_wdg = *wdg; - dupe_wdg->dev_node = strdup(tmp_list->link_name); - dupe_wdg->next = watchdog_list; - watchdog_list = dupe_wdg; - watchdog_list_items++; - } - /* for performance reasons we could remove - * the link_list entry - */ - } - break; - } - } - } - } - } + rewinddir(dp); - closedir(dp); - } + while ((entry = readdir(dp))) { + if (entry->d_type == DT_CHR) { + 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) && + is_watchdog(statbuf.st_rdev)) { + + int wdfd = watchdog_init_fd(entry_name, -1); + struct watchdog_list_item *wdg = + calloc(1, sizeof(struct watchdog_list_item)); + int len; + struct link_list_item *tmp_list = NULL; + + wdg->dev = statbuf.st_rdev; + 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(wdg->dev), minor(wdg->dev)); + len = readlink(entry_name, buf, sizeof(buf) - 1); + if (len > 0) { + buf[len] = '\0'; + wdg->dev_driver = strdup(basename(buf)); + } else if ((wdg->dev_ident) && + (strcmp(wdg->dev_ident, + "Software Watchdog") == 0)) { + wdg->dev_driver = strdup("softdog"); + } + + /* create dupes if we have memorized links + * to this node + */ + for (tmp_list = link_list; tmp_list; + tmp_list = tmp_list->next) { + if (!strcmp(tmp_list->dev_node, + wdg->dev_node)) { + struct watchdog_list_item *dupe_wdg = + calloc(1, sizeof(struct watchdog_list_item)); + + /* as long as we never purge watchdog_list + * there is no need to dupe strings + */ + *dupe_wdg = *wdg; + dupe_wdg->dev_node = strdup(tmp_list->link_name); + dupe_wdg->next = watchdog_list; + watchdog_list = dupe_wdg; + watchdog_list_items++; + } + /* for performance reasons we could remove + * the link_list entry + */ + } + } + } + } - /* cleanup link list */ - while (link_list) { - struct link_list_item *tmp_list = link_list; + closedir(dp); + } - link_list = link_list->next; - free(tmp_list->dev_node); - free(tmp_list->link_name); - free(tmp_list); - } + /* cleanup link list */ + while (link_list) { + struct link_list_item *tmp_list = link_list; + + link_list = link_list->next; + free(tmp_list->dev_node); + free(tmp_list->link_name); + free(tmp_list); + } +} + +static void +watchdog_checkbusy() +{ + DIR *dproc; + struct dirent *entry; + + dproc = opendir("/proc"); + if (!dproc) { + /* no proc directory to search through */ + return; + } + + while ((entry = readdir(dproc)) != NULL) { + pid_t local_pid; + char *leftover; + DIR *dpid; + char procpath[NAME_MAX+10] = { 0 }; + + if (entry->d_name[0] == '.') { + continue; + } + + local_pid = strtol(entry->d_name, &leftover, 10); + if (leftover[0] != '\0') + continue; + + snprintf(procpath, sizeof(procpath), "/proc/%s/fd", entry->d_name); + dpid = opendir(procpath); + if (!dpid) { + /* silently continue - might be just a race */ + continue; + } + while ((entry = readdir(dpid)) != NULL) { + struct watchdog_list_item *wdg; + char entry_name[sizeof(procpath)+NAME_MAX+1] = { 0 }; + char buf[NAME_MAX+1] = { 0 }; + int len; + + if (entry->d_type != DT_LNK) { + continue; + } + snprintf(entry_name, sizeof(entry_name), + "%s/%s", procpath, entry->d_name); + len = readlink(entry_name, buf, sizeof(buf) - 1); + if (len < 1) { + continue; + } + buf[len] = '\0'; + for (wdg = watchdog_list; wdg != NULL; wdg = wdg->next) { + if (!strcmp(buf, wdg->dev_node)) { + char name[16]; + FILE *file; + + wdg->busy_pid = local_pid; + snprintf(procpath, sizeof(procpath), "/proc/%d/status", local_pid); + file = fopen(procpath, "r"); + if (file) { + if (fscanf(file, "Name:\t%15[a-zA-Z0-9 _-]", name) == 1) { + wdg->busy_name = strdup(name); + } + fclose(file); + } + } + } + } + closedir(dpid); + } + + closedir(dproc); + + return; } int watchdog_info(void) @@ -462,13 +560,23 @@ int wdg_cnt = 0; watchdog_populate_list(); + watchdog_checkbusy(); 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", + if (wdg->busy_pid) { + printf("\n[%d] %s\nIdentity: Busy: PID %d (%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->busy_pid, + wdg->busy_name?wdg->busy_name:"<unknown>", wdg->dev_driver?wdg->dev_driver:"<unknown>"); + } else { + printf("\n[%d] %s\nIdentity: %s\nDriver: %s\n", + wdg_cnt, wdg->dev_node, + wdg->dev_ident?wdg->dev_ident: + "Error: device hogged via alias major/minor?", + 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"); } @@ -512,6 +620,7 @@ watchdogdev, (int) timeout_watchdog); if ((watchdog_init() < 0) || (watchdog_init_interval() < 0)) { printf("Failed to initialize watchdog!!!\n"); + watchdog_info(); return -1; } printf("\n"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.5.1+20211210.92ff8d8/src/sbd-md.c new/sbd-1.5.1+20220716.c43276f/src/sbd-md.c --- old/sbd-1.5.1+20211210.92ff8d8/src/sbd-md.c 2021-12-10 16:45:02.000000000 +0100 +++ new/sbd-1.5.1+20220716.c43276f/src/sbd-md.c 2022-07-16 04:38:08.000000000 +0200 @@ -593,9 +593,9 @@ } } -out: free(s_node); +out: free(s_mbox); + free(s_node); free(s_header); - free(s_mbox); return rc; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.5.1+20211210.92ff8d8/tests/regressions.sh new/sbd-1.5.1+20220716.c43276f/tests/regressions.sh --- old/sbd-1.5.1+20211210.92ff8d8/tests/regressions.sh 2021-12-10 16:45:02.000000000 +0100 +++ new/sbd-1.5.1+20220716.c43276f/tests/regressions.sh 2022-07-16 04:38:08.000000000 +0200 @@ -28,8 +28,9 @@ # - Can the unit/service file be tested? or at least the wrapper? : ${SBD_BINARY:="/usr/sbin/sbd"} -: ${SBD_PRELOAD="libsbdtestbed.so"} +: ${SBD_PRELOAD:="libsbdtestbed.so"} : ${SBD_USE_DM:="yes"} +: ${SBD_TRANSLATE_AIO:= "no"} sbd() { LD_PRELOAD=${SBD_PRELOAD} SBD_DEVICE="${SBD_DEVICE}" SBD_PRELOAD_LOG=${SBD_PRELOAD_LOG} SBD_WATCHDOG_DEV=/dev/watchdog setsid ${SBD_BINARY} -p ${SBD_PIDFILE} "$@" @@ -40,9 +41,19 @@ } sbd_setup() { - trap sbd_teardown EXIT + trap 'sbd_teardown $?' EXIT + trap 'sbd_teardown 134' ABRT + trap 'sbd_teardown 131' QUIT + trap 'sbd_teardown 143' TERM + trap 'sbd_teardown 130' INT + trap "sbd_teardown 1" ERR + if [[ -d /dev/shm ]]; then + SBD_IMGPATH=/dev/shm + else + SBD_IMGPATH=/tmp + fi for N in $(seq 3) ; do - F[$N]=$(mktemp /tmp/sbd.device.$N.XXXXXX) + F[$N]=$(mktemp ${SBD_IMGPATH}/sbd.device.$N.XXXXXX) sbd_wipe_disk ${F[$N]} if [[ "${SBD_USE_DM}" == "yes" ]]; then R[$N]=$(echo ${F[$N]}|cut -f4 -d.) @@ -66,6 +77,8 @@ } sbd_teardown() { + # disable traps prior to cleanup to avoid loops + trap '' EXIT ABRT QUIT TERM INT ERR for N in $(seq 3) ; do if [[ "${SBD_USE_DM}" == "yes" ]]; then dmsetup remove sbd_${N}_${R[$N]} @@ -76,6 +89,25 @@ rm -f ${SBD_PIDFILE} rm -f ${SBD_PRELOAD_LOG} done + # now that everything should be clean + # return to original handlers to terminate + # as requested + trap - EXIT ABRT QUIT TERM INT ERR + if [[ $1 -eq 134 ]]; then + echo "Received SIGABRT!!!" + kill -ABRT $$ + elif [[ $1 -eq 131 ]]; then + echo "Received SIGQUIT!!!" + kill -QUIT $$ + elif [[ $1 -eq 143 ]]; then + echo "Received SIGTERM!!!" + kill -TERM $$ + elif [[ $1 -eq 130 ]]; then + echo "Received SIGINT!!!" + kill -INT $$ + else + exit $1 + fi } sbd_dev_fail() { @@ -97,12 +129,16 @@ } 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} + if [[ "${SBD_PRELOAD_LOG}" != "" ]]; then + echo > ${SBD_PRELOAD_LOG} + fi + if [[ "${SBD_PIDFILE}" != "" ]]; then + 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} + fi } _ok() { @@ -317,6 +353,11 @@ _in_log "sysrq-trigger ('c')" } +echo "SBD_BINARY = \"${SBD_BINARY}\"" +echo "SBD_PRELOAD = \"${SBD_PRELOAD}\"" +echo "SBD_USE_DM = \"${SBD_USE_DM}\"" +echo "SBD_TRANSLATE_AIO = \"${SBD_TRANSLATE_AIO}"\" + sbd_setup _ok test "${WATCHDOG_TIMEOUT}" -eq "${WATCHDOG_TIMEOUT}"