title: Read Only Root
linktitle: ro-root
parent: Home
ctime: 2012-08-02

For GNU/Linux desktop installations, I prefer to have the root filesystem,
which mounts to /, be mostly read-only.  This means that /home, /var and /tmp
need to be mounted elsewhere.  The benefits of this approach are several, but
two in particular stand out for desktop use cases.

 * It is much easier to do a clean install the OS.  User data in /home, and
   in some cases application data in /var, need not be backed up and restored
   in the process.  Of course recent backups should still be available.
 * A root fs that is rarely written to is a good candidate for SSD (solid state
   disk) storage.  This allows one the performance benefit of SSD while
   mitigating a critical deficiency.  Current SSD technology is not nearly
   as reliable as mechanical disk in read/write environments, so reducing
   writes to SSD is a productive strategy.

Placing /home on a separate partition is easy, and GNU/Linux desktop installers
have supported this for some time.  And thanks to the recent introduction of
/run (see [here](http://lwn.net/Articles/436012/) to learn more), migrating
/var to a separate filesystem is now pretty easy for desktop installs.

Of course, with multiple partitions, there is the issue of what to do if one of
them fills up.  A common solution is to use LVM.  Volumes are given minimal
practical sizes, and then incrementally grown as required.  LVM works fine on
the desktop, but requires a bit more knowledge and effort to administer.

A simpler solution is to use bind mounts.  By bind mounting /var from /home/var
and /tmp from /home/tmp, all user, variable and temporary data are on a single
partition.  The root partition will be nearly static in content and size.  I
currently use a 25 GB root partition on desktop installs, and that filesystem is
generally only about 25% full, even with a large number of development tools
installed.  A swap partition is present of course, and the rest of the available
hard drive storage space is assigned to the home partition, which now holds the
contents of /var and /tmp.  Essentially, /home, /var and /tmp share a common
large pool of storage, so there is less need for a volume manager.  I am finding
this configuration to be quite optimal for developer desktops at my company.

# Using bind mounts in a new installation

These notes assume Xubuntu 12.04 desktop i386 installation, but a similar
process should work for other distributions and versions.

 * Boot from the xubuntu 12.04 desktop CD
 * Run the installation
 * Use a custom configuration when asked
 * At least three partitions are required: root, swap and home
 * Proceed with installation until the installer asks to reboot to continue

Before rebooting, access a shell and type the following commands

    cd target # where the new root filesystem is currently mounted
    cp -a var home/var # copy var to its new storage location
    mv var var.old # can remove later
    mkdir var # Need some dirs and symlinks during boot for some OSes
    ln -s /run var/run
    ln -s /run/lock var/lock
    cp -a tmp home/tmp # copy tmp to its new storage location
    mv tmp tmp.old
    mkdir tmp
    vi etc/fstab # add the following 2 bind mounts to end of /etc/fstab
        /home/var /var bind defaults,bind,noatime,mode=0755 0 0
        /home/tmp /tmp bind defaults,bind,noatime,mode=1777 0 0
    sync

Now allow the installer to reboot.  The system should boot up using the bind
mounts for /var and /tmp, so their contents will actually be stored in the home
partition at locations /home/var and /home/tmp, respectively.  Once the system
appears to be working OK, you may remove the /var.old and /tmp.old directories.

# Upgrading to use bind mounts

First, boot from a recovery or live CD, then run commands like the following
commands.

    mkdir /mnt
    mount /dev/sda1 /mnt # replace /dev/sda1 with dev for your root
    mount /dev/sda2 /mnt/home # replace /dev/sda2 with dev for your home
    cd /mnt
    cp -a var home/var # copy /var to its new storage location
    mv var var.old # can remove later
    mkdir var # Need some dirs and symlinks during boot for some OSes
    ln -s /run var/run
    ln -s /run/lock var/lock
    cp -a tmp home/tmp # copyt /tmp to its new storage location
    mv tmp tmp.old # can remove later
    mkdir tmp
    vi etc/fstab # add the following 2 bind mounts to end of /etc/fstab
        /home/var /var bind defaults,bind,noatime,mode=0755 0 0
        /home/tmp /tmp bind defaults,bind,noatime,mode=1777 0 0
    sync

Now remove the CD and reboot.  You should be using bind mounts.  Once the system
appears to be working OK, you may remove the /var.old and /tmp.old directories.
