LVM automatic snapshots on boot

If you are using LVM on your system (be it server or personal desktop) it is good to have snapshot ready in case something goes wrong during daily operations. Prerequisite is that you have enough space on your volume group to create required logical volume snapshots and for this guide system with systemd.

Here is a link to arch wiki where I "stole" most of the code, of course :-)
https://wiki.archlinux.org/index.php/Create_root_filesystem_snapshots_with_LVM

What I added is snapshotting other volumes (home in this case) not only root, deleting previous snapshot and setting size of snapshot to match the size of the origin. I will drop here the whole setup and not just the part that is different from the wiki so its easier to follow.

Here is our LV setup:

~$ sudo lvs
  LV   VG       Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  data vg1 -wi-ao---- 186.26g                                                    
  home vg1 -wi-ao---- <93.13g                                                    
  root vg1 -wi-ao----  46.56g                                                    
  swap vg1 -wi-ao---- <16.66g

Idea is to have root and home snapshotted with every boot. We will use systemd service for this task.

  • create systemd service file /etc/systemd/system/make-lvm-snapshot.service for creating and deleting previous snapshots
[Unit]
Description=make LVM snapshots
Requires=local-fs-pre.target
Wants=local-fs.target
DefaultDependencies=no
Conflicts=shutdown.target
After=local-fs-pre.target
Before=local-fs.target

[Install]
WantedBy=make-snapshots.target

[Service]
Type=oneshot
ExecStart=/bin/bash -c '/sbin/lvs | /bin/grep -q "root_snap" && /sbin/lvremove -y vg1/root_snap || /bin/echo "No root snapshot"'
ExecStart=/bin/bash -c '/sbin/lvcreate -l 100%%ORIGIN -n root_snap -s vg1/root'
ExecStart=/bin/bash -c '/sbin/lvs | /bin/grep -q "home_snap" && /sbin/lvremove -y vg1/home_snap || /bin/echo "No home snapshot"'
ExecStart=/bin/bash -c '/sbin/lvcreate -l 50%%ORIGIN -n home_snap -s vg1/home'

Little explanation on this. For root since it's smaller in size I use 100%%ORIGIN when setting snapshot size. This means if original volume is 40G, snapshot can hold 40G of changes...every 0 into 1, every 1 into 0. So it means your snapshot will never become invalid. You don't exactly need this much, but just in case. The most changes I had was when upgrading distro version, it was over 70%...You can test manually lvcreate command so you are assured everything is working OK. Run /sbin/lvcreate -l 100%ORIGIN -n root_snap -s vg1/root. Notice I removed one '%' because in systemd file you need to use another '%' as an escape char. If all is good you can remove snapshot or leave it and it will be automatically removed on reboot once we finish the setup.

Also important part is WantedBy because this service will be called on boot by target specified here which we will also create on the next step.

Now enable the service:

systemctl daemon reload
systemctl enable make-lvm-snapshot.service
  • create /etc/systemd/system/make-snapshots.target
[Unit]
Description=Make Snapshots
Requires=graphical.target

Adjust Requires= if you don't start in desktop environment. This target needs to be added to your grub.cfg so It will be started during boot process

  • add boot entry to /etc/default/grub. Keep in mind that adding it here and updating grub will result in snapshot made on every reboot. If you wanna make snapshot manually you can create custom menu entry in boot.cfg. Arch wiki mentioned above deals with that. I wanna have it run on every boot so I don't need to worry If I have most recent snapshot if something goes wrong during work. So put this in the file:
...
GRUB_CMDLINE_LINUX_DEFAULT="quiet systemd.unit=make-snapshots.target"
...

...then update grub with sudo update-grub

  • now all is left is to reboot. After check your lvs and it will show snapshots created
~$ sudo lvs
[sudo] password for zzorica: 
  LV        VG       Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  data      vg1 -wi-ao---- 186.26g                                                    
  home      vg1 owi-aos--- <93.13g                                                    
  home_snap vg1 swi-a-s---  46.93g      home   0.01                                   
  root      vg1 owi-aos---  46.56g                                                    
  root_snap vg1 swi-a-s--- <46.75g      root   0.02                                   
  swap      vg1 -wi-ao---- <16.66g   

And that's it. Now you have fresh snapshot on every boot. If you accidentally delete some file you can mount snapshot and restore the file or if you wanna restore whole volume you can just merge snapshot. If you wanna restore whole root volume use lvconvert --merge /dev/vg1/root_snap, reboot and it will be restored on next reboot. Don't forget to disable systemd service make-lvm-snapshot before reboot so to keep last "working" snapshot just in case. Once you are clear that all is good, re-enable the service.