Speed-up system by SquashFs


Please note that this blog has been moved.

Now it has its own domain: mynixworld.info🙂

If you want to read the latest version of this article (recommended) please click here and I open the page for you.

It has been a while since I installed Gentoo. I always searched for new ways to improve the speed my system boot and run. After goggling  little bit on net I found something about SquashFs and how to use it to squash your portage tree. But can I use the same technique to squash my entire /usr ? Well, this article says that you can.

Basically SquashFs allows you to create a compressed (zlib, lzo or xz) readonly filesystem. But we need to write to it, do we?

So we need another filesystem designed to allow us to write the filesystem content. That would be AnotherUnionFS (aufs). As Wikipedia says:

aufs it’s an advanced multi layered unification filesystem which implements union mount for Linux filesystem. It aimed to improve reliability and performance, but also introduced some new concepts, like writable branch balancing and other improvements“.

So it seems something we can use.

If you had installed SquashFS and aufs then it is a good time to do some modification in your system:

(in your DISTDIR is located outside of /usr then skip the next two steps below)

  1. define in your /etc/make.conf the path to DISTDIR, which should be outside /usr folder (ex: DISTDIR=”/var/portage/distfiles”)
  2. make sure you move the above folder from /usr/portage/distfiles location to the new DISTDIR location
  3. squash your /usr folder to a compressed filesystem image:
mksquashfs /usr /var/portage/portage-current.sqfs -b 65536
  1. create the following /etc/init.d/squash_usr init script that will help us to mount/unmount the compressed image filesystem when system starts/stops:
#!/sbin/runscript
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
#
# /etc/init.d/squash_portage allows efficient compression of
# Gentoo portage arborescence
#
# It requires support for the loop device and squashfs enabled in the kernel,
# module autoloading is also *highly* recommended.
# sys-fs/squashfs and sys-fs/aufs are necessary for read-write support.
#
# Author: Mathias Laurin <mathias_laurin@users.sourceforge.net>
# 2006-11-28, v.0.1.5(4)
# 2009-02-24, v.0.1.6(1) Weedy <weedy2887@gmail.com>
# 2009-03-20, v.0.1.7(1) j0inty <j0inty@stollfuss.net>
# 2009-07-10, v.0.1.8(1) j0inty
# 2009-09-01. v.0.1.9(1) nall <soir@fuzzysock.net>

source /etc/make.globals
source /etc/make.conf

MNTDIR="/usr"
SQFS_DIRNAME="/var/portage"
SQFS_CUR="$SQFS_DIRNAME/portage.sqfs"
SQFS_NEW="$SQFS_DIRNAME/portage-current.sqfs"
SQFS_OLD="$SQFS_DIRNAME/portage-old.sqfs"
DEF_RW="/dev/shm/.portage-rw"
SQFS_OPTS="-force-uid -force-gid portage -no-duplicates"

depend() {
	need localmount modules
}

check_support() {
  if ! [ -w /dev/loop0 ] ; then
	eerror "ERROR: loopback support is not available."
	return 1
  fi
  if ! [[ $(grep -s $'\taufs$' /proc/filesystems) ]] ; then
	eerror "ERROR: aufs filesystem support is not available."
	return 1
  fi
  if ! [[ $(grep -s $'\tsquashfs$' /proc/filesystems) ]] ; then
	eerror "ERROR: squashfs filesystem support is not available."
	return 1
  fi
  return 0
}

makeImage() {
  mksquashfs $MNTDIR $SQFS_NEW $SQFS_OPTS # 2>/dev/null
  retval=$?
  ln -sf $SQFS_NEW $SQFS_CUR
  eend $retval
}

start() {
  check_support || return 1
  if [ -f "$SQFS_CUR" ]; then
  ebegin "SQFS-PORTAGE: Mounting $SQFS_CUR read-only squashfs image as $MNTDIR"
  	mount -t squashfs -o loop,ro $SQFS_CUR $MNTDIR
  	retval=$?
  	[ $retval -ne 0 ] && return $retval
else
  if [ ! -f "/usr/portage/metadata/timestamp.chk" ]; then
  	ebegin "SQFS-PORTAGE: $SQFS_CUR looks empty or corrupted, using the original"
  fi
fi

ebegin "Mounting $PORTAGE_RW read-write with aufs as $MNTDIR"
if [ ! $PORTAGE_RW ] ; then
  einfo "  will be mounted in tmpfs (RAM)"
  PORTAGE_RW="${DEF_RW}"
fi
[ -d $PORTAGE_RW ] || mkdir -p $PORTAGE_RW
  mount -t aufs -o udba=reval,br=$PORTAGE_RW:$MNTDIR aufs $MNTDIR
eend $?
}

stop() {
  ebegin "SQFS-PORTAGE: Stopping and unmounting"
  	[ ! $PORTAGE_RW ] && PORTAGE_RW="${DEF_RW}"
  	if [ $(du -s --exclude=.w* $PORTAGE_RW | cut -f 1) -gt 4 ]; then
  		einfo "  Changes detected, updating image."
  		mv -f $SQFS_NEW $SQFS_OLD
  		makeImage
  		rm -f $SQFS_OLD
  	else
  		einfo "  No changes detected, skipping update."
  		eend 0
  	fi

  einfo "  Unmounting the $MNTDIR aufs/squash image"
  umount -l -t aufs  $MNTDIR
  umount -l -t squashfs $MNTDIR
  rm -rf $PORTAGE_RW
  eend 0
}
  1. make sure you tell your system to start that script after booting:
rc-update add squash_usr

That’s all, it should works!

A more abstract version for this can be found here.

Note: don’t delete the original /usr folder (located on the physical partition) in order to free some space unless you know what you are doing! Keep in mind that a lot of utilities are located on /usr/bin or /usr/sbin, a lot of libraries are located on /usr/lib, some configuration are stored event on /usr/share/.

I had deleted some folders inside the original /usr to free some space (that’s why I am using a SquashFS in the first place), BUT I had kept the following folders:

  • bin
  • lib
  • lib64 (or lib32 or both , depending on if you are using multilib Gentoo system or not)
  • sbin
  • share/slim
  • tmp

Well, you are not supposed to keep the entire contents of those folders but only the necessary utilities/libraries/configuration files. So it is a matter of try and error if you want to get dirty on your hands.

Another issue (the biggest one I guess) you have to think about would be: how those utilities/libraries/configuration files from your original /usr folder (used just at boot-time) get updated when you rebuild your system? I’m asking this because you will have mounted the SquashFS image and not the physical /usr folder. So after you are successfully booting your system and your SquashFS image get mounted as /usr, everything you will update on your /usr will be stored inside the SquashFS image (ex: /var/portage/portage-current.sqfs) and not on the original /usr folder.

My advice is to analyze the whole scenario before starting and doing anything. What I have learned from here is that “you can” and “how to do it” but not “whether it can be applied to a particular situation or not”.

Warning: before doing anything backup your data ;o)

Note: if you are using a SSD disk drive and not a HDD instead, I am not quite sure that you will gain in performance but for sure you will free some space on your disk.

About Eugen Mihailescu

Always looking to learn more about *nix world, about the fundamental concepts of arithmetic, algebra and geometry. I am also passionate about programming, database and systems administration.
This entry was posted in kernel, linux, Uncategorized and tagged , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s