From 5d0bffdbbadd38173a9bfbf4ffb8d455b5f0b990 Mon Sep 17 00:00:00 2001 From: Goldwyn Rodrigues 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 #include #include +#include #include #include #include @@ -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