2011-05-17

I’m cur­rently ex­per­i­ment­ing with a low-ef­fort tech­nique for mim­ic­k­ing the ben­e­fits of a hy­brid solid state/​hard disk drive.

My ap­proach is to use a union mount with mul­ti­ple writable branches to com­bine fold­ers from both an SSD and HDD into a sin­gle home folder in the root filesys­tem. The re­sult is a uni­fied home folder that con­tains a mix­ture of files from each drive in a way that is trans­par­ent to the op­er­at­ing sys­tem:

Hybrid SSD/HDD home folder

Newly cre­ated files are stored on the same de­vice as their par­ent folder. Files created at the root of the home folder are typ­i­cally con­fig­u­ra­tion files and so de­fault to the SSD.

As the screen­shot re­veals, I have also drafted a Nautilus ex­ten­sion that de­tects which stor­age back end each file uses and la­bels those which use the SSD.

The branches of the union mount ex­ist ex­ter­nally as fold­ers within the root filesys­tem. I chose to place them within /home/.ssd and /home/.hdd. On my sys­tem / al­ready uses the SSD so /home/.ssd can sim­ply ex­ist as a reg­u­lar folder, while /home/.hdd is mounted sep­a­rately. /etc/fstab con­tains:

# / containing /home/.ssd (Physical SSD)
UUID=... / ext4 noatime,discard,errors=remount-ro 0 1

# /home/.hdd (Physical HDD)
UUID=... /home/.hdd ext4 errors=remount-ro 0 2

The de­fault file cre­ation pol­icy in aufs is to store new files within the same branch as their par­ent folder, with files cre­ated in the root di­rec­tory of the union filesys­tem de­fault­ing to the first listed branch. As long as the SSD branch is listed first, no other pol­icy needs to be ex­plic­itly de­fined:

# /home/ak from SSD and HDD mounts
none /home/ak aufs noauto,br:/home/.ssd/ak=rw:/home/.hdd/ak=rw 0 0

It is crit­i­cal that this en­try in /etc/fstab be mounted only af­ter the pre­vi­ous two lines so that the in­cor­po­rated branches con­tain mounted filesys­tems and not empty mount points. Until I learn how to spec­ify a par­tic­u­lar mount or­der in /etc/fstab, I have dis­abled au­to­matic mount­ing of the union mount (noauto above) and in­stead mount it dur­ing /etc/rc.local:

# Workaround to mount aufs only *after* its branches exist
mount /home/ak

Back end de­tec­tion is ac­com­plished with a cus­tom em­blem in ~/.local/share/icons/hicolor/24x24/emblems and a Nautilus-Python ex­ten­sion saved as ~/.nautilus/python-extensions/ssd-emblem.py that checks for par­al­lel files in /home/.ssd:

import os.path
import nautilus

class SsdEmblem(nautilus.InfoProvider):
def update_file_info(self, file):
union = "/home/ak/"
ssd = "/home/.ssd/ak/"

path = os.path.realpath(file.get_location().get_path())

if path.startswith(union) and os.path.exists(path.replace(union, ssd, 1)):
file.add_emblem("ssd")

After us­ing this for a week I’m pleased with the re­sults. There is a no­tice­able im­prove­ment in lo­gin times com­pared with my pre­vi­ous con­fig­u­ra­tion that stored the en­tire home folder on a HDD.

I would like there to be an easy way to switch the stor­age back end of in­di­vid­ual files and fold­ers, ide­ally via a Nautilus con­text menu item. This looks pos­si­ble via UDBA, but there are sev­eral po­ten­tial quirks in­volved that I haven’t spent the time to thor­oughly in­ves­ti­gate.

Obviously, more work would need to be done for this to be scal­able to multi-user en­vi­ron­ments or to be com­pat­i­ble with en­crypted home fold­ers. I have no plans to de­velop these ar­eas.