Converting Ext3 to LVM

Basic steps. This will need a cleanup (and is only relevant for RHEL/Fedora at the moment)

LVM (Logical Volume Manager) is a layer that sits between physical volumes and your filesystems. It's a bit like partitioning on steroids, but the key is that it's dynamically variable. Windows users will find it similar to the Dynamic Disk functionality (but much cooler).

LVM allows you to pool physical resources together (typically hard drives) into a Volume Group, and then carve out chunks into Logical Volumes. You then format these with a filesystem as you would normally do to an on-disk partition. LVM also gives you the ability to resize your logical volumes (provided you haven't used all the space in your volume group). With modern filesystem tools, this can even be done with zero downtime!

This procedure assumes you've got an existing system with a bunch of partitions that you'd like to convert to LVM. Most of our systems use md-based RAID arrays as the block device for each filesystem, which features in this procedure. You may need to adjust the procedure accordingly.

The GRUB bootloader can't boot directly to an LVM system. This means your kernel and initrd (if required) will need their own partition for /boot. After this, the rest of the drive is given over to LVM.

  • Add an additional hard drive to the dedicated server, assume it will be /dev/sdc

  • Partition with 100MB for the new /boot and the rest for LVM, set the partition types to fd (md autodetect)

  • Replicate the existing RAID setup, but this time with only two RAID volumes. You'll need to choose not-yet-used md minor numbers. We'll assume /dev/md5 and /dev/md6 are free. Notice that we're building a "degraded" RAID-1 array. We don't need the full array right now.

    • mdadm --create /dev/md5 --level 1 -n 2 -x 0 /dev/sdc1 missing

    • mdadm --create /dev/md6 --level 1 -n 2 -x 0 /dev/sdc2 missing

  • Create the filesystem for /boot

    • mke2fs -j -L /boot /dev/md5 - the 100MB RAID

  • Prepare the rest of the disk for use in LVM
    • pvcreate /dev/md6 - the big RAID

    • vgcreate SERVERNAME /dev/md6

  • Create all your logical volumes now
    • lvcreate -L 500M -n root /dev/SERVERNAME

    • lvcreate -L 2G -n swap /dev/SERVERNAME

    • lvcreate -L 4G -n var /dev/SERVERNAME

    • lvcreate -L 4G -n usr /dev/SERVERNAME

    • lvcreate -l 100%FREE -n data /dev/SERVERNAME

  • Create the filesystem on each logical volume you just created
    • mke2fs -j -L something /dev/SERVERNAME/something - label the filesystem with the mountpoint name when making the filesystem

    • mkswap /dev/SERVERNAME/swap

  • Start preparing the new system for migration
    • mkdir /newroot

    • mount -t ext3 /dev/SERVERNAME/root /newroot -o rw,noatime,nodiratime

    • mkdir -p /newroot/{boot,usr,var,data}

    • mount the usr, var and data logical volumes under /newroot/whatever, and /newroot/boot from the 100MB RAID partition

  • Copy all your data across. You'll want to shutdown as many processes and services as you can before doing this
    • cp -ax / /newroot

    • cp -ax /usr/ /newroot/usr/

    • cp -ax /var/ /newroot/var/

    • cp -ax /data/ /newroot/data/

    • cp -ax /boot/ /newroot/boot/

  • Make a copy of /etc/{fstab,mtab} and /boot/grub/grub.conf in /root

    • Edit fstab and change all of the mount points to reflect the new LV names

      • Immediately after the root filesystem mount entry, add an entry for /boot to mount /dev/md5. Maintain the MD device minor number as it is now.

      • Also make the changes in the mtab file. Remove entries mentioning /newroot

    • Edit grub.conf and remove /boot from the beginning of all paths (this bit may be RedHat-specific)

      • Also change the root= parameter to be /dev/SERVERNAME/root

  • When you are ready to make the cutover, shut down all services except SSH, disable cron, cfengine etc.
  • Do a final rsync from the same partitions

    rsync -avx --delete /      /newroot/
    rsync -avx --delete /boot/ /newroot/boot/
    rsync -avx --delete /usr/  /newroot/usr/
    rsync -avx --delete /var/  /newroot/var/
    rsync -avx --delete /data/ /newroot/data/
  • Copy the edited {fstab,mtab} to /newroot/etc/

  • Copy the edited grub.conf to /newroot/boot/grub/

  • mount -t proc none /newroot/proc

  • mount /dev /newroot/dev -o bind

  • chroot /newroot

  • mkinitrd -f /boot/initrd-XXXX XXXX - use the most recently installed kernel version for XXXX

    • This is very important as the initrd will read the current fstab/mtab files and put in commands to bring up the RAID and LVM at boot time
  • run grub - obviously change this if the parameters aren't quite correct

    device (hd2) /dev/sdc
    root (hd2,0)
    setup (hd2)
  • exit the chroot
  • umount /newroot/dev /newroot/proc /newroot/boot /newroot/data /newroot/usr /newroot/var /newroot

  • shutdown the dedicated server
  • remove the original disks
  • put the new disk in the first slot
  • boot up into the OS
  • put a/the second disk and resync the RAID
  • Done!