Cleaning up broken snapshots (snapper + btrfs)

The combination of btrfs + snapper is a great solution for the Linux desktop. Perhaps even the best thing since sliced bread. Once properly set-up, you can rollback any file that you may accidentally damage at some point. I’ve found it invaluable during software upgrades/migrations (oops, are all your desktop panels gone after upgrading? don’t worry, just roll back) or when running into bugs (oops, the Digikam library got corrupted? don’t worry, just roll back).

Configuring snapper involves letting systemd activate it regularly using systemd timers. This works well, although you may end up having corrupt / incomplete snapshots if your computer crashes in the middle of a snapper operation.

Having broken snapshots will be made known to you in the journal with events such as:
:1: parser error : Document is empty

This message indicates that you have work to do to clean up broken snapshots. The following Bash oneliner may help you do this:

IFS=$'\n';
for x in $(grep -hr SUBVOLUME /etc/snapper/configs | cut -d '"' -f 2); do
  for y in "$x/.snapshots/"*; do
    z="$y/info.xml";
    if ! [ -s "$z" ]; then echo "***$y***"; ls -lah "$y";
      read -p "Delete? (y/n)" R; if ! [ "$R" = "y" ]; then continue; fi;
      set -x; btrfs subvol del "$y/snapshot"; rm -rf "$y"; set +x;
fi; done; done; unset IFS
  • I’ve broken the oneliner over multiple lines for this post, but just merge them together for use in a shell.
  • This is just a oneliner and not a real program. The way I do it here, is not the recommended way to loop in Bash though it should work fine for this use case (the alternative, using read + while, won’t work here due to a nested read). Refactoring would make it more complex, at which point I’d suggest to just make it a Python program.
  • It needs to run as root.
  • As always, have back-ups. Caveat emptor.