Wednesday, December 9, 2009

Recently, I've been working on getting a package that enables copy-on-write for Ubuntu 9.10, the use-case would be Grid Appliance, a project that I have been working on for the past 3 and half years. Previously, I had used Debian, created a special kernel, and messed around with the init scripts. During which, I experimented with both UnionFS and AUFS, both of which required kernel patches. The former, UnionFS, was replaced with AUFS due to stability concerns.

To begin my research, I first investigated the possibility of a union filesystem in the modern kernel. To my surprise, it seems that kernel maintainers are uninterested in this feature unless it can be implemented in a truly transparent method. Thus AUFS, most likely, will not be included in the kernel and Ubuntu has or plans to phase it out in the near future. UnionFS shares an even worse fate, as most developers have moved towards AUFS for stability reasons. Luckily, I found something called UnionFS-Fuse, which implements the UnionFS system on top of Fuse, or file system in user-space as opposed to kernel file systems. I was first hesitant in this method, it occurred to me that Fuse ensures that I won't have to deal with kernel issues meaning that regardless of the direction taken by the kernel developers, I'll have a working union filesystem.

The next step was figuring out where to insert the cow init script. It turns out that Ubuntu 9.10 uses Upstart, a relational, event-based, threaded init system. This replaces the old init system, based off of System V, which provides an explicit, in-order init system. Upstart poses a challenge for cow filesystems, as the first step in Upstart is to mount all the file systems by issuing the "startup" event. To get around this challenge, I've appended a "pre-start script" command that executes the cow init script prior to starting the mounting of the other file systems. This appears to work as I've set the virtual machine disk to rdonly and the system boot perfectly*.

Yeah, it doesn't boot perfectly, because in Ubuntu 9.10 uses grub2 and checks whether or not the last startup sequence was ended successfully. This requires a non-trivial change that I am still figuring out. I can easily edit out the contents, but that won't work when an update occurs. I guess its time to start reading grub manipulation utilities to prevent that.