Use external harddrive as root filesystem for Raspberry Pi

My intention is to run a web and file server with Raspberry Pi (rpi). The micro SD-card is unfit by its capacity and lifetime (write cycles). To avoid that the primary SD-card will wear out too fast, we have to extend the storage. Raspberry Pi offers the capability to connect to further external storage over USB. I assume to keep costs low, they offer only USB 2.0 instead of USB 3.0. Since I have a two old external USB 2.5 HDD and an USB 2.0 Hub it fits perfectly the purpose. The USB hub has a separate power supply and powers the external hdd. The hdd are connected with the rpi over the hub. As side note, you could also use a USB 3.0 external HDD, but it will operate with USB 2.0 speed.

Basically we going to do:

  • Connect rpi with the USB hub
  • We attach the external hdd to the hub
  • We change the root filesystem from the SD-card to the HDD
  • The previous files has to copied or moved to the HDD
  • We configure to boot and used the HDD as root filesystem

These steps have been nearly automated by Adafruit’s script.

The previous /boot/commandline.txt will be copied to /boot/commandline.txt.bak. It should contain as root a partition of the SD card (in my case /dev/mmcblk0p6).

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p6 rootfstype=ext4 elevator=deadline rootwait

The previous root filesystem stays on the SD card. You can use that as disaster recovery by copying the backup to the current file. Disconnect the power of your rpi and read the micro SD card in another linux notebook with a sd card reader. Put it back to the Raspberry Pi and it will boot root from the SD card partition again.

The new /boot/commandline.txt should contain your root with the usb hdd. One piece of advice, don’t use something like this.

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/sda1 rootfstype=ext4 elevator=deadline rootwait

You will get into trouble as soon you attach multiple usb storage drives to the hub. There is no guarantee that your usb root fs device will still get /dev/sda1. To avoid the situation we have use a unique id.

Use fdisk -l to detect your usb hdd

Disk /dev/sdb: 320.1 GB, 320072933376 bytes
255 heads, 63 sectors/track, 38913 cylinders, total 625142448 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000
   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1               1   625142447   312571223+  ee  GPT

As you can see the partition is GPT managed. GUID Partition Table (GPT) is a standard for the layout of the partition table on a physical hard disk, using globally unique identifiers (GUID).

Use gdisk to obtain the IDs

root@pelion:/boot# gdisk /dev/sdb
GPT fdisk (gdisk) version 0.8.5
Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present
Found valid GPT with protective MBR; using GPT.
Command (? for help): i
Using 1
Partition GUID code: EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 (Microsoft basic data)
Partition unique GUID: C4960036-C20B-4243-A063-51CB0320A104
First sector: 2048 (at 1024.0 KiB)
Last sector: 625141759 (at 298.1 GiB)
Partition size: 625139712 sectors (298.1 GiB)
Attribute flags: 0000000000000000
Partition name: 'primary'

The partition unique GUID is the one that works everytime. As identifier we have to declare that it is the unique identifer of the partition → PARTUUID.

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=PARTUUID=C4960036-C20B-4243-A063-51CB0320A104 rootdelay=5 rootfstype=ext4 elevator=deadline rootwait

You are safe to boot regardless of any other attached usb drives.