diff options
Diffstat (limited to 'sbin/dumpfs/dumpfs.c')
-rw-r--r-- | sbin/dumpfs/dumpfs.c | 234 |
1 files changed, 128 insertions, 106 deletions
diff --git a/sbin/dumpfs/dumpfs.c b/sbin/dumpfs/dumpfs.c index dd18313..aae7e1e 100644 --- a/sbin/dumpfs/dumpfs.c +++ b/sbin/dumpfs/dumpfs.c @@ -1,4 +1,16 @@ /* + * Copyright (c) 2002 Networks Associates Technology, Inc. + * All rights reserved. + * + * This software was developed for the FreeBSD Project by Marshall + * Kirk McKusick and Network Associates Laboratories, the Security + * Research Division of Network Associates, Inc. under DARPA/SPAWAR + * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS + * research program + * + * Copyright (c) 1982, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. * Copyright (c) 1983, 1992, 1993 * The Regents of the University of California. All rights reserved. * @@ -49,6 +61,7 @@ static const char rcsid[] = #include <sys/time.h> #include <sys/disklabel.h> +#include <ufs/ufs/dinode.h> #include <ufs/ffs/fs.h> #include <err.h> @@ -72,6 +85,11 @@ union { long dev_bsize = 1; +/* + * Possible superblock locations ordered from most to least likely. + */ +static int sblock_try[] = SBLOCKSEARCH; + int dumpfs(const char *); int dumpcg(const char *, int, int); void pbits(void *, int); @@ -107,67 +125,94 @@ int dumpfs(const char *name) { ssize_t n; + time_t time; + int64_t fssize; int fd, c, i, j, k, size; if ((fd = open(name, O_RDONLY, 0)) < 0) goto err; - if (lseek(fd, (off_t)SBOFF, SEEK_SET) == (off_t)-1) - goto err; - if ((n = read(fd, &afs, SBSIZE)) == -1) - goto err; - - if (n != SBSIZE) { - warnx("%s: non-existent or truncated superblock, skipped", - name); - (void)close(fd); - return (1); + for (i = 0; sblock_try[i] != -1; i++) { + if (lseek(fd, (off_t)sblock_try[i], SEEK_SET) == (off_t)-1) + goto err; + if ((n = read(fd, &afs, SBLOCKSIZE)) == -1) + goto err; + if ((afs.fs_magic == FS_UFS1_MAGIC || + (afs.fs_magic == FS_UFS2_MAGIC && + afs.fs_sblockloc == numfrags(&afs, sblock_try[i]))) && + afs.fs_bsize <= MAXBSIZE && + afs.fs_bsize >= sizeof(struct fs)) + break; + } + if (sblock_try[i] == -1) { + fprintf(stderr, "Cannot find filesystem superblock\n"); + return (1); } - if (afs.fs_magic != FS_MAGIC) { - warnx("%s: superblock has bad magic number, skipped", name); - (void)close(fd); - return (1); - } - if (afs.fs_postblformat == FS_42POSTBLFMT) - afs.fs_nrpos = 8; dev_bsize = afs.fs_fsize / fsbtodb(&afs, 1); - printf("magic\t%x\ttime\t%s", afs.fs_magic, - ctime(&afs.fs_time)); - printf("id\t[ %x %x ]\n", afs.fs_id[0], afs.fs_id[1]); - printf("cylgrp\t%s\tinodes\t%s\n", - afs.fs_postblformat == FS_42POSTBLFMT ? "static" : "dynamic", - afs.fs_inodefmt < FS_44INODEFMT ? "4.2/4.3BSD" : "4.4BSD"); - printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n", - afs.fs_cstotal.cs_nbfree, afs.fs_cstotal.cs_ndir, - afs.fs_cstotal.cs_nifree, afs.fs_cstotal.cs_nffree); - printf("ncg\t%d\tncyl\t%d\tsize\t%d\tblocks\t%d\n", - afs.fs_ncg, afs.fs_ncyl, afs.fs_size, afs.fs_dsize); + if (afs.fs_magic == FS_UFS2_MAGIC) { + fssize = afs.fs_size; + time = afs.fs_time; + printf("magic\t%x (UFS2)\ttime\t%s", + afs.fs_magic, ctime(&time)); + printf("offset\t%qd\tid\t[ %x %x ]\n", + afs.fs_sblockloc, afs.fs_id[0], afs.fs_id[1]); + printf("ncg\t%d\tsize\t%qd\tblocks\t%d\n", + afs.fs_ncg, fssize, afs.fs_dsize); + } else { + fssize = afs.fs_old_size; + printf("magic\t%x (UFS1)\ttime\t%s", + afs.fs_magic, ctime(&afs.fs_old_time)); + printf("id\t[ %x %x ]\n", afs.fs_id[0], afs.fs_id[1]); + printf("ncg\t%d\tsize\t%qd\tblocks\t%d\n", + afs.fs_ncg, fssize, afs.fs_dsize); + } printf("bsize\t%d\tshift\t%d\tmask\t0x%08x\n", afs.fs_bsize, afs.fs_bshift, afs.fs_bmask); printf("fsize\t%d\tshift\t%d\tmask\t0x%08x\n", afs.fs_fsize, afs.fs_fshift, afs.fs_fmask); printf("frag\t%d\tshift\t%d\tfsbtodb\t%d\n", afs.fs_frag, afs.fs_fragshift, afs.fs_fsbtodb); - printf("cpg\t%d\tbpg\t%d\tfpg\t%d\tipg\t%d\n", - afs.fs_cpg, afs.fs_fpg / afs.fs_frag, afs.fs_fpg, afs.fs_ipg); - printf("minfree\t%d%%\toptim\t%s\tmaxcontig %d\tmaxbpg\t%d\n", + printf("minfree\t%d%%\toptim\t%s\tsymlinklen %d\n", afs.fs_minfree, afs.fs_optim == FS_OPTSPACE ? "space" : "time", - afs.fs_maxcontig, afs.fs_maxbpg); - printf("rotdelay %dms\trps\t%d\n", - afs.fs_rotdelay, afs.fs_rps); - printf("ntrak\t%d\tnsect\t%d\tnpsect\t%d\tspc\t%d\n", - afs.fs_ntrak, afs.fs_nsect, afs.fs_npsect, afs.fs_spc); - printf("symlinklen %d\ttrackskew %d\tinterleave %d\tcontigsumsize %d\n", - afs.fs_maxsymlinklen, afs.fs_trackskew, afs.fs_interleave, - afs.fs_contigsumsize); - printf("nindir\t%d\tinopb\t%d\tnspf\t%d\tmaxfilesize\t%qu\n", - afs.fs_nindir, afs.fs_inopb, afs.fs_nspf, afs.fs_maxfilesize); + afs.fs_maxsymlinklen); + if (afs.fs_magic == FS_UFS2_MAGIC) { + printf("%s %d\tmaxbpg\t%d\tmaxcontig %d\tcontigsumsize %d\n", + "maxbsize", afs.fs_maxbsize, afs.fs_maxbpg, + afs.fs_maxcontig, afs.fs_contigsumsize); + printf("nbfree\t%qd\tndir\t%qd\tnifree\t%qd\tnffree\t%qd\n", + afs.fs_cstotal.cs_nbfree, afs.fs_cstotal.cs_ndir, + afs.fs_cstotal.cs_nifree, afs.fs_cstotal.cs_nffree); + printf("bpg\t%d\tfpg\t%d\tipg\t%d\n", + afs.fs_fpg / afs.fs_frag, afs.fs_fpg, afs.fs_ipg); + printf("nindir\t%d\tinopb\t%d\tmaxfilesize\t%qu\n", + afs.fs_nindir, afs.fs_inopb, afs.fs_maxfilesize); + printf("sbsize\t%d\tcgsize\t%d\tcsaddr\t%d\tcssize\t%d\n", + afs.fs_sbsize, afs.fs_cgsize, afs.fs_csaddr, afs.fs_cssize); + } else { + printf("maxbpg\t%d\tmaxcontig %d\tcontigsumsize %d\n", + afs.fs_maxbpg, afs.fs_maxcontig, afs.fs_contigsumsize); + printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n", + afs.fs_old_cstotal.cs_nbfree, afs.fs_old_cstotal.cs_ndir, + afs.fs_old_cstotal.cs_nifree, afs.fs_old_cstotal.cs_nffree); + printf("cpg\t%d\tbpg\t%d\tfpg\t%d\tipg\t%d\n", + afs.fs_old_cpg, afs.fs_fpg / afs.fs_frag, afs.fs_fpg, + afs.fs_ipg); + printf("nindir\t%d\tinopb\t%d\tnspf\t%d\tmaxfilesize\t%qu\n", + afs.fs_nindir, afs.fs_inopb, afs.fs_old_nspf, + afs.fs_maxfilesize); + printf("sbsize\t%d\tcgsize\t%d\tcgoffset %d\tcgmask\t0x%08x\n", + afs.fs_sbsize, afs.fs_cgsize, afs.fs_old_cgoffset, + afs.fs_old_cgmask); + printf("csaddr\t%d\tcssize\t%d\n", + afs.fs_old_csaddr, afs.fs_cssize); + printf("rotdelay %dms\trps\t%d\ttrackskew %d\tinterleave %d\n", + afs.fs_old_rotdelay, afs.fs_old_rps, afs.fs_old_trackskew, + afs.fs_old_interleave); + printf("nsect\t%d\tnpsect\t%d\tspc\t%d\n", + afs.fs_old_nsect, afs.fs_old_npsect, afs.fs_old_spc); + } printf("sblkno\t%d\tcblkno\t%d\tiblkno\t%d\tdblkno\t%d\n", afs.fs_sblkno, afs.fs_cblkno, afs.fs_iblkno, afs.fs_dblkno); - printf("sbsize\t%d\tcgsize\t%d\tcgoffset %d\tcgmask\t0x%08x\n", - afs.fs_sbsize, afs.fs_cgsize, afs.fs_cgoffset, afs.fs_cgmask); - printf("csaddr\t%d\tcssize\t%d\tshift\t%d\tmask\t0x%08x\n", - afs.fs_csaddr, afs.fs_cssize, afs.fs_csshift, afs.fs_csmask); printf("cgrotor\t%d\tfmod\t%d\tronly\t%d\tclean\t%d\n", afs.fs_cgrotor, afs.fs_fmod, afs.fs_ronly, afs.fs_clean); printf("flags\t"); @@ -177,43 +222,24 @@ dumpfs(const char *name) printf("unclean "); if (afs.fs_flags & FS_DOSOFTDEP) printf("soft-updates "); - if ((afs.fs_flags & ~(FS_UNCLEAN | FS_DOSOFTDEP)) != 0) - printf("unknown flags (%#x)", - afs.fs_flags & ~(FS_UNCLEAN | FS_DOSOFTDEP)); + if (afs.fs_flags & FS_NEEDSFSCK) + printf("needs fsck run "); + if (afs.fs_flags & FS_INDEXDIRS) + printf("indexed directories "); + if ((afs.fs_flags & + ~(FS_UNCLEAN | FS_DOSOFTDEP | FS_NEEDSFSCK | FS_INDEXDIRS)) != 0) + printf("unknown flags (%#x)", afs.fs_flags & + ~(FS_UNCLEAN | FS_DOSOFTDEP | + FS_NEEDSFSCK | FS_INDEXDIRS)); putchar('\n'); - if (afs.fs_cpc != 0) - printf("blocks available in each of %d rotational positions", - afs.fs_nrpos); - else - printf("(no rotational position table)\n"); - for (c = 0; c < afs.fs_cpc; c++) { - printf("\ncylinder number %d:", c); - for (i = 0; i < afs.fs_nrpos; i++) { - if (fs_postbl(&afs, c)[i] == -1) - continue; - printf("\n position %d:\t", i); - for (j = fs_postbl(&afs, c)[i], k = 1; ; - j += fs_rotbl(&afs)[j], k++) { - printf("%5d", j); - if (k % 12 == 0) - printf("\n\t\t"); - if (fs_rotbl(&afs)[j] == 0) - break; - } - } - } printf("\ncs[].cs_(nbfree,ndir,nifree,nffree):\n\t"); afs.fs_csp = calloc(1, afs.fs_cssize); - for (i = 0, j = 0; i < afs.fs_cssize; i += afs.fs_bsize, j++) { - size = afs.fs_cssize - i < afs.fs_bsize ? - afs.fs_cssize - i : afs.fs_bsize; - if (lseek(fd, - (off_t)(fsbtodb(&afs, (afs.fs_csaddr + j * afs.fs_frag))) * - (off_t)dev_bsize, SEEK_SET) == (off_t)-1) - goto err; - if (read(fd, (char *)afs.fs_csp + i, size) != size) - goto err; - } + if (lseek(fd, + (off_t)(fsbtodb(&afs, afs.fs_csaddr)) * (off_t)dev_bsize, + SEEK_SET) == (off_t)-1) + goto err; + if (read(fd, (char *)afs.fs_csp, afs.fs_cssize) != afs.fs_cssize) + goto err; for (i = 0; i < afs.fs_ncg; i++) { struct csum *cs = &afs.fs_cs(&afs, i); if (i && i % 4 == 0) @@ -222,13 +248,14 @@ dumpfs(const char *name) cs->cs_nbfree, cs->cs_ndir, cs->cs_nifree, cs->cs_nffree); } printf("\n"); - if (afs.fs_ncyl % afs.fs_cpg) { - printf("cylinders in last group %d\n", - i = afs.fs_ncyl % afs.fs_cpg); - printf("blocks in last group %d\n", - i * afs.fs_spc / NSPB(&afs)); + if (fssize % afs.fs_fpg) { + if (afs.fs_magic == FS_UFS1_MAGIC) + printf("cylinders in last group %d\n", + howmany(afs.fs_old_size % afs.fs_fpg, + afs.fs_old_spc / afs.fs_old_nspf)); + printf("blocks in last group %d\n\n", + (fssize % afs.fs_fpg) / afs.fs_frag); } - printf("\n"); for (i = 0; i < afs.fs_ncg; i++) if (dumpcg(name, fd, i)) goto err; @@ -244,6 +271,7 @@ err: if (fd != -1) int dumpcg(const char *name, int fd, int c) { + time_t time; off_t cur; int i, j; @@ -255,12 +283,19 @@ dumpcg(const char *name, int fd, int c) warnx("%s: error reading cg", name); return (1); } - printf("magic\t%x\ttell\t%qx\ttime\t%s", - afs.fs_postblformat == FS_42POSTBLFMT ? - ((struct ocg *)&acg)->cg_magic : acg.cg_magic, - cur, ctime(&acg.cg_time)); - printf("cgx\t%d\tncyl\t%d\tniblk\t%d\tndblk\t%d\n", - acg.cg_cgx, acg.cg_ncyl, acg.cg_niblk, acg.cg_ndblk); + if (afs.fs_magic == FS_UFS2_MAGIC) { + time = acg.cg_time; + printf("magic\t%x\ttell\t%qx\ttime\t%s", + acg.cg_magic, cur, ctime(&time)); + printf("cgx\t%d\tndblk\t%d\tniblk\t%d\tinitiblk %d\n", + acg.cg_cgx, acg.cg_ndblk, acg.cg_niblk, acg.cg_initediblk); + } else { + printf("magic\t%x\ttell\t%qx\ttime\t%s", + acg.cg_magic, cur, ctime(&acg.cg_old_time)); + printf("cgx\t%d\tncyl\t%d\tniblk\t%d\tndblk\t%d\n", + acg.cg_cgx, acg.cg_old_ncyl, acg.cg_old_niblk, + acg.cg_ndblk); + } printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n", acg.cg_cs.cs_nbfree, acg.cg_cs.cs_ndir, acg.cg_cs.cs_nifree, acg.cg_cs.cs_nffree); @@ -286,23 +321,10 @@ dumpcg(const char *name, int fd, int c) pbits(cg_clustersfree(&acg), acg.cg_nclusterblks); } else printf("\n"); - printf("iused:\t"); + printf("inodes used:\t"); pbits(cg_inosused(&acg), afs.fs_ipg); - printf("free:\t"); + printf("blks free:\t"); pbits(cg_blksfree(&acg), afs.fs_fpg); - printf("b:\n"); - for (i = 0; i < afs.fs_cpg; i++) { - if (cg_blktot(&acg)[i] == 0) - continue; - printf(" c%d:\t(%d)\t", i, cg_blktot(&acg)[i]); - for (j = 0; j < afs.fs_nrpos; j++) { - if (afs.fs_cpc > 0 && - fs_postbl(&afs, i % afs.fs_cpc)[j] == -1) - continue; - printf(" %d", cg_blks(&afs, &acg, i)[j]); - } - printf("\n"); - } return (0); }; |