GliderJan Varho

Merging Persistence Changes in Ubuntu Live USB

  • aufs
  • filesystem
  • live
  • LZMA
  • persistence
  • Ubuntu
  • USB

When using Ubuntu Live USB there is the option of using persistence to store changes on the USB. It uses aufs to layer a read-write filesystem on top of a read-only squashfs compressed filesystem. This is great, because it fits over 2GB worth stuff into a c. 700MB default live system and still allows changes to be stored.

The bad news is that updates quickly eat the rw space because old versions of applications cannot be removed to free space. Also, removing useless applications (like OO.o/LO in my case) doesn't free space, but can actually consume it.

Here's the process I used to merge changes back to the ro filesystem, in order to hopefully claim back some space. This is based on information on the Live CD Customization page in Ubuntu community documentation and various man pages.

Lets assume we have a directory on the hard drive where we've copied the casper/filesystem.squashfs file on the USB as fs.ro and the casper-rw file as fs.rw. First we mount the aufs by layering these:

mkdir -p tmp-ro tmp-rw tmp-aufs sudo mount -o loop fs.ro tmp-ro/ sudo mount -o loop fs.rw tmp-rw/ sudo mount -t aufs -o br:tmp-rw:tmp-ro none tmp-aufs/

Now tmp-ro shows the squshfs, tmp-rw shows the changes stored in caster-rw and tmp-aufs shows the layered filesystem as the live OS would see it.

Next we can generate the new squashfs using mksquashfs (from squashfs-tools):

sudo mksquashfs tmp-aufs/ filesystem.squashfs

Unfortunately, the mksquashfs from natty doesn't seem to support lzma, so it's gzip compression only

We can also generate new manifests based on the packages installed. I suppose this only matters if you mean to use the USB for installing to a HDD, but I did it anyway:

sudo chroot tmp-aufs/ dpkg-query -W --showformat='${Package} ${Version}\n' \ > filesystem.manifest cp filesystem.manifest filesystem.manifest-desktop sed -i -e '/ubiquity/d' -e '/casper/d' filesystem.manifest-desktop

Now we don't need the original filesystems anymore:

sudo umount tmp-aufs/ sudo umount tmp-rw/ sudo umount tmp-ro/ rm -rf tmp-rw tmp-aufs

Instead we temporarily mount the new squashfs to get the filesystem size:

sudo mount -o loop filesystem.squashfs tmp-ro/ printf $(sudo du -sx --block-size=1 tmp-ro | cut -f1) > filesystem.size sudo umount tmp-ro/ rmdir tmp-ro

Finally, we can make a new casper-rw of whatever size we need (I used 1GB):

dd if=/dev/zero of=casper-rw bs=1M count=1000 mkfs.ext3 -F casper-rw

Now the resulting files can be copied to the USB (back-up the old ones first!) and all should work. This procedure can also be used to easily customize USB installations from within the live environment.