resize2fs

Resizing ext3-on-LVM-on-dmcrypt file systems, moving disk space from one LV to another

Back in 2008 I wrote a small article about resizing LVM physical volumes. I had to do something similar, but slighly more complicated, recently. My /usr logical volume (LV) was getting full on my laptop disk, thus I wanted to shrink another LV and move some of that space to /usr. Here's one way you can do that.

Requirements: a Live CD containing all required utilities (cryptsetup, LVM tools, resize2fs), I used grml.

Important: If you plan to perform any of these steps, make sure you have recent backups! I take no responsibility for any data loss you might experience. You have been warned!

First, shutdown the laptop and boot using the Live CD. Then, open the dm-crypt device (/dev/hda3 in my case) by entering your passphrase:

  $ cryptsetup luksOpen /dev/hda3 foo

Activate all (newly available) LVM volume groups in that encrypted device:

  $ vgchange -a y

(maybe you also need a vgscan and/or lvscan, not sure)

Check how much free space we have for putting into our /usr LV:

  $ vgdisplay | grep Free
  Free  PE / Size       0 / 0   

OK, so we have none. Thus, we need to shrink another LV (/home, in my case) and put that newly freed space into the /usr LV. In order to do that, we have to check the current size of the /home LV:

  $ mount -t ext3 /dev/vg-whole/lv-home /mnt
  $ df --block-size=1M | grep -C 1 /mnt
  $ umount /mnt

(if you know how to find out the size of an ext3 file system without mounting it, please let me know) Update: See comments for suggestions.

Write down the total amount of 1M chunks of space on the file system (116857 in my case), we'll need that later. Now run 'fsck' on the /home LVM logical volume, which is needed for the 'resize2fs' step afterwards. This will take quite a while.

  $ fsck -f /dev/vg-whole/lv-home

Next step is resizing the ext3 file system in the /home LVM logical volume, making it 1GB smaller than before (of course you must have >= 1 GB of free space on /home for that to work). We use fancy bash calculations to do the math.

Note: I'm not so sure about the sizes here, in my first attempt something went wrong and resize2fs said "filesystem too small" or the like. Maybe I'm confusing the size units from 'df' and 'resize2fs', or the bash calculation goes wrong? Please leave a comment if you know more!

  $ resize2fs /dev/vg-whole/lv-home $((116857-1024))M

Then, we can safely reduce the LV itself. Note: order is very important here, you must shrink the ext3 filesystem first, and then shrink the LV! Doing it the other way around will destroy your filesystem!

  $ lvreduce -L -1G /dev/vg-whole/lv-home

Now that we have 1 GB of free space to spend on LVs, we assign that space to the /usr LVM logical volume like this:

  $ lvextend -L +1G /dev/vg-whole/lv-usr

As usual, we then run 'fsck' on the filesystem in order to be able to use 'resize2fs' to resize it to the biggest possible size (that's the default if resize2fs gets no parameters):

  $ fsck -f /dev/vg-whole/lv-usr
  $ resize2fs /dev/vg-whole/lv-usr

That's it. You can now shutdown the Live CD system and boot into the normal OS with the new space allocations:

  $ vgchange -a n
  $ cryptsetup luksClose foo
  $ halt

Resizing a dm-crypt / LVM / ext3 partition

I've bought a new hard drive for my laptop recently, because I finally got fed up with my constantly-full disk. Having to browse around in $HOME looking for stuff which can be safely deleted just because I want to run fetchmail (and that would fill up my disk) just sucks. So, after getting a cheapo 160 GB 2.5" disk (the old one was 80 GB), I had to move all my data to the new disk.

As I didn't want to re-install from scratch I started with dd'ing the whole disk over to the new one (using a live CD and an external USB hard-drive enclosure). This took pretty long, but went fine otherwise.

The new disk then contained all my partitions (hda1-hda3) and also GRUB in the MBR etc., as expected, but was still only 80 GB in size, of course. So the first step is to enlarge the hda3 partition, which is a dm-crypt volume that contains various LVM logical volumes (for /home, /usr, /var, swap, etc.), each of them using the ext3 filesystem (except for the swap volume, of course).

0. Perform backups, boot from a live CD

Important: If you plan to perform any of these steps, make sure you have recent backups! I take no responsibility for any data loss you might experience. You have been warned!

First off, you should boot from a live CD which has all the tools you'll need, including cryptsetup, LVM tools, resize2fs, etc. You can use the nice grml live CD for instance.

1. Resize partition

This sounds scary (and it is!), but the way I enlarged the encrypted hda3 partition was by first deleting it via fdisk. First, issue the "p" command in fdisk, write down the exact start cylinder of hda3. Then delete hda3. Now create a new hda3 partition which starts at exactly the same cylinder as the old hda3 but is larger, i.e. in my case it has ca. 80 GB additional space.

Your data will still be there if you don't screw up, and the partition is bigger now. Using something like gparted will likely not work as expected, as the partition is encrypted!

2. Resize dm-crypt volume

Nothing to be done, it seems dm-crypt automatically adapts and notices that the partition is bigger. Just "open" the encrypted volume using cryptsetup now:

  $ cryptsetup luksOpen /dev/hda3 foo

3. Resize LVM physical volume

Next step is to tell LVM about the new space. We first resize the LVM physical volume on the foo "partition" to use up all newly-available space.

  $ pvresize /dev/mapper/foo

4. Resize LVM logical volume

Now we can pump the new space into any of the logical volumes (or into multiple ones). I only increased one logical volume, my /home:

  $ lvresize -L +74 GB /dev/vg-whole/lv-home

5. Resize ext3 filesystem

The final step is to resize the ext3 filesystem on the lv-home logical volume (after running the obligatory fsck -n). I first used ext2resize, but that failed horribly:

  $ fsck -n /dev/vg-whole/lv-home
  $ ext2resize /dev/vg-whole/lv-home
  error: Invalid argument: seeking to 3258921205760

This seems to be a known bug, ext2resize apparently cannot handle large disks or something, and as I found out a few minutes later it's pretty much deprecated anyway. The better solution is to use resize2fs:

  $ fsck -n /dev/vg-whole/lv-home
  $ resize2fs /dev/vg-whole/lv-home

That's it. We can now reboot the system from disk and enjoy ca. 80 GB of additional hard drive space. Yay!

Syndicate content