|
|
ed0026 |
commit 8af0d0c8aabe9ef6bb76c0e5032836d3c8bdc9d7
|
|
|
ed0026 |
Author: Andrew Beekhof <andrew@beekhof.net>
|
|
|
ed0026 |
Date: Tue Aug 13 12:31:25 2013 +1000
|
|
|
ed0026 |
|
|
|
ed0026 |
Feature: Fencing: Support agents that need the host to be unfenced at startup
|
|
|
ed0026 |
|
|
|
ed0026 |
diff --git a/fencing/commands.c b/fencing/commands.c
|
|
|
ed0026 |
index c7c1bf0..73a7fc1 100644
|
|
|
ed0026 |
--- a/fencing/commands.c
|
|
|
ed0026 |
+++ b/fencing/commands.c
|
|
|
ed0026 |
@@ -635,8 +635,9 @@ target_list_type(stonith_device_t * dev)
|
|
|
ed0026 |
return check_type;
|
|
|
ed0026 |
}
|
|
|
ed0026 |
|
|
|
ed0026 |
-static void
|
|
|
ed0026 |
-schedule_internal_command(stonith_device_t * device,
|
|
|
ed0026 |
+void
|
|
|
ed0026 |
+schedule_internal_command(const char *origin,
|
|
|
ed0026 |
+ stonith_device_t * device,
|
|
|
ed0026 |
const char *action,
|
|
|
ed0026 |
const char *victim,
|
|
|
ed0026 |
int timeout,
|
|
|
ed0026 |
@@ -654,12 +655,12 @@ schedule_internal_command(stonith_device_t * device,
|
|
|
ed0026 |
cmd->action = strdup(action);
|
|
|
ed0026 |
cmd->victim = victim ? strdup(victim) : NULL;
|
|
|
ed0026 |
cmd->device = strdup(device->id);
|
|
|
ed0026 |
- cmd->origin = strdup("st_internal_cmd");
|
|
|
ed0026 |
- cmd->client = strdup("st_internal_client");
|
|
|
ed0026 |
- cmd->client_name = strdup("st_internal_client_name");
|
|
|
ed0026 |
+ cmd->origin = strdup(origin);
|
|
|
ed0026 |
+ cmd->client = strdup(crm_system_name);
|
|
|
ed0026 |
+ cmd->client_name = strdup(crm_system_name);
|
|
|
ed0026 |
|
|
|
ed0026 |
cmd->internal_user_data = internal_user_data;
|
|
|
ed0026 |
- cmd->done_cb = done_cb;
|
|
|
ed0026 |
+ cmd->done_cb = done_cb; /* cmd, not internal_user_data, is passed to 'done_cb' as the userdata */
|
|
|
ed0026 |
|
|
|
ed0026 |
schedule_stonith_command(cmd, device);
|
|
|
ed0026 |
}
|
|
|
ed0026 |
@@ -1093,9 +1094,7 @@ can_fence_host_with_device(stonith_device_t * dev, struct device_search_s *searc
|
|
|
ed0026 |
time_t now = time(NULL);
|
|
|
ed0026 |
|
|
|
ed0026 |
if (dev->targets == NULL || dev->targets_age + 60 < now) {
|
|
|
ed0026 |
- schedule_internal_command(dev,
|
|
|
ed0026 |
- "list",
|
|
|
ed0026 |
- NULL,
|
|
|
ed0026 |
+ schedule_internal_command(__FUNCTION__, dev, "list", NULL,
|
|
|
ed0026 |
search->per_device_timeout, search, dynamic_list_search_cb);
|
|
|
ed0026 |
|
|
|
ed0026 |
/* we'll respond to this search request async in the cb */
|
|
|
ed0026 |
@@ -1107,9 +1106,7 @@ can_fence_host_with_device(stonith_device_t * dev, struct device_search_s *searc
|
|
|
ed0026 |
}
|
|
|
ed0026 |
|
|
|
ed0026 |
} else if (safe_str_eq(check_type, "status")) {
|
|
|
ed0026 |
- schedule_internal_command(dev,
|
|
|
ed0026 |
- "status",
|
|
|
ed0026 |
- search->host,
|
|
|
ed0026 |
+ schedule_internal_command(__FUNCTION__, dev, "status", search->host,
|
|
|
ed0026 |
search->per_device_timeout, search, status_search_cb);
|
|
|
ed0026 |
/* we'll respond to this search request async in the cb */
|
|
|
ed0026 |
return;
|
|
|
ed0026 |
@@ -1395,6 +1392,26 @@ stonith_send_async_reply(async_command_t * cmd, const char *output, int rc, GPid
|
|
|
ed0026 |
free_xml(reply);
|
|
|
ed0026 |
}
|
|
|
ed0026 |
|
|
|
ed0026 |
+void
|
|
|
ed0026 |
+unfence_cb(GPid pid, int rc, const char *output, gpointer user_data)
|
|
|
ed0026 |
+{
|
|
|
ed0026 |
+ async_command_t * cmd = user_data;
|
|
|
ed0026 |
+ stonith_device_t *dev = g_hash_table_lookup(device_list, cmd->device);
|
|
|
ed0026 |
+
|
|
|
ed0026 |
+ log_operation(cmd, rc, pid, NULL, output);
|
|
|
ed0026 |
+
|
|
|
ed0026 |
+ if(dev) {
|
|
|
ed0026 |
+ dev->active_pid = 0;
|
|
|
ed0026 |
+ mainloop_set_trigger(dev->work);
|
|
|
ed0026 |
+ } else {
|
|
|
ed0026 |
+ crm_trace("Device %s does not exist", cmd->device);
|
|
|
ed0026 |
+ }
|
|
|
ed0026 |
+
|
|
|
ed0026 |
+ if(rc != 0) {
|
|
|
ed0026 |
+ crm_exit(DAEMON_RESPAWN_STOP);
|
|
|
ed0026 |
+ }
|
|
|
ed0026 |
+}
|
|
|
ed0026 |
+
|
|
|
ed0026 |
static void
|
|
|
ed0026 |
cancel_stonith_command(async_command_t * cmd)
|
|
|
ed0026 |
{
|
|
|
ed0026 |
diff --git a/fencing/internal.h b/fencing/internal.h
|
|
|
ed0026 |
index 737fc18..9a8b096 100644
|
|
|
ed0026 |
--- a/fencing/internal.h
|
|
|
ed0026 |
+++ b/fencing/internal.h
|
|
|
ed0026 |
@@ -162,6 +162,18 @@ bool fencing_peer_active(crm_node_t *peer);
|
|
|
ed0026 |
|
|
|
ed0026 |
int stonith_manual_ack(xmlNode * msg, remote_fencing_op_t * op);
|
|
|
ed0026 |
|
|
|
ed0026 |
+void unfence_cb(GPid pid, int rc, const char *output, gpointer user_data);
|
|
|
ed0026 |
+
|
|
|
ed0026 |
+void
|
|
|
ed0026 |
+schedule_internal_command(const char *origin,
|
|
|
ed0026 |
+ stonith_device_t * device,
|
|
|
ed0026 |
+ const char *action,
|
|
|
ed0026 |
+ const char *victim,
|
|
|
ed0026 |
+ int timeout,
|
|
|
ed0026 |
+ void *internal_user_data,
|
|
|
ed0026 |
+ void (*done_cb) (GPid pid, int rc, const char *output,
|
|
|
ed0026 |
+ gpointer user_data));
|
|
|
ed0026 |
+
|
|
|
ed0026 |
extern char *stonith_our_uname;
|
|
|
ed0026 |
extern gboolean stand_alone;
|
|
|
ed0026 |
extern GHashTable *device_list;
|
|
|
ed0026 |
diff --git a/fencing/main.c b/fencing/main.c
|
|
|
ed0026 |
index e002125..3fa7b5a 100644
|
|
|
ed0026 |
--- a/fencing/main.c
|
|
|
ed0026 |
+++ b/fencing/main.c
|
|
|
ed0026 |
@@ -573,6 +573,7 @@ fencing_topology_init(xmlNode * msg)
|
|
|
ed0026 |
}
|
|
|
ed0026 |
|
|
|
ed0026 |
#define rsc_name(x) x->clone_name?x->clone_name:x->id
|
|
|
ed0026 |
+static bool have_fence_scsi = FALSE;
|
|
|
ed0026 |
|
|
|
ed0026 |
static void cib_device_update(resource_t *rsc, pe_working_set_t *data_set)
|
|
|
ed0026 |
{
|
|
|
ed0026 |
@@ -661,6 +662,22 @@ static void cib_device_update(resource_t *rsc, pe_working_set_t *data_set)
|
|
|
ed0026 |
data = create_device_registration_xml(rsc_name(rsc), provider, agent, params);
|
|
|
ed0026 |
stonith_device_register(data, NULL, TRUE);
|
|
|
ed0026 |
|
|
|
ed0026 |
+ /* If required, unfence ourselves on cluster startup
|
|
|
ed0026 |
+ *
|
|
|
ed0026 |
+ * Make this generic/smarter if/when more than a single agent needs this
|
|
|
ed0026 |
+ */
|
|
|
ed0026 |
+ if(have_fence_scsi == FALSE && safe_str_eq(agent, "fence_scsi")) {
|
|
|
ed0026 |
+ stonith_device_t *device = g_hash_table_lookup(device_list, rsc->id);
|
|
|
ed0026 |
+
|
|
|
ed0026 |
+ if(device) {
|
|
|
ed0026 |
+ have_fence_scsi = TRUE;
|
|
|
ed0026 |
+ crm_notice("Unfencing ourselves with %s (%s)", agent, device->id);
|
|
|
ed0026 |
+ schedule_internal_command(__FUNCTION__, device, "on", stonith_our_uname, 0, NULL, unfence_cb);
|
|
|
ed0026 |
+ } else {
|
|
|
ed0026 |
+ crm_err("Device %s does not exist", rsc->id);
|
|
|
ed0026 |
+ }
|
|
|
ed0026 |
+ }
|
|
|
ed0026 |
+
|
|
|
ed0026 |
stonith_key_value_freeall(params, 1, 1);
|
|
|
ed0026 |
free_xml(data);
|
|
|
ed0026 |
}
|