Automatic SD card backup with USBmount

As I've mentioned before, I'm using HP Microserver Gen8 as a small home NAS. There is a lot of stuff stored there, but the primary reason why I actually started using NAS (back then slow, but hackable D-link DNS-323) was to store my photo collection. With ZFS, mirrored drives and extra backup to off-site location, the data on it should be reasonably safe, right? However that's not all that useful if most of the recent photos reside on the SD card inside the camera on in the case somewhere, just because I didn't have time to copy them to the NAS yet. So what can we do about it if we have 15 minutes to spare? Let's automate it a bit!

What will you need?

USB SD card reader - obviously. The simpler, the better - chances are you won't really need those multi format readers anyway, so save yourself the trouble and money. I recommend a reader, that can indicate activity with flashing LED or something similar. (I'll explain why later)

The other think you'll need is USBmount. Sure it's discontinued, but hey still works. There's a package in Debian/Ubuntu repositories, not sure about other distributions, but if you look at the source, it's just set of udev scripts and configs, so creating a package or even installing it manually shouldn't be a lot of work. (this is also a reason, why I'm not overly concerned by its discontinued status - it's really not that much code)

But we're on Ubuntu here and we also only have those 15 minutes to spare, so apt is the way to go:

apt install usbmount

Now we're all set. Let's automate some stuff.

Setting it all up

So the idea is following: When I plug in card reader, USBmount will mount it and execute a script that will automatically copy all the photos from SD card and unmount the card. After the apt command above, the mounting part is already sorted, we just need to add a simple script to copy the photos:

#!/usr/bin/env bash

SOURCE_VENDOR="Generic-"
SOURCE_MODEL="SD/MMC"
SOURCE_SUBDIR="DCIM"
IMPORT_DIR="/data/photos/import"

if [[ ${UM_VENDOR} == ${SOURCE_VENDOR} ]] && [[ ${UM_MODEL} == ${SOURCE_MODEL} ]]; then
    cp -rxt "${IMPORT_DIR}/$(date +%F_%H-%M-%S)/" "${UM_MOUNTPOINT}/${SOURCE_SUBDIR}/"* \
    && umount "${UM_MOUNTPOINT}"
fi

The way it works is quite simple, the only thing that isn't obvious is the fact, that after mounting the SD card, USBmount will execute our script with some extra environment variables. Here we're using these:

  • UM_MOUNTPOINT - mountpoint, where our card was mounted
  • UM_VENDOR - vendor of the device
  • UM_MODEL - model name of the device

Use of mountpoint is obvious - we need to know where to look for the files and when we're finished, we'll also unmount the card. The vendor and model is used, so that we only copy files from the reader and not from any random USB device that happens to be plugged in.

So go ahead, modify all four variables to reflect your environment. If you're using this to import photos as well, chances are, you won't need to change SOURCE_SUBDIR, but the others will very likely need to be different.

Finally, place the script to:

/etc/usbmount/mount.d

You'll notice, there's already 00_create_model_symlink file there. The scripts are executed in alphabetical order, so name yours something like 50_copy_photos_from_SD, so it's executed afterwards (make sure it's executable) and you're done.

Let's test it

Now it's time to test it. So here's what you should see:

  • you plug in USB reader with the card in it
  • activity led will start flashing and will only stop once the work is done (this is why the activity LED is a good idea)
  • you're safe to unplug the reader

With this setup in place it only takes me seconds to copy the photos over. Sure they are still sitting my import folder, but now they are backed up. Also since I got into habit of importing the photos right after I get back home, the import date is a good indicator, that'll help me organize photos later on. Also chances are there is only one event per folder , as opposed to multiple different events on a card that I neglected to copy over for a long time - as was the practice before.

Future upgrades

So far I'm only copying photos from the SD card, because I decided to play it safe. I think I can add a step to erase them from the card if import was successful. I've used to check if all is OK before formating the card in my camera, but now I just trust the automation anyway and don't really make sure the photos were copied over successfully - it never failed. Actually right now I'm sometimes not sure if I already plugged that card in, so sometimes I do it twice - just in case. (and then later on when I'm sorting the photos I notice the duplicates) Removing the imported photos would get rid of that uncertainty.

I'm also thinking about buying multiple readers (they are extremely cheap) and use each based on some ID or so in slightly different way. For example to copy the files to different directory, so I could pre-sort them. (So I'd be import/traveling, import/family, etc., you get the idea) For a few extra bucks, this would save me some effort when trying to figure out the event that is a source of the photos.

I'm not really using any external USB drives, but if you do, this could be a great way to back it up or back up to it.

Finally, this could be probably rewritten as systemd service, so I might try that sometimes. However that would be out of our initial 15 minute plan as I'm not all that familiar with it.

The end

Thanks for reading this, hope you'll find it useful. If you have any suggestions how to improve the process, let me know, I'd love to learn some new stuff.