|
|
7ebc05 |
commit 5efd173dac6b22eee48f1f9372b2e86cb6d27282
|
|
|
7ebc05 |
Author: Andrew Beekhof <andrew@beekhof.net>
|
|
|
7ebc05 |
Date: Thu Apr 3 16:02:23 2014 +1100
|
|
|
7ebc05 |
|
|
|
7ebc05 |
Feature: PE: Automatically re-unfence a node if the fencing device definition changes
|
|
|
7ebc05 |
|
|
|
7ebc05 |
Ensures all resources that require unfencing are stopped first
|
|
|
7ebc05 |
If unfencing is enabled, this is the new default for resource.requires
|
|
|
7ebc05 |
|
|
|
7ebc05 |
(cherry picked from commit 26fe2e39b9e060597cddeeb69d8b846784dfac55)
|
|
|
7ebc05 |
|
|
|
7ebc05 |
Conflicts:
|
|
|
7ebc05 |
include/crm/pengine/internal.h
|
|
|
7ebc05 |
include/crm/pengine/status.h
|
|
|
7ebc05 |
lib/pengine/complex.c
|
|
|
7ebc05 |
|
|
|
7ebc05 |
diff --git a/fencing/main.c b/fencing/main.c
|
|
|
7ebc05 |
index c40610e..e002125 100644
|
|
|
7ebc05 |
--- a/fencing/main.c
|
|
|
7ebc05 |
+++ b/fencing/main.c
|
|
|
7ebc05 |
@@ -573,7 +573,6 @@ fencing_topology_init(xmlNode * msg)
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
#define rsc_name(x) x->clone_name?x->clone_name:x->id
|
|
|
7ebc05 |
-static bool have_fence_scsi = FALSE;
|
|
|
7ebc05 |
|
|
|
7ebc05 |
static void cib_device_update(resource_t *rsc, pe_working_set_t *data_set)
|
|
|
7ebc05 |
{
|
|
|
7ebc05 |
@@ -662,34 +661,6 @@ static void cib_device_update(resource_t *rsc, pe_working_set_t *data_set)
|
|
|
7ebc05 |
data = create_device_registration_xml(rsc_name(rsc), provider, agent, params);
|
|
|
7ebc05 |
stonith_device_register(data, NULL, TRUE);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
- /* If required, unfence ourselves on cluster startup
|
|
|
7ebc05 |
- *
|
|
|
7ebc05 |
- * Make this generic/smarter if/when more than a single agent needs this
|
|
|
7ebc05 |
- */
|
|
|
7ebc05 |
- if(have_fence_scsi == FALSE && safe_str_eq(agent, "fence_scsi")) {
|
|
|
7ebc05 |
- stonith_device_t *device = g_hash_table_lookup(device_list, rsc->id);
|
|
|
7ebc05 |
-
|
|
|
7ebc05 |
- if(stonith_our_uname == NULL) {
|
|
|
7ebc05 |
- crm_trace("Cannot unfence ourselves: no local host name");
|
|
|
7ebc05 |
-
|
|
|
7ebc05 |
- } else if(device == NULL) {
|
|
|
7ebc05 |
- crm_err("Cannot unfence ourselves: no such device '%s'", rsc->id);
|
|
|
7ebc05 |
-
|
|
|
7ebc05 |
- } else {
|
|
|
7ebc05 |
- const char *alias = g_hash_table_lookup(device->aliases, stonith_our_uname);
|
|
|
7ebc05 |
-
|
|
|
7ebc05 |
- if (!alias) {
|
|
|
7ebc05 |
- alias = stonith_our_uname;
|
|
|
7ebc05 |
- }
|
|
|
7ebc05 |
-
|
|
|
7ebc05 |
- if (device->targets && string_in_list(device->targets, alias)) {
|
|
|
7ebc05 |
- have_fence_scsi = TRUE;
|
|
|
7ebc05 |
- crm_notice("Unfencing ourselves with %s (%s)", agent, device->id);
|
|
|
7ebc05 |
- schedule_internal_command(__FUNCTION__, device, "on", stonith_our_uname, 0, NULL, unfence_cb);
|
|
|
7ebc05 |
- }
|
|
|
7ebc05 |
- }
|
|
|
7ebc05 |
- }
|
|
|
7ebc05 |
-
|
|
|
7ebc05 |
stonith_key_value_freeall(params, 1, 1);
|
|
|
7ebc05 |
free_xml(data);
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
diff --git a/include/crm/msg_xml.h b/include/crm/msg_xml.h
|
|
|
7ebc05 |
index 8575163..055f476 100644
|
|
|
7ebc05 |
--- a/include/crm/msg_xml.h
|
|
|
7ebc05 |
+++ b/include/crm/msg_xml.h
|
|
|
7ebc05 |
@@ -200,6 +200,7 @@
|
|
|
7ebc05 |
# define XML_RSC_ATTR_MULTIPLE "multiple-active"
|
|
|
7ebc05 |
# define XML_RSC_ATTR_PRIORITY "priority"
|
|
|
7ebc05 |
# define XML_RSC_ATTR_REQUIRES "requires"
|
|
|
7ebc05 |
+# define XML_RSC_ATTR_PROVIDES "provides"
|
|
|
7ebc05 |
# define XML_RSC_ATTR_CONTAINER "container"
|
|
|
7ebc05 |
# define XML_RSC_ATTR_INTERNAL_RSC "internal_rsc"
|
|
|
7ebc05 |
# define XML_OP_ATTR_ON_FAIL "on-fail"
|
|
|
7ebc05 |
diff --git a/include/crm/pengine/internal.h b/include/crm/pengine/internal.h
|
|
|
7ebc05 |
index dd52e7f..657c647 100644
|
|
|
7ebc05 |
--- a/include/crm/pengine/internal.h
|
|
|
7ebc05 |
+++ b/include/crm/pengine/internal.h
|
|
|
7ebc05 |
@@ -261,6 +261,7 @@ op_digest_cache_t *rsc_action_digest_cmp(resource_t * rsc, xmlNode * xml_op, nod
|
|
|
7ebc05 |
pe_working_set_t * data_set);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
gboolean is_remote_node(xmlNode *xml);
|
|
|
7ebc05 |
+void clear_bit_recursive(resource_t * rsc, unsigned long long flag);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
resource_t * rsc_contains_remote_node(pe_working_set_t * data_set, resource_t *rsc);
|
|
|
7ebc05 |
#endif
|
|
|
7ebc05 |
diff --git a/include/crm/pengine/status.h b/include/crm/pengine/status.h
|
|
|
7ebc05 |
index b74bf83..ddf9dd7 100644
|
|
|
7ebc05 |
--- a/include/crm/pengine/status.h
|
|
|
7ebc05 |
+++ b/include/crm/pengine/status.h
|
|
|
7ebc05 |
@@ -60,6 +60,7 @@ enum pe_find {
|
|
|
7ebc05 |
|
|
|
7ebc05 |
# define pe_flag_stonith_enabled 0x00000010ULL
|
|
|
7ebc05 |
# define pe_flag_have_stonith_resource 0x00000020ULL
|
|
|
7ebc05 |
+# define pe_flag_enable_unfencing 0x00000040ULL
|
|
|
7ebc05 |
|
|
|
7ebc05 |
# define pe_flag_stop_rsc_orphans 0x00000100ULL
|
|
|
7ebc05 |
# define pe_flag_stop_action_orphans 0x00000200ULL
|
|
|
7ebc05 |
@@ -165,6 +166,7 @@ struct node_s {
|
|
|
7ebc05 |
|
|
|
7ebc05 |
# define pe_rsc_notify 0x00000010ULL
|
|
|
7ebc05 |
# define pe_rsc_unique 0x00000020ULL
|
|
|
7ebc05 |
+# define pe_rsc_fence_device 0x00000040ULL
|
|
|
7ebc05 |
|
|
|
7ebc05 |
# define pe_rsc_provisional 0x00000100ULL
|
|
|
7ebc05 |
# define pe_rsc_allocating 0x00000200ULL
|
|
|
7ebc05 |
@@ -329,6 +331,12 @@ enum pe_ordering {
|
|
|
7ebc05 |
|
|
|
7ebc05 |
pe_order_runnable_left = 0x100, /* 'then' requires 'first' to be runnable */
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+ pe_order_pseudo_left = 0x200, /* 'then' can only be pseudo if 'first' is runnable */
|
|
|
7ebc05 |
+ pe_order_implies_then_on_node = 0x400, /* If 'first' is required on 'nodeX',
|
|
|
7ebc05 |
+ * ensure instances of 'then' on 'nodeX' are too.
|
|
|
7ebc05 |
+ * Only really useful if 'then' is a clone and 'first' is not
|
|
|
7ebc05 |
+ */
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
pe_order_restart = 0x1000, /* 'then' is runnable if 'first' is optional or runnable */
|
|
|
7ebc05 |
pe_order_stonith_stop = 0x2000, /* only applies if the action is non-pseudo */
|
|
|
7ebc05 |
pe_order_serialize_only = 0x4000, /* serialize */
|
|
|
7ebc05 |
diff --git a/lib/pengine/clone.c b/lib/pengine/clone.c
|
|
|
7ebc05 |
index c6c69e6..b13cceb 100644
|
|
|
7ebc05 |
--- a/lib/pengine/clone.c
|
|
|
7ebc05 |
+++ b/lib/pengine/clone.c
|
|
|
7ebc05 |
@@ -46,7 +46,7 @@ mark_as_orphan(resource_t * rsc)
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
-static void
|
|
|
7ebc05 |
+void
|
|
|
7ebc05 |
clear_bit_recursive(resource_t * rsc, unsigned long long flag)
|
|
|
7ebc05 |
{
|
|
|
7ebc05 |
GListPtr gIter = rsc->children;
|
|
|
7ebc05 |
diff --git a/lib/pengine/complex.c b/lib/pengine/complex.c
|
|
|
7ebc05 |
index 8a6049d..8b774c0 100644
|
|
|
7ebc05 |
--- a/lib/pengine/complex.c
|
|
|
7ebc05 |
+++ b/lib/pengine/complex.c
|
|
|
7ebc05 |
@@ -340,12 +340,13 @@ gboolean
|
|
|
7ebc05 |
common_unpack(xmlNode * xml_obj, resource_t ** rsc,
|
|
|
7ebc05 |
resource_t * parent, pe_working_set_t * data_set)
|
|
|
7ebc05 |
{
|
|
|
7ebc05 |
+ bool isdefault = FALSE;
|
|
|
7ebc05 |
xmlNode *expanded_xml = NULL;
|
|
|
7ebc05 |
xmlNode *ops = NULL;
|
|
|
7ebc05 |
resource_t *top = NULL;
|
|
|
7ebc05 |
const char *value = NULL;
|
|
|
7ebc05 |
+ const char *rclass = NULL; /* Look for this after any templates have been expanded */
|
|
|
7ebc05 |
const char *id = crm_element_value(xml_obj, XML_ATTR_ID);
|
|
|
7ebc05 |
- const char *class = crm_element_value(xml_obj, XML_AGENT_ATTR_CLASS);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
crm_log_xml_trace(xml_obj, "Processing resource input...");
|
|
|
7ebc05 |
|
|
|
7ebc05 |
@@ -375,6 +376,8 @@ common_unpack(xmlNode * xml_obj, resource_t ** rsc,
|
|
|
7ebc05 |
(*rsc)->orig_xml = NULL;
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+ /* Do not use xml_obj from here on, use (*rsc)->xml in case templates are involved */
|
|
|
7ebc05 |
+ rclass = crm_element_value((*rsc)->xml, XML_AGENT_ATTR_CLASS);
|
|
|
7ebc05 |
(*rsc)->parent = parent;
|
|
|
7ebc05 |
|
|
|
7ebc05 |
ops = find_xml_node((*rsc)->xml, "operations", FALSE);
|
|
|
7ebc05 |
@@ -538,47 +541,67 @@ common_unpack(xmlNode * xml_obj, resource_t ** rsc,
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+ if (safe_str_eq(rclass, "stonith")) {
|
|
|
7ebc05 |
+ set_bit(data_set->flags, pe_flag_have_stonith_resource);
|
|
|
7ebc05 |
+ set_bit((*rsc)->flags, pe_rsc_fence_device);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_REQUIRES);
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ handle_requires_pref:
|
|
|
7ebc05 |
if (safe_str_eq(value, "nothing")) {
|
|
|
7ebc05 |
|
|
|
7ebc05 |
} else if (safe_str_eq(value, "quorum")) {
|
|
|
7ebc05 |
set_bit((*rsc)->flags, pe_rsc_needs_quorum);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
} else if (safe_str_eq(value, "unfencing")) {
|
|
|
7ebc05 |
- set_bit((*rsc)->flags, pe_rsc_needs_fencing);
|
|
|
7ebc05 |
- set_bit((*rsc)->flags, pe_rsc_needs_unfencing);
|
|
|
7ebc05 |
- if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
|
|
|
7ebc05 |
- crm_notice("%s requires (un)fencing but fencing is disabled", (*rsc)->id);
|
|
|
7ebc05 |
+ if (is_set((*rsc)->flags, pe_rsc_fence_device)) {
|
|
|
7ebc05 |
+ crm_config_warn("%s is a fencing device but requires (un)fencing", (*rsc)->id);
|
|
|
7ebc05 |
+ value = "quorum";
|
|
|
7ebc05 |
+ isdefault = TRUE;
|
|
|
7ebc05 |
+ goto handle_requires_pref;
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ } else if (is_not_set(data_set->flags, pe_flag_stonith_enabled)) {
|
|
|
7ebc05 |
+ crm_config_warn("%s requires (un)fencing but fencing is disabled", (*rsc)->id);
|
|
|
7ebc05 |
+ value = "quorum";
|
|
|
7ebc05 |
+ isdefault = TRUE;
|
|
|
7ebc05 |
+ goto handle_requires_pref;
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ } else {
|
|
|
7ebc05 |
+ set_bit((*rsc)->flags, pe_rsc_needs_fencing);
|
|
|
7ebc05 |
+ set_bit((*rsc)->flags, pe_rsc_needs_unfencing);
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
} else if (safe_str_eq(value, "fencing")) {
|
|
|
7ebc05 |
set_bit((*rsc)->flags, pe_rsc_needs_fencing);
|
|
|
7ebc05 |
if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
|
|
|
7ebc05 |
- crm_notice("%s requires fencing but fencing is disabled", (*rsc)->id);
|
|
|
7ebc05 |
+ crm_config_warn("%s requires (un)fencing but fencing is disabled", (*rsc)->id);
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
} else {
|
|
|
7ebc05 |
if (value) {
|
|
|
7ebc05 |
crm_config_err("Invalid value for %s->requires: %s%s",
|
|
|
7ebc05 |
(*rsc)->id, value,
|
|
|
7ebc05 |
- is_set(data_set->flags,
|
|
|
7ebc05 |
- pe_flag_stonith_enabled) ? "" : " (stonith-enabled=false)");
|
|
|
7ebc05 |
+ is_set(data_set->flags, pe_flag_stonith_enabled) ? "" : " (stonith-enabled=false)");
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
- if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
|
|
|
7ebc05 |
- set_bit((*rsc)->flags, pe_rsc_needs_fencing);
|
|
|
7ebc05 |
- value = "fencing (default)";
|
|
|
7ebc05 |
+ isdefault = TRUE;
|
|
|
7ebc05 |
+ if (is_set(data_set->flags, pe_flag_enable_unfencing)) {
|
|
|
7ebc05 |
+ value = "unfencing";
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ } else if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
|
|
|
7ebc05 |
+ value = "fencing";
|
|
|
7ebc05 |
|
|
|
7ebc05 |
} else if (data_set->no_quorum_policy == no_quorum_ignore) {
|
|
|
7ebc05 |
- value = "nothing (default)";
|
|
|
7ebc05 |
+ value = "nothing";
|
|
|
7ebc05 |
|
|
|
7ebc05 |
} else {
|
|
|
7ebc05 |
- set_bit((*rsc)->flags, pe_rsc_needs_quorum);
|
|
|
7ebc05 |
- value = "quorum (default)";
|
|
|
7ebc05 |
+ value = "quorum";
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
+ goto handle_requires_pref;
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
- pe_rsc_trace((*rsc), "\tRequired to start: %s", value);
|
|
|
7ebc05 |
+ pe_rsc_trace((*rsc), "\tRequired to start: %s%s", value, isdefault?" (default)":"");
|
|
|
7ebc05 |
|
|
|
7ebc05 |
value = g_hash_table_lookup((*rsc)->meta, XML_RSC_ATTR_FAIL_TIMEOUT);
|
|
|
7ebc05 |
if (value != NULL) {
|
|
|
7ebc05 |
@@ -606,10 +629,6 @@ common_unpack(xmlNode * xml_obj, resource_t ** rsc,
|
|
|
7ebc05 |
pe_rsc_trace((*rsc), "\tAction notification: %s",
|
|
|
7ebc05 |
is_set((*rsc)->flags, pe_rsc_notify) ? "required" : "not required");
|
|
|
7ebc05 |
|
|
|
7ebc05 |
- if (safe_str_eq(class, "stonith")) {
|
|
|
7ebc05 |
- set_bit(data_set->flags, pe_flag_have_stonith_resource);
|
|
|
7ebc05 |
- }
|
|
|
7ebc05 |
-
|
|
|
7ebc05 |
(*rsc)->utilization =
|
|
|
7ebc05 |
g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
diff --git a/lib/pengine/unpack.c b/lib/pengine/unpack.c
|
|
|
7ebc05 |
index 56ed291..39ded96 100644
|
|
|
7ebc05 |
--- a/lib/pengine/unpack.c
|
|
|
7ebc05 |
+++ b/lib/pengine/unpack.c
|
|
|
7ebc05 |
@@ -77,6 +77,35 @@ unpack_config(xmlNode * config, pe_working_set_t * data_set)
|
|
|
7ebc05 |
GHashTable *config_hash =
|
|
|
7ebc05 |
g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str, g_hash_destroy_str);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+ xmlXPathObjectPtr xpathObj = NULL;
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ if(is_not_set(data_set->flags, pe_flag_enable_unfencing)) {
|
|
|
7ebc05 |
+ xpathObj = xpath_search(data_set->input, "//nvpair[@name='provides' and @value='unfencing']");
|
|
|
7ebc05 |
+ if(xpathObj && numXpathResults(xpathObj) > 0) {
|
|
|
7ebc05 |
+ set_bit(data_set->flags, pe_flag_enable_unfencing);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+ freeXpathObject(xpathObj);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ if(is_not_set(data_set->flags, pe_flag_enable_unfencing)) {
|
|
|
7ebc05 |
+ xpathObj = xpath_search(data_set->input, "//nvpair[@name='requires' and @value='unfencing']");
|
|
|
7ebc05 |
+ if(xpathObj && numXpathResults(xpathObj) > 0) {
|
|
|
7ebc05 |
+ set_bit(data_set->flags, pe_flag_enable_unfencing);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+ freeXpathObject(xpathObj);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+#ifdef REDHAT_COMPAT_6
|
|
|
7ebc05 |
+ if(is_not_set(data_set->flags, pe_flag_enable_unfencing)) {
|
|
|
7ebc05 |
+ xpathObj = xpath_search(data_set->input, "//primitive[@type='fence_scsi']");
|
|
|
7ebc05 |
+ if(xpathObj && numXpathResults(xpathObj) > 0) {
|
|
|
7ebc05 |
+ set_bit(data_set->flags, pe_flag_enable_unfencing);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+ freeXpathObject(xpathObj);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+#endif
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
data_set->config_hash = config_hash;
|
|
|
7ebc05 |
|
|
|
7ebc05 |
unpack_instance_attributes(data_set->input, config, XML_CIB_TAG_PROPSET, NULL, config_hash,
|
|
|
7ebc05 |
diff --git a/pengine/allocate.c b/pengine/allocate.c
|
|
|
7ebc05 |
index b9ce069..88258f4 100644
|
|
|
7ebc05 |
--- a/pengine/allocate.c
|
|
|
7ebc05 |
+++ b/pengine/allocate.c
|
|
|
7ebc05 |
@@ -123,6 +123,7 @@ check_rsc_parameters(resource_t * rsc, node_t * node, xmlNode * rsc_entry,
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
changed = TRUE;
|
|
|
7ebc05 |
+ trigger_unfencing(rsc, node, "Device definition changed", NULL, data_set);
|
|
|
7ebc05 |
if (active_here) {
|
|
|
7ebc05 |
force_restart = TRUE;
|
|
|
7ebc05 |
crm_notice("Forcing restart of %s on %s, %s changed: %s -> %s",
|
|
|
7ebc05 |
@@ -169,6 +170,7 @@ CancelXmlOp(resource_t * rsc, xmlNode * xml_op, node_t * active_node,
|
|
|
7ebc05 |
crm_info("Action %s on %s will be stopped: %s",
|
|
|
7ebc05 |
key, active_node->details->uname, reason ? reason : "unknown");
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+ /* TODO: This looks highly dangerous if we ever try to schedule 'key' too */
|
|
|
7ebc05 |
cancel = custom_action(rsc, strdup(key), RSC_CANCEL, active_node, FALSE, TRUE, data_set);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
free(cancel->task);
|
|
|
7ebc05 |
@@ -227,6 +229,7 @@ check_action_definition(resource_t * rsc, node_t * active_node, xmlNode * xml_op
|
|
|
7ebc05 |
key = NULL;
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+ crm_trace("Testing %s_%s_%d on %s", rsc->id, task, interval, active_node?active_node->details->uname:"N/A");
|
|
|
7ebc05 |
if (interval == 0 && safe_str_eq(task, RSC_STATUS)) {
|
|
|
7ebc05 |
/* Reload based on the start action not a probe */
|
|
|
7ebc05 |
task = RSC_START;
|
|
|
7ebc05 |
@@ -252,6 +255,7 @@ check_action_definition(resource_t * rsc, node_t * active_node, xmlNode * xml_op
|
|
|
7ebc05 |
op_version, crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC));
|
|
|
7ebc05 |
|
|
|
7ebc05 |
custom_action(rsc, key, task, NULL, FALSE, TRUE, data_set);
|
|
|
7ebc05 |
+ trigger_unfencing(rsc, NULL, "Device parameters changed", NULL, data_set);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
} else if ((digest_data->rc == RSC_DIGEST_ALL) || (digest_data->rc == RSC_DIGEST_UNKNOWN)) {
|
|
|
7ebc05 |
/* Changes that can potentially be handled by a reload */
|
|
|
7ebc05 |
@@ -259,6 +263,7 @@ check_action_definition(resource_t * rsc, node_t * active_node, xmlNode * xml_op
|
|
|
7ebc05 |
const char *digest_all = crm_element_value(xml_op, XML_LRM_ATTR_OP_DIGEST);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
did_change = TRUE;
|
|
|
7ebc05 |
+ trigger_unfencing(rsc, NULL, "Device parameters changed (reload)", NULL, data_set);
|
|
|
7ebc05 |
crm_log_xml_info(digest_data->params_all, "params:reload");
|
|
|
7ebc05 |
key = generate_op_key(rsc->id, task, interval);
|
|
|
7ebc05 |
pe_rsc_info(rsc, "Parameters to %s on %s changed: was %s vs. now %s (reload:%s) %s",
|
|
|
7ebc05 |
@@ -1262,8 +1267,40 @@ any_managed_resources(pe_working_set_t * data_set)
|
|
|
7ebc05 |
return FALSE;
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+void
|
|
|
7ebc05 |
+trigger_unfencing(
|
|
|
7ebc05 |
+ resource_t * rsc, node_t *node, const char *reason, action_t *dependancy, pe_working_set_t * data_set)
|
|
|
7ebc05 |
+{
|
|
|
7ebc05 |
+ if(is_not_set(data_set->flags, pe_flag_enable_unfencing)) {
|
|
|
7ebc05 |
+ /* No resources require it */
|
|
|
7ebc05 |
+ return;
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ } else if (rsc != NULL && is_not_set(rsc->flags, pe_rsc_fence_device)) {
|
|
|
7ebc05 |
+ /* Wasnt a stonith device */
|
|
|
7ebc05 |
+ return;
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ } else if(node) {
|
|
|
7ebc05 |
+ action_t *unfence = pe_fence_op(node, "on", FALSE, data_set);
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ crm_notice("Unfencing %s: %s", node->details->uname, reason);
|
|
|
7ebc05 |
+ if(FALSE && dependancy) {
|
|
|
7ebc05 |
+ order_actions(dependancy, unfence, pe_order_optional);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ } else if(rsc) {
|
|
|
7ebc05 |
+ GHashTableIter iter;
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ g_hash_table_iter_init(&iter, rsc->allowed_nodes);
|
|
|
7ebc05 |
+ while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
|
|
|
7ebc05 |
+ if(node->details->online && node->details->unclean == FALSE && node->details->shutdown == FALSE) {
|
|
|
7ebc05 |
+ trigger_unfencing(rsc, node, reason, dependancy, data_set);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+}
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
action_t *
|
|
|
7ebc05 |
-pe_fence_op(node_t * node, const char *op, pe_working_set_t * data_set)
|
|
|
7ebc05 |
+pe_fence_op(node_t * node, const char *op, bool optional, pe_working_set_t * data_set)
|
|
|
7ebc05 |
{
|
|
|
7ebc05 |
char *key = NULL;
|
|
|
7ebc05 |
action_t *stonith_op = NULL;
|
|
|
7ebc05 |
@@ -1279,13 +1316,18 @@ pe_fence_op(node_t * node, const char *op, pe_working_set_t * data_set)
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
if(stonith_op == NULL) {
|
|
|
7ebc05 |
- stonith_op = custom_action(NULL, key, CRM_OP_FENCE, node, FALSE, TRUE, data_set);
|
|
|
7ebc05 |
+ stonith_op = custom_action(NULL, key, CRM_OP_FENCE, node, optional, TRUE, data_set);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
add_hash_param(stonith_op->meta, XML_LRM_ATTR_TARGET, node->details->uname);
|
|
|
7ebc05 |
add_hash_param(stonith_op->meta, XML_LRM_ATTR_TARGET_UUID, node->details->id);
|
|
|
7ebc05 |
add_hash_param(stonith_op->meta, "stonith_action", op);
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+ if(optional == FALSE) {
|
|
|
7ebc05 |
+ crm_trace("%s is no longer optional", stonith_op->uuid);
|
|
|
7ebc05 |
+ pe_clear_action_bit(stonith_op, pe_action_optional);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
return stonith_op;
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
@@ -1323,7 +1365,7 @@ stage6(pe_working_set_t * data_set)
|
|
|
7ebc05 |
if (need_stonith && node->details->unclean && pe_can_fence(data_set, node)) {
|
|
|
7ebc05 |
pe_warn("Scheduling Node %s for STONITH", node->details->uname);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
- stonith_op = pe_fence_op(node, NULL, data_set);
|
|
|
7ebc05 |
+ stonith_op = pe_fence_op(node, NULL, FALSE, data_set);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
stonith_constraints(node, stonith_op, data_set);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
diff --git a/pengine/allocate.h b/pengine/allocate.h
|
|
|
7ebc05 |
index 042d3aa..712de60 100644
|
|
|
7ebc05 |
--- a/pengine/allocate.h
|
|
|
7ebc05 |
+++ b/pengine/allocate.h
|
|
|
7ebc05 |
@@ -51,7 +51,7 @@ struct resource_alloc_functions_s {
|
|
|
7ebc05 |
void (*append_meta) (resource_t * rsc, xmlNode * xml);
|
|
|
7ebc05 |
};
|
|
|
7ebc05 |
|
|
|
7ebc05 |
-action_t *pe_fence_op(node_t * node, const char *op, pe_working_set_t * data_set);
|
|
|
7ebc05 |
+action_t *pe_fence_op(node_t * node, const char *op, bool optional, pe_working_set_t * data_set);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
extern GHashTable *rsc_merge_weights(resource_t * rsc, const char *rhs, GHashTable * nodes,
|
|
|
7ebc05 |
const char *attr, float factor, enum pe_weights flags);
|
|
|
7ebc05 |
@@ -161,6 +161,8 @@ extern void rsc_migrate_reload(resource_t * rsc, pe_working_set_t * data_set);
|
|
|
7ebc05 |
extern void rsc_stonith_ordering(resource_t * rsc, action_t * stonith_op,
|
|
|
7ebc05 |
pe_working_set_t * data_set);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+void trigger_unfencing(resource_t * rsc, node_t *node, const char *reason, action_t *dependancy, pe_working_set_t * data_set);
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
extern enum pe_graph_flags native_update_actions(action_t * first, action_t * then, node_t * node,
|
|
|
7ebc05 |
enum pe_action_flags flags,
|
|
|
7ebc05 |
enum pe_action_flags filter,
|
|
|
7ebc05 |
diff --git a/pengine/graph.c b/pengine/graph.c
|
|
|
7ebc05 |
index 779f0e0..9c82d23 100644
|
|
|
7ebc05 |
--- a/pengine/graph.c
|
|
|
7ebc05 |
+++ b/pengine/graph.c
|
|
|
7ebc05 |
@@ -430,11 +430,49 @@ update_action(action_t * then)
|
|
|
7ebc05 |
uname : "", other->type);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
if (first == other->action) {
|
|
|
7ebc05 |
+ /*
|
|
|
7ebc05 |
+ * 'first' was not expanded (ie. from 'start' to 'running'), which could mean it:
|
|
|
7ebc05 |
+ * - has no associated resource,
|
|
|
7ebc05 |
+ * - was a primitive,
|
|
|
7ebc05 |
+ * - was pre-expanded (ie. 'running' instead of 'start')
|
|
|
7ebc05 |
+ *
|
|
|
7ebc05 |
+ * The third argument here to graph_update_action() is a node which is used under two conditions:
|
|
|
7ebc05 |
+ * - Interleaving, in which case first->node and
|
|
|
7ebc05 |
+ * then->node are equal (and NULL)
|
|
|
7ebc05 |
+ * - If 'then' is a clone, to limit the scope of the
|
|
|
7ebc05 |
+ * constraint to instances on the supplied node
|
|
|
7ebc05 |
+ *
|
|
|
7ebc05 |
+ */
|
|
|
7ebc05 |
+ int otype = other->type;
|
|
|
7ebc05 |
+ node_t *node = then->node;
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ if(is_set(otype, pe_order_implies_then_on_node)) {
|
|
|
7ebc05 |
+ /* Normally we want the _whole_ 'then' clone to
|
|
|
7ebc05 |
+ * restart if 'first' is restarted, so then->node is
|
|
|
7ebc05 |
+ * needed.
|
|
|
7ebc05 |
+ *
|
|
|
7ebc05 |
+ * However for unfencing, we want to limit this to
|
|
|
7ebc05 |
+ * instances on the same node as 'first' (the
|
|
|
7ebc05 |
+ * unfencing operation), so first->node is supplied.
|
|
|
7ebc05 |
+ *
|
|
|
7ebc05 |
+ * Swap the node, from then on we can can treat it
|
|
|
7ebc05 |
+ * like any other 'pe_order_implies_then'
|
|
|
7ebc05 |
+ */
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ clear_bit(otype, pe_order_implies_then_on_node);
|
|
|
7ebc05 |
+ set_bit(otype, pe_order_implies_then);
|
|
|
7ebc05 |
+ node = first->node;
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
clear_bit(first_flags, pe_action_pseudo);
|
|
|
7ebc05 |
- changed |= graph_update_action(first, then, then->node, first_flags, other->type);
|
|
|
7ebc05 |
+ changed |= graph_update_action(first, then, node, first_flags, otype);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+ /* 'first' was for a complex resource (clone, group, etc),
|
|
|
7ebc05 |
+ * create a new dependancy if necessary
|
|
|
7ebc05 |
+ */
|
|
|
7ebc05 |
} else if (order_actions(first, then, other->type)) {
|
|
|
7ebc05 |
- /* Start again to get the new actions_before list */
|
|
|
7ebc05 |
+ /* This was the first time 'first' and 'then' were associated,
|
|
|
7ebc05 |
+ * start again to get the new actions_before list
|
|
|
7ebc05 |
+ */
|
|
|
7ebc05 |
changed |= (pe_graph_updated_then | pe_graph_disable);
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
diff --git a/pengine/native.c b/pengine/native.c
|
|
|
7ebc05 |
index 4016a3c..d0eb950 100644
|
|
|
7ebc05 |
--- a/pengine/native.c
|
|
|
7ebc05 |
+++ b/pengine/native.c
|
|
|
7ebc05 |
@@ -1236,9 +1236,7 @@ native_internal_constraints(resource_t * rsc, pe_working_set_t * data_set)
|
|
|
7ebc05 |
|
|
|
7ebc05 |
resource_t *top = uber_parent(rsc);
|
|
|
7ebc05 |
int type = pe_order_optional | pe_order_implies_then | pe_order_restart;
|
|
|
7ebc05 |
- gboolean is_stonith =
|
|
|
7ebc05 |
- (rsc->xml && safe_str_eq(crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS), "stonith")) ?
|
|
|
7ebc05 |
- TRUE : FALSE;
|
|
|
7ebc05 |
+ gboolean is_stonith = is_set(rsc->flags, pe_rsc_fence_device);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
custom_action_order(rsc, generate_op_key(rsc->id, RSC_STOP, 0), NULL,
|
|
|
7ebc05 |
rsc, generate_op_key(rsc->id, RSC_START, 0), NULL, type, data_set);
|
|
|
7ebc05 |
@@ -1253,6 +1251,34 @@ native_internal_constraints(resource_t * rsc, pe_working_set_t * data_set)
|
|
|
7ebc05 |
pe_order_runnable_left, data_set);
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
+ if (is_stonith == FALSE
|
|
|
7ebc05 |
+ && is_set(data_set->flags, pe_flag_enable_unfencing)
|
|
|
7ebc05 |
+ && is_set(rsc->flags, pe_rsc_needs_unfencing)) {
|
|
|
7ebc05 |
+ /* Check if the node needs to be unfenced first */
|
|
|
7ebc05 |
+ node_t *node = NULL;
|
|
|
7ebc05 |
+ GHashTableIter iter;
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ if(rsc != top) {
|
|
|
7ebc05 |
+ /* Only create these constraints once, rsc is almost certainly cloned */
|
|
|
7ebc05 |
+ clear_bit_recursive(top, pe_rsc_needs_unfencing);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ g_hash_table_iter_init(&iter, rsc->allowed_nodes);
|
|
|
7ebc05 |
+ while (g_hash_table_iter_next(&iter, NULL, (void **)&node)) {
|
|
|
7ebc05 |
+ action_t *unfence = pe_fence_op(node, "on", TRUE, data_set);
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ custom_action_order(top, generate_op_key(top->id, top == rsc?RSC_STOP:RSC_STOPPED, 0), NULL,
|
|
|
7ebc05 |
+ NULL, strdup(unfence->uuid), unfence,
|
|
|
7ebc05 |
+ pe_order_optional, data_set);
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ crm_debug("Stopping %s prior to unfencing %s", top->id, unfence->uuid);
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+ custom_action_order(NULL, strdup(unfence->uuid), unfence,
|
|
|
7ebc05 |
+ top, generate_op_key(top->id, RSC_START, 0), NULL,
|
|
|
7ebc05 |
+ pe_order_implies_then_on_node, data_set);
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+ }
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
if (is_not_set(rsc->flags, pe_rsc_managed)) {
|
|
|
7ebc05 |
pe_rsc_trace(rsc, "Skipping fencing constraints for unmanaged resource: %s", rsc->id);
|
|
|
7ebc05 |
return;
|
|
|
7ebc05 |
@@ -2456,20 +2482,9 @@ native_create_probe(resource_t * rsc, node_t * node, action_t * complete,
|
|
|
7ebc05 |
probe = custom_action(rsc, key, RSC_STATUS, node, FALSE, TRUE, data_set);
|
|
|
7ebc05 |
update_action_flags(probe, pe_action_optional | pe_action_clear);
|
|
|
7ebc05 |
|
|
|
7ebc05 |
- /* Check if the node needs to be unfenced first */
|
|
|
7ebc05 |
- if (is_set(rsc->flags, pe_rsc_needs_unfencing)) {
|
|
|
7ebc05 |
- action_t *unfence = pe_fence_op(node, "on", data_set);
|
|
|
7ebc05 |
-
|
|
|
7ebc05 |
- crm_notice("Unfencing %s for %s", node->details->uname, rsc->id);
|
|
|
7ebc05 |
- order_actions(unfence, probe, pe_order_implies_then);
|
|
|
7ebc05 |
-
|
|
|
7ebc05 |
- /* The lack of ordering constraints on STONITH_UP would
|
|
|
7ebc05 |
- * traditionally mean unfencing is initiated /before/ the
|
|
|
7ebc05 |
- * devices are started.
|
|
|
7ebc05 |
- *
|
|
|
7ebc05 |
- * However this is a non-issue as stonithd is now smart
|
|
|
7ebc05 |
- * enough to be able to use devices directly from the cib
|
|
|
7ebc05 |
- */
|
|
|
7ebc05 |
+ if(is_set(rsc->flags, pe_rsc_fence_device)) {
|
|
|
7ebc05 |
+ crm_crit("TODO: %s: Trigger when probing the device or the resource that needs unfencing?", rsc->id);
|
|
|
7ebc05 |
+ trigger_unfencing(NULL, node, "node discovery", probe, data_set);
|
|
|
7ebc05 |
}
|
|
|
7ebc05 |
|
|
|
7ebc05 |
/*
|
|
|
7ebc05 |
diff --git a/pengine/regression.sh b/pengine/regression.sh
|
|
|
7ebc05 |
index aa50854..9cb6c18 100755
|
|
|
7ebc05 |
--- a/pengine/regression.sh
|
|
|
7ebc05 |
+++ b/pengine/regression.sh
|
|
|
7ebc05 |
@@ -317,6 +317,11 @@ do_test bug-cl-5170 "Prevent clone from starting with on-fail=block"
|
|
|
7ebc05 |
do_test clone-fail-block-colocation "Move colocated group when failed clone has on-fail=block"
|
|
|
7ebc05 |
|
|
|
7ebc05 |
echo ""
|
|
|
7ebc05 |
+do_test unfence-startup "Clean unfencing"
|
|
|
7ebc05 |
+do_test unfence-definition "Unfencing when the agent changes"
|
|
|
7ebc05 |
+do_test unfence-parameters "Unfencing when the agent parameters changes"
|
|
|
7ebc05 |
+
|
|
|
7ebc05 |
+echo ""
|
|
|
7ebc05 |
do_test master-0 "Stopped -> Slave"
|
|
|
7ebc05 |
do_test master-1 "Stopped -> Promote"
|
|
|
7ebc05 |
do_test master-2 "Stopped -> Promote : notify"
|