Updated patch with addition of corosync_quorumtool -w command so that
pcs can access it.
Signed-Off-By: Christine Caulfield <ccaulfie@xxxxxxxxxx>
diff --git a/exec/votequorum.c b/exec/votequorum.c
index 78e6b7b..396dddc 100644
--- a/exec/votequorum.c
+++ b/exec/votequorum.c
@@ -150,6 +150,7 @@ static int votequorum_exec_send_quorum_notification(void *conn, uint64_t context
#define VOTEQUORUM_RECONFIG_PARAM_EXPECTED_VOTES 1
#define VOTEQUORUM_RECONFIG_PARAM_NODE_VOTES 2
+#define VOTEQUORUM_RECONFIG_PARAM_CANCEL_WFA 3
static int votequorum_exec_send_reconfigure(uint8_t param, unsigned int nodeid, uint32_t value);
@@ -345,6 +346,9 @@ static void message_handler_req_lib_votequorum_qdevice_poll (void *conn,
static void message_handler_req_lib_votequorum_qdevice_master_wins (void *conn,
const void *message);
+static void message_handler_req_lib_votequorum_cancel_wait_for_all (void *conn,
+ const void *message);
+
static struct corosync_lib_handler quorum_lib_service[] =
{
{ /* 0 */
@@ -386,6 +390,10 @@ static struct corosync_lib_handler quorum_lib_service[] =
{ /* 9 */
.lib_handler_fn = message_handler_req_lib_votequorum_qdevice_master_wins,
.flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 10 */
+ .lib_handler_fn = message_handler_req_lib_votequorum_cancel_wait_for_all,
+ .flow_control = COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED
}
};
@@ -2070,6 +2078,14 @@ static void message_handler_req_exec_votequorum_reconfigure (
recalculate_quorum(1, 0); /* Allow decrease */
break;
+ case VOTEQUORUM_RECONFIG_PARAM_CANCEL_WFA:
+ update_wait_for_all_status(0);
+ log_printf(LOGSYS_LEVEL_INFO, "wait_for_all_status reset by user on node %d.",
+ req_exec_quorum_reconfigure->nodeid);
+ recalculate_quorum(0, 0);
+
+ break;
+
}
LEAVE();
@@ -2876,3 +2892,26 @@ out:
LEAVE();
}
+
+static void message_handler_req_lib_votequorum_cancel_wait_for_all (void *conn,
+ const void *message)
+{
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+ cs_error_t error = CS_OK;
+
+ if (wait_for_all_status == 0) {
+ error = CS_ERR_NOT_EXIST;
+ goto out;
+ }
+
+ votequorum_exec_send_reconfigure(VOTEQUORUM_RECONFIG_PARAM_CANCEL_WFA,
+ us->node_id, 0);
+
+
+out:
+ res_lib_votequorum_status.header.size = sizeof(res_lib_votequorum_status);
+ res_lib_votequorum_status.header.id = MESSAGE_RES_VOTEQUORUM_CANCEL_WFA;
+ res_lib_votequorum_status.header.error = error;
+ corosync_api->ipc_response_send(conn, &res_lib_votequorum_status, sizeof(res_lib_votequorum_status));
+
+}
diff --git a/include/corosync/ipc_votequorum.h b/include/corosync/ipc_votequorum.h
index c06814f..16a0891 100644
--- a/include/corosync/ipc_votequorum.h
+++ b/include/corosync/ipc_votequorum.h
@@ -50,7 +50,8 @@ enum req_votequorum_types {
MESSAGE_REQ_VOTEQUORUM_QDEVICE_UNREGISTER,
MESSAGE_REQ_VOTEQUORUM_QDEVICE_UPDATE,
MESSAGE_REQ_VOTEQUORUM_QDEVICE_POLL,
- MESSAGE_REQ_VOTEQUORUM_QDEVICE_MASTER_WINS
+ MESSAGE_REQ_VOTEQUORUM_QDEVICE_MASTER_WINS,
+ MESSAGE_REQ_VOTEQUORUM_CANCEL_WFA
};
enum res_votequorum_types {
@@ -58,7 +59,8 @@ enum res_votequorum_types {
MESSAGE_RES_VOTEQUORUM_GETINFO,
MESSAGE_RES_VOTEQUORUM_TRACKSTART,
MESSAGE_RES_VOTEQUORUM_NOTIFICATION,
- MESSAGE_RES_VOTEQUORUM_EXPECTEDVOTES_NOTIFICATION
+ MESSAGE_RES_VOTEQUORUM_EXPECTEDVOTES_NOTIFICATION,
+ MESSAGE_RES_VOTEQUORUM_CANCEL_WFA
};
struct mar_votequorum_ring_id {
diff --git a/include/corosync/votequorum.h b/include/corosync/votequorum.h
index 9bc5690..465c993 100644
--- a/include/corosync/votequorum.h
+++ b/include/corosync/votequorum.h
@@ -183,6 +183,13 @@ cs_error_t votequorum_context_set (
void *context);
/**
+ * Cancel wait_for_all. Only to be used with GREAT care and
+ * and good knowledge and experience.
+ */
+cs_error_t votequorum_cancel_wait_for_all (
+ votequorum_handle_t handle);
+
+/**
* Register a quorum device
*
* it will be DEAD until polled
diff --git a/lib/libvotequorum.versions b/lib/libvotequorum.versions
index 7a37030..05dbc95 100644
--- a/lib/libvotequorum.versions
+++ b/lib/libvotequorum.versions
@@ -14,4 +14,5 @@ COROSYNC_VOTEQUORUM_1.0 {
votequorum_trackstop;
votequorum_context_get;
votequorum_context_set;
+ votequorum_cancel_wait_for_all;
};
diff --git a/lib/libvotequorum.verso b/lib/libvotequorum.verso
index 66ce77b..ae9a76b 100644
--- a/lib/libvotequorum.verso
+++ b/lib/libvotequorum.verso
@@ -1 +1 @@
-7.0.0
+8.0.0
diff --git a/lib/votequorum.c b/lib/votequorum.c
index be4ef43..3775bed 100644
--- a/lib/votequorum.c
+++ b/lib/votequorum.c
@@ -797,3 +797,42 @@ error_exit:
return (error);
}
+
+cs_error_t votequorum_cancel_wait_for_all (
+ votequorum_handle_t handle)
+{
+ cs_error_t error;
+ struct votequorum_inst *votequorum_inst;
+ struct iovec iov;
+ struct req_lib_votequorum_general req_lib_votequorum_general;
+ struct res_lib_votequorum_status res_lib_votequorum_status;
+
+ error = hdb_error_to_cs(hdb_handle_get (&votequorum_handle_t_db, handle, (void *)&votequorum_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ req_lib_votequorum_general.header.size = sizeof (struct req_lib_votequorum_general);
+ req_lib_votequorum_general.header.id = MESSAGE_REQ_VOTEQUORUM_CANCEL_WFA;
+
+ iov.iov_base = (char *)&req_lib_votequorum_general;
+ iov.iov_len = sizeof (struct req_lib_votequorum_general);
+
+ error = qb_to_cs_error(qb_ipcc_sendv_recv (
+ votequorum_inst->c,
+ &iov,
+ 1,
+ &res_lib_votequorum_status,
+ sizeof (struct res_lib_votequorum_status), CS_IPC_TIMEOUT_MS));
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_votequorum_status.header.error;
+
+error_exit:
+ hdb_handle_put (&votequorum_handle_t_db, handle);
+
+ return (error);
+}
diff --git a/man/Makefile.am b/man/Makefile.am
index 41284cb..30c3d28 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -77,6 +77,7 @@ autogen_man = cpg_context_get.3 \
votequorum_setvotes.3 \
votequorum_trackstart.3 \
votequorum_trackstop.3 \
+ votequorum_cancel_wait_for_all.3 \
votequorum_qdevice_register.3 \
votequorum_qdevice_unregister.3 \
votequorum_qdevice_update.3 \
diff --git a/man/votequorum_cancel_wait_for_all.3.in b/man/votequorum_cancel_wait_for_all.3.in
new file mode 100644
index 0000000..157d9bc
--- /dev/null
+++ b/man/votequorum_cancel_wait_for_all.3.in
@@ -0,0 +1,88 @@
+.\"/*
+.\" * Copyright (c) 2014 Red Hat, Inc.
+.\" *
+.\" * All rights reserved.
+.\" *
+.\" * Author: Christine Caulfield <ccaulfie@xxxxxxxxxx>
+.\" *
+.\" * This software licensed under BSD license, the text of which follows:
+.\" *
+.\" * Redistribution and use in source and binary forms, with or without
+.\" * modification, are permitted provided that the following conditions are met:
+.\" *
+.\" * - Redistributions of source code must retain the above copyright notice,
+.\" * this list of conditions and the following disclaimer.
+.\" * - Redistributions in binary form must reproduce the above copyright notice,
+.\" * this list of conditions and the following disclaimer in the documentation
+.\" * and/or other materials provided with the distribution.
+.\" * - Neither the name of the MontaVista Software, Inc. nor the names of its
+.\" * contributors may be used to endorse or promote products derived from this
+.\" * software without specific prior written permission.
+.\" *
+.\" * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+.\" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+.\" * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+.\" * THE POSSIBILITY OF SUCH DAMAGE.
+.\" */
+.TH VOTEQUORUM_CANCEL_WAIT_FOR_ALL 3 @BUILDDATE@ "corosync Man Page" "Corosync Cluster Engine Programmer's Manual"
+.SH NAME
+votequorum_cancel_wait_for_all \- Force quorum in an incomplete wait_for_all cluster
+.SH SYNOPSIS
+.B #include <corosync/votequorum.h>
+.sp
+.BI "int votequorum_cancel_wait_for_all(votequorum_handle_t *" handle ");"
+.SH DESCRIPTION
+The
+.B votequorum_cancel_wait_for_all
+function is used to cancel the wait_for_all_status flag.
+.PP
+If you have not read and fully (and I mean fully) understood the votequorum(5)
+man page then don't even think about reading this one any further. It's not for you.
+.PP
+In a two_node cluster or a cluster with wait_for_all flag set (wait_for_all is
+enabled automatically in a two_node cluster), quorum will be suspended until
+all of the nodes in the nodelist have joined the cluster.
+.PP
+In some circumstances it might be necessary to override this situation, for example
+if a node comes up on its own and it is known for an absolute certainty that the other
+node is not available. In this case this call will allow the single node to proceed
+on its own.
+.PP
+This function call should not be called by any application software, it exists for
+use by the pcs cluster management software and should always be used in that context.
+.PP
+Be very, very, very careful with the use of this function and its pcs command. Using
+it without fully understanding the consequences can cause split brains and data
+corruption. You have been warned.
+.PP
+I'll say this again. Do NOT use this function unless you have checked, at least three times,
+that you fully understand the consequences of doing so and consulted your manager or Red Hat
+support. Ideally both.
+.PP
+
+.fi
+.SH RETURN VALUE
+This call returns the CS_OK value if successful, otherwise an error is returned.
+.PP
+.SH ERRORS
+@COMMONIPCERRORS@
+.SH "SEE ALSO"
+.BR votequorum_overview (8),
+.BR votequorum_initialize (3),
+.BR votequorum_finalize (3),
+.BR votequorum_getinfo (3),
+.BR votequorum_trackstop (3),
+.BR votequorum_fd_get (3),
+.BR votequorum_dispatch (3),
+.BR votequorum_context_set (3),
+.BR votequorum_context_get (3),
+.BR votequorum_setexpected (3),
+.BR votequorum_setvotes (3)
+.PP
diff --git a/test/testvotequorum2.c b/test/testvotequorum2.c
index 0a2e926..008d401 100644
--- a/test/testvotequorum2.c
+++ b/test/testvotequorum2.c
@@ -103,6 +103,7 @@ static void usage(const char *command)
printf(" -c Cast vote (default yes)\n");
printf(" -q Don't print device status every poll time (default=will print)\n");
printf(" -m Master wins (default no)\n");
+ printf(" -W Cancel wait_for_all status\n");
printf(" -1 Print status once and exit\n");
}
@@ -112,11 +113,12 @@ int main(int argc, char *argv[])
int cast_vote = 1, master_wins = 0;
int pollcount=0, polltime=1, quiet=0, once=0;
int send_old_ringid = 0;
+ int cancel_wfa = 0;
int err;
int opt;
votequorum_callbacks_t callbacks;
const char *devicename = "QDEVICE";
- const char *options = "F:n:p:t:cmq1h";
+ const char *options = "F:n:p:t:cmq1hW";
memset(&callbacks, 0, sizeof(callbacks));
callbacks.votequorum_notify_fn = votequorum_notification_fn;
@@ -147,6 +149,9 @@ int main(int argc, char *argv[])
case 't':
polltime = atoi(optarg);
break;
+ case 'W':
+ cancel_wfa = 1;
+ break;
case 'h':
usage(argv[0]);
exit(0);
@@ -167,6 +172,14 @@ int main(int argc, char *argv[])
if (!quiet) {
print_info(1);
}
+ if (cancel_wfa) {
+ ret = votequorum_cancel_wait_for_all(handle);
+ if (ret != CS_OK)
+ printf("cancel_wait_for_all returned %d\n", ret);
+ else
+ printf("cancel_wait_for_all succeeded\n");
+ goto out;
+ }
if (once) {
exit(0);
}
diff --git a/tools/corosync-quorumtool.c b/tools/corosync-quorumtool.c
index 11124b3..ddcffe9 100644
--- a/tools/corosync-quorumtool.c
+++ b/tools/corosync-quorumtool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009-2012 Red Hat, Inc.
+ * Copyright (c) 2009-2014 Red Hat, Inc.
*
* All rights reserved.
*
@@ -65,7 +65,8 @@ typedef enum {
CMD_SETVOTES,
CMD_SETEXPECTED,
CMD_MONITOR,
- CMD_UNREGISTER_QDEVICE
+ CMD_UNREGISTER_QDEVICE,
+ CMD_CANCEL_WFA
} command_t;
/*
@@ -142,6 +143,7 @@ static void show_usage(const char *name)
printf(" -H show nodeids in hexadecimal rather than decimal\n");
printf(" -i show node IP addresses instead of the resolved name\n");
printf(" -f forcefully unregister a quorum device *DANGEROUS* (*)\n");
+ printf(" -w Cancel wait_for_all status to unblock quorum *DANGEROUS* (*)\n");
printf(" -h show this help text\n");
printf(" -V show version and exit\n");
printf("\n");
@@ -705,7 +707,7 @@ static void close_all(void) {
}
int main (int argc, char *argv[]) {
- const char *options = "VHslpmfe:v:hin:";
+ const char *options = "VHslpmfe:v:hiwn:";
char *endptr;
int opt;
int votes = 0;
@@ -747,6 +749,13 @@ int main (int argc, char *argv[]) {
case 'l':
command_opt = CMD_SHOWNODES;
break;
+ case 'w':
+ command_opt = CMD_CANCEL_WFA;
+ if (!using_votequorum()) {
+ fprintf(stderr, "You cannot cancel wait_for_all, corosync is not using votequorum\n");
+ exit(2);
+ }
+ break;
case 'p':
machine_parsable = 1;
break;
@@ -825,6 +834,9 @@ int main (int argc, char *argv[]) {
case CMD_UNREGISTER_QDEVICE:
ret = unregister_qdevice();
break;
+ case CMD_CANCEL_WFA:
+ ret = votequorum_cancel_wait_for_all(v_handle);
+ break;
}
close_all();
_______________________________________________
discuss mailing list
discuss@xxxxxxxxxxxx
http://lists.corosync.org/mailman/listinfo/discuss