[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