[Ocfs2-tools-devel] [PATCH 34/39] libo2cb: Teach the control device handshake about the protocol version

Joel Becker joel.becker at oracle.com
Fri Mar 14 16:52:57 PDT 2008


The handshake with the ocfs2_control device now requires the filesystem
protocol version to be passed.  This version is negotiated by the control
daemon, and is based on /sys/fs/ocfs2/max_locking_protocol.

For this first pass, just write back what max_locking_protocol contains.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 include/o2cb/o2cb.h |    5 +++
 libo2cb/o2cb_abi.c  |   85 +++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 87 insertions(+), 3 deletions(-)

diff --git a/include/o2cb/o2cb.h b/include/o2cb/o2cb.h
index cc465d1..59e3667 100644
--- a/include/o2cb/o2cb.h
+++ b/include/o2cb/o2cb.h
@@ -113,6 +113,11 @@ errcode_t o2cb_get_node_num(const char *cluster_name,
 			    const char *node_name,
 			    uint16_t *node_num);
 
+struct ocfs2_protocol_version {
+	uint8_t	pv_major;
+	uint8_t pv_minor;
+};
+errcode_t o2cb_get_max_locking_protocol(struct ocfs2_protocol_version *proto);
 errcode_t o2cb_control_open(unsigned int this_node);
 void o2cb_control_close(void);
 errcode_t o2cb_control_node_down(const char *uuid, unsigned int nodeid);
diff --git a/libo2cb/o2cb_abi.c b/libo2cb/o2cb_abi.c
index d6f7b3f..6f02a26 100644
--- a/libo2cb/o2cb_abi.c
+++ b/libo2cb/o2cb_abi.c
@@ -43,6 +43,7 @@
 #include "o2cb_crc32.h"
 
 #define CLUSTER_STACK_FILE	"/sys/fs/ocfs2/cluster_stack"
+#define LOCKING_PROTOCOL_FILE	"/sys/fs/ocfs2/max_locking_protocol"
 #define OCFS2_STACK_LABEL_LEN	4
 #define CONTROL_DEVICE		"/dev/misc/ocfs2_control"
 
@@ -107,12 +108,13 @@ static int control_device_fd = -1;
 static char *configfs_path;
 
 
-static ssize_t read_stack_file(char *line, size_t count)
+static ssize_t read_single_line_file(const char *file, char *line,
+				     size_t count)
 {
 	ssize_t ret = 0;
 	FILE *f;
 
-	f = fopen(CLUSTER_STACK_FILE, "r");
+	f = fopen(file, "r");
 	if (f) {
 		if (fgets(line, count, f))
 			ret = strlen(line);
@@ -123,6 +125,11 @@ static ssize_t read_stack_file(char *line, size_t count)
 	return ret;
 }
 
+static ssize_t read_stack_file(char *line, size_t count)
+{
+	return read_single_line_file(CLUSTER_STACK_FILE, line, count);
+}
+
 static errcode_t determine_stack(void)
 {
 	ssize_t len;
@@ -164,6 +171,63 @@ errcode_t o2cb_get_stack_name(const char **name)
 	return 0;
 }
 
+static ssize_t read_locking_proto_file(char *line, size_t count)
+{
+	return read_single_line_file(LOCKING_PROTOCOL_FILE, line, count);
+}
+
+errcode_t o2cb_get_max_locking_protocol(struct ocfs2_protocol_version *proto)
+{
+	ssize_t len;
+	char line[100];
+	errcode_t err;
+	unsigned int major, minor;
+
+	len = read_locking_proto_file(line, sizeof(line));
+	if (len <= 0) {
+		switch (-len) {
+			case EACCES:
+			case EPERM:
+				err = O2CB_ET_PERMISSION_DENIED;
+				break;
+
+			case ENOMEM:
+				err = O2CB_ET_NO_MEMORY;
+				break;
+
+			case 0:
+			case ENOENT:
+			case ENOTDIR:
+				err = O2CB_ET_SERVICE_UNAVAILABLE;
+				break;
+
+			default:
+				err = O2CB_ET_INTERNAL_FAILURE;
+				break;
+		}
+		goto out;
+	}
+
+	if (line[len - 1] == '\n') {
+		line[len - 1] = '\0';
+		len--;
+	}
+
+	err = O2CB_ET_SERVICE_UNAVAILABLE;
+	if (sscanf(line, "%u.%u", &major, &minor) != 2)
+		goto out;
+	/* Major and minor can't be more than a u8 */
+	if ((major > (uint8_t)-1) || (minor > (uint8_t)-1))
+		goto out;
+
+	proto->pv_major = major;
+	proto->pv_minor = minor;
+	err = 0;
+
+out:
+	return err;
+}
+
 
 errcode_t o2cb_create_cluster(const char *cluster_name)
 {
@@ -1876,6 +1940,8 @@ errcode_t o2cb_get_node_num(const char *cluster_name, const char *node_name,
 #define OCFS2_CONTROL_PROTO_LEN			4
 #define OCFS2_CONTROL_MESSAGE_SETNODE_OP	"SETN"
 #define OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN	14
+#define OCFS2_CONTROL_MESSAGE_SETVERSION_OP	"SETV"
+#define OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN	11
 #define OCFS2_CONTROL_MESSAGE_DOWN_OP		"DOWN"
 #define OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN	47
 #define OCFS2_CONTROL_MESSAGE_NODENUM_LEN	8
@@ -1884,6 +1950,7 @@ static errcode_t o2cb_control_handshake(unsigned int this_node)
 	errcode_t err = 0;
 	int found = 0;
 	size_t ret;
+	struct ocfs2_protocol_version proto;
 	char buf[OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN + 1];
 
 	if (control_device_fd == -1) {
@@ -1891,6 +1958,10 @@ static errcode_t o2cb_control_handshake(unsigned int this_node)
 		goto out;
 	}
 
+	err = o2cb_get_max_locking_protocol(&proto);
+	if (err)
+		goto out;
+
 	buf[OCFS2_CONTROL_PROTO_LEN] = '\0';
 	while (1)
 	{
@@ -1920,12 +1991,20 @@ static errcode_t o2cb_control_handshake(unsigned int this_node)
 	}
 
 	snprintf(buf, OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN + 1,
-		 "SETN %08X\n", this_node);
+		 OCFS2_CONTROL_MESSAGE_SETNODE_OP " %08X\n", this_node);
 	ret = write(control_device_fd, buf,
 		    OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN);
 	if (ret != OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN)
 		err = O2CB_ET_IO;
 
+	snprintf(buf, OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN + 1,
+		 OCFS2_CONTROL_MESSAGE_SETVERSION_OP " %02X %02X\n",
+		 proto.pv_major, proto.pv_minor);
+	ret = write(control_device_fd, buf,
+		    OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN);
+	if (ret != OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN)
+		err = O2CB_ET_IO;
+
 out:
 	return err;
 }
-- 
1.5.3.8




More information about the Ocfs2-tools-devel mailing list