Module Name: src Committed By: mlelstv Date: Sat Feb 27 09:05:59 UTC 2010
Modified Files: src/usr.sbin/dumpfs: dumpfs.8 dumpfs.c Log Message: Add support to print the WAPBL journal. To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/usr.sbin/dumpfs/dumpfs.8 cvs rdiff -u -r1.53 -r1.54 src/usr.sbin/dumpfs/dumpfs.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/dumpfs/dumpfs.8 diff -u src/usr.sbin/dumpfs/dumpfs.8:1.18 src/usr.sbin/dumpfs/dumpfs.8:1.19 --- src/usr.sbin/dumpfs/dumpfs.8:1.18 Sat Jan 3 21:05:21 2004 +++ src/usr.sbin/dumpfs/dumpfs.8 Sat Feb 27 09:05:59 2010 @@ -1,4 +1,4 @@ -.\" $NetBSD: dumpfs.8,v 1.18 2004/01/03 21:05:21 wiz Exp $ +.\" $NetBSD: dumpfs.8,v 1.19 2010/02/27 09:05:59 mlelstv Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -58,6 +58,8 @@ Print details of the cylinder group summary. .It Fl s Print details of the superblock. +.It Fl j +Print details of the WAPBL journal. .It Fl v Be even more verbose. .El @@ -67,8 +69,9 @@ .Fl c , .Fl i , .Fl m , +.Fl s , or -.Fl s +.Fl j are given, then .Nm defaults to @@ -107,3 +110,7 @@ .Fl s options, and the inode dump were added for .Nx 2.0 . +The +.Fl j , +option was added for +.Nx 6.0 . Index: src/usr.sbin/dumpfs/dumpfs.c diff -u src/usr.sbin/dumpfs/dumpfs.c:1.53 src/usr.sbin/dumpfs/dumpfs.c:1.54 --- src/usr.sbin/dumpfs/dumpfs.c:1.53 Thu May 7 06:40:38 2009 +++ src/usr.sbin/dumpfs/dumpfs.c Sat Feb 27 09:05:59 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: dumpfs.c,v 1.53 2009/05/07 06:40:38 lukem Exp $ */ +/* $NetBSD: dumpfs.c,v 1.54 2010/02/27 09:05:59 mlelstv Exp $ */ /* * Copyright (c) 1983, 1992, 1993 @@ -39,15 +39,19 @@ #if 0 static char sccsid[] = "@(#)dumpfs.c 8.5 (Berkeley) 4/29/95"; #else -__RCSID("$NetBSD: dumpfs.c,v 1.53 2009/05/07 06:40:38 lukem Exp $"); +__RCSID("$NetBSD: dumpfs.c,v 1.54 2010/02/27 09:05:59 mlelstv Exp $"); #endif #endif /* not lint */ #include <sys/param.h> #include <sys/time.h> +#include <sys/wapbl.h> +#include <sys/wapbl_replay.h> + #include <ufs/ufs/dinode.h> #include <ufs/ufs/ufs_bswap.h> +#include <ufs/ufs/ufs_wapbl.h> #include <ufs/ffs/fs.h> #include <ufs/ffs/ffs_extern.h> @@ -76,6 +80,14 @@ } cgun; #define acg cgun.cg +union { + struct wapbl_wc_header wh; + struct wapbl_wc_null wn; + char pad[MAXBSIZE]; +} jbuf; +#define awh jbuf.wh +#define awn jbuf.wn + #define OPT_FLAG(ch) (1 << ((ch) & 31)) #define ISOPT(opt) (opt_flags & (opt)) #define opt_alt_super OPT_FLAG('a') @@ -83,9 +95,10 @@ #define opt_cg_summary OPT_FLAG('m') #define opt_cg_info OPT_FLAG('c') #define opt_inodes OPT_FLAG('i') +#define opt_journal OPT_FLAG('j') #define opt_verbose OPT_FLAG('v') #define DFLT_CHECK (opt_alt_super | opt_cg_info | opt_inodes | \ - opt_cg_summary | opt_superblock) + opt_cg_summary | opt_superblock | opt_journal ) #define DFLT_OPTS (opt_superblock | opt_cg_summary | opt_cg_info | opt_verbose) long dev_bsize = 512; @@ -100,6 +113,9 @@ int print_cginfo(const char *, int); int print_inodes(const char *, int, int, int); int print_alt_super(const char *, int); +int print_journal(const char *, int); +void print_journal_header(const char *); +off_t print_journal_entries(const char *, size_t); int dumpcg(const char *, int, int); int main(int, char **); int openpartition(const char *, int, char *, size_t); @@ -114,13 +130,14 @@ { int ch, eval; - while ((ch = getopt(argc, argv, "acimsvF")) != -1) + while ((ch = getopt(argc, argv, "acimsjvF")) != -1) switch(ch) { case 'a': /* alternate superblocks */ case 'c': /* cylinder group info */ case 'i': /* actual inodes */ case 'm': /* cylinder group summary */ case 's': /* superblock */ + case 'j': /* journal */ case 'v': /* more verbose */ opt_flags |= OPT_FLAG(ch); break; @@ -215,6 +232,8 @@ rval = print_cgsum(name, fd); if (rval == 0 && ISOPT(opt_alt_super)) rval = print_alt_super(name, fd); + if (rval == 0 && ISOPT(opt_journal)) + rval = print_journal(name, fd); if (rval == 0 && ISOPT(opt_cg_info)) rval = print_cginfo(name, fd); else if (rval == 0 && ISOPT(opt_inodes)) @@ -687,7 +706,6 @@ i->di_gen, i->di_uid, i->di_gid); } - void pbits(int offset, void *vp, int max) { @@ -710,11 +728,182 @@ printf("\n"); } +int +print_journal(const char *name, int fd) +{ + daddr_t off; + size_t count, blklen, bno, skip; + off_t boff, head, tail, len; + uint32_t generation; + + if (afs.fs_journal_version != UFS_WAPBL_VERSION) + return 0; + + generation = 0; + head = tail = 0; + + switch (afs.fs_journal_location) { + case UFS_WAPBL_JOURNALLOC_END_PARTITION: + case UFS_WAPBL_JOURNALLOC_IN_FILESYSTEM: + + off = afs.fs_journallocs[0]; + count = afs.fs_journallocs[1]; + blklen = afs.fs_journallocs[2]; + + for (bno=0; bno<count; bno += skip / DEV_BSIZE) { + + skip = blklen; + + boff = bno * DEV_BSIZE; + if (bno >= 2 && + ((head >= tail && (boff < tail || boff >= head)) || + (head < tail && (boff >= head && boff < tail)))) + continue; + + printf("journal block %lu offset %lld\n", + (unsigned long)bno, (long long) boff); + + if (lseek(fd, (off_t)(off*DEV_BSIZE) + boff, SEEK_SET) + == (off_t)-1) + return (1); + if (read(fd, &jbuf, blklen) != (ssize_t)blklen) { + warnx("%s: error reading journal", name); + return 1; + } + + switch (awh.wc_type) { + case 0: + break; + case WAPBL_WC_HEADER: + print_journal_header(name); + if (awh.wc_generation > generation) { + head = awh.wc_head; + tail = awh.wc_tail; + } + generation = awh.wc_generation; + skip = awh.wc_len; + break; + default: + len = print_journal_entries(name, blklen); + skip = awh.wc_len; + if (len != (off_t)skip) + printf(" CORRUPTED RECORD\n"); + break; + } + + if (blklen) + skip = (skip + blklen - 1) / blklen * blklen; + if (skip == 0) + break; + + } + break; + } + + return 0; +} + +static const char * +wapbl_type_string(unsigned t) +{ + static char buf[12]; + + switch (t) { + case WAPBL_WC_BLOCKS: + return "blocks"; + case WAPBL_WC_REVOCATIONS: + return "revocations"; + case WAPBL_WC_INODES: + return "inodes"; + case WAPBL_WC_HEADER: + return "header"; + } + + snprintf(buf,sizeof(buf),"%08x",t); + return buf; +} + +void +print_journal_header(const char *name) +{ + printf(" type %s len %d version %u\n", + wapbl_type_string(awh.wc_type), awh.wc_len, + awh.wc_version); + printf(" checksum %08x generation %9u\n", + awh.wc_checksum, awh.wc_generation); + printf(" fsid %08x.%08x time %llu nsec %u\n", + awh.wc_fsid[0], awh.wc_fsid[1], + (unsigned long long)awh.wc_time, awh.wc_timensec); + printf(" log_bshift %10u fs_bshift %10u\n", + awh.wc_log_dev_bshift, awh.wc_fs_dev_bshift); + printf(" head %10lld tail %10lld\n", + (long long)awh.wc_head, (long long)awh.wc_tail); + printf(" circ_off %10lld circ_size %10lld\n", + (long long)awh.wc_circ_off, (long long)awh.wc_circ_size); +} + +off_t +print_journal_entries(const char *name, size_t blklen) +{ + int i, n; + struct wapbl_wc_blocklist *wcb; + struct wapbl_wc_inodelist *wci; + off_t len = 0; + int ph; + + printf(" type %s len %d", + wapbl_type_string(awn.wc_type), awn.wc_len); + + switch (awn.wc_type) { + case WAPBL_WC_BLOCKS: + case WAPBL_WC_REVOCATIONS: + wcb = (struct wapbl_wc_blocklist *)&awn; + printf(" blkcount %u\n", wcb->wc_blkcount); + ph = (blklen - offsetof(struct wapbl_wc_blocklist, wc_blocks)) + / sizeof(wcb->wc_blocks[0]); + n = MIN(wcb->wc_blkcount, ph); + for (i=0; i<n; i++) { + if (ISOPT(opt_verbose)) { + printf(" %3d: daddr %14llu dlen %d\n", i, + (unsigned long long)wcb->wc_blocks[i].wc_daddr, + wcb->wc_blocks[i].wc_dlen); + } + len += wcb->wc_blocks[i].wc_dlen; + } + if (awn.wc_type == WAPBL_WC_BLOCKS) { + if (len % blklen) + len += blklen - len % blklen; + } else + len = 0; + break; + case WAPBL_WC_INODES: + wci = (struct wapbl_wc_inodelist *)&awn; + printf(" count %u clear %u\n", + wci->wc_inocnt, wci->wc_clear); + ph = (blklen - offsetof(struct wapbl_wc_inodelist, wc_inodes)) + / sizeof(wci->wc_inodes[0]); + n = MIN(wci->wc_inocnt, ph); + for (i=0; i<n; ++i) { + if (ISOPT(opt_verbose)) { + printf(" %3d: inumber %10u imode %08x\n", i, + wci->wc_inodes[i].wc_inumber, + wci->wc_inodes[i].wc_imode); + } + } + break; + default: + printf("\n"); + break; + } + + return len + blklen; +} + void usage(void) { - (void)fprintf(stderr, "usage: dumpfs [-acFimsv] filesys | device [...]\n"); + (void)fprintf(stderr, "usage: dumpfs [-acFimsjv] filesys | device [...]\n"); exit(1); }