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