[Ocfs2-tools-devel] [PATCH 25/29] mkfs.ocfs2: Add --global-heartbeat option
Sunil Mushran
sunil.mushran at oracle.com
Fri Jul 23 16:43:32 PDT 2010
In normal course, we expect users to use tunefs.ocfs2 --update-cluster-stack
to update the disk with the running cluster information. But starting an
o2cb cluster stack with global heartbeat requires a ocfs2 volume with global
heartbeat enabled. The mkfs option has been provided for this reason.
Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
---
mkfs.ocfs2/check.c | 79 ++++++++++++++++++++++++++++++++++++++-------------
mkfs.ocfs2/mkfs.c | 30 +++++++++++++++++++-
mkfs.ocfs2/mkfs.h | 1 +
3 files changed, 89 insertions(+), 21 deletions(-)
diff --git a/mkfs.ocfs2/check.c b/mkfs.ocfs2/check.c
index 597b87b..1a0f7ec 100644
--- a/mkfs.ocfs2/check.c
+++ b/mkfs.ocfs2/check.c
@@ -28,7 +28,8 @@
#define WHOAMI "mkfs.ocfs2"
/* For ocfs2_fill_cluster_information(). Errors are to be ignored */
-static void cluster_fill(char **stack_name, char **cluster_name)
+static void cluster_fill(char **stack_name, char **cluster_name,
+ uint8_t *stack_flags)
{
errcode_t err;
struct o2cb_cluster_desc cluster;
@@ -48,13 +49,14 @@ static void cluster_fill(char **stack_name, char **cluster_name)
*/
*stack_name = cluster.c_stack;
*cluster_name = cluster.c_cluster;
+ *stack_flags = cluster.c_flags;
} else
- *stack_name = strdup("o2cb");
+ *stack_name = strdup(OCFS2_CLASSIC_CLUSTER_STACK);
}
/* For ocfs2_fill_cluster_information(). Errors are to be ignored */
static void disk_fill(const char *device, char **stack_name,
- char **cluster_name)
+ char **cluster_name, uint8_t *stack_flags)
{
errcode_t err;
ocfs2_filesys *fs = NULL;
@@ -65,7 +67,7 @@ static void disk_fill(const char *device, char **stack_name,
return;
if (!ocfs2_clusterinfo_valid(OCFS2_RAW_SB(fs->fs_super))) {
- *stack_name = strdup("o2cb");
+ *stack_name = strdup(OCFS2_CLASSIC_CLUSTER_STACK);
goto close;
}
@@ -75,6 +77,7 @@ static void disk_fill(const char *device, char **stack_name,
*stack_name = strdup(desc.c_stack);
*cluster_name = strdup(desc.c_cluster);
+ *stack_flags = desc.c_flags;
close:
ocfs2_close(fs);
@@ -151,18 +154,43 @@ int ocfs2_fill_cluster_information(State *s)
int rc = -1;
char *user_cluster_name = NULL;
char *user_stack_name = NULL;
+ uint8_t user_stack_flags = 0;
char *o2cb_cluster_name = NULL;
char *o2cb_stack_name = NULL;
+ uint8_t o2cb_stack_flags = 0;
char *disk_cluster_name = NULL;
char *disk_stack_name = NULL;
+ uint8_t disk_stack_flags = 0;
+ int clusterinfo = 0;
if (s->mount == MOUNT_LOCAL)
return 0;
- cluster_fill(&o2cb_stack_name, &o2cb_cluster_name);
- disk_fill(s->device_name, &disk_stack_name, &disk_cluster_name);
+ /* cluster stack as provided by the user */
user_stack_name = s->cluster_stack;
user_cluster_name = s->cluster_name;
+ user_stack_flags = s->stack_flags;
+
+ /* currently active cluster stack */
+ cluster_fill(&o2cb_stack_name, &o2cb_cluster_name, &o2cb_stack_flags);
+
+ /* cluster stack configured on disk */
+ disk_fill(s->device_name, &disk_stack_name, &disk_cluster_name,
+ &disk_stack_flags);
+
+ if (!disk_stack_name)
+ disk_stack_name = strdup(o2cb_stack_name);
+ if (!strcmp(disk_stack_name, "")) {
+ free(disk_stack_name);
+ disk_stack_name = strdup(o2cb_stack_name);
+ }
+
+ if (!disk_cluster_name)
+ disk_cluster_name = strdup(o2cb_cluster_name);
+ if (!strcmp(disk_cluster_name, "")) {
+ free(disk_cluster_name);
+ disk_cluster_name = strdup(o2cb_cluster_name);
+ }
if (pick_one(s, "cluster stack", user_stack_name, o2cb_stack_name,
disk_stack_name, &s->cluster_stack))
@@ -173,13 +201,12 @@ int ocfs2_fill_cluster_information(State *s)
&s->cluster_name))
return -1;
+ if (s->feature_flags.opt_incompat & OCFS2_FEATURE_INCOMPAT_CLUSTERINFO)
+ clusterinfo++;
+
if (s->cluster_stack) {
- if (!strcmp(s->cluster_stack, "o2cb")) {
- /*
- * We've already checked for conflicts above. Now
- * clear out the stack so that fill_super knows
- * it's a classic filesystem.
- */
+ if (!clusterinfo &&
+ !strcmp(s->cluster_stack, OCFS2_CLASSIC_CLUSTER_STACK)) {
free(s->cluster_stack);
s->cluster_stack = NULL;
} else if (!s->cluster_name) {
@@ -189,28 +216,40 @@ int ocfs2_fill_cluster_information(State *s)
goto out;
}
}
- if (!s->cluster_stack && s->cluster_name) {
+
+ if (!clusterinfo && !s->cluster_stack && s->cluster_name) {
/* The classic stack doesn't write a name */
free(s->cluster_name);
s->cluster_name = NULL;
}
+
+ /*
+ * Currently stack_flags is only used by the o2cb stack. The user value
+ * is given highest precedence for bootstrapping.
+ */
+ if (!strcmp(s->cluster_stack, OCFS2_CLASSIC_CLUSTER_STACK)) {
+ if (user_stack_flags)
+ s->stack_flags = user_stack_flags;
+ else if (o2cb_stack_flags)
+ s->stack_flags = o2cb_stack_flags;
+ else if (disk_stack_flags)
+ s->stack_flags = disk_stack_flags;
+ } else
+ s->stack_flags = 0;
+
if (s->cluster_stack) {
fprintf(stdout,
"Cluster stack: %s\n"
"Cluster name: %s\n"
- "NOTE: Selecting extended slot map for userspace "
- "cluster stack\n",
- s->cluster_stack, s->cluster_name);
+ "Stack Flags: 0x%x\n"
+ "NOTE: Feature extended slot map will be enabled\n",
+ s->cluster_stack, s->cluster_name, s->stack_flags);
} else
fprintf(stdout, "Cluster stack: classic o2cb\n");
rc = 0;
out:
- if (user_stack_name)
- free(user_stack_name);
- if (user_cluster_name)
- free(user_cluster_name);
if (o2cb_stack_name)
free(o2cb_stack_name);
if (o2cb_cluster_name)
diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
index 9444fcd..66ed9ad 100644
--- a/mkfs.ocfs2/mkfs.c
+++ b/mkfs.ocfs2/mkfs.c
@@ -129,6 +129,7 @@ enum {
FEATURES_OPTION,
CLUSTER_STACK_OPTION,
CLUSTER_NAME_OPTION,
+ GLOBAL_HEARTBEAT_OPTION,
};
static uint64_t align_bytes_to_clusters_ceil(State *s,
@@ -782,6 +783,7 @@ get_state(int argc, char **argv)
char *vol_label = NULL;
char *stack_name = NULL;
char *cluster_name = NULL;
+ int globalhb = 0;
unsigned int initial_slots = 0;
char *dummy;
State *s;
@@ -817,6 +819,7 @@ get_state(int argc, char **argv)
{ "fs-features=", 1, 0, FEATURES_OPTION },
{ "cluster-stack=", 1, 0, CLUSTER_STACK_OPTION },
{ "cluster-name=", 1, 0, CLUSTER_NAME_OPTION },
+ { "global-heartbeat", 0, 0, GLOBAL_HEARTBEAT_OPTION },
{ 0, 0, 0, 0}
};
@@ -1008,6 +1011,10 @@ get_state(int argc, char **argv)
cluster_name = strdup(optarg);
break;
+ case GLOBAL_HEARTBEAT_OPTION:
+ globalhb = 1;
+ break;
+
default:
usage(progname);
break;
@@ -1110,11 +1117,31 @@ get_state(int argc, char **argv)
if (mount != -1)
s->mount = mount;
- if ((stack_name || cluster_name) && (s->mount == MOUNT_LOCAL)) {
+ if ((stack_name || cluster_name || globalhb) &&
+ (s->mount == MOUNT_LOCAL)) {
com_err(progname, 0,
"Local mount is incompatible with specifying a cluster stack");
exit(1);
}
+
+ if (globalhb) {
+ if (stack_name &&
+ strcmp(stack_name, OCFS2_CLASSIC_CLUSTER_STACK)) {
+ com_err(progname, 0, "Global heartbeat is incompatible "
+ "with the cluster stack, %s", stack_name);
+ exit(1);
+ }
+ if (!(s->feature_flags.opt_incompat &
+ OCFS2_FEATURE_INCOMPAT_CLUSTERINFO)) {
+ s->feature_flags.opt_incompat |=
+ OCFS2_FEATURE_INCOMPAT_CLUSTERINFO;
+ printf("'clusterinfo' feature enabled\n");
+ }
+ if (!stack_name)
+ s->cluster_stack = OCFS2_CLASSIC_CLUSTER_STACK;
+ s->stack_flags |= OCFS2_CLUSTER_O2CB_GLOBAL_HEARTBEAT;
+ }
+
if (stack_name)
s->cluster_stack = stack_name;
if (cluster_name)
@@ -2255,6 +2282,7 @@ format_superblock(State *s, SystemFileDiskRecord *rec,
s->cluster_stack, OCFS2_STACK_LABEL_LEN);
memcpy(di->id2.i_super.s_cluster_info.ci_cluster,
s->cluster_name, OCFS2_CLUSTER_NAME_LEN);
+ di->id2.i_super.s_cluster_info.ci_stackflags = s->stack_flags;
}
/*
diff --git a/mkfs.ocfs2/mkfs.h b/mkfs.ocfs2/mkfs.h
index c3aecd6..e6b3ce1 100644
--- a/mkfs.ocfs2/mkfs.h
+++ b/mkfs.ocfs2/mkfs.h
@@ -218,6 +218,7 @@ struct _State {
unsigned char *uuid;
char *cluster_stack;
char *cluster_name;
+ uint8_t stack_flags;
uint32_t vol_generation;
int fd;
--
1.7.0.4
More information about the Ocfs2-tools-devel
mailing list