File bug-1074039_pacemaker-stonith-ng-pcmk_delay_base.patch of Package pacemaker.14737
commit 3e3cf385e0c9780fc95a4491703413b3dad54eb3
Author: Klaus Wenninger <klaus.wenninger@aon.at>
Date: Wed Jun 21 11:55:57 2017 +0200
Feature: stonith-ng: add pcmk_delay_base as static base-delay
Index: pacemaker/fencing/commands.c
===================================================================
--- pacemaker.orig/fencing/commands.c
+++ pacemaker/fencing/commands.c
@@ -147,6 +147,24 @@ get_action_delay_max(stonith_device_t *
return delay_max_ms;
}
+static int
+get_action_delay_base(stonith_device_t * device, const char * action)
+{
+ const char *value = NULL;
+ int delay_base_ms = 0;
+
+ if (safe_str_neq(action, "off") && safe_str_neq(action, "reboot")) {
+ return 0;
+ }
+
+ value = g_hash_table_lookup(device->params, STONITH_ATTR_DELAY_BASE);
+ if (value) {
+ delay_base_ms = crm_get_msec(value);
+ }
+
+ return delay_base_ms;
+}
+
/*!
* \internal
* \brief Override STONITH timeout with pcmk_*_timeout if available
@@ -424,6 +442,7 @@ static void
schedule_stonith_command(async_command_t * cmd, stonith_device_t * device)
{
int delay_max = 0;
+ int delay_base = 0;
CRM_CHECK(cmd != NULL, return);
CRM_CHECK(device != NULL, return);
@@ -453,11 +472,26 @@ schedule_stonith_command(async_command_t
mainloop_set_trigger(device->work);
delay_max = get_action_delay_max(device, cmd->action);
+ delay_base = get_action_delay_base(device, cmd->action);
+ if (delay_max == 0) {
+ delay_max = delay_base;
+ }
+ if (delay_max < delay_base) {
+ crm_warn("Base-delay (%dms) is larger than max-delay (%dms) "
+ "for %s on %s - limiting to max-delay",
+ delay_base, delay_max, cmd->action, device->id);
+ delay_base = delay_max;
+ }
if (delay_max > 0) {
- cmd->start_delay = rand() % delay_max;
- crm_notice("Delaying %s on %s for %lldms (timeout=%ds)",
- cmd->action, device->id, cmd->start_delay, cmd->timeout);
- cmd->delay_id = g_timeout_add(cmd->start_delay, start_delay_helper, cmd);
+ cmd->start_delay =
+ ((delay_max != delay_base)?(rand() % (delay_max - delay_base)):0)
+ + delay_base;
+ crm_notice("Delaying %s on %s for %lldms (timeout=%ds, base=%dms, "
+ "max=%dms)",
+ cmd->action, device->id, cmd->start_delay, cmd->timeout,
+ delay_base, delay_max);
+ cmd->delay_id =
+ g_timeout_add(cmd->start_delay, start_delay_helper, cmd);
}
}
@@ -1729,6 +1763,7 @@ add_action_specific_attributes(xmlNode *
{
int action_specific_timeout;
int delay_max;
+ int delay_base;
CRM_CHECK(xml && action && device, return);
@@ -1750,6 +1785,23 @@ add_action_specific_attributes(xmlNode *
action, delay_max, device->id);
crm_xml_add_int(xml, F_STONITH_DELAY_MAX, delay_max / 1000);
}
+
+ delay_base = get_action_delay_base(device, action);
+ if (delay_base > 0) {
+ crm_xml_add_int(xml, F_STONITH_DELAY_BASE, delay_base / 1000);
+ }
+
+ if ((delay_max > 0) && (delay_base == 0)) {
+ crm_trace("Action %s has maximum random delay %dms on %s",
+ action, delay_max, device->id);
+ } else if ((delay_max == 0) && (delay_base > 0)) {
+ crm_trace("Action %s has a static delay of %dms on %s",
+ action, delay_base, device->id);
+ } else if ((delay_max > 0) && (delay_base > 0)) {
+ crm_trace("Action %s has a minimum delay of %dms and a randomly chosen "
+ "maximum delay of %dms on %s",
+ action, delay_base, delay_max, device->id);
+ }
}
/*
Index: pacemaker/fencing/main.c
===================================================================
--- pacemaker.orig/fencing/main.c
+++ pacemaker/fencing/main.c
@@ -1382,7 +1382,18 @@ main(int argc, char **argv)
(" <shortdesc lang=\"en\">Enable random delay for stonith actions and specify the maximum of random delay</shortdesc>\n");
printf
(" <longdesc lang=\"en\">This prevents double fencing when using slow devices such as sbd.\n"
- "Use this to enable random delay for stonith actions and specify the maximum of random delay.</longdesc>\n");
+ "Use this to enable random delay for stonith actions.\n"
+ "The overall delay is derived from a random delay value adding a static delay so that the sum is kept below the maximum delay.</longdesc>\n");
+ printf(" <content type=\"time\" default=\"0s\"/>\n");
+ printf(" </parameter>\n");
+
+ printf(" <parameter name=\"%s\" unique=\"0\">\n", STONITH_ATTR_DELAY_BASE);
+ printf
+ (" <shortdesc lang=\"en\">Enable base delay for stonith actions and specify base delay value</shortdesc>\n");
+ printf
+ (" <longdesc lang=\"en\">This prevents double fencing when different delays are configured on the nodes.\n"
+ "Use this to enable static delay for stonith actions.\n"
+ "The overall delay is derived from a random delay value adding a static delay so that the sum is kept below the maximum delay.</longdesc>\n");
printf(" <content type=\"time\" default=\"0s\"/>\n");
printf(" </parameter>\n");
Index: pacemaker/fencing/remote.c
===================================================================
--- pacemaker.orig/fencing/remote.c
+++ pacemaker/fencing/remote.c
@@ -67,6 +67,8 @@ typedef struct device_properties_s {
int custom_action_timeout[st_phase_max];
/* Action-specific maximum random delay for each phase */
int delay_max[st_phase_max];
+ /* Action-specific base delay for each phase */
+ int delay_base[st_phase_max];
} device_properties_t;
typedef struct st_query_result_s {
@@ -1675,6 +1677,13 @@ parse_action_specific(xmlNode *xml, cons
peer, device, props->delay_max[phase], action);
}
+ props->delay_base[phase] = 0;
+ crm_element_value_int(xml, F_STONITH_DELAY_BASE, &props->delay_base[phase]);
+ if (props->delay_base[phase]) {
+ crm_trace("Peer %s with device %s returned base delay %d for %s",
+ peer, device, props->delay_base[phase], action);
+ }
+
/* Handle devices with automatic unfencing */
if (safe_str_eq(action, "on")) {
int required = 0;
Index: pacemaker/include/crm/fencing/internal.h
===================================================================
--- pacemaker.orig/include/crm/fencing/internal.h
+++ pacemaker/include/crm/fencing/internal.h
@@ -69,6 +69,8 @@ xmlNode *create_device_registration_xml(
# define F_STONITH_ACTION_DISALLOWED "st_action_disallowed"
/*! Maximum of random fencing delay for a device */
# define F_STONITH_DELAY_MAX "st_delay_max"
+/*! Base delay used for a fencing delay */
+# define F_STONITH_DELAY_BASE "st_delay_base"
/*! Has this device been verified using a monitor type
* operation (monitor, list, status) */
# define F_STONITH_DEVICE_VERIFIED "st_monitor_verified"
@@ -111,6 +113,7 @@ xmlNode *create_device_registration_xml(
# define STONITH_ATTR_HOSTLIST "pcmk_host_list"
# define STONITH_ATTR_HOSTCHECK "pcmk_host_check"
# define STONITH_ATTR_DELAY_MAX "pcmk_delay_max"
+# define STONITH_ATTR_DELAY_BASE "pcmk_delay_base"
# define STONITH_ATTR_ACTION_LIMIT "pcmk_action_limit"
# define STONITH_ATTR_ACTION_OP "action"