Sunday 19 May 2013

SquashFS Portage tree saving time and space

Gentoo Portage, as a package manager, has one annoying side-effect of using quite a lot of disk space and being, generally, slow. As I was looking to reduce the number of small file writes that emerge --sync inflicts on my SSD, I've came back to an old and dusty trick - keeping your portage tree as a SquashFS file. It's much faster than the standard setup and uses less (76MB vs almost 400MB) disk space. Interested? Then read on!

Squashes by Olivia Bee

Requirements:

  • SquashFS enabled in the kernel: File systems -> Miscellaneous filesystems -> <M> SquashFS 4.0 - Squashed file system support and [*] Include support for ZLIB compressed file systems
  • Installed sys-fs/squashfs-tools
  • Distfiles moved out of the portage tree, e.g. (in /etc/portage/make.conf): DISTDIR="/var/squashed/distfiles"

I'm also assuming that your /tmp folder is mounted as tmpfs (in-memory temporary file system) since one of the goals of this exercise is limiting the amount of writes emerge --sync inflicts on the SSD. You are using an SSD, right?

You will need an entry in /etc/fstab for /usr/portage:

/var/squashed/portage /usr/portage squashfs ro,noauto,x-systemd.automount 0 0

This uses a squashed portage tree stored as a file named /var/squashed/portage. If you are not using systemd then replace ro,noauto,x-systemd.automount with just ro,defaults.

Now execute mv /usr/portage/ /tmp/ and you are ready to start using the update script. Ah yes, forgot about this part! Here it is:

#!/bin/bash
# grab default portage settings
source /etc/portage/make.conf
# make a read-write copy of the tree
cp -a /usr/portage /tmp/portage
umount /usr/portage
# standard sync
rsync -avz --delete $SYNC /tmp/portage && rm /var/squashed/portage
mksquashfs /tmp/portage /var/squashed/portage && rm -r /tmp/portage
mount /usr/portage
# the following two are optional
eix-update
emerge -avuDN system world

And that's it. Since the SquashFS is read only, this script needs to first make a writeable copy of the tree (in theory, this is doable with UnionFS as well, but all I was able to achieve with it were random kernel panics), then updates the copy through rsync and rebuilds the squashed file. Make sure you have a fast rsync mirror configured.

For me, this decreased the on-disk space usage of the portage tree from over 400MB to 76MB, cut the sync time at least in half and made all emerge/eix/equery operations much faster. The memory usage of a mounted tree will be about 80MB, if you really want to conserve RAM you can just call umount /usr/portage when you no longer need it.