Genkernel and AUFS for Writable Live Media in Gentoo

I recently wanted to create a Live USB with a very basic Gentoo installation but with the particular feature of being able to emerge packages from it. For that feature, I quickly learned I needed to have boot configured so that /usr was mounted read & write (or at least /usr/portage) and there are a number of ways to do that:

  1. Genkernel's default scripts mount some of the common work folder into the memory (namely /etc, /root, /home and /var) and you can add /usr to that list by modifying the initrd.defaults included in the initrd. To do so, take a copy of the initrd.defaults script from /usr/share/genkernel/defaults, modify it to include /usr in the ROOT_TREES varible, then include that modified copy in the initrd by using commands similar to the ones included at the end of this post (there's a subtle reason why you can't just add /usr/portage but you can check that out by grepping ROOT_TREES in initrd.scripts). The obvious drawback of this approach is that, since these all are mounted on memory, you better have a lot of memory to handle the portage tree and the rest of your activities in the Live Media.
  2. Use UnionFS, which is supported by Genkernel. To do so, simply add the --unionfs to your call to genkernel and then add the unionfs flag to the kernel boot line in the boot loader (grub, lilo, syslinux, ...). The drawback of this approach is that UnionFS is already being deprecated by AUFS so you probably want to keep reading for an AUFS solution.
  3. Use AUFS support in Genkernel, as explained below.

I'm not going to cover the basics of creating a Live Media from a Gentoo Stage 3 installation, there are plenty How-Tos about that. After you have emerged your kernel sources and genkernel, you need to emerge aufs3 (aufs2 if you are using any kernel before 3.0) and it will automatically patch your kernel sources to include aufs support (these brilliant Gentoo developers :)) and only after that can you run genkernel to compile and install your kernel image. Yet, the module is compiled outside the kernel and not included in genkernel's initrd by default, so it won't be available while booting. To fix this, you can either use genkernel's --all-ramdisk-modules, which will copy all of your kernel modules to the initrd and will probably bloat your initrd, or you can manually add the kernel module to your initrd. To do this, you need to decompress the initrd image, add the aufs kernel module and compress it back, as follows:

[raw] [code lang="bash"] # mkdir initrd.fix # cd initrd.fix # zcat /boot/| cpio -i # cp -r /lib/modules//misc/ lib/modules// # find . | cpio -H newc -o | gzip -c > /boot/[/code] [/raw]

After that, just add the aufs kernel option to your kernel line in the boot loader and you should be good to go! Share any questions or shortcuts in the comments.