This is the mail archive of the cluster-cvs@sourceware.org mailing list for the cluster.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

cluster: STABLE2 - Add Filesystem UUID to GFS2 utils.


Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=4c8966c74e8493de3a88dabf6290db9cf4c876ae
Commit:        4c8966c74e8493de3a88dabf6290db9cf4c876ae
Parent:        c85529e1d3d9d7511231f953bffcf83c1bc059bc
Author:        Bob Peterson <rpeterso@redhat.com>
AuthorDate:    Fri Feb 20 16:56:49 2009 -0600
Committer:     Bob Peterson <rpeterso@redhat.com>
CommitterDate: Fri Feb 20 16:56:49 2009 -0600

Add Filesystem UUID to GFS2 utils.

bz #242701

1. Added the ability for gfs2_edit to print the uuid value with
   -p sb and also to show it in the "structures" display.
2. Added the ability for gfs2_tool to print the uuid value with
   "sb"..."all" and "sb"..."uuid" and the ability to change the uuid
   through the same mechanism.
3. Updated the gfs2_tool.8 man page to reflect those changes.
4. This version of mkfs concocts the new uuid randomly, but does not
   allow the users to specify it (the same as mkfs.ext3 and mkfs.xfs)
---
 gfs2/edit/gfs2hex.c       |    3 ++
 gfs2/libgfs2/libgfs2.h    |    4 ++-
 gfs2/libgfs2/ondisk.c     |   37 +++++++++++++++++++++++++++
 gfs2/libgfs2/structures.c |   12 +-------
 gfs2/man/gfs2_tool.8      |    6 ++++
 gfs2/mkfs/main_mkfs.c     |   61 +++++++++++++++++++++++++++++++++++++++++---
 gfs2/tool/sb.c            |   55 ++++++++++++++++++++++++++++++++++++++++
 7 files changed, 162 insertions(+), 16 deletions(-)

diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
index a63c421..75fc59f 100644
--- a/gfs2/edit/gfs2hex.c
+++ b/gfs2/edit/gfs2hex.c
@@ -436,6 +436,9 @@ void gfs2_sb_print2(struct gfs2_sb *sb)
 		gfs2_inum_print2("quota ino ", &gfs1_quota_di);
 		gfs2_inum_print2("license   ", &gfs1_license_di);
 	}
+#ifdef GFS2_HAS_UUID
+	print_it("  sb_uuid", "%s", NULL, str_uuid(sb->sb_uuid));
+#endif
 }
 
 /******************************************************************************
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index c62371e..b8d222c 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -679,7 +679,7 @@ void gfs2_rgrp_free(osi_list_t *rglist, enum update_flags updated);
 
 /* structures.c */
 void build_master(struct gfs2_sbd *sdp);
-void build_sb(struct gfs2_sbd *sdp);
+void build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid);
 void build_jindex(struct gfs2_sbd *sdp);
 void build_per_node(struct gfs2_sbd *sdp);
 void build_inum(struct gfs2_sbd *sdp);
@@ -705,6 +705,8 @@ int write_sb(struct gfs2_sbd *sdp);
 
 /* ondisk.c */
 uint32_t gfs2_disk_hash(const char *data, int len);
+const char *str_uuid(const unsigned char *uuid);
+void gfs2_print_uuid(const unsigned char *uuid);
 
 extern void print_it(const char *label, const char *fmt,
 					 const char *fmt2, ...);
diff --git a/gfs2/libgfs2/ondisk.c b/gfs2/libgfs2/ondisk.c
index 40eb259..5364190 100644
--- a/gfs2/libgfs2/ondisk.c
+++ b/gfs2/libgfs2/ondisk.c
@@ -3,6 +3,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <inttypes.h>
+#include <ctype.h>
 
 #include <linux/types.h>
 #include "libgfs2.h"
@@ -98,6 +99,9 @@ void gfs2_sb_in(struct gfs2_sb *sb, char *buf)
 
 	CPIN_08(sb, str, sb_lockproto, GFS2_LOCKNAME_LEN);
 	CPIN_08(sb, str, sb_locktable, GFS2_LOCKNAME_LEN);
+#ifdef GFS2_HAS_UUID
+	CPIN_08(sb, str, sb_uuid, sizeof(sb->sb_uuid));
+#endif
 }
 
 void gfs2_sb_out(struct gfs2_sb *sb, char *buf)
@@ -117,8 +121,37 @@ void gfs2_sb_out(struct gfs2_sb *sb, char *buf)
 
 	CPOUT_08(sb, str, sb_lockproto, GFS2_LOCKNAME_LEN);
 	CPOUT_08(sb, str, sb_locktable, GFS2_LOCKNAME_LEN);
+#ifdef GFS2_HAS_UUID
+	memcpy(str->sb_uuid, sb->sb_uuid, 16);
+#endif
 }
 
+const char *str_uuid(const unsigned char *uuid)
+{
+	static char str[64];
+	char *ch;
+	int i;
+
+	memset(str, 0, sizeof(str));
+	ch = str;
+	for (i = 0; i < 16; i++) {
+		sprintf(ch, "%02X", uuid[i]);
+		ch += 2;
+		if ((i == 3) || (i == 5) || (i == 7) || (i == 9)) {
+			*ch = '-';
+			ch++;
+		}
+	}
+	return str;
+}
+
+#ifdef GFS2_HAS_UUID
+void gfs2_print_uuid(const unsigned char *uuid)
+{
+	print_it("  uuid", "%s", NULL, str_uuid(uuid));
+}
+#endif
+
 void gfs2_sb_print(struct gfs2_sb *sb)
 {
 	gfs2_meta_header_print(&sb->sb_header);
@@ -134,6 +167,10 @@ void gfs2_sb_print(struct gfs2_sb *sb)
 
 	pv(sb, sb_lockproto, "%s", NULL);
 	pv(sb, sb_locktable, "%s", NULL);
+
+#ifdef GFS2_HAS_UUID
+	gfs2_print_uuid(sb->sb_uuid);
+#endif
 }
 
 void gfs2_rindex_in(struct gfs2_rindex *ri, char *buf)
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index fdb9bdd..8aa91f5 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -33,7 +33,7 @@ void build_master(struct gfs2_sbd *sdp)
 }
 
 void
-build_sb(struct gfs2_sbd *sdp)
+build_sb(struct gfs2_sbd *sdp, const unsigned char *uuid)
 {
 	unsigned int x;
 	struct gfs2_buffer_head *bh;
@@ -59,15 +59,7 @@ build_sb(struct gfs2_sbd *sdp)
 	strcpy(sb.sb_lockproto, sdp->lockproto);
 	strcpy(sb.sb_locktable, sdp->locktable);
 #ifdef GFS2_HAS_UUID
-	{
-		int fd = open("/dev/urandom", O_RDONLY);
-		int n;
-		if (fd >= 0)
-			n = read(fd, &sb.sb_uuid, 16);
-		if (fd < 0 || n != 16)
-			memset(&sb.sb_uuid, 0, 16);
-		close(fd);
-	}
+	memcpy(sb.sb_uuid, uuid, sizeof(sb.sb_uuid));
 #endif
 	bh = bget(&sdp->buf_list, sdp->sb_addr);
 	gfs2_sb_out(&sb, bh->b_data);
diff --git a/gfs2/man/gfs2_tool.8 b/gfs2/man/gfs2_tool.8
index c28356a..a938a49 100644
--- a/gfs2/man/gfs2_tool.8
+++ b/gfs2/man/gfs2_tool.8
@@ -90,6 +90,12 @@ View (and possibly replace) the multihost format number in the
 file system superblock.  The file system shouldn't be mounted by any
 client when you do this.  No one should have to use this.
 .TP
+\fBsb\fP \fIdevice\fR \fBuuid\fP \fI[newvalue]\fR
+View (and possibly replace) the uuid in the file system superblock.
+The file system shouldn't be mounted by any client when you do this.
+The new uuid value should be in the standard uuid format.  For
+example: 1AEA8269-15C5-72BD-6D83-8720B17AA4EE
+.TP
 \fBsb\fP \fIdevice\fR \fBall\fP
 Print out the superblock.
 .TP
diff --git a/gfs2/mkfs/main_mkfs.c b/gfs2/mkfs/main_mkfs.c
index df82677..d590969 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -11,8 +11,10 @@
 #include <errno.h>
 #include <stdarg.h>
 #include <mntent.h>
-
+#include <ctype.h>
+#include <sys/time.h>
 #include <linux/types.h>
+
 #include "libgfs2.h"
 #include "gfs2_mkfs.h"
 #include "libvolume_id.h"
@@ -325,6 +327,50 @@ void check_mount(char *device)
 	return;
 }
 
+/*
+ * get_random_bytes - Generate a series of random bytes using /dev/urandom.
+ *
+ * Modified from original code in gen_uuid.c in e2fsprogs/lib
+ */
+static void get_random_bytes(void *buf, int nbytes)
+{
+	int i, n = nbytes, fd;
+	int lose_counter = 0;
+	unsigned char *cp = (unsigned char *) buf;
+	struct timeval	tv;
+
+	gettimeofday(&tv, 0);
+	fd = open("/dev/urandom", O_RDONLY);
+	srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
+	/* Crank the random number generator a few times */
+	gettimeofday(&tv, 0);
+	for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
+		rand();
+	if (fd >= 0) {
+		while (n > 0) {
+			i = read(fd, cp, n);
+			if (i <= 0) {
+				if (lose_counter++ > 16)
+					break;
+				continue;
+			}
+			n -= i;
+			cp += i;
+			lose_counter = 0;
+		}
+		close(fd);
+	}
+
+	/*
+	 * We do this all the time, but this is the only source of
+	 * randomness if /dev/random/urandom is out to lunch.
+	 */
+	for (cp = buf, i = 0; i < nbytes; i++)
+		*cp++ ^= (rand() >> 7) & 0xFF;
+
+	return;
+}
+
 /**
  * print_results - print out summary information
  * @sdp: the command line
@@ -332,7 +378,8 @@ void check_mount(char *device)
  */
 
 static void
-print_results(struct gfs2_sbd *sdp, uint64_t real_device_size)
+print_results(struct gfs2_sbd *sdp, uint64_t real_device_size,
+	      unsigned char uuid[16])
 {
 	if (sdp->debug)
 		printf("\n");
@@ -363,7 +410,7 @@ print_results(struct gfs2_sbd *sdp, uint64_t real_device_size)
 		       sdp->buf_list.spills);
 		printf("Writes:                    %u\n", sdp->writes);
 	}
-
+	printf("UUID:                      %s\n", str_uuid(uuid));
 	printf("\n");
 }
 
@@ -381,6 +428,7 @@ main_mkfs(int argc, char *argv[])
 	int error;
 	int rgsize_specified = 0;
 	uint64_t real_device_size;
+	unsigned char uuid[16];
 
 	memset(sdp, 0, sizeof(struct gfs2_sbd));
 	sdp->bsize = GFS2_DEFAULT_BSIZE;
@@ -437,12 +485,15 @@ main_mkfs(int argc, char *argv[])
 
 	compute_rgrp_layout(sdp, rgsize_specified);
 
+	/* Generate a random uuid */
+	get_random_bytes(uuid, sizeof(uuid));
+
 	/* Build ondisk structures */
 
 	build_rgrps(sdp, TRUE);
 	build_root(sdp);
 	build_master(sdp);
-	build_sb(sdp);
+	build_sb(sdp, uuid);
 	build_jindex(sdp);
 	build_per_node(sdp);
 	build_inum(sdp);
@@ -470,5 +521,5 @@ main_mkfs(int argc, char *argv[])
 		die("error closing device (%d): %s\n",
 		    error, strerror(errno));
 
-	print_results(sdp, real_device_size);
+	print_results(sdp, real_device_size, uuid);
 }
diff --git a/gfs2/tool/sb.c b/gfs2/tool/sb.c
index c130ed4..65a3be8 100644
--- a/gfs2/tool/sb.c
+++ b/gfs2/tool/sb.c
@@ -12,6 +12,7 @@
 #include <sys/ioctl.h>
 #include <limits.h>
 #include <errno.h>
+#include <ctype.h>
 
 #include <linux/gfs2_ondisk.h>
 
@@ -30,6 +31,31 @@ void print_it(const char *label, const char *fmt, const char *fmt2, ...)
 }
 
 /**
+ * str_to_hexchar - convert a string consisting of two isxdigits back to hex.
+ * Returns: the hex character
+ */
+int str_to_hexchar(const char *estring)
+{
+	int ch = 0;
+
+	if (isdigit(*estring))
+		ch = (*estring - '0') * 0x10;
+	else if (*estring >= 'a' && *estring <= 'f')
+		ch = (*estring - 'a' + 0x0a) * 0x10;
+	else if (*estring >= 'A' && *estring <= 'F')
+		ch = (*estring - 'A' + 0x0a) * 0x10;
+
+	estring++;
+	if (isdigit(*estring))
+		ch += (*estring - '0');
+	else if (*estring >= 'a' && *estring <= 'f')
+		ch += (*estring - 'a' + 0x0a);
+	else if (*estring >= 'A' && *estring <= 'F')
+		ch += (*estring - 'A' + 0x0a);
+	return ch;
+}
+
+/**
  * do_sb - examine/modify a unmounted FS' superblock
  * @argc:
  * @argv:
@@ -125,6 +151,35 @@ do_sb(int argc, char **argv)
 			printf("new multihost format = %u\n",
 			       sb.sb_multihost_format);
 		}
+	} else if (strcmp(field, "uuid") == 0) {
+		printf("current uuid = %s\n", str_uuid(sb.sb_uuid));
+
+		if (newval) {
+			int i;
+			unsigned char uuid[16], *cp;
+
+			if (strlen(newval) != 36)
+				die("uuid %s is the wrong length; must be 36 "
+				    "hex characters long.\n", newval);
+			cp = uuid;
+			for (i = 0; i < 36; i++) {
+				if ((i == 8) || (i == 13) ||
+				    (i == 18) || (i == 23)) {
+					if (newval[i] == '-')
+						continue;
+					die("uuid %s has an invalid format.",
+					    newval);
+				}
+				if (!isxdigit(newval[i]))
+					die("uuid %s has an invalid hex "
+					    "digit '%c' at offset %d.\n",
+					    newval, newval[i], i + 1);
+				*cp = str_to_hexchar(&newval[i++]);
+				cp++;
+			}
+			memcpy(sb.sb_uuid, uuid, 16);
+			printf("new uuid = %s\n", str_uuid(sb.sb_uuid));
+		}
 	} else if (strcmp(field, "all") == 0) {
 		gfs2_sb_print(&sb);
 		newval = FALSE;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]