Convert an existing Linux file system to LVM

Why?

As I frequently reinstall my OS (for various reasons) but in the mean time I still want to be able to access my old OS for daily use, I do a lot resizing of filesystems and partitioning of my hard disk. When the time has come to use the new OS installation as a daily driver, I like to reclaim my old OS space so I can have all the space available.

Now there can be roughly two situations to be in: either your old OS is physically after your new OS or vice versa. In the first situation the solution is simple: remove your old partition, extend your current partition to the end and resize2fs your existing partition to fill up in the remaining space. The latter is more cumbersome. If you delete the old partition, you are left with free space before your current filesystem. If you were to resize2fs your current filesystem to use up the free space in the beginning, it would have to move each and every file as the filesystem can only expand at the end. This problem can be solved with the use of LVM which introduces another layer in between the physical blocks on your disk and the blocks as used in the filesystem.

So the first time I came across LVM, I wondered if I can convert my existing filesystem into an LVM partition. As I couldn’t find any (working) solutions on the internet, I decided to work out my own solution. Was this faster than just backing up all my data? No way near. In the time it took to work this all out I could have reinstalled my OS dozens of times. And you only have to apply this once, because once you switched to LVM you will never have this problem again. Did I also mention it is extremely dangerous to mess with your filesystem like this?

Before we get started

Before we get started, I want you to know that messing with your filesystem is extremely dangerous. You should have a backup of all your data because one miscalculation will mess up your filesystem.

Also I assume you know how filesystems and partitions work and how you can manipulate them on a low level. You also should be well informed what LVM is, how it works, what its benefits are and have a basic understanding of the technical details. If you are wondering if your experience meets these requirements, this article probably isn’t for you.

Also needless to say, this operation can only be done when none of the partitions is mounted, so a live media is needed. I use Ubuntu 18.10 in this example as a root user.

Let’s get started

In this example I will use a 10 GiB disk partitioned as follows:

Device       Start      End  Sectors  Size Type
/dev/sda1     2048   976895   974848  476M EFI System
/dev/sda2   976896  2930687  1953792  954M Linux filesystem
/dev/sda3  2930688 20969471 18038784  8,6G Linux filesystem

with ext4 filesystems on sda2 and sda3, both utilizing the full partition. sda3 contains the root filesystem.

I recommend you to check all the concerning filesystems with fsck first. Also make sure you have the needed LVM utilities installed on your existing installation (lvm2 in this example).

We need to calculate the size our new Physical Volume will be. This PV will eventually encapsulate the Logical Volume which will contain our existing filesystem. I will use Physical Extents of size 4 MiB as that seems to be the standard nowadays. In my case sda3 is 18038784 sectors big. This results in 8808 MiB of space. So with 4 MiB PE’s we have exactly 2202 PE’s.

However if your calculations return a non-integer of PE’s, you have to round it down, calculate the number of sectors needed and resize your filesystem accordingly. For example if your partition (and filesystem) is 18038776 sectors big, this will result in 2201,99… 4MiB PE’s. So effectively only 2201 PE’s fit in this partition and you have to resize your filesystem (not partition!) to 18030592 sectors. I assume you know how to do this with resize2fs.

A PV needs exactly 1 MiB (2048 sectors) in front of the LV to store its metadata. As we don’t have that space, we have to free it at the end from sda2. First decrease the filesystem on sda2 by 2048 sectors. Then decrease the size of sda2 by 2048 sectors as well so we have enough unpartioned space before sda3.

resize2fs /dev/sda2 1951744s
fdisk /dev/sda
> d
> 2 (delete partition 2)
> n
> 2 (recreate partition 2)
> 976896 (first sector is the same)
> +1951743 (size is total sectors-1)
> n (keep existing filesystem signature)
> w (write changes to disk)

Now extend sda3 to contain these extra 2048 sectors.

fdisk /dev/sda
> d
> 3 (delete partition 3)
> n
> 3 (recreate partition 3)
> 2928640 (first sector is previously first sector-2048)
> 20969471 (last sector stays the same)
> w (write changes to disk)

Make a PV on sda3 with only 1 copy of the metadata in the beginning of the PV.

pvcreate -M2 --metadatacopies 1 /dev/sda3

Make a Volume Group with PE size 4MiB with the name vg0 containing only sda3.

vgcreate -M2 -s 4M vg0 /dev/sda3

Make an LV with 2202 PE’s and without zero’ing any existing signature in the LV.

lvcreate -l2202 -Zn vg0

Finally check if the filesystem is alright.

fsck -f /dev/mapper/vg0-lvol0

To boot back into the system we have to repair GRUB. This can be different dependent on which OS you run and in which mode (EFI or legacy).

mkdir rootmount
mount /dev/mapper/vg0-lvol0 rootmount/
mount /dev/sda1 rootmount/boot/efi
mount --bind /dev rootmount/dev
mount --bind /dev/pts rootmount/dev/pts
mount --bind /proc rootmount/proc
mount --bind /sys rootmount/sys
sudo chroot rootmount/
grub-install /dev/sda
update-grub

Although not strictly necessary, it is also good practice to change the partition type of your newly create LVM partition to ‘8E’ (Linux LVM).

Now you should be able to reboot back into your existing installation while now being on an Logical Volume.

Leave a Reply

Your email address will not be published. Required fields are marked *