dumpfs.c revision 98542
11558Srgrimes/* 298542Smckusick * Copyright (c) 2002 Networks Associates Technology, Inc. 398542Smckusick * All rights reserved. 498542Smckusick * 598542Smckusick * This software was developed for the FreeBSD Project by Marshall 698542Smckusick * Kirk McKusick and Network Associates Laboratories, the Security 798542Smckusick * Research Division of Network Associates, Inc. under DARPA/SPAWAR 898542Smckusick * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS 998542Smckusick * research program 1098542Smckusick * 1198542Smckusick * Copyright (c) 1982, 1989, 1993 1298542Smckusick * The Regents of the University of California. All rights reserved. 1398542Smckusick * (c) UNIX System Laboratories, Inc. 141558Srgrimes * Copyright (c) 1983, 1992, 1993 151558Srgrimes * The Regents of the University of California. All rights reserved. 161558Srgrimes * 171558Srgrimes * Redistribution and use in source and binary forms, with or without 181558Srgrimes * modification, are permitted provided that the following conditions 191558Srgrimes * are met: 201558Srgrimes * 1. Redistributions of source code must retain the above copyright 211558Srgrimes * notice, this list of conditions and the following disclaimer. 221558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 231558Srgrimes * notice, this list of conditions and the following disclaimer in the 241558Srgrimes * documentation and/or other materials provided with the distribution. 251558Srgrimes * 3. All advertising materials mentioning features or use of this software 261558Srgrimes * must display the following acknowledgement: 271558Srgrimes * This product includes software developed by the University of 281558Srgrimes * California, Berkeley and its contributors. 291558Srgrimes * 4. Neither the name of the University nor the names of its contributors 301558Srgrimes * may be used to endorse or promote products derived from this software 311558Srgrimes * without specific prior written permission. 321558Srgrimes * 331558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 341558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 351558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 361558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 371558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 381558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 391558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 401558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 411558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 421558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 431558Srgrimes * SUCH DAMAGE. 441558Srgrimes */ 451558Srgrimes 461558Srgrimes#ifndef lint 4736998Scharnierstatic const char copyright[] = 481558Srgrimes"@(#) Copyright (c) 1983, 1992, 1993\n\ 491558Srgrimes The Regents of the University of California. All rights reserved.\n"; 501558Srgrimes#endif /* not lint */ 511558Srgrimes 521558Srgrimes#ifndef lint 5336998Scharnier#if 0 5423673Speterstatic char sccsid[] = "@(#)dumpfs.c 8.5 (Berkeley) 4/29/95"; 5536998Scharnier#endif 5636998Scharnierstatic const char rcsid[] = 5750476Speter "$FreeBSD: head/sbin/dumpfs/dumpfs.c 98542 2002-06-21 06:18:05Z mckusick $"; 581558Srgrimes#endif /* not lint */ 591558Srgrimes 601558Srgrimes#include <sys/param.h> 611558Srgrimes#include <sys/time.h> 6296478Sphk#include <sys/disklabel.h> 631558Srgrimes 6498542Smckusick#include <ufs/ufs/dinode.h> 651558Srgrimes#include <ufs/ffs/fs.h> 661558Srgrimes 6723673Speter#include <err.h> 681558Srgrimes#include <fcntl.h> 691558Srgrimes#include <fstab.h> 701558Srgrimes#include <stdio.h> 711558Srgrimes#include <stdlib.h> 7223673Speter#include <unistd.h> 731558Srgrimes 741558Srgrimesunion { 751558Srgrimes struct fs fs; 761558Srgrimes char pad[MAXBSIZE]; 771558Srgrimes} fsun; 781558Srgrimes#define afs fsun.fs 791558Srgrimes 801558Srgrimesunion { 811558Srgrimes struct cg cg; 821558Srgrimes char pad[MAXBSIZE]; 831558Srgrimes} cgun; 841558Srgrimes#define acg cgun.cg 851558Srgrimes 861558Srgrimeslong dev_bsize = 1; 871558Srgrimes 8898542Smckusick/* 8998542Smckusick * Possible superblock locations ordered from most to least likely. 9098542Smckusick */ 9198542Smckusickstatic int sblock_try[] = SBLOCKSEARCH; 9298542Smckusick 9392839Simpint dumpfs(const char *); 9492839Simpint dumpcg(const char *, int, int); 9592839Simpvoid pbits(void *, int); 9692839Simpvoid usage(void) __dead2; 971558Srgrimes 981558Srgrimesint 9992839Simpmain(int argc, char *argv[]) 1001558Srgrimes{ 10192806Sobrien struct fstab *fs; 1021558Srgrimes int ch, eval; 1031558Srgrimes 10423673Speter while ((ch = getopt(argc, argv, "")) != -1) 1051558Srgrimes switch(ch) { 1061558Srgrimes case '?': 1071558Srgrimes default: 1081558Srgrimes usage(); 1091558Srgrimes } 1101558Srgrimes argc -= optind; 1111558Srgrimes argv += optind; 1121558Srgrimes 1131558Srgrimes if (argc < 1) 1141558Srgrimes usage(); 1151558Srgrimes 1161558Srgrimes for (eval = 0; *argv; ++argv) 1171558Srgrimes if ((fs = getfsfile(*argv)) == NULL) 1181558Srgrimes eval |= dumpfs(*argv); 1191558Srgrimes else 1201558Srgrimes eval |= dumpfs(fs->fs_spec); 1211558Srgrimes exit(eval); 1221558Srgrimes} 1231558Srgrimes 1241558Srgrimesint 12592839Simpdumpfs(const char *name) 1261558Srgrimes{ 12735341Srnordier ssize_t n; 12898542Smckusick time_t time; 12998542Smckusick int64_t fssize; 1301558Srgrimes int fd, c, i, j, k, size; 1311558Srgrimes 1321558Srgrimes if ((fd = open(name, O_RDONLY, 0)) < 0) 1331558Srgrimes goto err; 13498542Smckusick for (i = 0; sblock_try[i] != -1; i++) { 13598542Smckusick if (lseek(fd, (off_t)sblock_try[i], SEEK_SET) == (off_t)-1) 13698542Smckusick goto err; 13798542Smckusick if ((n = read(fd, &afs, SBLOCKSIZE)) == -1) 13898542Smckusick goto err; 13998542Smckusick if ((afs.fs_magic == FS_UFS1_MAGIC || 14098542Smckusick (afs.fs_magic == FS_UFS2_MAGIC && 14198542Smckusick afs.fs_sblockloc == numfrags(&afs, sblock_try[i]))) && 14298542Smckusick afs.fs_bsize <= MAXBSIZE && 14398542Smckusick afs.fs_bsize >= sizeof(struct fs)) 14498542Smckusick break; 14535341Srnordier } 14698542Smckusick if (sblock_try[i] == -1) { 14798542Smckusick fprintf(stderr, "Cannot find filesystem superblock\n"); 14898542Smckusick return (1); 14998542Smckusick } 15023673Speter 1511558Srgrimes dev_bsize = afs.fs_fsize / fsbtodb(&afs, 1); 15298542Smckusick if (afs.fs_magic == FS_UFS2_MAGIC) { 15398542Smckusick fssize = afs.fs_size; 15498542Smckusick time = afs.fs_time; 15598542Smckusick printf("magic\t%x (UFS2)\ttime\t%s", 15698542Smckusick afs.fs_magic, ctime(&time)); 15798542Smckusick printf("offset\t%qd\tid\t[ %x %x ]\n", 15898542Smckusick afs.fs_sblockloc, afs.fs_id[0], afs.fs_id[1]); 15998542Smckusick printf("ncg\t%d\tsize\t%qd\tblocks\t%d\n", 16098542Smckusick afs.fs_ncg, fssize, afs.fs_dsize); 16198542Smckusick } else { 16298542Smckusick fssize = afs.fs_old_size; 16398542Smckusick printf("magic\t%x (UFS1)\ttime\t%s", 16498542Smckusick afs.fs_magic, ctime(&afs.fs_old_time)); 16598542Smckusick printf("id\t[ %x %x ]\n", afs.fs_id[0], afs.fs_id[1]); 16698542Smckusick printf("ncg\t%d\tsize\t%qd\tblocks\t%d\n", 16798542Smckusick afs.fs_ncg, fssize, afs.fs_dsize); 16898542Smckusick } 1691558Srgrimes printf("bsize\t%d\tshift\t%d\tmask\t0x%08x\n", 1701558Srgrimes afs.fs_bsize, afs.fs_bshift, afs.fs_bmask); 1711558Srgrimes printf("fsize\t%d\tshift\t%d\tmask\t0x%08x\n", 1721558Srgrimes afs.fs_fsize, afs.fs_fshift, afs.fs_fmask); 1731558Srgrimes printf("frag\t%d\tshift\t%d\tfsbtodb\t%d\n", 1741558Srgrimes afs.fs_frag, afs.fs_fragshift, afs.fs_fsbtodb); 17598542Smckusick printf("minfree\t%d%%\toptim\t%s\tsymlinklen %d\n", 1761558Srgrimes afs.fs_minfree, afs.fs_optim == FS_OPTSPACE ? "space" : "time", 17798542Smckusick afs.fs_maxsymlinklen); 17898542Smckusick if (afs.fs_magic == FS_UFS2_MAGIC) { 17998542Smckusick printf("%s %d\tmaxbpg\t%d\tmaxcontig %d\tcontigsumsize %d\n", 18098542Smckusick "maxbsize", afs.fs_maxbsize, afs.fs_maxbpg, 18198542Smckusick afs.fs_maxcontig, afs.fs_contigsumsize); 18298542Smckusick printf("nbfree\t%qd\tndir\t%qd\tnifree\t%qd\tnffree\t%qd\n", 18398542Smckusick afs.fs_cstotal.cs_nbfree, afs.fs_cstotal.cs_ndir, 18498542Smckusick afs.fs_cstotal.cs_nifree, afs.fs_cstotal.cs_nffree); 18598542Smckusick printf("bpg\t%d\tfpg\t%d\tipg\t%d\n", 18698542Smckusick afs.fs_fpg / afs.fs_frag, afs.fs_fpg, afs.fs_ipg); 18798542Smckusick printf("nindir\t%d\tinopb\t%d\tmaxfilesize\t%qu\n", 18898542Smckusick afs.fs_nindir, afs.fs_inopb, afs.fs_maxfilesize); 18998542Smckusick printf("sbsize\t%d\tcgsize\t%d\tcsaddr\t%d\tcssize\t%d\n", 19098542Smckusick afs.fs_sbsize, afs.fs_cgsize, afs.fs_csaddr, afs.fs_cssize); 19198542Smckusick } else { 19298542Smckusick printf("maxbpg\t%d\tmaxcontig %d\tcontigsumsize %d\n", 19398542Smckusick afs.fs_maxbpg, afs.fs_maxcontig, afs.fs_contigsumsize); 19498542Smckusick printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n", 19598542Smckusick afs.fs_old_cstotal.cs_nbfree, afs.fs_old_cstotal.cs_ndir, 19698542Smckusick afs.fs_old_cstotal.cs_nifree, afs.fs_old_cstotal.cs_nffree); 19798542Smckusick printf("cpg\t%d\tbpg\t%d\tfpg\t%d\tipg\t%d\n", 19898542Smckusick afs.fs_old_cpg, afs.fs_fpg / afs.fs_frag, afs.fs_fpg, 19998542Smckusick afs.fs_ipg); 20098542Smckusick printf("nindir\t%d\tinopb\t%d\tnspf\t%d\tmaxfilesize\t%qu\n", 20198542Smckusick afs.fs_nindir, afs.fs_inopb, afs.fs_old_nspf, 20298542Smckusick afs.fs_maxfilesize); 20398542Smckusick printf("sbsize\t%d\tcgsize\t%d\tcgoffset %d\tcgmask\t0x%08x\n", 20498542Smckusick afs.fs_sbsize, afs.fs_cgsize, afs.fs_old_cgoffset, 20598542Smckusick afs.fs_old_cgmask); 20698542Smckusick printf("csaddr\t%d\tcssize\t%d\n", 20798542Smckusick afs.fs_old_csaddr, afs.fs_cssize); 20898542Smckusick printf("rotdelay %dms\trps\t%d\ttrackskew %d\tinterleave %d\n", 20998542Smckusick afs.fs_old_rotdelay, afs.fs_old_rps, afs.fs_old_trackskew, 21098542Smckusick afs.fs_old_interleave); 21198542Smckusick printf("nsect\t%d\tnpsect\t%d\tspc\t%d\n", 21298542Smckusick afs.fs_old_nsect, afs.fs_old_npsect, afs.fs_old_spc); 21398542Smckusick } 2141558Srgrimes printf("sblkno\t%d\tcblkno\t%d\tiblkno\t%d\tdblkno\t%d\n", 2151558Srgrimes afs.fs_sblkno, afs.fs_cblkno, afs.fs_iblkno, afs.fs_dblkno); 2162154Sdg printf("cgrotor\t%d\tfmod\t%d\tronly\t%d\tclean\t%d\n", 2172154Sdg afs.fs_cgrotor, afs.fs_fmod, afs.fs_ronly, afs.fs_clean); 21848875Smpp printf("flags\t"); 21948875Smpp if (afs.fs_flags == 0) 22048875Smpp printf("none"); 22148875Smpp if (afs.fs_flags & FS_UNCLEAN) 22248875Smpp printf("unclean "); 22348875Smpp if (afs.fs_flags & FS_DOSOFTDEP) 22448875Smpp printf("soft-updates "); 22598542Smckusick if (afs.fs_flags & FS_NEEDSFSCK) 22698542Smckusick printf("needs fsck run "); 22798542Smckusick if (afs.fs_flags & FS_INDEXDIRS) 22898542Smckusick printf("indexed directories "); 22998542Smckusick if ((afs.fs_flags & 23098542Smckusick ~(FS_UNCLEAN | FS_DOSOFTDEP | FS_NEEDSFSCK | FS_INDEXDIRS)) != 0) 23198542Smckusick printf("unknown flags (%#x)", afs.fs_flags & 23298542Smckusick ~(FS_UNCLEAN | FS_DOSOFTDEP | 23398542Smckusick FS_NEEDSFSCK | FS_INDEXDIRS)); 23448875Smpp putchar('\n'); 2351558Srgrimes printf("\ncs[].cs_(nbfree,ndir,nifree,nffree):\n\t"); 23671073Siedowse afs.fs_csp = calloc(1, afs.fs_cssize); 23798542Smckusick if (lseek(fd, 23898542Smckusick (off_t)(fsbtodb(&afs, afs.fs_csaddr)) * (off_t)dev_bsize, 23998542Smckusick SEEK_SET) == (off_t)-1) 24098542Smckusick goto err; 24198542Smckusick if (read(fd, (char *)afs.fs_csp, afs.fs_cssize) != afs.fs_cssize) 24298542Smckusick goto err; 2431558Srgrimes for (i = 0; i < afs.fs_ncg; i++) { 2441558Srgrimes struct csum *cs = &afs.fs_cs(&afs, i); 2451558Srgrimes if (i && i % 4 == 0) 2461558Srgrimes printf("\n\t"); 2471558Srgrimes printf("(%d,%d,%d,%d) ", 2481558Srgrimes cs->cs_nbfree, cs->cs_ndir, cs->cs_nifree, cs->cs_nffree); 2491558Srgrimes } 2501558Srgrimes printf("\n"); 25198542Smckusick if (fssize % afs.fs_fpg) { 25298542Smckusick if (afs.fs_magic == FS_UFS1_MAGIC) 25398542Smckusick printf("cylinders in last group %d\n", 25498542Smckusick howmany(afs.fs_old_size % afs.fs_fpg, 25598542Smckusick afs.fs_old_spc / afs.fs_old_nspf)); 25698542Smckusick printf("blocks in last group %d\n\n", 25798542Smckusick (fssize % afs.fs_fpg) / afs.fs_frag); 2581558Srgrimes } 2591558Srgrimes for (i = 0; i < afs.fs_ncg; i++) 2601558Srgrimes if (dumpcg(name, fd, i)) 2611558Srgrimes goto err; 2621558Srgrimes (void)close(fd); 2631558Srgrimes return (0); 2641558Srgrimes 2651558Srgrimeserr: if (fd != -1) 2661558Srgrimes (void)close(fd); 26723673Speter warn("%s", name); 2681558Srgrimes return (1); 2691558Srgrimes}; 2701558Srgrimes 2711558Srgrimesint 27292839Simpdumpcg(const char *name, int fd, int c) 2731558Srgrimes{ 27498542Smckusick time_t time; 2751558Srgrimes off_t cur; 2761558Srgrimes int i, j; 2771558Srgrimes 2781558Srgrimes printf("\ncg %d:\n", c); 27916603Speter if ((cur = lseek(fd, (off_t)(fsbtodb(&afs, cgtod(&afs, c))) * 28016603Speter (off_t)dev_bsize, SEEK_SET)) == (off_t)-1) 2811558Srgrimes return (1); 2821558Srgrimes if (read(fd, &acg, afs.fs_bsize) != afs.fs_bsize) { 28323673Speter warnx("%s: error reading cg", name); 2841558Srgrimes return (1); 2851558Srgrimes } 28698542Smckusick if (afs.fs_magic == FS_UFS2_MAGIC) { 28798542Smckusick time = acg.cg_time; 28898542Smckusick printf("magic\t%x\ttell\t%qx\ttime\t%s", 28998542Smckusick acg.cg_magic, cur, ctime(&time)); 29098542Smckusick printf("cgx\t%d\tndblk\t%d\tniblk\t%d\tinitiblk %d\n", 29198542Smckusick acg.cg_cgx, acg.cg_ndblk, acg.cg_niblk, acg.cg_initediblk); 29298542Smckusick } else { 29398542Smckusick printf("magic\t%x\ttell\t%qx\ttime\t%s", 29498542Smckusick acg.cg_magic, cur, ctime(&acg.cg_old_time)); 29598542Smckusick printf("cgx\t%d\tncyl\t%d\tniblk\t%d\tndblk\t%d\n", 29698542Smckusick acg.cg_cgx, acg.cg_old_ncyl, acg.cg_old_niblk, 29798542Smckusick acg.cg_ndblk); 29898542Smckusick } 2991558Srgrimes printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n", 3001558Srgrimes acg.cg_cs.cs_nbfree, acg.cg_cs.cs_ndir, 3011558Srgrimes acg.cg_cs.cs_nifree, acg.cg_cs.cs_nffree); 3021558Srgrimes printf("rotor\t%d\tirotor\t%d\tfrotor\t%d\nfrsum", 3031558Srgrimes acg.cg_rotor, acg.cg_irotor, acg.cg_frotor); 3041558Srgrimes for (i = 1, j = 0; i < afs.fs_frag; i++) { 3051558Srgrimes printf("\t%d", acg.cg_frsum[i]); 3061558Srgrimes j += i * acg.cg_frsum[i]; 3071558Srgrimes } 3081558Srgrimes printf("\nsum of frsum: %d", j); 3091558Srgrimes if (afs.fs_contigsumsize > 0) { 3101558Srgrimes for (i = 1; i < afs.fs_contigsumsize; i++) { 3111558Srgrimes if ((i - 1) % 8 == 0) 3121558Srgrimes printf("\nclusters %d-%d:", i, 3131558Srgrimes afs.fs_contigsumsize - 1 < i + 7 ? 3141558Srgrimes afs.fs_contigsumsize - 1 : i + 7); 3151558Srgrimes printf("\t%d", cg_clustersum(&acg)[i]); 3161558Srgrimes } 3171558Srgrimes printf("\nclusters size %d and over: %d\n", 3181558Srgrimes afs.fs_contigsumsize, 3191558Srgrimes cg_clustersum(&acg)[afs.fs_contigsumsize]); 3201558Srgrimes printf("clusters free:\t"); 3211558Srgrimes pbits(cg_clustersfree(&acg), acg.cg_nclusterblks); 3221558Srgrimes } else 3231558Srgrimes printf("\n"); 32498542Smckusick printf("inodes used:\t"); 3251558Srgrimes pbits(cg_inosused(&acg), afs.fs_ipg); 32698542Smckusick printf("blks free:\t"); 3271558Srgrimes pbits(cg_blksfree(&acg), afs.fs_fpg); 3281558Srgrimes return (0); 3291558Srgrimes}; 3301558Srgrimes 3311558Srgrimesvoid 33292839Simppbits(void *vp, int max) 3331558Srgrimes{ 33492806Sobrien int i; 33592806Sobrien char *p; 3361558Srgrimes int count, j; 3371558Srgrimes 3381558Srgrimes for (count = i = 0, p = vp; i < max; i++) 3391558Srgrimes if (isset(p, i)) { 3401558Srgrimes if (count) 3411558Srgrimes printf(",%s", count % 6 ? " " : "\n\t"); 3421558Srgrimes count++; 3431558Srgrimes printf("%d", i); 3441558Srgrimes j = i; 3451558Srgrimes while ((i+1)<max && isset(p, i+1)) 3461558Srgrimes i++; 3471558Srgrimes if (i != j) 3481558Srgrimes printf("-%d", i); 3491558Srgrimes } 3501558Srgrimes printf("\n"); 3511558Srgrimes} 3521558Srgrimes 3531558Srgrimesvoid 35492839Simpusage(void) 3551558Srgrimes{ 3561558Srgrimes (void)fprintf(stderr, "usage: dumpfs filesys | device\n"); 3571558Srgrimes exit(1); 3581558Srgrimes} 359