How to‎ > ‎

Migrating from LVM to partitions

Traditionally, linux systems were installed on disks which usually were partitioned. That is good sometimes, but not always. So, the Linux Volume Manager (LVM) vas created, to overcome the limitations of the traditional partitioned disk usage. Some of the limitations are: inability to mirror or span volumes, a maximum number of partitions which sometimes may be too small. LVM has many advantages, such as ability to create a volume spanning many disk drives, ability to grow a voluume, ability to add more disks to the volume group. But it has a big disadvantage: there aren't too many replication/cloning tools available.
The major drawback of LVM is that it doesn't contain a filesystem, but logical volumes and each logical volume may be split across multiple phisical volumes. This is the main reason why cloning applications such as Ghost, Clonezilla or Acronis TrueImage do not copy data stored on LVM as a filesystem, but as a raw data. This process may be much slower than copying a filesystem.
Cloning tools must also be capable of understanding a specific filesystem to copy it. While NTFS, reiserfs, ext2 and ext3 are popular and supported by many cloning tools, ext4 is relatively new and at the time when I wrote this, the only tool able to clone ext4 filesystems is Clonezilla. Other tools may clone an ext4 filesystem, but using the raw copy method.

CentOS is a popular linux distribution, which by default uses LVM for storage devices.If someone wants to make a copy of the disk where the operating system is installed, it must use a disk equal to or larger than the one where the operating system is installed. Also, if the LVM configuration includes multiple disks, the cloning task is no longer an option, and other methods must be used. One of them is to use LVM's mirroring mechanism, but this require strong knowledge of LVM and it's utilities. If the storage requirements are modest, migrating from LVM to the traditional partitioning scheme is a possible option.

Migrating (and resizing volumes) from LVM to partitions

For someone looking to clone fast a disk with Linux on it, using a cloning tool like Clonezilla or Acronis True Image may be much easier than using other methods. Since many Linux installers prefer to use LVM, the user must manually partition the disk at install time, or install it using the defaults and convert it from LVM to partitions later.

This is the scenario below: I have a CentOS Linux 6 installed with default options, and then I migrate it to a partitioning scheme using custom sizes for the partitions and using ext3 filesystem instead of the default ext4. I want to create a supplemental /data partition, where I will store miscellaneous files. At this time, ext4 is not supported by as many tools as ext3.

After installation, I have:

The initial /etc/fstab file

# /etc/fstab
# Created by anaconda on Thu Aug 11 11:03:32 2011
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/VolGroup-lv_root /                       ext4    defaults        1 1
UUID=dbea6d02-7b89-4148-9ac1-da79af1c7027 /boot                   ext4    defaults        1 2
/dev/mapper/VolGroup-lv_swap swap                    swap    defaults        0 0
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc
A very important aspect regading /etc/fstab: the volume containing the root filesystem and the swap are referenced by their logical volume name, the boot partition is referenced by it's UUID. Why is this important: on a running system is impossible to have accessible at a specific time two different volumes with a specific volume group name and the same volume name. So, an exact replica of the LVM configuration from one disk to another can't be done on a single system while both disks are accessible. Copying LVM is possible with tools like modorescue, but the entire LVM configuration and data must be migrated from the local LVM to a remote machine or to an intermediate storage medium.

And for the boot loader

/boot/grub/grub.conf

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=/dev/mapper/VolGroup-lv_root
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title centos (2.6.32-71.el6.i686)
    root (hd0,0)
    kernel /vmlinuz-2.6.32-71.el6.i686 ro root=/dev/mapper/VolGroup-lv_root rd_LVM_LV=VolGroup/lv_root rd_LVM_LV=VolGroup/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us crashkernel=auto rhgb quiet
    initrd /initramfs-2.6.32-71.el6.i686.img

The boot loader configuration references the root file system location, which is provided as a kernel parameter. rd_LVM_LV, a kernel parameter which instructs LVM to initialize only the volume names referenced by rd_LVM_LV kernel parameters.


The migration from LVM to partitions procedure isn't quite simple. The target disk must be initialized, partitioned ahd the filesystems and swap partitions to be formatted, the data must be copied from LVM to partitions. A boot loader must be installed on the target, the boot loader configuration must be adjusted. As well, the /etc/fstab contents must be modified according to the new coordinates of the filesystems. an important thing which must not be forgot: on systems running with SeLinux enabled, after copying the data, an automatic relabel must be triggered for the next boot. Otherwise, the system may refuse to boot properly.

Partitioning the new disk

The new disk must be added to the system. After that, a live CD containing the tools required for partitioning must be used to boot the system. A disk which is fine enough is the CentOS 6 DVD, used with the third boot option: 'Rescue installed system'. Afer keyboard selection, optional network configuration and startup, at the 'Rescue' dialog select 'Continue' if you want to find your linux installation mounted read-write on /mnt/sysimage. After that, a shell must be started.

Now, in the shell prompt, the first task is to identify the drives. The /mnt/sysimage is mounted with the detected linux installation. The new disk should have an empty partition table. Now it's time to create the partition layout on the target disk. cfdisk is a very nice tool for this purpose.
I used the following layout:
Device    mount     size    file system type
sdb1        /boot   512M     ext3

sdb2        /       1024M    ext3
extended
    sdb5    swap    1024M    swap
    sdb6    /var    8192M    ext3
    sdb7    /tmp    2048M    ext3
    sdb8    /usr    4096M    ext3
    sdb9    /home   5192M    ext3
    sdb10   /data   5192M    ext3
    sdb11   /opt    5192M    ext3

After partitioning, the filesystems must be formatted. I also added labels to the filesystems, so they could be mounted later using the label.
# mkfs.ext3 -L boot /dev/sdb1
# mkfs.ext3 -L root /dev/sdb2
# mkswap -L swap /dev/sdb5
# mkfs.ext3 -L var /dev/sdb6
# mkfs.ext3 -L tmp /dev/sdb7
# mkfs.ext3 -L usr /dev/sdb8
# mkfs.ext3 -L data /dev/sdb9
# mkfs.ext3 -L data /dev/sdb10
# mkfs.ext3 -L opt /dev/sdb11

Now it's time to copy the data to the new filesystems:
# mkdir /mnt/newdisk
# mount /dev/sdb2 /mnt/newdisk
# cd /mnt/newdisk; mkdir {dev,mnt,boot,opt,usr,var,tmp,home,data}
# mount /dev/sdb1 /mnt/newdisk/boot
# mount /dev/sdb6 /mnt/newdisk/var
# mount /dev/sdb7 /mnt/newdisk/tmp
# mount /dev/sdb8 /mnt/newdisk/usr
# mount /dev/sdb9 /mnt/newdisk/home
# mount /dev/sdb10 /mnt/newdisk/data
# mount /dev/sdb11 /mnt/newdisk/opt

And it's good to adjust the file modes for some entries:
# chmod +t /mnt/newdisk/tmp
# chmod go+rw /mnt/newdisk/tmp

The data from the old system is located on /mnt/sysimage. Copy the data located on the new mount points:
# for dir in $(ls -1 /mnt/sysimage | grep '\(boot\|var\|tmp\|usr\|home\|opt\)'); do \
> echo dir; \
> cp -v -ax /mnt/sysimage/$dir /mnt/newdisk/;\
> done;


And the data located on the root filesystem too, but exclude the contents of the special directories /dev, /proc, /selinux and /sys:
# umount /mnt/sysimage/selinux
# for dir in $(ls -1 /mnt/sysimage | grep -v '\(boot\|var\|tmp\|usr\|home\|opt\|sys\|proc\|dev\|mnt\|lost\)'); do \
> echo dir; \
> cp -v -ax /mnt/sysimage/$dir /mnt/newdisk/;\
> done;


Handle the /proc, /dev and /sys:
# mkdir /mnt/newdisk/{proc,sys,dev}
# chmod -w /mnt/newdisk/proc
# chmod go+w /mnt/newdisk/dev
# chmod +t /mnt/newdisk/dev

To make the target disk bootable, it's time to install the grub boot loader on it:
# mount -o bind /dev /mnt/newdisk/dev
# chroot /mnt/newdisk
# grub
> root (hd1,0)
> setup (hd1)
> quit

Because on the target disk LVM will not be required to boot, the kernel command line no longer requires the parameters rd_LVM_LV and these can be removed and replaced by rd_NO_LVM. Also, pass on the command line the proper value for 'root=' parameter:
# vi /boot/grub/grub.conf
ESC:%s/\/dev\/mapper\/VolGroup-lv_root/LABEL=root/g
ESC:%s/rd_LVM_LV=VolGroup\/lv_root rd_LVM_LV=VolGroup\/lv_swap/rd_NO_LVM/g
ESC:wq

The new /boot/grub/brub.conf file now looks like:
# cat /boot/grub/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /boot/, eg.
#          root (hd0,0)
#          kernel /vmlinuz-version ro root=LABEL=root
#          initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title centos (2.6.32-71.el6.i686)
    root (hd0,0)
    kernel /vmlinuz-2.6.32-71.el6.i686 ro root=LABEL=root rd_NO_LVM rd_NO_LUKS rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us crashkernel=auto rhgb quiet
    initrd /initramfs-2.6.32-71.el6.i686.img

The contents of /etc/fstab from the target disk must be modified too:
# vi /etc/fstab
# the old mount point for / and swap location
#UUID=dbea6d02-7b89-4148-9ac1-da79af1c7027 /boot                   ext4    defaults        1 2
#/dev/mapper/VolGroup-lv_swap swap                    swap    defaults        0 0
LABEL=root    /         ext3    defaults    1 1
LABEL=swap    swap      swap    defaults    1 2
LABEL=boot    /boot     ext3    defaults    1 2
LABEL=home    /home     ext3    defaults    1 2
LABEL=var     /var      ext3    defaults    1 2
LABEL=tmp     /tmp      ext3    defaults    1 2
LABEL=usr     /usr      ext3    defaults    1 2
LABEL=opt     /opt      ext3    defaults    1 2
LABEL=data    /data     ext3    defaults    1 2
tmpfs                   /dev/shm                tmpfs   defaults        0 0
devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
sysfs                   /sys                    sysfs   defaults        0 0
proc                    /proc                   proc    defaults        0 0



And finally, exit the chroot and schedule a complete filesystem selinux relabel, otherwise the new installation won't be bootable:
# exit
#
touch /mnt/newdisk/.autorelabel

# touch /mnt/newdisk/var/.autorelabel
# touch /mnt/newdisk/tmp/.autorelabel
# touch /mnt/newdisk/usr/.autorelabel
# touch /mnt/newdisk/home/.autorelabel
# touch /mnt/newdisk/opt/.autorelabel


Now it's time to power off the system, unplug the old disk, power on and boot from the new disk. On the first boot it will take a time for relabel to complete and it may require a reboot. After that, your new partitioned CentOS 6 system will be clonable and resizable with standard imaging tools.


Comments