austin adams

Storing Big Directories on a Separate Disk

August 16, 2016

Don’t tell rms, but sometimes I play Steam games. Fitting a bunch of 10+ GiB games onto a Chromebook with a ~20 GiB disk, however, is practically impossible1. Two solutions came to mind:

  1. Buy another drive
  2. Expand my storage with external media

Option 1 requires hundreds of dollars and, worst of all, effort, so I took the second route using an SD card.

Putting Directories on an SD Card

Overview

I tell systemd via /etc/fstab to mount an SD card at /mnt/somewhere as soon as I connect it. Then, the tricky part: I create systemd mount units for bind mounts to the directories I want on the SD card. And to get systemd to do the bind mounts automatically, I make the auto-generated mnt-somewhere.mount unit “want” the bind-mount units.

Step-by-Step

On systemd 215 on Debian Jessie, I did the following:

  1. Formatted the SD card as f2fs because I’m brave and using a newer-ish kernel. Use whatever filesystem you want; this isn’t particularly important.

    # mkfs.f2fs -l mylabel /dev/sdX
    
  2. Made a mountpoint:

    # mount /mnt/bonus
    
  3. Added an /etc/fstab entry for the card:

    UUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX	/mnt/bonus	f2fs	rw,nofail	0 0
    

    The systemd-specific nofail option tells systemd not to complain if the card isn’t connected at bootup.

  4. Now, after doing a systemctl daemon-reload, the SD card should be mounted:

    NAME   FSTYPE LABEL   UUID                                 MOUNTPOINT
    ...
    sdb                                                        
    └─sdb1 f2fs   mylabel XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX /mnt/bonus
    ...
    
  5. Next I created an ‘overlay’, a directory structure mimicking my root filesystem so that I can easily identify which directory goes where (e.g., I’d bind-mount /mnt/bonus/overlay/var/x to /var/x).

    # mkdir -p /mnt/bonus/overlay/home/austin/{.steam,Documents/bonus}
    # chown austin:austin /mnt/bonus/overlay/home/austin/{.steam,Documents/bonus}
    

    Creating mountpoints:

    $ mkdir ~/.steam ~/Documents/bonus
    
  6. From /etc/fstab, systemd automatically created a mount unit named mnt-bonus.mount, which I used for dependency management. You can see it with systemctl cat:

    $ systemctl cat mnt-bonus.mount
    # /run/systemd/generator/mnt-bonus.mount
    # Automatically generated by systemd-fstab-generator
    
    [Unit]
    SourcePath=/etc/fstab
    Documentation=man:fstab(5) man:systemd-fstab-generator(8)
    
    [Mount]
    What=/dev/disk/by-uuid/e7c2e32a-4a7c-4a34-b72c-0274f81bba6f
    Where=/mnt/bonus
    Type=f2fs
    Options=rw,nofail
    
  7. So, to tell systemd to make the bind-mounts automatically once it mounts the SD card at /mnt/bonus, I created a directory named /etc/systemd/system/mnt-bonus.mount.wants/ and added home-austin-Documents-bonus.mount and home-austin-.steam.mount as follows:

    # mkdir /etc/systemd/system/mnt-bonus.mount.wants
    # cat >/etc/systemd/system/mnt-bonus.mount.wants/home-austin-Documents-bonus.mount <<EOF
    [Unit]
    After=mnt-bonus.mount
    
    [Mount]
    What=/mnt/bonus/overlay/home/austin/Documents/bonus
    Where=/home/austin/Documents/bonus
    Type=none
    Options=bind,nofail
    EOF
    # cat >/etc/systemd/system/mnt-bonus.mount.wants/home-austin-.steam.mount <<EOF
    [Unit]
    After=mnt-bonus.mount
    
    [Mount]
    What=/mnt/bonus/overlay/home/austin/.steam
    Where=/home/austin/.steam
    Type=none
    Options=bind,nofail
    EOF
    
  8. After running another systemctl daemon-reload, ~/Documents/bonus and ~/.steam should begin pointing to the SD card!

    $ mount
    ...
    /dev/sdb1 on /mnt/bonus type f2fs (rw,relatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
    /dev/sdb1 on /home/austin/Documents/sr type f2fs (rw,relatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
    /dev/sdb1 on /home/austin/.steam type f2fs (rw,relatime,background_gc=on,user_xattr,acl,inline_data,extent_cache,active_logs=6)
    
  9. Later, when I want to unmount the SD card and respective bind-mounts, I can simply run:

    # eject /dev/sdX
    

Caveats


  1. $ df -h /
    Filesystem      Size  Used Avail Use% Mounted on
    /dev/dm-2        26G   22G  2.6G  90% /
    

    And that’s without any games! ↩︎