Hello community, here is the log from the commit of package sbd for openSUSE:Factory checked in at 2018-10-04 19:02:46 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/sbd (Old) and /work/SRC/openSUSE:Factory/.sbd.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "sbd" Thu Oct 4 19:02:46 2018 rev:26 rq:639933 version:1.3.1+20180920.bf16663 Changes: -------- --- /work/SRC/openSUSE:Factory/sbd/sbd.changes 2018-07-31 16:00:02.543611894 +0200 +++ /work/SRC/openSUSE:Factory/.sbd.new/sbd.changes 2018-10-04 19:02:49.287119646 +0200 @@ -1,0 +2,8 @@ +Thu Oct 4 08:53:37 UTC 2018 - y...@suse.com + +- Update to version 1.3.1+20180920.bf16663: +- sbd-common: avoid statting potential links +- sbd-inquisitor: SBD_DELAY_START can be configured with a delay value (bsc#1107321) +- sbd-common: don't follow symlinks outside /dev for watchdog + +------------------------------------------------------------------- Old: ---- sbd-1.3.1+20180703.f95b98e.tar.xz New: ---- sbd-1.3.1+20180920.bf16663.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ sbd.spec ++++++ --- /var/tmp/diff_new_pack.ad4JfO/_old 2018-10-04 19:02:49.751119158 +0200 +++ /var/tmp/diff_new_pack.ad4JfO/_new 2018-10-04 19:02:49.759119150 +0200 @@ -23,7 +23,7 @@ %endif Name: sbd -Version: 1.3.1+20180703.f95b98e +Version: 1.3.1+20180920.bf16663 Release: 0 Summary: Storage-based death License: GPL-2.0-or-later ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.ad4JfO/_old 2018-10-04 19:02:49.787119120 +0200 +++ /var/tmp/diff_new_pack.ad4JfO/_new 2018-10-04 19:02:49.787119120 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/ClusterLabs/sbd.git</param> - <param name="changesrevision">68cfbecb2dea0e66a947c4165c9abecb435e0ec2</param> + <param name="changesrevision">bf16663dbb99b9406dd5f264d98fbb86448219dc</param> </service> </servicedata> \ No newline at end of file ++++++ sbd-1.3.1+20180703.f95b98e.tar.xz -> sbd-1.3.1+20180920.bf16663.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.3.1+20180703.f95b98e/src/sbd-common.c new/sbd-1.3.1+20180920.bf16663/src/sbd-common.c --- old/sbd-1.3.1+20180703.f95b98e/src/sbd-common.c 2018-07-03 18:10:33.000000000 +0200 +++ new/sbd-1.3.1+20180920.bf16663/src/sbd-common.c 2018-09-20 17:49:45.000000000 +0200 @@ -251,7 +251,8 @@ #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 "/dev/" +#define WATCHDOG_NODEDIR_LEN 5 struct watchdog_list_item { dev_t dev; @@ -261,6 +262,12 @@ struct watchdog_list_item *next; }; +struct link_list_item { + char *dev_node; + char *link_name; + struct link_list_item *next; +}; + static struct watchdog_list_item *watchdog_list = NULL; static int watchdog_list_items = 0; @@ -273,7 +280,8 @@ struct dirent *entry; char entry_name[280]; DIR *dp; - char buf[256] = ""; + char buf[280] = ""; + struct link_list_item *link_list = NULL; if (watchdog_list != NULL) { return; @@ -287,7 +295,7 @@ FILE *file; snprintf(entry_name, sizeof(entry_name), - SYS_CLASS_WATCHDOG "/%s/dev", entry->d_name); + SYS_CLASS_WATCHDOG "/%s/dev", entry->d_name); file = fopen(entry_name, "r"); if (file) { int major, minor; @@ -308,12 +316,59 @@ /* 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_CHR) || (entry->d_type == DT_LNK)) { + 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; + } + } + } + + rewinddir(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); + WATCHDOG_NODEDIR "%s", entry->d_name); if(!stat(entry_name, &statbuf) && S_ISCHR(statbuf.st_mode)) { int i; @@ -321,7 +376,9 @@ 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)); + 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); @@ -341,23 +398,60 @@ } 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) { + 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)) { + (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; } } } } } + closedir(dp); } + + /* 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); + } } int watchdog_info(void) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.3.1+20180703.f95b98e/src/sbd-inquisitor.c new/sbd-1.3.1+20180920.bf16663/src/sbd-inquisitor.c --- old/sbd-1.3.1+20180703.f95b98e/src/sbd-inquisitor.c 2018-07-03 18:10:33.000000000 +0200 +++ new/sbd-1.3.1+20180920.bf16663/src/sbd-inquisitor.c 2018-09-20 17:49:45.000000000 +0200 @@ -831,7 +831,8 @@ int P_count = 0; int qb_facility; const char *value = NULL; - int start_delay = 0; + bool delay_start = false; + long delay = 0; if ((cmdname = strrchr(argv[0], '/')) == NULL) { cmdname = argv[0]; @@ -913,9 +914,19 @@ value = getenv("SBD_DELAY_START"); if(value) { - start_delay = crm_is_true(value); + delay_start = crm_is_true(value); + + if (!delay_start) { + delay = crm_get_msec(value) / 1000; + if (delay > 0) { + delay_start = true; + } + } } - cl_log(LOG_DEBUG, "Start delay: %d (%s)", (int)start_delay, value?value:"default"); + cl_log(LOG_DEBUG, "Delay start: %s%s%s", + delay_start? "yes (" : "no", + delay_start? (delay > 0 ? value: "msgwait") : "", + delay_start? ")" : ""); while ((c = getopt(argc, argv, "czC:DPRTWZhvw:d:n:p:1:2:3:4:5:t:I:F:S:s:")) != -1) { switch (c) { @@ -1115,10 +1126,12 @@ open_any_device(servants_leader); } - if(start_delay) { - unsigned long delay = get_first_msgwait(servants_leader); + if (delay_start) { + if (delay <= 0) { + delay = get_first_msgwait(servants_leader); + } - sleep(delay); + sleep((unsigned long) delay); } } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sbd-1.3.1+20180703.f95b98e/src/sbd.sysconfig new/sbd-1.3.1+20180920.bf16663/src/sbd.sysconfig --- old/sbd-1.3.1+20180703.f95b98e/src/sbd.sysconfig 2018-07-03 18:10:33.000000000 +0200 +++ new/sbd-1.3.1+20180920.bf16663/src/sbd.sysconfig 2018-09-20 17:49:45.000000000 +0200 @@ -23,7 +23,7 @@ # SBD_STARTMODE=always -## Type: yesno +## Type: yesno / integer ## Default: no # # Whether to delay after starting sbd on boot for "msgwait" seconds. @@ -31,6 +31,14 @@ # other nodes are still waiting in the fence acknowledgement phase. # This is an occasional issue with virtual machines. # +# This can also be enabled by being set to a specific delay value, in +# seconds. Sometimes a longer delay than the default, "msgwait", is +# needed, for example in the cases where it's considered to be safer to +# wait longer than: +# corosync token timeout + consensus timeout + pcmk_delay_max + msgwait +# +# Be aware that the special value "1" means "yes" rather than "1s". +# # Consider that you might have to adapt the startup-timeout accordingly # if the default isn't sufficient. (TimeoutStartSec for systemd) #