6

LVM (Logical Volume Manager) has some useful enhancements. You can make a snapshot, then check new programs and if they don't work as expected or you don't like them you can simply revert to your previous installation. This is also very useful for developer to test things. You can make backups on the running system from a snapshot without worrying about changes during the backup. No need to set devices read only or exclude particular directories.

Can this be used on a Raspberry Pi? Is there a way to setup LVM on it?

Ingo
  • 40,606
  • 15
  • 76
  • 189

1 Answers1

11

You can move the installation of the Raspberry Pi OS to a LVM volume.
But what does it help me?

  1. You can take snapshots from your running system.
  2. You can install software and if you don't like it you can revert to the snapshot.
  3. If you like installed software you can commit the snapshot, in fact delete the snapshot.
  4. It is very easy to make backups on the running system. Just make a snapshot, mount it and backup it, no worry about changing files from the running system.
  5. You can heavy modify your system, also with drivers and firmware and deinstall essential software until it doesn't boot anymore (kernel panic, rainbow screen). It doesn't matter. You simply boot into the snapshot, means into the running system the snapshot was taken. Then you can revert to the snapshot.

Prepare the installation with LVM drivers

Moving the installation isn't the problem but the LVM drivers must be loaded on boot up so the root partition can be mounted and used for booting. Fortunately the Raspberry Pi supports loading a ramdisk for `initrd` so we have to do an additional step to create the initram containing drivers for LVM.

The following is only for a quick setup an initramfs where you have to monitor kernel updates by yourself. To use a more automated setup an initramfs you can look at How can I use an init ramdisk (initramfs) on boot up Raspberry Pi?.

If you are unexperienced with linux please try it first with a new image how I did for this How To. You can loose all data.

For reference I use Raspberry Pi OS (32-bit) with desktop 2020-08-20, flashed it to a SD Card and boot it in a RasPi. First do an upgrade to get the latest software versions and install drivers:

rpi ~$ sudo -Es
rpi ~# apt update
rpi ~# apt full-upgrade
rpi ~# apt install initramfs-tools
rpi ~# apt install lvm2

I only use this installation on a RPi3 (incl. RPi3+) and a RPi4. Enable using an initramfs by settings in /boot/config.txt, but using the current kernel/module names. The current available kernel/module names you will find with, for example:

rpi ~# ls /lib/modules/
4.19.97+  4.19.97-v7+  4.19.97-v7l+  4.19.97-v8+

The following should be inserted at the top of /boot/config.txt. For further filter settings look at Conditional filters in config.txt.

[pi3]
initramfs initrd.img-4.19.97-v7+ followkernel
[pi4]
initramfs initrd.img-4.19.97-v7l+ followkernel
# if you want to use the experimental 64 bit kernel, then enable this instead
#arm_64bit=1
#initramfs initrd.img-4.19.97-v8+ followkernel
[all]

I only want to load listed modules into the ramdisk, not all possible. We have to set option list in /etc/initramfs-tools/initramfs.conf:

rpi ~# sed -i 's/^MODULES=most/MODULES=list/' /etc/initramfs-tools/initramfs.conf

If you have trouble with drivers of your hardware with this setting, for example for a display, then you can modify option MODULES for initramfs.

Now create the ramdisks. Because we create them on a fat filesystem (boot partition) you will get some warnings. fat does not support all options, but you can ignore the warnings.

rpi ~# mkinitramfs -o /boot/initrd.img-4.19.97-v7+ 4.19.97-v7+
rpi ~# mkinitramfs -o /boot/initrd.img-4.19.97-v7l+ 4.19.97-v7l+
rpi ~# apt clean

Reboot. It should do it as always but now using the initram. Check with:

rpi ~$ journalctl -b | grep initr
Apr 17 11:20:38 raspberrypi kernel: Trying to unpack rootfs image as initramfs...
Apr 17 11:20:38 raspberrypi kernel: Freeing initrd memory: 13448K


Moving the Raspberry Pi OS to the LVM volume

Poweroff your system and attach its SD Card to a debian like computer. It must also have LVM2 installed (sudo apt install lvm2) even you don't use it there. We need it to setup LVM on the SD Card. We will now backup the installation on the SD Card, create a logical volume (lv) there and restore it to the lv. I will create a volume of 6 GB. You can use what you like but leave enough space for snapshots. I suggest to start with minimal space because with LVM it is no problem to extend the volume at any time. My SD Card is attached to /dev/sdb:

Backup the Raspberry Pi OS

pc ~$ sudo -Es
pc ~# fsck.vfat /dev/sdb1
pc ~# fsck.ext4 -f /dev/sdb2
pc ~# mkdir /mnt/sdb2
pc ~# mount /dev/sdb2 /mnt/sdb2
pc ~# mount /dev/sdb1 /mnt/sdb2/boot
pc ~# tar -cvzf raspios-buster.tar.gz -C /mnt/sdb2 -V "Backup of the Raspberry Pi OS Buster with Desktop" ./ # last characters are dot and slash
pc ~# umount -R /mnt/sdb2

If you like you can test the backup before overwriting the SD Card:

pc ~# tar -tvf raspios-buster.tar.gz

Partition the SD Card, create LVM volumes and format them. You are free to use sizes what you like.

# partition the SD Card
pc ~# parted /dev/sdb mktable msdos
pc ~# parted /dev/sdb mkpart primary fat32 2048s 257MiB
pc ~# parted /dev/sdb mkpart primary ext4 257MiB 100%
pc ~# parted /dev/sdb set 2 lvm on

# Create volumes
pc ~# pvcreate /dev/sdb2         # define physical volume
pc ~# vgcreate rpi.vg /dev/sdb2  # create volume group using physical volume
pc ~# lvcreate rpi.vg --name root.lv --size 6GiB  # create logical volume in volume group

# Format the volumes and mount them
pc ~# mkfs.vfat -F 32 -n BOOT /dev/sdb1
pc ~# mkfs.ext4 -L rootfs /dev/mapper/rpi.vg-root.lv
pc ~# mount /dev/mapper/rpi.vg-root.lv /mnt/sdb2
pc ~# mkdir /mnt/sdb2/boot
pc ~# mount /dev/sdb1 /mnt/sdb2/boot

Now we restore the Raspberry Pi OS into the new volumes:

pc ~# tar -xvf raspios-buster.tar.gz -C /mnt/sdb2

Change device names in boot/cmdline.txt and in etc/fstab because they have changed. Set them to /dev/mmcblk0p1 and to /dev/mapper/rpi.vg-root.lv:

pc ~# sed -i 's/root=PARTUUID=[a-z0-9]*-02/root=\/dev\/mapper\/rpi.vg-root.lv/' /mnt/sdb2/boot/cmdline.txt
pc ~# sed -i 's/^PARTUUID=[a-z0-9]*-01/\/dev\/mmcblk0p1/' /mnt/sdb2/etc/fstab
pc ~# sed -i 's/^PARTUUID=[a-z0-9]*-02/\/dev\/mapper\/rpi.vg-root.lv/' /mnt/sdb2/etc/fstab

Clean up

pc ~# umount -R /mnt/sdb2
pc ~# fsck.vfat /dev/sdb1
pc ~# fsck.ext4 -f /dev/mapper/rpi.vg-root.lv
pc ~# rmdir /mnt/sdb2
pc ~# exit
pc ~$


Take snapshots and backups

Now put the SD Card into the RasPi, boot and login. Everything should be the same as before but we can use the Logical Volume Manager. Look at man lvm what's available. You can make your first snapshot from this base installation so you can always revert to it:

rpi ~$ sudo lvcreate --snapshot --name rpi_base --size 6GiB rpi.vg/root.lv
rpi ~$ sudo lvs
LV       VG       Attr       LSize Pool Origin  Data%  Meta%  Move Log Cpy%Sync Convert
root.lv  rpi.vg   owi-aos--- 6.00g
rpi_base rpi.vg   swi-a-s--- 6.00g      root.lv 0.01
rpi ~$

Revert and remove(!) snapshot. You should create it afterwards immediately again.

rpi ~$ sudo lvconvert --merge rpi.vg/rpi_base
rpi ~$ sudo systemctl reboot

Be patient! It may take some time, about some minutes. Never switch off your RasPi.

Login and immediately create the snapshot again:

rpi ~$ sudo lvcreate --snapshot --name rpi_base --size 6GiB rpi.vg/root.lv

To commit simply delete the snapshot:

rpi ~$ sudo lvremove rpi.vg/rpi_base

To make a backup:
simply make a snapshot, mount it and backup it, e.g. with the base installation. You can use what ever backup tool you like.

rpi ~$ sudo mount /dev/mapper/rpi.vg-rpi_base /mnt/
rpi ~$ tar -czf - -C /mnt/ ./ | ssh backup-server dd of=raspi.tar.gz bs=10k

To boot into the snapshot:
Modify /boot/cmdline.txt and /etc/fstab and change the entries:

/dev/mapper/rpi.vg-root.lv
to
/dev/mapper/rpi.vg-rpi_base

Then boot the RasPi. In case you have destroid your working system then you can revert it to the snapshot with:

rpi ~$ sudo lvconvert --merge rpi.vg/rpi_base

Before rebooting don't forget to change /boot/cmdline.txt back to root=/dev/mapper/rpi.vg-root.lv. Also revert the entry in /etc/fstab.


Don't forget

For future mounts of the SD Card on your PC don't forget to use:

pc ~$ sudo mount /dev/mapper/rpi.vg-root.lv /mnt/sdb2
pc ~$ sudo mount /dev/sdb1 /mnt/sdb2/boot

And don't forget to update the initramfs when you have made driver updates, for example:

rpi ~$ ls /lib/modules/
4.19.97+  4.19.97-v7+  4.19.97-v7l+  4.19.97-v8+
rpi ~$ sudo mkinitramfs -o /boot/initrd.img-4.19.97-v7+ 4.19.97-v7+
rpi ~$ sudo mkinitramfs -o /boot/initrd.img-4.19.97-v7l+ 4.19.97-v7l+

If the version changed then you must also update the entries in /boot/config.txt, otherwise the bootloader will not find the renamed kernel and boot stucks. Don't worry. You can attach the SD Card to your PC, mount it and correct config.txt.


references:
[1] Can the raspberry boot to an LVM root partition?
[2] Can a Raspberry Pi be used to create a backup of itself?

Ingo
  • 40,606
  • 15
  • 76
  • 189
  • thanks for sharing. do you know what would be pro's and cons of using this over openzfs? – ipatch Jan 11 '20 at 20:17
  • @ipatch Sorry, I don't know openzfs. I have only used **lvm** yet because its direct supported by the kernel and part of the operating system. I think that's an important advantage. – Ingo Jan 11 '20 at 22:49
  • How would you compare the `LVM approach` to backup to the [`rpi-clone` script on github](https://github.com/billw2/rpi-clone)? In other words, which would you recommend to the "average" RPi user? – Seamus Jan 27 '20 at 20:52
  • @Seamus For comparison I have answered [here](https://raspberrypi.stackexchange.com/questions/5427/can-a-raspberry-pi-be-used-to-create-a-backup-of-itself/87063#comment182497_87063). The main problem for an "average" user isn't LVM. It is that he has to use an init ramdisk that isn't supported by Raspbian and need some knowledge about that. So I would say using a script like rpi-clone would be less error prone for a normal user. But if initramfs will be supported in the future (I believe it will come) then LVM can be available to everyone. – Ingo Jan 27 '20 at 22:12
  • @Ingo: When you say, **'... use an init ramdisk that isn't supported by Raspbian'**, do you mean that **a.)** LVM can't be done under Raspbian at the present time (i.e. under `buster`) - or **b.)** LVM is ***"challenging"*** for an "average" user? – Seamus Jan 28 '20 at 00:07
  • @Seamus It can be done with all Raspbian versions including `buster` but it is challenging and error prone in particular for inexperienced users. Failing the setup is drastic because boot up fails and an "average" user may be lost. – Ingo Jan 28 '20 at 00:14
  • @Ingo: So - you should have a good backup of your system before beginning, eh? :) – Seamus Jan 28 '20 at 03:05
  • @Seamus You should always have a good backup of your system ;-) – Ingo Jan 28 '20 at 08:59
  • Great explanation, thanks! – Paolo Apr 14 '20 at 10:03