public inbox for cluster-cvs@sourceware.org
help / color / mirror / Atom feed
* cluster: RHEL5 - Add Filesystem UUID to GFS2 utils.
@ 2009-01-30 16:40 Bob Peterson
  0 siblings, 0 replies; only message in thread
From: Bob Peterson @ 2009-01-30 16:40 UTC (permalink / raw)
  To: cluster-cvs-relay

Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=0c637449a093e45aea57bbd2c8027674be7ad982
Commit:        0c637449a093e45aea57bbd2c8027674be7ad982
Parent:        ed7b4cbf776bf0f209f0fe3b30841ae1f0c415cb
Author:        Bob Peterson <rpeterso@redhat.com>
AuthorDate:    Fri Jan 30 10:39:15 2009 -0600
Committer:     Bob Peterson <rpeterso@redhat.com>
CommitterDate: Fri Jan 30 10:39: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       |    1 +
 gfs2/libgfs2/libgfs2.h    |    4 ++-
 gfs2/libgfs2/ondisk.c     |   29 +++++++++++++++++++++
 gfs2/libgfs2/structures.c |    3 +-
 gfs2/man/gfs2_tool.8      |    6 ++++
 gfs2/mkfs/main_mkfs.c     |   60 +++++++++++++++++++++++++++++++++++++++++---
 gfs2/tool/sb.c            |   55 +++++++++++++++++++++++++++++++++++++++++
 7 files changed, 151 insertions(+), 7 deletions(-)

diff --git a/gfs2/edit/gfs2hex.c b/gfs2/edit/gfs2hex.c
index ba6fcdd..8b18708 100644
--- a/gfs2/edit/gfs2hex.c
+++ b/gfs2/edit/gfs2hex.c
@@ -449,6 +449,7 @@ void gfs2_sb_print2(struct gfs2_sb *sb)
 		gfs2_inum_print2("quota ino ", &gfs1_quota_di);
 		gfs2_inum_print2("license   ", &gfs1_license_di);
 	}
+	print_it("  sb_uuid", "%s", NULL, str_uuid(sb->sb_uuid));
 }
 
 /******************************************************************************
diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
index 4540347..44205a9 100644
--- a/gfs2/libgfs2/libgfs2.h
+++ b/gfs2/libgfs2/libgfs2.h
@@ -696,7 +696,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);
@@ -722,6 +722,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 adaf39f..4d14448 100644
--- a/gfs2/libgfs2/ondisk.c
+++ b/gfs2/libgfs2/ondisk.c
@@ -16,6 +16,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <inttypes.h>
+#include <ctype.h>
 
 #include <linux/types.h>
 #include "libgfs2.h"
@@ -111,6 +112,7 @@ 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);
+	CPIN_08(sb, str, sb_uuid, sizeof(sb->sb_uuid));
 }
 
 void gfs2_sb_out(struct gfs2_sb *sb, char *buf)
@@ -130,6 +132,31 @@ 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);
+	CPOUT_08(sb, str, sb_uuid, sizeof(sb->sb_uuid));
+}
+
+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;
+}
+
+void gfs2_print_uuid(const unsigned char *uuid)
+{
+	print_it("  uuid", "%s", NULL, str_uuid(uuid));
 }
 
 void gfs2_sb_print(struct gfs2_sb *sb)
@@ -147,6 +174,8 @@ void gfs2_sb_print(struct gfs2_sb *sb)
 
 	pv(sb, sb_lockproto, "%s", NULL);
 	pv(sb, sb_locktable, "%s", NULL);
+
+	gfs2_print_uuid(sb->sb_uuid);
 }
 
 void gfs2_rindex_in(struct gfs2_rindex *ri, char *buf)
diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
index 09c4a70..8a7dc07 100644
--- a/gfs2/libgfs2/structures.c
+++ b/gfs2/libgfs2/structures.c
@@ -46,7 +46,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;
@@ -71,6 +71,7 @@ build_sb(struct gfs2_sbd *sdp)
 	sb.sb_root_dir = sdp->md.rooti->i_di.di_num;
 	strcpy(sb.sb_lockproto, sdp->lockproto);
 	strcpy(sb.sb_locktable, sdp->locktable);
+	memcpy(sb.sb_uuid, uuid, sizeof(sb.sb_uuid));
 
 	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 503cddb..6753427 100644
--- a/gfs2/man/gfs2_tool.8
+++ b/gfs2/man/gfs2_tool.8
@@ -93,6 +93,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 512448f..634b894 100644
--- a/gfs2/mkfs/main_mkfs.c
+++ b/gfs2/mkfs/main_mkfs.c
@@ -25,8 +25,9 @@
 #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"
@@ -323,6 +324,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
@@ -330,7 +375,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");
@@ -361,7 +407,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");
 }
 
@@ -379,6 +425,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;
@@ -435,12 +482,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);
@@ -468,5 +518,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 dbb1a4b..5cd91eb 100644
--- a/gfs2/tool/sb.c
+++ b/gfs2/tool/sb.c
@@ -25,6 +25,7 @@
 #include <sys/ioctl.h>
 #include <limits.h>
 #include <errno.h>
+#include <ctype.h>
 
 #include <linux/gfs2_ondisk.h>
 
@@ -43,6 +44,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:
@@ -138,6 +164,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;


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2009-01-30 16:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-01-30 16:40 cluster: RHEL5 - Add Filesystem UUID to GFS2 utils Bob Peterson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).