From mboxrd@z Thu Jan 1 00:00:00 1970 From: rpeterso@sourceware.org Date: 30 Jul 2007 15:31:23 -0000 Subject: [Cluster-devel] cluster/gfs2 edit/gfs2hex.c edit/hexedit.c lib ... Message-ID: <20070730153123.7878.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 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);