Apr 4, 2009
A week ago, I encountered some space problems on my FreeBSD system during a system wide portupgrade. Fortunately, I had backed up my system just before the adventure, so my system was saved.
The procedure I followed to restore my data, was:
1- recreate my partitioning, giving 10 more Gigs to the system, using the FreeBSD installation CD
2- copy all the data on it
Since I backed up my FreeBSD system on an external ext3 hard drive, I needed to copy it back from “outside” my freebsd system. My first option was to use Fixit from the FreeBSD installation CD set, but I had problems mounting my partition because of the inode block size of my ext3 partition. Bref. I decided to mount everything from my Linux (ubuntu) system, and copy everything back from there!
I only way to do this was to recompile my kernel with the right “UFS write” flag. And it JUST WORKED!! I copied back __ALL__ my FreeBSD system on the new slices, rebooted my machine, and here I am writing this post from my old-new FreeBSD system! :)
What I did
By default, up to the Linux kernel 2.6.29, UFS file system write support is considered as “dangereous/experimental” and so, not set. Which means that, by default, a Linux machine will only mount your UFS partitions in readonly:
$ sudo mount -t ufs -o ufstype=ufs2 /dev/sdb5 /mnt/ mount: wrong fs type, bad option, bad superblock on /dev/sdb5, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so $ dmesg | tail -n 1 [ 871.777769] ufs was compiled with read-only support, can't be mounted as read-write
In order to actually mount it, you need to specify the readonly flag:
$ sudo mount -t ufs -o ro,ufstype=ufs2 /dev/sdb2 /mnt/
First of all, you need to download you kernel’s sources, and copy the .config of your current kernel:
$ sudo -s # apt-get install linux-source-2.6.27 # cd /usr/src # bzip2 -dc linux-source-2.6.27.tar.bz2 | tar xf - # cp /boot/config-2.6.27-2-686 .config
To add the UFS write support to your kernel, uncomment/add the CONFIG_UFS_FS_WRITE flag in the config of your kernel, then re-compile it:
$ grep CONFIG_UFS_FS_WRITE /usr/src/linux-source-2.6.27/.config CONFIG_UFS_FS_WRITE=y
To compile my kernel, I followed the instruction here. I just added CONCURRENCY_LEVEL=2 to use the 2 cores of my CPU.
$ sudo -s # CONCURRENCY_LEVEL=2 make-kpkg --initrd --append-to-version=-2-686-ufs kernel-image kernel-headers
Once the compilation is through, install your freshly built kernel (you should find the .deb files in /usr/src/) , and reboot on it.
$ sudo dpkg -i /usr/src/linux-image-2.6.27-1-686-ufs_2.6.27-1-686-ufs-10.00.Custom_i386.deb
NOTE for debian users: If you get kernel panics when booting. It could be because of the missing initrd associated to the new kernel. In this case, if you are using kernel-package-12.009 (or higher?) make sure you copy initramfs hooks so that your package generates the initrd uppon installation (and removes it when package is uninstalled):
cp /usr/share/kernel-package/examples/etc/kernel/postinst.d/initramfs /etc/kernel/postinst.d/ cp /usr/share/kernel-package/examples/etc/kernel/postrm.d/initramfs /etc/kernel/postrm.d/
Once you have booted on your new “UFS-writable” kernel:
$ sudo fdisk -l /dev/sdb Disk /dev/sdb: 500.1 GB, 500107862016 bytes 255 heads, 63 sectors/track, 60801 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x8f8000b1 Device Boot Start End Blocks Id System /dev/sdb1 1 1958 15727603+ 83 Linux /dev/sdb2 * 1959 4569 20972857+ a5 FreeBSD /dev/sdb3 4570 4830 2096482+ 82 Linux swap / Solaris /dev/sdb4 4831 60801 449587057+ 83 Linux
In this case, /dev/sdb2 contains my UFS slices.
If we take a closer look at /dev/ we will be able to see all the slices (this actually works by default)
$ ls -l /dev/sdb* brw-rw---- 1 root disk 8, 16 2009-04-04 16:20 /dev/sdb brw-rw---- 1 root disk 8, 17 2009-04-04 14:20 /dev/sdb1 brw-rw---- 1 root disk 8, 18 2009-04-04 16:20 /dev/sdb2 <--- FreeBSD paartition brw-rw---- 1 root disk 8, 19 2009-04-04 16:20 /dev/sdb3 brw-rw---- 1 root disk 8, 20 2009-04-04 14:20 /dev/sdb4 brw-rw---- 1 root disk 8, 21 2009-04-04 16:20 /dev/sdb5 <--- FreeBSD / slice brw-rw---- 1 root disk 8, 22 2009-04-04 16:20 /dev/sdb6 <--- FreeBSD swap brw-rw---- 1 root disk 8, 23 2009-04-04 16:20 /dev/sdb7 <--- FreeBSD /var slice brw-rw---- 1 root disk 8, 24 2009-04-04 16:20 /dev/sdb8 <--- FreeBSD /tmp slice brw-rw---- 1 root disk 8, 25 2009-04-04 16:20 /dev/sdb9 <--- FreeBSD /usr slice
Then, I mounted the slices in the right order and to the right mount points (in /mnt/) to have my FreeBSD exact filesystem environment. Then I copied back all the data using the old and nice tar technique, as root:
# ( cd /path/to/backup && tar cpf - . ) | ( cd /mnt/ && tar xvfp - )
Once the "un"-tar was done, I rebooted on my FreeBSD system (from which I am writing this post), forced the fsck of all my slices: everything seems to be OK!
The CONFIG_UFS_FS_WRITE kernel flag is still set as experimental, but it did work like charm for me (using kernel 2.6.27).
If you do use it, and you find a bug, please report it refering to this doc :)
Hope this was helpful.
Ignace M -ghantoos-