From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26703 invoked by alias); 30 Jan 2009 16:40:39 -0000 Received: (qmail 26697 invoked by alias); 30 Jan 2009 16:40:39 -0000 X-SWARE-Spam-Status: No, hits=0.3 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_22,J_CHICKENPOX_42,J_CHICKENPOX_63,J_CHICKENPOX_66,J_CHICKENPOX_72,KAM_MX,SPF_HELO_PASS X-Spam-Status: No, hits=0.3 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_22,J_CHICKENPOX_42,J_CHICKENPOX_63,J_CHICKENPOX_66,J_CHICKENPOX_72,KAM_MX,SPF_HELO_PASS X-Spam-Check-By: sourceware.org X-Spam-Checker-Version: SpamAssassin 3.2.4 (2008-01-01) on bastion.fedora.phx.redhat.com Subject: cluster: RHEL5 - Add Filesystem UUID to GFS2 utils. To: cluster-cvs-relay@redhat.com X-Project: Cluster Project X-Git-Module: cluster.git X-Git-Refname: refs/heads/RHEL5 X-Git-Reftype: branch X-Git-Oldrev: ed7b4cbf776bf0f209f0fe3b30841ae1f0c415cb X-Git-Newrev: 0c637449a093e45aea57bbd2c8027674be7ad982 From: Bob Peterson Message-Id: <20090130164012.C53BF12056C@lists.fedorahosted.org> Date: Fri, 30 Jan 2009 16:40:00 -0000 X-Scanned-By: MIMEDefang 2.58 on 172.16.52.254 Mailing-List: contact cluster-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: cluster-cvs-owner@sourceware.org X-SW-Source: 2009-q1/txt/msg00364.txt.bz2 Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=0c637449a093e45aea57bbd2c8027674be7ad982 Commit: 0c637449a093e45aea57bbd2c8027674be7ad982 Parent: ed7b4cbf776bf0f209f0fe3b30841ae1f0c415cb Author: Bob Peterson AuthorDate: Fri Jan 30 10:39:15 2009 -0600 Committer: Bob Peterson 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 #include #include +#include #include #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 #include #include - +#include #include + #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 #include #include +#include #include @@ -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;