Friday, January 25, 2008

Shrinking a Linux LVM Partition

This is a work-in-progress as I am figuring this out as I do it.

I have a notebook computer that has linux on it (Fedora 8). At one time I had it set up to dual-boot linux and XP, but when I purchased a larger drive for it I figured I would use the old drive for XP and the new drive for linux and just swap them around when I want to change OS. That was stupid. It is way too much of a hassle to swap the drives around so now I almost never use XP. The problem is that once in a while there is an application I would like to use that only runs in windows and dows not work well in Wine.

So now I want to move things around on the drive to make room for a Windows partition. Here is what I currently have:

Laptop Hard Drive: 160GB: 19457 cylinders of 16065 * 512 bytes.

/dev/sda1125Linux xt3 /boot
/dev/sda22616000Linux LVM

I also have a 250GB USB Hard Drive: 30401 cylinders of 16065 * 512 bytes.

/dev/sdb115009NTFS (Copy of XP partition from my original drive)
/dev/sdb251005112Linux ext3 /boot (from old drive)
/dev/sdb3511312161Linux lvm (from old drive)

The layout of the LVM Physical Volume is as follows:

LogVolRoot0 - 625 extents (Fedora 7 root)
(unused) - 625 extents
LVFedora8 - 625 extents (Fedora 8 root)
LogVolSwap - 62 extents
LVHome - 1948 extents
(unused) - 878 extents

I decided to try using the Logical Volume Management GUI tool to try to move things around. First I created an LVM partition on the unallocated portion of the USB hard drive (/dev/sdb4). I did this by going to the "Uninitialized Entries" section of the tool, expanding the /dev/sdb entry, selecting "Partition 4" and then selecting "Initalize Entry".

Next I selected the physical view of my volume group, than on the diagram I selected the extents of one of the Logical Volumes that I wish to move around (LVHome), and then selected "Migrate Selected Extents from Volume". This gave me a windows that allowed me to choose where to put the extents... I chose the LVM partition on /dev/sdb4. This took quite a while to complete. It is kind of amazing that it even worked while the volume was active and the file system mounted and in-use.

Next... the same thing for LVFedora8. This is a little scary since this is the root volume that I am currently running on. This took a while too... and the system is still running.

Next, I am going to move the LVFedroa8 volume back, and hope it puts it at the open space towards the front of the partition (right after LogVolRoot0). Ok... well that did not quite work =(. It put it right back where it was. Next I will try moving it to the USB drive, and then moving it back with the "contiguous" option selected. Fingers crossed... Nope! Once again it put it back where it was originally. I may have something to do with the allocation policy that is configured on the Volume group... but I think I found a different way to do this...

While the move was going on I opened up a shell windows and did a ps. I saw that it was using the "pvmove" command to move the data:

/usr/sbin/pvmove --alloc contiguous /dev/sdb4:1948-2572 /dev/sda1

Looking at the man page for pvmove revealed that I can specify which tracks I want to use in both the source and destination. I am going to try to use the pvmove command to do this instead of using the gui.

At first, I tried using the same disk as the source and destination... just moving to a different location. This did not work. Here is what did work:

  1. /usr/sbin/pvmove --interval 30 --name LogVolSwap /dev/sda2:1875-1936 /dev/sdb4
  2. /usr/sbin/pvmove --interval 30 --name LogVolSwap /dev/sdb4:1948-2009 /dev/sda2:624-686
  3. /usr/sbin/pvmove --name LVFedora8 --interval 30 /dev/sda2:1937-2561 /dev/sdb4
  4. /usr/sbin/pvmove --name LVFedora8 --interval 30 /dev/sdb4:1948-2572 /dev/sda2:686-1311
  5. pvresize --setphysicalvolumesize 100G /dev/sda2
  6. fdisk /dev/sda (delete and recreate partition 2 as a smaller size, create 3rd partition for XP)
  7. pvresize /dev/sda2
  8. /usr/sbin/pvmove --name LogVolHome --interval 30 /dev/sdb4:0-1947 /dev/sda2
A few general notes on pvmove: The --interval 30 tells is to display a status on the terminal every 30 seconds, --name LogVolSwap tells it to only move tracks that are within the specified source that are also part of the LogVolSwap logical volume.

Line 1: This is moving the swap LV from the interal drive (sda1) to the USB drive (sda2).
Line 2: Move the swap back to the internal drive, but put it in the first unused portion of the partition (tracks 686-1311).
Line 3: Move the Fedora 8 LV from the internal drive to the USB drive.
Line 4: Move Fedora 8 back to the internal drive, but starting at the first free track.
Line 5: Resize the LVM physical volume to a size smaller than we are going to make the partition (for now)
Line 6: Resize the partition with fdisk.
Line 7: Resize the LVM physical volume up to the partition size (don't specify a size and pvresize will make it fit in the partition).
Line 8: Move the Home LV from the USB drive to the internal drive.

Now I dd the XP partition from the USB drive to /dev/sda3, edit by grub.conf to chainload, reboot and ... it doesn't work. :(

Possible problems...
- The XP partition is too far into the drive to be bootable (I have heard rumors of a limit around 130GB)
- XP doesn't like the fact that it is on a different partition
- I messed up copying XP

Thats as far as I got before I ran out of time. I'll keep this out here as a starting point in case I come back to this later.