forked from pool/ocfs2-tools
d2c24a0629
Patch refactoring to keep libdlm through dlopen OBS-URL: https://build.opensuse.org/request/show/212363 OBS-URL: https://build.opensuse.org/package/show/network:ha-clustering:Factory/ocfs2-tools?expand=0&rev=73
175 lines
4.3 KiB
Diff
175 lines
4.3 KiB
Diff
From 4b99b5a6042fe9b33079df64ab13817a309de528 Mon Sep 17 00:00:00 2001
|
|
From: Goldwyn Rodrigues <rgoldwyn@suse.com>
|
|
Date: Fri, 27 Dec 2013 09:52:09 -0600
|
|
Subject: [PATCH] Auto setup cluster_stack based on what is on disk
|
|
|
|
This happens only the first time.
|
|
mount.ocfs2 reads the stack from the filesystems superblock. If the
|
|
stack is not setup, it will modprobe the modules and write the
|
|
appropriate stack name to cluster_stack file.
|
|
If it is already present, it tries to edit/re-write it, if different.
|
|
If it fails, the mount fails.
|
|
---
|
|
include/o2cb/o2cb.h | 1 +
|
|
libo2cb/o2cb_abi.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
mount.ocfs2/mount.ocfs2.c | 6 +++
|
|
3 files changed, 111 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 5eca49d..c751abf 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>
|
|
@@ -145,6 +146,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);
|
|
@@ -2383,3 +2400,90 @@ 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, OCFS2_PCMK_CLUSTER_STACK,
|
|
+ OCFS2_STACK_LABEL_LEN)) ||
|
|
+ (!strncmp(stack_name, OCFS2_CMAN_CLUSTER_STACK,
|
|
+ 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,
|
|
+ OCFS2_STACK_LABEL_LEN);
|
|
+ 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.4
|
|
|