SSD caching for Linux: bcache

So after all the mucking and messing I finally set up bcache on my desktop, running Ubuntu 14.04. I followed a modified procedure by my friend John and his article here (in Chinese) so I am rounding it up here, starting from a computer without an OS.

Let’s assume you have two hard drives, one spinning platters drive at /dev/sda and an SSD at /dev/sdb. My machine uses BIOS boot (being 6 years old, that is expected) and defaults to /dev/sdb device.

You need to first partition your drives:

  • /dev/sda: spinning platters
    • /dev/sda1: unused (will become the backing device)
  • /dev/sdb: SSD
    • /dev/sdb1: /boot (you must have this, or your system won’t boot)
    • /dev/sdb2: / (will become our swap space)
    • /dev/sdb3: unused (will become our cache)

And just install your OS. This will take a while, stay put. After you have rebooted into your fresh install, update your system, install all the drivers, and reboot again. I had a pitfall here as I tried to set up bcache when using the Live CD environment. It locked the cache partition up and cost me half an hour searching around a method to unlock the cache and make things work.

Now we are going to move the system. The safer way to do this is to switch to single-user mode but I did it under a GUI session and that didn’t break it. We need t prepare the partitions that will become our cache and backing partition. You need to do all of this under root user, and you need to use bash since my commands are littered with bashism.

First, install the bcache-tools package:

add-apt-repository ppa:g2p/storage
apt-get update
apt-get install bcache-tools

And create the cache:

for each in /dev/{sda1,sdb3}; do wipefs -a $each; done
make-bcache -B /dev/sda1 -C /dev/sdb3

And now move the system over:

mkdir -p /mnt/{old,new}
mount -o ro /dev/sdb2 /mnt/old
mount /dev/bcache0 /mnt/new
rsync -a /mnt/{old,new}/

Now is the tricky part: change the /etc/fstab file so our root device points to the bcache. The original tutorial calls for vi, but I have a tendency to use sed.

mount -o bind /dev /mnt/new/dev
mount -t proc none /mnt/new/proc
mount -t sysfs none /mnt/new/sys
#mount -o bind /boot/efi /mnt/new/boot/efi # You need this when using UEFI boot environment.
chroot /mnt/new bash -l
getuuid() { ls -l /dev/disk/by-uuid | grep $1 | sed "s/ /\n/g" | tail -n3 | head -n1; }; sed s/$(getuuid sdb2)/$(getuuid bcache0)/ -i /etc/fstab # bash dark magic

And regenerate the boot configuration file.

update-grub

And reboot. Usually you are good to go here and we now just nicks the old root partition by making it your swap. Now your boot, swap and cache partitions are cached. Optionally, turn on writeback cache which improves write performance as well as read at the cost of system reliability:

echo writeback > /sys/block/bcache0/bcache/cache_mode

So how is your bcache looking? Mine allowed my computer to behave almost the same as when I used one single Intel 520 Series 480GB SSD, even though now the SSD is only 60GB in size.

Leave a Reply