GParted is among the most well-known and respected open-source partition editors. From creation to deletion, resizing, copying, and moving, it is a tool built to manage the full gamut of disk partitionining operations.

In part one of our migration process, we cloned the installation to a new drive in new hardware. In part two, we moved to a LUKS-encrypted root. Now we have a few adjustments we wish to make to our partitioning scheme, regaining space so that we may move the rest of the system beneath the umbrella of encryption.

The Plan

We have the following arrangement on the system drive:

/dev/sda (150GB)
     sda1: ext3 /boot (300MB)
     sda2: ext3 oldroot (38GB)
     sda3: lvm Volume00 (112GB)
          Volume00-home: ext3 /home (70GB)
          Volume00-swap: swap (2GB)
          Volume00-root: LUKS (40GB)
               luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34: / ext3 (40GB)

Despite our efforts thus far, the issue remains that our home volume is not yet protected by encryption. We can tackle this two ways, either by building a new home crypto-volume and copying data as we did for root, or by simply reclaiming space enough to abandon a separate home volume and copy that data beneath the already encrypted root. I elect for the latter, mainly because the use of a single crypto-volume avoids the potential for multiple pass-phrase entry at boot, and also because there is no compelling reason for a separate home on this particular system.

In order to gain the space necessary, we will remove the old unused root, add that space for use by LVM, grow our new crypto-root, and then copy the data from home. This is no big deal, and the partition is easily deleted with fdisk or gparted. But there is one issue. Because this is not the last partition on the disk, resizing for our needs is not as simple as an fdisk delete and recreate, moving the end boundary to the end of the drive. Now we need to move the start of the partition. Enter GParted.

GParted

While GParted can be run at any time, some functionality for a given storage device may not be available, nor entirely safe, if it is in-use (mounted) by the operating system. For this reason, we elect to boot the system with the GParted Live CD.

NOTE: Be aware that there is a perfectly good alternative to partition resizing of any kind. We could instead elect to create an LVM partition using the unallocated space and do standard LVM operations to incorporate it into our root logical volume (pvcreate, vgextend, lvextend). But we continue with full confidence in GParted, the main benefit being mostly cosmetic in the end: a tidy partition table.

Booted into the live environment, we start GParted. After deleting the old root partition at /dev/sda2, we are left with a good illustration of the situation at hand. We have a region of unallocated space before the LVM partition:
sda2_unallocated

We need to resize/move the sda3 partition, which contains our priceless crypto-LVM/root within it:
sda3_lvm

The resize dialog gets right to the point. Adjusting the amount of space before and after the partition moves its start and end positions on disk:
sda3_resize1

Drag the start boundary all the way to the left (or enter 0) to effect a move/resize, absorbing every bit of the unallocated space before the partition:
sda3_resize2

Operation pending. We can still back out without affecting anything. Click apply, and be prepared for a lengthy wait.
sda3_resize4

When all is said and done, we have moved and resized our LVM partition to utilize the full disk:
sda3_resizedone

Note that used space has not changed. We address that next.

Resize LVM, LUKS, Ext3

The work done so far has resized the outermost container, the partition. Like Russian nesting dolls, we need to grow each in turn before we can address the filesystem. A testament to the tools, we can actually do all of the following booted into the live system.

First LVM:

pvs
  PV         VG       Fmt  Attr PSize   PFree 
  /dev/sda3  Volume00 lvm2 a--  148.75g 36.98g

vgs
  VG       #PV #LV #SN Attr   VSize   VFree 
  Volume00   1   3   0 wz--n- 148.75g 36.98g

lvs
  LV   VG       Attr       LSize  Pool Origin Data%  Move Log Cpy%Sync Convert
  home Volume00 -wn-ao---- 69.00g                                             
  root Volume00 -wi-ao---- 40.76g                                             
  swap Volume00 -wi-ao----  2.00g

lvresize Volume00/root -l+100%FREE
  Extending logical volume root to 77.75 GiB
  Logical volume root successfully resized

lvs
  LV   VG       Attr       LSize  Pool Origin Data%  Move Log Cpy%Sync Convert
  home Volume00 -wn-ao---- 69.00g                                             
  root Volume00 -wi-ao---- 77.75g                                             
  swap Volume00 -wi-ao----  2.00g

NOTE: I would normally expect to first do a pvresize to grow the PV, but the PV already knew about the extra space, likely a gift from GParted.

Then LUKS:

cryptsetup resize luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34  
echo $?
0

Finally the filesystem:

df -h /
Filesystem                                             Size  Used Avail Use% Mounted on
/dev/mapper/luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34   40G   29G  9.2G  76% /

resize2fs /dev/mapper/luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34 
resize2fs 1.42.8 (20-Jun-2013)
Filesystem at /dev/mapper/luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34 is mounted on /; on-line resizing required
old_desc_blocks = 3, new_desc_blocks = 5
The filesystem on /dev/mapper/luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34 is now 20380160 blocks long.

df -h /
Filesystem                                             Size  Used Avail Use% Mounted on
/dev/mapper/luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34   77G   29G   45G  40% /

We are left with a nice large root to accommodate our /home data.

Home Copy

With 45GB free in our root, we should have plenty of space after cleaning out some garbage in home:

df -h /home
Filesystem                 Size  Used Avail Use% Mounted on
/dev/mapper/Volume00-home   64G  5.0G   56G   9% /home

A good old rsync will suffice to copy that whopping 5GB of data from the existing home volume to the home within the crypto-root. First things first, bug out to runlevel 3 (or single/rescue mode for overkill) to ensure home is not in use so we can mount it somewhere else:

init 3
umount /home
mkdir /oldhome
mount /dev/mapper/Volume00-home /oldhome

Finally rsync the data:

rsync -a /oldhome/ /home

When done, remember to pound out the /home mount from /etc/fstab lest we accidentally mount our old unencrypted home volume on next boot:

#/dev/Volume00/home	/home			ext3	defaults	1 2

A reboot confirms that everything is working as it should.

LVM Cleanup

Almost half the disk is tied up in our abandoned home. Once happy with the new arrangement, we can easily reclaim that space starting at the LVM layer, and then working our way up. This is just a second run at container resizing as above, LVM, LUKS, Ext3, all live.

lvs
  LV   VG       Attr       LSize  Pool Origin Data%  Move Log Cpy%Sync Convert
  home Volume00 -wn-a----- 69.00g                                             
  root Volume00 -wi-ao---- 77.75g                                             
  swap Volume00 -wi-ao----  2.00g

lvremove Volume00/home
Do you really want to remove active logical volume home? [y/n]: y
  Logical volume "home" successfully removed

vgs
  VG       #PV #LV #SN Attr   VSize   VFree 
  Volume00   1   2   0 wz--n- 148.75g 69.00g

lvextend -L+50G Volume00/root
  Extending logical volume root to 127.75 GiB
  Logical volume root successfully resized

cryptsetup resize luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34  
echo $?
0

resize2fs /dev/mapper/luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34
resize2fs 1.42.8 (20-Jun-2013)
Filesystem at /dev/mapper/luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34 is mounted on /; on-line resizing required
old_desc_blocks = 5, new_desc_blocks = 8
The filesystem on /dev/mapper/luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34 is now 33487360 blocks long.

df -h /
Filesystem                                             Size  Used Avail Use% Mounted on
/dev/mapper/luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34  126G   36G   85G  30% /

NOTE: With ample disk available, we left some space unallocated in the VG. This is just a hedge for flexibility. If we need more space in the future, we can always add it live just as we did here.

Partition Re-Numbering

Our partition table consists of the following, as revealed by fdisk:

Device    Boot     Start       End    Blocks  Id System
/dev/sda1 *           63    619919    309928+ 83 Linux
/dev/sda3         620544 312580095 155979776  8e Linux LVM

While it is no problem whatsoever to be “missing” a partition in sequence, we continue the intrepid pursuit of the trivial and wish to renumber sda3 to sda2. The easiest way to rectify this is to simply delete and re-create the partition using fdisk. Since it is the last partition, fdisk will normally default to the same start and end sectors when creating the new one (something to double-check). While this can be done live followed by an immediate reboot, it is safest to do this from rescue mode with the disk not in use.

fdisk /dev/sda
ddelete, partition number 3
new, primary, partition number 2, first sector default, last sector default
type, partition number 2, 8e
write

Reboot. Just a reminder, this is completely unnecessary. 🙂

Everything Encrypted

We leave with this on the system disk:

/dev/sda (150GB)
     sda1: ext3 /boot (300MB)
     sda2: lvm Volume00 (150GB)
          Volume00-swap: swap (2GB)
          Volume00-root: LUKS (127GB)
               luks-cc7e78ee-87a9-4ad0-9c82-31de01389b34 ext3 (127GB)
          unallocated: (19GB)

A tidy partition and volume layout with nearly everything encrypted. In part four, we will contend with encrypting swap and explore encryption possibilities more fully.