From 4c80d4b994e99443ae403f22d3e65fd5e2c3edb7 Mon Sep 17 00:00:00 2001 From: Goldwyn Rodrigues Date: Fri, 23 Aug 2013 22:39:54 -0500 Subject: [PATCH 7/7] mount.ocfs2 performs module loading/cluster_stack setup --- mount.ocfs2/Makefile | 2 +- mount.ocfs2/mount.ocfs2.c | 6 +++ mount.ocfs2/mount.ocfs2.h | 1 + mount.ocfs2/stack.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++ mount.ocfs2/stack.h | 2 + 5 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 mount.ocfs2/stack.c create mode 100644 mount.ocfs2/stack.h diff --git a/mount.ocfs2/Makefile b/mount.ocfs2/Makefile index 2736f5f..8f80b62 100644 --- a/mount.ocfs2/Makefile +++ b/mount.ocfs2/Makefile @@ -15,7 +15,7 @@ LIBO2CB_DEPS = $(TOPDIR)/libo2cb/libo2cb.a DEFINES = -DVERSION=\"$(VERSION)\" -CORE_CFILES = fstab.c mntent.c realpath.c sundries.c xmalloc.c opts.c +CORE_CFILES = fstab.c mntent.c realpath.c sundries.c xmalloc.c opts.c stack.c MOUNT_CFILES = mount.ocfs2.c HFILES = $(subst .c,.h,$(MOUNT_CFILES) $(CORE_CFILES)) diff --git a/mount.ocfs2/mount.ocfs2.c b/mount.ocfs2/mount.ocfs2.c index f2ca5cb..4b9ba1f 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 = 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) { diff --git a/mount.ocfs2/mount.ocfs2.h b/mount.ocfs2/mount.ocfs2.h index 91d97d0..e76d8c3 100644 --- a/mount.ocfs2/mount.ocfs2.h +++ b/mount.ocfs2/mount.ocfs2.h @@ -47,6 +47,7 @@ #include "mntent.h" #include "mount_constants.h" #include "opts.h" +#include "stack.h" #include "ocfs2/ocfs2.h" #include "ocfs2/bitops.h" diff --git a/mount.ocfs2/stack.c b/mount.ocfs2/stack.c new file mode 100644 index 0000000..8a9ea93 --- /dev/null +++ b/mount.ocfs2/stack.c @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include +#include +#include "stack.h" + +#define CLUSTER_STACK_FILE "/sys/fs/ocfs2/cluster_stack" +#define MODPROBE_COMMAND "/sbin/modprobe" +#define USER_KERNEL_MODULE "ocfs2_stack_user" +#define O2CB_KERNEL_MODULE "ocfs2_stack_o2cb" +#define USER_STACK_NAME "pcmk" +#define CLASSIC_STACK_NAME "o2cb" +#define OCFS2_STACK_LABEL_LEN 4 + +static int read_single_line_file(char *filename, char *line, size_t count) +{ + ssize_t ret = 0; + FILE *f; + + f = fopen(filename, "r"); + if (f) { + if (fgets(line, count, f)) + ret = strlen(line); + fclose(f); + } else + ret = -errno; + + 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 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; +} + + +static int modprobe_and_write_stack(char *stack_name) +{ + perform_modprobe("ocfs2"); + if (!strncmp(stack_name, USER_STACK_NAME, OCFS2_STACK_LABEL_LEN)) + perform_modprobe(USER_KERNEL_MODULE); + else if (strncmp(stack_name, CLASSIC_STACK_NAME, OCFS2_STACK_LABEL_LEN)) + perform_modprobe(O2CB_KERNEL_MODULE); + else + return -EINVAL; + + write_single_line_file(CLUSTER_STACK_FILE, stack_name, + strlen(stack_name)); + return 0; +} + +errcode_t setup_stack(char *stack_name) +{ + char line[64]; + int modprobe_performed = 0; + errcode_t err = 0; + 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 = O2CB_ET_SERVICE_UNAVAILABLE; + goto out; + } + + if (!strncmp(line, CLASSIC_STACK_NAME, OCFS2_STACK_LABEL_LEN) || + !strncmp(line, USER_STACK_NAME, OCFS2_STACK_LABEL_LEN)) + err = 0; + else + err = O2CB_ET_INTERNAL_FAILURE; + + } else if (len == -ENOENT) { + if (!modprobe_performed) { + modprobe_and_write_stack(stack_name); + err = O2CB_ET_INTERNAL_FAILURE; + modprobe_performed = 1; + goto redo; + } else + err = O2CB_ET_INTERNAL_FAILURE; + } +out: + return err; +} + diff --git a/mount.ocfs2/stack.h b/mount.ocfs2/stack.h new file mode 100644 index 0000000..ec5f2de --- /dev/null +++ b/mount.ocfs2/stack.h @@ -0,0 +1,2 @@ +#include +errcode_t setup_stack(char *stack_name); -- 1.8.1.4