CVSROOT:        /cvs/cluster
Module name:    cluster
Changes by:     [EMAIL PROTECTED]       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);

Reply via email to