[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