On my Debian 9 virtual machines i wanted to be able to:
- create snapshots to get consistent backups
- easily extend the size of the disk
Snapshotting the disk images is not an option as some of those backups run every hour and i’m only interested in the files, not the whole VM.
On this page i describe what i did to convert my existing root file system to an LVM setup. LVM is set up on a new disk and the data from the existing root file system is copied to the new LVM root file system. This also involves modifying /etc/fstab
and some initramfs configuration, recreating the initramfs and reinstalling grub.
Create a new disk and add it to the VM. How this is done depends an which virtualization tools are used. I use Proxmox so i added an additional disk with 12 gb through the GUI. This disk is added as /dev/vdb
to the VM.
Create a partition /dev/vdb1
spanning the whole disk with e.g. cfdisk
or parted
and assign it partition type “8e” (Linux LVM).
To use LVM initialize the partition /dev/vdb1
to be used with LVM and create a volume group named vgroup
and logical volumes for root and swap:
# pvcreate /dev/vdb1 # vgcreate vgroup /dev/vdb1
Before creating the logical volumes for / named root
and swap named swap
, check the sizes of the existing root (10gb) and swap (2 gb) partition. The root file system has a size of 10 gb and the swap partition is created using the remaining free disk space.
# lvcreate -L 10G -n root vgroup # lvcreate -l 100%FREE -n swap vgroup
Create the file system on the new root lv, the example below creates an ext4 file system:
# mkfs.ext4 /dev/vgroup/root
Initialize the new swap partition:
# mkswap /dev/vgroup/swap
For the system to be able to mount the root file system after switching to the new disk the disk UUID for the root and swap file system need to be changed in /etc/fstab
. This should be done now. Enter blkid as root to get the UUIDs of the new LVs:
# blkid /dev/vda1: LABEL="root" UUID="d2a6d74f-bc44-4232-9239-f921da8985bc" TYPE="ext4" PARTUUID="2b039b23-01" /dev/vda2: UUID="6dd0ebe4-a535-4d1f-b0e7-544ec9f0c89c" TYPE="swap" PARTUUID="2b039b23-02" /dev/vdb1: UUID="jT11Ff-vGtf-kQX5-bRbf-y5pr-5JC6-RpQMRv" TYPE="LVM2_member" PARTUUID="0c0689e5-01" /dev/mapper/vgroup-root: UUID="a163fcb6-38bf-47c2-84b0-2d80cfffa76d" TYPE="ext4" /dev/mapper/vgroup-swap: UUID="c3420a3d-47a6-4f2f-9dba-abce6fc01e4c" TYPE="swap"
In /etc/fstab
duplicate the configuration for the root and swap partitions, change the UUIDs to use the LVs UUIDs and comment those lines for now.
# vim /etc/fstab
# / was on /dev/vda1 during installation UUID=d2a6d74f-bc44-4232-9239-f921da8985bc / ext4 errors=remount-ro 0 1 #UUID=a163fcb6-38bf-47c2-84b0-2d80cfffa76d / ext4 errors=remount-ro 0 1 # swap was on /dev/vda2 during installation UUID=6dd0ebe4-a535-4d1f-b0e7-544ec9f0c89c none swap sw 0 0 #UUID=c3420a3d-47a6-4f2f-9dba-abce6fc01e4c none swap sw 0 0
When booting from the new LVM disk, this message can appear during the early boot process after some waiting time:
Gave up waiting for suspend/resume device
This is because the swap device is used as suspend/resume device and the old swap partitions UUID is configured in the initramfs. This UUID is configured in the file /etc/initramfs-tools/conf.d/resume
. Make a backup of this file before the changeing the UUID to the new one. For this to take effect a rebuild of the initramfs is necessary.
# vim /etc/initramfs-tools/conf.d/resume
RESUME=UUID=c3420a3d-47a6-4f2f-9dba-abce6fc01e4c
The next steps are done using Rescue mode from a Debian 9 (net)install disk.
First get the (net)install disk image for Debian 9 (or whatever distribution is used) and add it as CD-Rom drive to the VM. Boot from this disk and enter Rescue mode.
Once in Rescue mode select the old root partition /dev/vda1
for the root file system and select Execute a shell in /dev/vda1
. This is the old root file system with the prepared /etc/fstab
and /etc/initramfs-tools/conf.d/resume
files containing the new disk UUIDs.
To copy the data to the new disk create a new mount point and mount the LV on it
# mkdir /aaAa # mount /dev/vgroup/root /aaAa
I use this little script rootfs2lvm
to copy everything to the new disk. The script can also be used to update the destination when the source has changed.
#!/bin/bash # (c) 2018 Christian valo Kivalo # Version 0.1 # copy filesystem contents to lvm mounted on $2 set -e usage() { printf '%b\n' "$0 $src $dst\n" exit 1 } die() { local ecode=$1; shift local reason="$1"; shift printf '%b\n' "$reason" exit $ecode } test $# -eq 2 || usage srcdir="$1" dstdir="$2" # test if $srcdir is / and if $dstdir is a mounted disks root test -d ${srcdir}/lost+found || die 244 "SRCDIR not mounted" test -d ${dstdir}/lost+found || die 245 "DSTDIR not mounted" # some directories and files should not be copied or deleted exclude="--exclude=${dstdir} --filter=exclude_/dev/* --filter=exclude_/run/* --filter=protect_/lost+found/ --filter=exclude_/proc/* --filter=exclude_/sys/*" # rsync options. _rsync_opt3 is empty, add --dry-run for testing _rsync_opt1="-aHAX --numeric-ids --stats --progress --human-readable" _rsync_opt2="--delete-during --inplace --delete-excluded" _rsync_opt3="" rsync "$_rsync_opt1" "$_rsync_opt2" "$_rsync_opt3" \ "$exclude" "$srcdir" "$dstdir"
Invoke the script with and wait until all data is copied to the new disk. This take some time depending on the amount of data.
# ./rootfs2lvm / /aaAa/
After the data is copied to the new disk exit the shell and select Choose a different root file system . Then select the new LVM root LV /dev/vgroup/root
.
First select Reinstall GRUB boot loader and enter /dev/vdb when prompted. After this select Execute a shell in /dev/vgroup/root
.
The following steps prepare the system to boot from the new disk.
First change /etc/fstab
and comment the fstab entries with the old disks UUID and uncomment the entries with the new UUIDs.
# / was on /dev/vda1 during installation #UUID=d2a6d74f-bc44-4232-9239-f921da8985bc / ext4 errors=remount-ro 0 1 UUID=a163fcb6-38bf-47c2-84b0-2d80cfffa76d / ext4 errors=remount-ro 0 1 # swap was on /dev/vda2 during installation #UUID=6dd0ebe4-a535-4d1f-b0e7-544ec9f0c89c none swap sw 0 0 UUID=c3420a3d-47a6-4f2f-9dba-abce6fc01e4c none swap sw 0 0
Update grub configuration to know about and load the lvm module and update the initramfs images
# update-grub # update-initramfs -k all -u
Preparation is finished. Now shutdown the VM and remove the old disk and make sure to boot from the new LVM disk.
Hope everything went well and the system comes up from the new disk