File 0008-mount.ocfs2-Read-stack-from-device-and-setup-stack-i.patch of Package ocfs2-tools

From 5d0bffdbbadd38173a9bfbf4ffb8d455b5f0b990 Mon Sep 17 00:00:00 2001
From: Goldwyn Rodrigues <rgoldwyn@suse.com>
Date: Tue, 3 Sep 2013 07:40:39 -0500
Subject: [PATCH 8/8] mount.ocfs2: Read stack from device and setup stack if
 not present

Note, this removes cman as the possible user stack.
---
 include/o2cb/o2cb.h       |   1 +
 libo2cb/o2cb_abi.c        | 103 ++++++++++++++++++++++++++++++++++++++++++++++
 mount.ocfs2/mount.ocfs2.c |   6 +++
 3 files changed, 110 insertions(+)

diff --git a/include/o2cb/o2cb.h b/include/o2cb/o2cb.h
index d512cf9..5ef9754 100644
--- a/include/o2cb/o2cb.h
+++ b/include/o2cb/o2cb.h
@@ -208,5 +208,6 @@ void o2cb_control_close(void);
 errcode_t o2cb_control_node_down(const char *uuid, unsigned int nodeid);
 
 errcode_t o2cb_get_hb_ctl_path(char *buf, int count);
+errcode_t o2cb_setup_stack(char *stack_name);
 
 #endif  /* _O2CB_H */
diff --git a/libo2cb/o2cb_abi.c b/libo2cb/o2cb_abi.c
index 26ed848..6d1e41a 100644
--- a/libo2cb/o2cb_abi.c
+++ b/libo2cb/o2cb_abi.c
@@ -29,6 +29,7 @@
 #include <sys/ioctl.h>
 #include <sys/ipc.h>
 #include <sys/sem.h>
+#include <sys/wait.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -103,6 +104,7 @@ static struct o2cb_stack_ops user_ops = {
 	.group_leave		= user_group_leave,
 };
 static struct o2cb_stack user_stack = {
+	.s_name		= "pcmk",
 	.s_ops		= &user_ops,
 };
 
@@ -142,6 +144,22 @@ static ssize_t read_single_line_file(const char *file, char *line,
 	return ret;
 }
 
+static int write_single_line_file(char *filename, char *line, size_t count)
+{
+	ssize_t ret = 0;
+	FILE *f;
+
+	f = fopen(filename, "w");
+	if (f) {
+		if (fputs(line, f))
+			ret = strlen(line);
+		fclose(f);
+	} else
+		ret = -errno;
+
+	return ret;
+}
+
 static ssize_t read_stack_file(char *line, size_t count)
 {
 	return read_single_line_file(CLUSTER_STACK_FILE, line, count);
@@ -2017,3 +2035,88 @@ errcode_t o2cb_get_hb_ctl_path(char *buf, int count)
 
 	return 0;
 }
+
+#define MODPROBE_COMMAND	"/sbin/modprobe"
+#define USER_KERNEL_MODULE	"ocfs2_stack_user"
+#define O2CB_KERNEL_MODULE	"ocfs2_stack_o2cb"
+
+static int perform_modprobe(char *module_name)
+{
+	pid_t child;
+	int child_status;
+
+	char *argv[3];
+
+	argv[0] = MODPROBE_COMMAND;
+	argv[1] = module_name;
+	argv[2] = NULL;
+
+	child = fork();
+	if (child == 0) {
+		execv(MODPROBE_COMMAND, argv);
+		/* If execv fails, we have a problem */
+		return -EINVAL;
+	} else 
+		wait(&child_status);
+
+	return child_status;
+}
+
+errcode_t o2cb_setup_stack(char *stack_name)
+{
+	char line[64];
+	int modprobe_performed = 0, write_performed = 0;
+	errcode_t err = O2CB_ET_SERVICE_UNAVAILABLE;
+	int len;
+
+redo:
+	len = read_single_line_file(CLUSTER_STACK_FILE, line, sizeof(line));
+
+	if (len > 0) {
+		if (line[len - 1] == '\n') {
+			line[len - 1] = '\0';
+			len--;
+		}
+
+		if (len != OCFS2_STACK_LABEL_LEN) {
+			err = O2CB_ET_INTERNAL_FAILURE;
+			goto out;
+		}
+
+		if (!strncmp(line, stack_name, OCFS2_STACK_LABEL_LEN)) {
+			err = 0;
+			goto out;
+		}
+
+		if (!write_performed) {
+			write_single_line_file(CLUSTER_STACK_FILE, stack_name,
+					strlen(stack_name));
+			write_performed = 1;
+			goto redo;
+		}
+
+	} else if (len == -ENOENT) {
+		if (!modprobe_performed) {
+			perform_modprobe("ocfs2");
+			if (!strncmp(stack_name, user_stack.s_name,
+						OCFS2_STACK_LABEL_LEN))
+				perform_modprobe(USER_KERNEL_MODULE);
+			else if (!strncmp(stack_name, classic_stack.s_name,
+						OCFS2_STACK_LABEL_LEN))
+				perform_modprobe(O2CB_KERNEL_MODULE);
+
+			write_single_line_file(CLUSTER_STACK_FILE, stack_name,
+					strlen(stack_name));
+			write_performed = 1;
+			goto redo;
+		} else
+			err = O2CB_ET_INTERNAL_FAILURE;
+	} else {
+		err = O2CB_ET_INTERNAL_FAILURE;
+		goto out;
+	}
+
+	err = 0;
+out:
+	return err;
+}
diff --git a/mount.ocfs2/mount.ocfs2.c b/mount.ocfs2/mount.ocfs2.c
index f2ca5cb..c009d82 100644
--- a/mount.ocfs2/mount.ocfs2.c
+++ b/mount.ocfs2/mount.ocfs2.c
@@ -357,6 +357,12 @@ int main(int argc, char **argv)
 	if (verbose)
 		printf("device=%s\n", mo.dev);
 
+	ret = o2cb_setup_stack((char *)OCFS2_RAW_SB(fs->fs_super)->s_cluster_info.ci_stack);
+	if (ret) {
+		com_err(progname, ret, "while setting up stack\n");
+		goto bail;
+	}
+
 	if (clustered) {
 		ret = o2cb_init();
 		if (ret) {
-- 
1.8.1.4

openSUSE Build Service is sponsored by