Skip to content

Commit

Permalink
Low: fenced: Remove relayed stonith operation.(Fix:CLBZ#5401)
Browse files Browse the repository at this point in the history
  • Loading branch information
HideoYamauchi committed May 6, 2020
1 parent a404b23 commit df71a07
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 3 deletions.
60 changes: 58 additions & 2 deletions daemons/fenced/fenced_commands.c
Expand Up @@ -2455,6 +2455,55 @@ stonith_send_reply(xmlNode * reply, int call_options, const char *remote_peer,
}
}

static void
remove_relay_op(xmlNode * request)
{
xmlNode *dev = get_xpath_object("//@" F_STONITH_ACTION, request, LOG_TRACE);
const char *relay_op_id = NULL;
const char *op_id = NULL;
const char *client_name = NULL;
const char *target = NULL;
remote_fencing_op_t *relay_op = NULL;

if (dev) {
target = crm_element_value(dev, F_STONITH_TARGET);
}

relay_op_id = crm_element_value(request, F_STONITH_REMOTE_OP_ID_RELAY);
op_id = crm_element_value(request, F_STONITH_REMOTE_OP_ID);
client_name = crm_element_value(request, F_STONITH_CLIENTNAME);

/* Delete RELAY operation. */
if (relay_op_id && target && safe_str_eq(target, stonith_our_uname)) {
relay_op = g_hash_table_lookup(stonith_remote_op_list, relay_op_id);

if (relay_op) {
GHashTableIter iter;
remote_fencing_op_t *list_op = NULL;
g_hash_table_iter_init(&iter, stonith_remote_op_list);

/* If the operation to be deleted is registered as a duplicate, delete the registration. */
while (g_hash_table_iter_next(&iter, NULL, (void **)&list_op)) {
GListPtr dup_iter = NULL;
if (list_op != relay_op) {
for (dup_iter = list_op->duplicates; dup_iter != NULL; dup_iter = dup_iter->next) {
remote_fencing_op_t *other = dup_iter->data;
if (other == relay_op) {
other->duplicates = g_list_remove(other->duplicates, relay_op);
break;
}
}
}
}
crm_info("Delete the relay op : %s - %s of %s for %s.(replaced by op : %s - %s of %s for %s)",
relay_op->id, relay_op->action, relay_op->target, relay_op->client_name,
op_id, relay_op->action, target, client_name);

g_hash_table_remove(stonith_remote_op_list, relay_op_id);
}
}
}

static int
handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,
xmlNode *request, const char *remote_peer)
Expand Down Expand Up @@ -2502,6 +2551,10 @@ handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,
if (remote_peer) {
create_remote_stonith_op(client_id, request, TRUE); /* Record it for the future notification */
}

/* Delete the DC node RELAY operation. */
remove_relay_op(request);

stonith_query(request, remote_peer, client_id, call_options);
return 0;

Expand Down Expand Up @@ -2582,6 +2635,7 @@ handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,

if (alternate_host && client) {
const char *client_id = NULL;
remote_fencing_op_t *op = NULL;

crm_notice("Forwarding complex self fencing request to peer %s", alternate_host);

Expand All @@ -2591,11 +2645,13 @@ handle_request(pcmk__client_t *client, uint32_t id, uint32_t flags,
client_id = crm_element_value(request, F_STONITH_CLIENTID);
}

/* Create a record of it, otherwise call_id will be 0 if we need to notify of failures */
create_remote_stonith_op(client_id, request, FALSE);
/* Create an operation for RELAY and send the ID in the RELAY message. */
/* When a QUERY response is received, delete the RELAY operation to avoid the existence of duplicate operations. */
op = create_remote_stonith_op(client_id, request, FALSE);

crm_xml_add(request, F_STONITH_OPERATION, STONITH_OP_RELAY);
crm_xml_add(request, F_STONITH_CLIENTID, client->id);
crm_xml_add(request, F_STONITH_REMOTE_OP_ID, op->id);
send_cluster_message(crm_get_peer(0, alternate_host), crm_msg_stonith_ng, request,
FALSE);
rc = -EINPROGRESS;
Expand Down
23 changes: 22 additions & 1 deletion daemons/fenced/fenced_remote.c
Expand Up @@ -984,6 +984,7 @@ create_remote_stonith_op(const char *client, xmlNode * request, gboolean peer)
remote_fencing_op_t *op = NULL;
xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, request, LOG_NEVER);
int call_options = 0;
const char *operation = NULL;

init_stonith_remote_op_hash_table(&stonith_remote_op_list);

Expand Down Expand Up @@ -1034,7 +1035,16 @@ create_remote_stonith_op(const char *client, xmlNode * request, gboolean peer)
op->client_id = strdup(client);
}

op->client_name = crm_element_value_copy(request, F_STONITH_CLIENTNAME);

/* For a RELAY operation, set fenced on the client. */
operation = crm_element_value(request, F_STONITH_OPERATION);

if (crm_str_eq(operation, STONITH_OP_RELAY, TRUE)) {
op->client_name = crm_strdup_printf("%s.%lu", crm_system_name,
(unsigned long) getpid());
} else {
op->client_name = crm_element_value_copy(request, F_STONITH_CLIENTNAME);
}

op->target = crm_element_value_copy(dev, F_STONITH_TARGET);
op->request = copy_xml(request); /* TODO: Figure out how to avoid this */
Expand Down Expand Up @@ -1085,6 +1095,8 @@ initiate_remote_stonith_op(pcmk__client_t *client, xmlNode *request,
xmlNode *query = NULL;
const char *client_id = NULL;
remote_fencing_op_t *op = NULL;
const char *relay_op_id = NULL;
const char *operation = NULL;

if (client) {
client_id = client->id;
Expand Down Expand Up @@ -1136,6 +1148,15 @@ initiate_remote_stonith_op(pcmk__client_t *client, xmlNode *request,
crm_xml_add(query, F_STONITH_CLIENTNAME, op->client_name);
crm_xml_add_int(query, F_STONITH_TIMEOUT, op->base_timeout);

/* In case of RELAY operation, RELAY information is added to the query to delete the original operation of RELAY. */
operation = crm_element_value(request, F_STONITH_OPERATION);
if (crm_str_eq(operation, STONITH_OP_RELAY, TRUE)) {
relay_op_id = crm_element_value(request, F_STONITH_REMOTE_OP_ID);
if (relay_op_id) {
crm_xml_add(query, F_STONITH_REMOTE_OP_ID_RELAY, relay_op_id);
}
}

send_cluster_message(NULL, crm_msg_stonith_ng, query, FALSE);
free_xml(query);

Expand Down
1 change: 1 addition & 0 deletions include/crm/fencing/internal.h
Expand Up @@ -64,6 +64,7 @@ stonith_history_t *stonith__sort_history(stonith_history_t *history);
# define F_STONITH_OPERATION "st_op"
# define F_STONITH_TARGET "st_target"
# define F_STONITH_REMOTE_OP_ID "st_remote_op"
# define F_STONITH_REMOTE_OP_ID_RELAY "st_remote_op_relay"
# define F_STONITH_RC "st_rc"
/*! Timeout period per a device execution */
# define F_STONITH_TIMEOUT "st_timeout"
Expand Down

0 comments on commit df71a07

Please sign in to comment.