I'd like to explain how I managed to run rapbian with a unionfs root partition. Possible uses are related with keeping the internal sd card in read only mode and use writable layer placed either in a different partition of the same device or in a different medium (such as usb, nfs, sshfs or tmpfs if you have a 512MB raspi). With this, we can avoid detroying our root filesystem (or even the device itself), and also performance of sd media is vastly improved with respect to read-write mounts.
I'm currently using unionfs because aufs gave me problems on patching. I didn't explored this issue because unionfs worked like a charm, but it is often recommended to use the more modern and stable aufs. One interesting feature in aufs that you miss with unionfs is the possibility of syncing ro and rw filesystems within a running system. Never do it in unionfs! The script currently assumes you have your sd card formatted with at least 3 partitions (a 4th one to hold home directory contents maybe also of interest for some setups, like mine, to store media files). Here is my partition layout:
Code: Select all
unionfs(/ro & /rw) / rw
/dev/mmcblk0p1 /boot ro (150MB)
/dev/mmcblk0p2 /ro ro (4GB)
/dev/mmcblk0p3 /rw rw (1GB)
/dev/mmcblk0p4 /home rw (3GB)
tmpfs /tmp rw (30MB)
tmpfs /var/log rw (30MB)
Configuration of tmpfs filesystem is done within raspbian itself (see http://www.raspberrypi.org/phpBB3/viewt ... 40#p213440), but we could do everything from the initramfs. Another interesting configuration could be:
Code: Select all
unionfs(/ro & /rw) / rw
/dev/mmcblk0p1 /boot ro (150MB)
/dev/mmcblk0p2 /ro ro (4GB)
tmpfs /rw rw (100MB)
Anyway, these are the steps I followed:
0-Prepare crosscompiling environment (Build Machine)
Follow steps 1 to 3 in the following post http://www.raspberrypi.org/phpBB3/viewt ... 29&t=22498
1- Get and patch kernel sources to support unionfs (Build Machine, home directory)
Code: Select all
cd
git clone --depth 1 git://github.com/raspberrypi/linux.git
cd linux
wget http://download.filesystems.org/unionfs/stable/unionfs-2.5.11_for_3.2.2.diff.gz
gunzip unionfs-2.5.11_for_3.2.2.diff.gz
patch -p1 < unionfs-2.5.11_for_3.2.2.diff
Code: Select all
sudo apt-get install busybox
mkdir initramfs
cd initramfs
fakeroot
mkdir -p bin lib dev etc proc sbin sys mnt/union mnt/ro mnt/rw
cp -a /bin/busybox bin/
ln -s busybox bin/sh
touch etc/mdev.conf
cp -a /lib/ld-* lib/
cp -a /lib/arm-linux-gnueabihf/{ld-*,libc-*,libc.so*,libdl*} lib/arm-linux-gnueabihf
cp -a /lib/arm-linux-gnueabihf/{libm-*,libm.so*,libpam.so*,libpam_misc*} lib/arm-linux-gnueabihf
Code: Select all
#!/bin/busybox sh
# Mount the /proc and /sys filesystems.
mount -t proc none /proc
mount -t sysfs none /sys
busybox --install -s
mknod /dev/null c 1 3
mknod /dev/tty c 5 0
# Select partitions here. This hardcodes the partitions inside the initramfs. It is also possible to parse
# kernel's command line and let the user choose from the the file cmdline.txt.
echo "This script mounts rootfs RO with an unionfs RW layer."
mdev -s
ROPART="/dev/mmcblk0p2"
RWPART="/dev/mmcblk0p3"
if [ ! -b "${ROPART}" ]; then
echo "No partition ${ROPART} has been found"
exec /bin/sh
exit 0
fi
if [ ! -b "${RWPART}" ]; then
echo "No partition ${RWPART} has been found"
exec /bin/sh
exit 0
fi
# Mount the partitions
# 1) mount the ro partition
mount -t ext2 -o ro,noatime ${ROPART} /mnt/ro
# 2) mount the rw partition, it could be any writable filesystem
# but you should make sure the needed modules are either
# compiled built-in or present inside the initramfs and explicitly loaded before
# this line
mount -t ext4 -o rw,noatime ${RWPART} /mnt/rw
# 3) mount the writable overlay to the static image
mount -t unionfs -o dirs=/mnt/rw=rw:/mnt/ro=ro none /mnt/union
# Clean up.
mkdir -p /mnt/union/rw /mnt/union/ro
mount --move /mnt/rw /mnt/union/rw
mount --move /mnt/ro /mnt/union/ro
umount /proc
umount /sys
# Boot the real thing
exec switch_root /mnt/union /sbin/init
echo "Failed to switch_root, dropping to a shell"
exec /bin/sh
Code: Select all
chmod a+x init
Code: Select all
find . | cpio -H newc -o > ../initramfs.cpio
cd ..
zcat /proc/config.gz > config.rpi
scp initramfs.cpio config.rpi USER@SERVER:BUILDIR
Configure kernel compilation issuing the following commands
Code: Select all
cp config.rpi .config
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig
Code: Select all
Select "General Setup-->Initial RAM filesystem and RAM disk (initramfs/initrd) support"
Enter "initramfs.cpio" in Initramfs source file(s)
Enable unionfs in "File Systems-->Miscellaneous filesystems-->Union file system"
Code: Select all
make -j6 ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- -k
Follow intructions in these post, steps 9 to 12: http://www.raspberrypi.org/phpBB3/viewt ... 29&t=22498
You should also remove any offending lines in /etc/fstab (any mention to root fs should be avoided). Mine looks like this:
Code: Select all
proc /proc proc defaults 0 0
/dev/mmcblk0p1 /boot vfat ro 0 2
/dev/mmcblk0p4 /home ext4 defaults,noatime 0 1
tmpfs /tmp tmpfs nodev,nosuid,size=30M,mode=1777 0 0
tmpfs /var/log tmpfs nodev,nosuid,size=30M,mode=1777 0 0
To revert the system to pure rw mode we only need to rename the kernel.img and copy back the stock kernel.img. To sync the read only partition with the read write one (for instance, after a system upgrade), we have to extract the card and do it from another linux host. I'd recommend rsync for that.
Cheers