Re: [PATCH] votequorum: add API to clear the wait_for_all status

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Linux Clusters]     [Corosync Project]     [Linux USB Devel]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]    [Linux Kernel]     [Linux SCSI]     [X.Org]

  Powered by Linux