[Cluster-devel] cluster/gfs2 edit/gfs2hex.c edit/hexedit.c lib ...
rpeterso at sourceware.org
rpeterso at sourceware.org
Mon Jul 30 15:31:23 UTC 2007
CVSROOT: /cvs/cluster
Module name: cluster
Changes by: rpeterso at sourceware.org 2007-07-30 15:31:23
Modified files:
gfs2/edit : gfs2hex.c hexedit.c
gfs2/libgfs2 : ondisk.h
Log message:
Added ability to parse and print journal information. For example:
gfs2_edit -p journal2 /dev/roth_vg/roth_lv
Also added the ability to jump relative block numbers. This is for
when you jump to a block by "editing" the block number:
Cursor up to block number, press <enter> to enter destination block.
Before you could type a structure or block number. Now you can type
in a structure, block number, or relative block number. For example,
if you're on the superblock (block 0x10) enter +0x300 will take you
to block 0x310. This number may be in decimal or hex and may be
positive or negative.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/gfs2hex.c.diff?cvsroot=cluster&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/edit/hexedit.c.diff?cvsroot=cluster&r1=1.17&r2=1.18
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/gfs2/libgfs2/ondisk.h.diff?cvsroot=cluster&r1=1.2&r2=1.3
--- cluster/gfs2/edit/gfs2hex.c 2007/07/16 23:16:35 1.11
+++ cluster/gfs2/edit/gfs2hex.c 2007/07/30 15:31:23 1.12
@@ -464,6 +464,7 @@
struct gfs2_rgrp rg;
struct gfs2_leaf lf;
struct gfs2_log_header lh;
+ struct gfs2_log_descriptor ld;
uint32_t magic;
@@ -528,6 +529,13 @@
gfs2_log_header_print(&lh);
break;
+ case GFS2_METATYPE_LD:
+ print_gfs2("Log descriptor");
+ eol(0);
+ gfs2_log_descriptor_in(&ld, buf);
+ gfs2_log_descriptor_print(&ld);
+ break;
+
case GFS2_METATYPE_EA:
print_gfs2("Eattr Block:");
eol(0);
--- cluster/gfs2/edit/hexedit.c 2007/07/16 23:16:35 1.17
+++ cluster/gfs2/edit/hexedit.c 2007/07/30 15:31:23 1.18
@@ -326,6 +326,25 @@
Erase();
}
+
+
+/* ------------------------------------------------------------------------ */
+/* get_block_type */
+/* returns: metatype if block is a GFS2 structure block type */
+/* 0 if block is not a GFS2 structure */
+/* ------------------------------------------------------------------------ */
+int get_block_type(const char *lpBuffer)
+{
+ int ret_type = 0;
+
+ if (*(lpBuffer+0)==0x01 && *(lpBuffer+1)==0x16 &&
+ *(lpBuffer+2)==0x19 && *(lpBuffer+3)==0x70 &&
+ *(lpBuffer+4)==0x00 && *(lpBuffer+5)==0x00 &&
+ *(lpBuffer+6)==0x00) /* If magic number appears at the start */
+ ret_type = *(lpBuffer+7);
+ return ret_type;
+}
+
/* ------------------------------------------------------------------------ */
/* display_block_type */
/* returns: metatype if block is a GFS2 structure block type */
@@ -366,11 +385,7 @@
ret_type = GFS2_METATYPE_RG;
struct_len = sizeof(struct gfs2_rgrp);
}
- else if (*(lpBuffer+0)==0x01 && *(lpBuffer+1)==0x16 &&
- *(lpBuffer+2)==0x19 && *(lpBuffer+3)==0x70 &&
- *(lpBuffer+4)==0x00 && *(lpBuffer+5)==0x00 &&
- *(lpBuffer+6)==0x00) { /* If magic number appears at the start */
- ret_type = *(lpBuffer+7);
+ else if ((ret_type = get_block_type(lpBuffer))) {
switch (*(lpBuffer+7)) {
case GFS2_METATYPE_SB: /* 1 */
print_gfs2("(superblock)");
@@ -1410,6 +1425,20 @@
temp_blk = masterblock(string);
}
}
+ else if (string[0] == '+') {
+ if (string[1] == '0' && string[2] == 'x')
+ sscanf(string, "%"SCNx64, &temp_blk);
+ else
+ sscanf(string, "%" PRIu64, &temp_blk);
+ temp_blk += block;
+ }
+ else if (string[0] == '-') {
+ if (string[1] == '0' && string[2] == 'x')
+ sscanf(string, "%"SCNx64, &temp_blk);
+ else
+ sscanf(string, "%" PRIu64, &temp_blk);
+ temp_blk -= block;
+ }
else if (string[0] == '0' && string[1] == 'x')
sscanf(string, "%"SCNx64, &temp_blk); /* retrieve in hex */
else
@@ -1843,6 +1872,79 @@
}/* interactive_mode */
/* ------------------------------------------------------------------------ */
+/* dump_journal - dump a journal file's contents. */
+/* ------------------------------------------------------------------------ */
+void dump_journal(const char *journal)
+{
+ struct gfs2_buffer_head *jindex_bh, *j_bh;
+ uint64_t jindex_block, jblock, j_size, jb;
+ int error, start_line, journal_num;
+ struct gfs2_dinode jdi;
+ char jbuf[bufsize];
+ struct gfs2_inode *j_inode;
+
+ start_line = line;
+ lines_per_row[dmode] = 1;
+ error = 0;
+ journal_num = atoi(journal + 7);
+ print_gfs2("Dumping journal #%d.", journal_num);
+ eol(0);
+ /* Figure out the block of the jindex file */
+ jindex_block = masterblock("jindex");
+ /* read in the block */
+ jindex_bh = bread(&sbd, jindex_block);
+ /* get the dinode data from it. */
+ gfs2_dinode_in(&di, jindex_bh->b_data); /* parse disk inode into structure */
+
+ do_dinode_extended(&di, jindex_bh->b_data); /* which parses the directory. */
+ brelse(jindex_bh, not_updated);
+
+ jblock = indirect->ii[0].dirent[journal_num + 2].block;
+ j_bh = bread(&sbd, jblock);
+ j_inode = inode_get(&sbd, j_bh);
+ gfs2_dinode_in(&jdi, j_bh->b_data); /* parse disk inode into structure */
+ j_size = jdi.di_size;
+
+ for (jb = 0; jb < j_size; jb += bufsize) {
+ error = gfs2_readi(j_inode, (void *)&jbuf, jb, bufsize);
+ if (!error) /* end of file */
+ break;
+ if (get_block_type(jbuf) == GFS2_METATYPE_LD) {
+ uint64_t *b;
+ int i = 0;
+
+ print_gfs2("Block #%4llx: ", jb / bufsize);
+ b = (uint64_t *)(jbuf + sizeof(struct gfs2_log_descriptor));
+ while (*b && (char *)b < (jbuf + bufsize)) {
+ if (!termlines ||
+ (print_entry_ndx >= start_row[dmode] &&
+ ((print_entry_ndx - start_row[dmode])+1) *
+ lines_per_row[dmode] <= termlines - start_line - 2)) {
+ if (i && i % 4 == 0) {
+ eol(0);
+ print_gfs2(" ");
+ }
+ i++;
+ print_gfs2("0x%08llx ", be64_to_cpu(*b));
+ }
+ b++;
+ }
+ eol(0);
+ } else if (get_block_type(jbuf) == GFS2_METATYPE_LH) {
+ struct gfs2_log_header lh;
+
+ gfs2_log_header_in(&lh, jbuf);
+ print_gfs2("Block #%4llx: Log header: Seq = 0x%x, tail = 0x%x, blk = 0x%x",
+ jb / bufsize, lh.lh_sequence, lh.lh_tail,
+ lh.lh_blkno);
+ eol(0);
+ }
+ }
+ brelse(j_bh, not_updated);
+ blockhist = -1; /* So we don't print anything else */
+}
+
+/* ------------------------------------------------------------------------ */
/* usage - print command line usage */
/* ------------------------------------------------------------------------ */
void usage(void)
@@ -1986,6 +2088,9 @@
sscanf(argv[i], "%"SCNd64, &temp_blk);
push_block(temp_blk);
}
+ else if (!strncmp(argv[i], "journal", 7) && isdigit(argv[i][7])) {
+ dump_journal(argv[i]);
+ }
else {
fprintf(stderr,"I don't know what '%s' means.\n", argv[i]);
usage();
@@ -2059,11 +2164,13 @@
else { /* print all the structures requested */
for (i = 0; i <= blockhist; i++) {
block = blockstack[i + 1].block;
+ if (!block)
+ break;
display(identify);
if (!identify) {
display_extended();
printf("-------------------------------------" \
- "-----------------");
+ "-----------------");
eol(0);
}
block = pop_block();
--- cluster/gfs2/libgfs2/ondisk.h 2006/06/14 13:55:11 1.2
+++ cluster/gfs2/libgfs2/ondisk.h 2007/07/30 15:31:23 1.3
@@ -35,6 +35,8 @@
extern void gfs2_ea_header_out(struct gfs2_ea_header *ea, char *buf);
extern void gfs2_log_header_in(struct gfs2_log_header *lh, char *buf);
extern void gfs2_log_header_out(struct gfs2_log_header *lh, char *buf);
+extern void gfs2_log_descriptor_in(struct gfs2_log_descriptor *ld, char *buf);
+extern void gfs2_log_descriptor_out(struct gfs2_log_descriptor *ld, char *buf);
extern void gfs2_inum_range_in(struct gfs2_inum_range *ir, char *buf);
extern void gfs2_inum_range_out(struct gfs2_inum_range *ir, char *buf);
extern void gfs2_statfs_change_in(struct gfs2_statfs_change *sc, char *buf);
More information about the Cluster-devel
mailing list