13 January 2011

Recreate a FreeBSD UFS FS

As a follow up to recreating a Solaris UFS FS, the following details
FreeBSD.  Just as with Solaris, when trying to determine how a filesystem
was created, 'newfs -N /dev/da2s1a' is not the answer, as it only produces
information relevant to a default FS creation.  Our host details for this
scenario are:
        HOST:                   beastie
        PROMPT:                 beastie [0]
        OS:                     FreeBSD 8.1
        DISK PARTITION:         da2s1a
Just as with Solaris, we start off with 'newfs' to create a generic
filesystem on 'da2s1a':
        beastie [0] /sbin/newfs /dev/da2s1a 
        /dev/da2s1a: 512.0MB (1048528 sectors) block size 16384, fragment size 2048
                using 4 cylinder groups of 128.00MB, 8192 blks, 16384 inodes.
        super-block backups (for fsck -b #) at:
         160, 262304, 524448, 786592
Now let's see what 'newfs -N' returns: 
        beastie [0] /sbin/newfs -N /dev/da2s1a  
        /dev/da2s1a: 512.0MB (1048528 sectors) block size 16384, fragment size 2048
                using 4 cylinder groups of 128.00MB, 8192 blks, 16384 inodes.
        super-block backups (for fsck -b #) at:
         160, 262304, 524448, 786592    
The output is identical to the first 'newfs' command.  The only difference
is that passing '-N' to 'newfs' tells 'newfs' to only print what would
be done and not create an FS.  The output also doesn't give us much
to work with to recreate the FS.  To get the FS creation parameters,
we need to look at 'dumpfs':   
        beastie [0] /sbin/dumpfs -m /dev/da2s1a
        # newfs command for /dev/da2s1a (/dev/da2s1a)
        newfs -O 2 -a 8 -b 16384 -d 16384 -e 2048 -f 2048 -g 16384 -h 64 -m 8\
         -o time -s 1048528 /dev/da2s1a
(The 'newfs' command shown above is one line though I've broken it up
(here and in the following details) over two for legibility, hence the
'\'.)  Let's see if 'dumpfs' is actually giving up true parameters for
'newfs'.  Below, I've mostly taken the options passed in a generic FS
creation and tweaked them, removing the size attribute (-s), and adding
a volume label (-L) and the number of bytes per inode (nbpi (-i)):
        beastie [0] /sbin/newfs -O2 -a 4 -b 4096 -d 4096 -e 1024 -f 512 -g 8192\
         -h 128 -m 2 -i 262144 -L testvol -o space /dev/da2s1a
        /dev/da2s1a: 512.0MB (1048528 sectors) block size 4096, fragment size 512
                using 38 cylinder groups of 13.53MB, 3463 blks, 64 inodes.
        super-block backups (for fsck -b #) at:
         144, 27848, 55552, 83256, 110960, 138664, 166368, 194072, 221776, 249480,
         277184, 304888, 332592, 360296, 388000, 415704, 443408, 471112, 498816,
         526520, 554224, 581928, 609632, 637336, 665040, 692744, 720448, 748152,
         775856, 803560, 831264, 858968, 886672, 914376, 942080, 969784, 997488,
         1025192
Going back to 'newfs -N', there's no output for a suitable rebuild
command and the output is back to the same as for a generic FS:
        beastie [0] /sbin/newfs -N /dev/da2s1a                                  
        /dev/da2s1a: 512.0MB (1048528 sectors) block size 16384, fragment size 2048
                using 4 cylinder groups of 128.00MB, 8192 blks, 16384 inodes.
        super-block backups (for fsck -b #) at:
         160, 262304, 524448, 786592
At this point, 'newfs -N' is definitely the wrong answer to determine
how a filesystem was created.  Back to 'dumpfs', we get back nearly all
of the appropriate 'newfs' parameters to recreate the FS:
        beastie [0] /sbin/dumpfs -m /dev/da2s1a
        # newfs command for /dev/da2s1a (/dev/da2s1a)
        newfs -L testvol -O 2 -a 4 -b 4096 -d 4096 -e 1024 -f 512 -g 8192 -h 128\
         -m 2 -o space -s 1048528 /dev/da2s1a
Those with a keen eye will notice that the 'dumpfs' devised 'newfs'
command is critically missing '-i' setting the inode density.  If we ran
the above command without the appropriate value to '-i', we would have
new values for our superblocks, among other things.  Assuming that you
set '-i' (nbpi) following the notes in the 'newfs' manpage, we'll need
to see the first 18 lines of 'dumpfs' output:
        beastie [0] /sbin/dumpfs /dev/da2s1a | /usr/bin/head -18
        magic   19540119 (UFS2) time    Thu Jan 13 18:03:00 2011
        superblock location     65536   id      [ 4d2f84a4 a6d95b30 ]
        ncg     38      size    1048528 blocks  1046254
        bsize   4096    shift   12      mask    0xfffff000
        fsize   512     shift   9       mask    0xfffffe00
        frag    8       shift   3       fsbtodb 0
        minfree 2%      optim   space   symlinklen 120
        maxbsize 4096   maxbpg  1024    maxcontig 4     contigsumsize 4
        nbfree  130779  ndir    2       nifree  2428    nffree  20
        bpg     3463    fpg     27704   ipg     64      unrefs  0
        nindir  512     inopb   16      maxfilesize     550831702015
        sbsize  1536    cgsize  4096    csaddr  200     cssize  1024
        sblkno  144     cblkno  160     iblkno  168     dblkno  200
        cgrotor 0       fmod    0       ronly   0       clean   1
        avgfpdir 128    avgfilesize 8192
        flags   none
        fsmnt
        volname testvol swuid   0
Again, assuming that you used the logic for '-i' from the manpage,
we can get the nbpi value using the following equation:
        nbpi = (size * fsize) / (4 * fsize)
               (1048528 * 512) / (4 * 512)
               536846336 / 2048
        nbpi = 262132
Due to constraints such as disk geometry and our other parameters,
'newfs' wasn't able to use our originally specified nbpi (-i) value
of "262144".  To meet those constraints, 'newfs' adjusted the nbpi to
"262132".  If we now take the earlier 'newfs' output from 'dumpfs -m',
adding the derived 'nbpi' value, we can recreate the FS:
        beastie [0] newfs -i 262132 -L testvol -O 2 -a 4 -b 4096 -d 4096 -e 1024\
         -f 512 -g 8192 -h 128 -m 2 -o space -s 1048528 /dev/da2s1a
        /dev/da2s1a: 512.0MB (1048528 sectors) block size 4096, fragment size 512
                using 38 cylinder groups of 13.53MB, 3463 blks, 64 inodes.
        super-block backups (for fsck -b #) at:
         144, 27848, 55552, 83256, 110960, 138664, 166368, 194072, 221776, 249480,
         277184, 304888, 332592, 360296, 388000, 415704, 443408, 471112, 498816,
         526520, 554224, 581928, 609632, 637336, 665040, 692744, 720448, 748152,
         775856, 803560, 831264, 858968, 886672, 914376, 942080, 969784, 997488,
         1025192

see also:
    Recreate a Solaris UFS FS
    Recreate a Linux EXT3 FS