Friday, January 2, 2015

Unionfs an alternative to AUFS

Overview:



This is in continuation to my article on 'Read only root filesystem using AUFS'. Unionfs is a Unification File System in Linux can be seen as alternative to AUFS, philosophically trying to solve similar kind of problems.

The changes were easy to incorporate into my existing build set up compared to AUFS. But the forum seems to be not as active .I never got any response to my post.

Contents of init file .

#init file    
#!/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 .
echo "This script mounts rootfs RO with an unionfs RW layer."
mdev -s

#create mount folders in initramfs
mkdir -p /mnt/rw /mnt/ro
# Mount the partitions
# 1) mount the ro partition
ubiattach /dev/ubi_ctrl  -m 4 -O 2048
mount -t ubifs -o ro,noatime  ubi0:rootfs  /mnt/ro
# 2) mount the rw partition, it could be any writable filesystem in the current case it is tmpfs
mount -t tmpfs -o size=30M        tmpfs  /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
if [ $? -ne 0 ]; then
echo    root-unionfs error:      Failed to move /mnt/rw /mnt/union/rw
exit 0
fi

mount --move /mnt/ro /mnt/union/ro
if [ $? -ne 0 ]; then
echo    root-unionfs error:      Failed to move /mnt/ro /mnt/union/ro
exit 0
fi

umount /proc
umount /sys
mount -t devtmpfs none   /mnt/union/dev
if [ $? -ne 0 ]; then
echo    root-unionfs error:      Failed to mount  devtmpfs   /mnt/union/dev
exit 0
fi
# Boot the real thing
exec switch_root /mnt/union /sbin/init

echo "Failed to switch_root, dropping to a shell"
exec /bin/sh


patch kernel 2.6.37 with unionfs patch


Get and patch from the below link.
http://download.filesystems.org/unionfs/unionfs-2.x-latest/unionfs-2.6_for_2.6.37.6.diff.gz



#Extract the patch and navigate to the kernl directory.
Gunzip unionfs-2.6_for_2.6.37.6.diff.gz
cd /'PATH of TI linux'/kernel  ;

#Now Patch the TI kernel
patch -p1 /'PATH of unionfs patch file'/unionfs-2.6_for_2.6.37.6.diff
    

Kernel menuconfig captured in .config with respect to unionfs


CONFIG_INITRAMFS_SOURCE="initramfs.cpio"
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_ROOT_GID=0
CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_UNION_FS=y
CONFIG_UNION_FS_XATTR=y
CONFIG_UNION_FS_DEBUG=y  




Create intramfs.cpio archive as mentioned in  folder and create an archive file and copy into the kernel source.

Recompile the kernel with initramfs and flash it on the kernel partition of the board, now reboot the  system with unionfs file system.

To make changes in read-only directory


mount -o remount,rw /ro
mount -t unionfs -o remount,rw unionfs /

Read only root filesystem using AUFS

Overview:


My prototype based on ti8168 evaluation board encounters frequent filesystem corruption due power outrage.  After looking on resources available on the web it was better if we have a read only root file system.articles on raspberry pi sited gave me a useful pointers to start my work on AUFS.my experience with AUFS mailing list has been overwhelming,would appreciate the maintainers for his prompt reply to all my query.

The idea is to implement a Read only root file-system using a AUFS support in kernel, AUFS is a filesystem  hosts read-only and read-write directories as AUFS file-system branches. currently the system incorporates two layers,the read-write layer will happen on tmpfs and read-only layer will host the ubifs root file system.My board support Linux kernel 2.6.37,so the discussion is with respect to this source.
 

Steps involved.


1. create a initramfs.  
2. patch the kernel with AUFS support

About initramfs

This is basic minimal root file system embedded in kernel, the kernel checks for the presence of the initramfs, if found, mounts it as / and runs /init. The init program is a shell script, in our case do the preparation to mount the read-write and read-only branches on Unification File System and finally give the complete control to real root file system.

The initramfs has a complete set of directories similar to a normal root file system. The busybox binary is statically build and copied to  /bin directory of initramfs. This is eventually available as cpio archive placed in the kernel source folder, this initial file system gets loaded into memory during the Linux boot process, the path of the archive is notified in the .config file of the kernel.

Initramfs creation.



#create initramfs folder to start the activity
mkdir initramfs
cd initramfs

# create required directories
mkdir -p aufs bin dev etc lib proc rootfs rw sbin sys usr/{bin,sbin}

# populate dev
mknod -m 622 dev/console c 5 1
mknod -m 622 dev/tty0 c 4 0

# Copy statically build busybox to initramfs
cp /bin/busybox bin/
ln -s busybox bin/sh

# create init file
cat > init <#!/bin/sh

echo "Waiting"
sleep 1

echo "Mounting dev proc sys"

mount -t devtmpfs none /dev
mount -t proc proc /proc
mount -t sysfs sysfs /sys

echo "Mount rootfs om mtd4  of raw NAND on /rootfs"
ubiattach /dev/ubi_ctrl  -m 4 -O 2048
mount -t ubifs -o ro,noatime  ubi0:rootfs  /rootfs

echo "Mounting rw on tmpfs"
mount    -o    rw    -t    tmpfs    aufs-tmpfs    /rw

# Remove old stuff
rm -rf /rw/tmp
rm -rf /rw/dev

#The upper is writable tmpfs /rw which should be invisible under the root dir,
#and the lower is readonly ubifs /rootfs which should be visible.
mount -t aufs -o noatime,br=/rw=rw:/rootfs=ro none /aufs


mkdir -p  /aufs/rootfs
mount --move /rootfs /aufs/rootfs


umount /sys
umount /proc
mount -t devtmpfs none /aufs/dev
exec switch_root /aufs /sbin/init
EOF

# make init executable
chmod a+x init

# create the initramfs image
find . | cpio -H newc -o > ../initramfs.cpio

#Copy the archive file to TI linux-2.6.x
cp ../initramfs.cpio /'PATH OF LINUX SOURCE'/



Patch the kernel with AUFS support

 
cd  /'Working kernel source Dir'/

# download aufs source
git clone git://git.code.sf.net/p/aufs/aufs2-standalone aufs2-standalone
cd  aufs2-standalone
git checkout origin/aufs2.2-37

#Copy aufs related files to kernel source tree
cp -a aufs2-standalone/fs .
cp aufs2-standalone/include/linux/aufs_type.h include/linux/

#Patch the kernel with AUFS related updates
patch -p1 < aufs2-standalone/aufs2-base.patch
patch -p1 < aufs2-standalone/aufs2-kbuild.patch
patch -p1 < aufs2-standalone/aufs2-standalone.patch
patch -p1 < aufs2-standalone/loopback.patch
patch -p1 < aufs2-standalone/proc_map.patch


Kernel menuconfig changes reflected in .config file.

CONFIG_INITRAMFS_SOURCE="initramfs.cpio"                                                CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_ROOT_GID=0
CONFIG_INITRAMFS_COMPRESSION_NONE=y
CONFIG_AUFS_FS=y
CONFIG_AUFS_BRANCH_MAX_127=y
CONFIG_AUFS_SBILIST=y
CONFIG_AUFS_HNOTIFY=y
CONFIG_AUFS_HFSNOTIFY=y
CONFIG_AUFS_PROC_MAP=y
CONFIG_AUFS_SP_IATTR=y
CONFIG_AUFS_SHWH=y 
CONFIG_AUFS_BDEV_LOOP=y                                             
CONFIG_AUFS_DEBUG=y 
CONFIG_AUFS_MAGIC_SYSRQ=y 


Recompile the kernel with the above changes and replace the current Linux image with this new build uImage.

Changing the root file-system for package updates


mount -o remount,rw /rootfs
mount -o remount,udba=notify /
mount -o remount,mod:/rootfs=rw /
#Now make changes in the '/', finally manual copy the changes to '/rootfs/' path
#reboot the system after copy
reboot


References