Shrink partition in xen guest

In a previous post I discussed extending a partition in a linux guest. Since I never can make up my mind, this post discusses the opposite, i.e. shrinking a paritition in a disk (again as opposed to a partition) in a logical volume. Since we do not have just one partition in the logical volume we have to delete and recreate.

The procedure is a little different since it is too large to make a backup in the other quest I do it on the xen host:

  • Create a logical volume the size of the one we are going to rearrange for backup
  • Mount the disk in the Logical Volume (LV) on another guest.
  • In the other guest use fdisk to recreate them with the right size

 

lvcreate -L 100G -n lv_vm_tmp /dev//

For instance:

lvcreate -L 100G -n lv_vm_ishpublic_tmp /dev/nebulus-vg

Backup the original volume to the temp volume we just created (double check that the original is first and the backup is second).

cp /dev// /dev//
cp /dev/nebulus-vg/lv_vm_ishpublic /dev/nebulus-vg/lv_vm_ishpublic_tmp

Now add this to your ‘utility’ host (we are going to mount the volume there to resize). In your xen config for utility add the disk. For instance my volume group is ‘nebulus-vg’ and the disk with partitions I want to resize is ‘lv_vm_ishpublic’.

disk = [ '/dev/nebulus-vg/lv_sirius_ubuntu,raw,xvda,rw', '/dev/nebulus-vg/lv_vm_ishpublic,raw,xvdb,rw' ]

Then:

  • Start your utility VM
  • login as root

Print the partitions on xvdb

root@sirius:~# fdisk /dev/xvdb

Welcome to fdisk (util-linux 2.25.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/xvdb: 100 GiB, 107374182400 bytes, 209715200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x76ff0726

Device     Boot     Start       End   Sectors Size Id Type
/dev/xvdb1           2048 201328639 201326592  96G 83 Linux
/dev/xvdb2      201330686 209713151   8382466   4G  5 Extended
/dev/xvdb5      201330688 209713151   8382464   4G 82 Linux swap / Solaris

Partition 3 does not start on physical sector boundary.


Command (m for help): q

Run a file system check:

e2fsck -f /dev/xvdb1

Try resizing the partition (we can pass a very low number to resize2fs so it will print the minimum we need:

resize2fs /dev/xvdb1 1G
resize2fs 1.42.10 (18-May-2014)
resize2fs: New size smaller than minimum (4468729)

You probably do not want to have the exact minimum, I use approx. double the size.

resize2fs /dev/xvdb1 8388608
resize2fs 1.42.10 (18-May-2014)
Resizing the filesystem on /dev/xvdb1 to 8388608 (4k) blocks.
The filesystem on /dev/xvdb1 is now 8388608 blocks long.

Though the filesystem is resized the partition is still the original size. We need to modify the partition table on the disk where the new end is. Calculate this from the output of resize2fs and the size of a sector from fdisk (sector size was 512 in my case, make sure you substitute the values you got!).

  • New filesystem size (output from resize2fs) = 8388608 (4k) blocks = 8388608 * 4 * 1024 = 34359738368 bytes
  • New filesystem size in sectors = 34359738368 / 512 = 67108864 sectors (if you get a fractional value round it up)
  • Therefore the end sector in fdisk will be start sector + size = 2048 + 67108864 = 67110912
  • I also want a 2G swap partition i.e. 2 * 1024 * 1024 * 1024 / 512 = 4194304 sectors
  • Therefore the end of the disk will be at 67110912 + 4096 = 71305217 sectors
 fdisk /dev/xvdb

Welcome to fdisk (util-linux 2.25.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/xvdb: 100 GiB, 107374182400 bytes, 209715200 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x76ff0726

Device     Boot     Start       End   Sectors Size Id Type
/dev/xvdb1           2048 201328639 201326592  96G 83 Linux
/dev/xvdb2      201330686 209713151   8382466   4G  5 Extended
/dev/xvdb5      201330688 209713151   8382464   4G 82 Linux swap / Solaris

Partition 3 does not start on physical sector boundary.


Command (m for help): d
Partition number (1,2,5, default 5):

Partition 5 has been deleted.

Command (m for help): d
Partition number (1,2, default 2):

Partition 2 has been deleted.

Command (m for help): d
Selected partition 1
Partition 1 has been deleted.

Create the new partitions:


 

Command (m for help): n Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): Using default response p. Partition number (1-4, default 1): First sector (2048-209715199, default 2048): Last sector, +sectors or +size{K,M,G,T,P} (2048-209715199, default 209715199): 67110912 Created a new partition 1 of type 'Linux' and of size 32 GiB. Command (m for help): n Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): Using default response p. Partition number (2-4, default 2): First sector (67110913-209715199, default 67112960): 67110913 Last sector, +sectors or +size{K,M,G,T,P} (67110913-209715199, default 209715199): 71305217 Created a new partition 2 of type 'Linux' and of size 2 GiB.

Toggle the filesystem type on the swap partition:

t 2 82

Write the table back to disk, quit and shutdown the utility system:


 

w q shutdown -h now

Back on the xen host we now need to reduce the logical volume size. First we need to know the physical extent:

 vgdisplay
  --- Volume group ---
  VG Name               nebulus-vg
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  12
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                7
  Open LV               5
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               3.64 TiB
  PE Size               4.00 MiB
  Total PE              953672
  Alloc PE / Size       129825 / 507.13 GiB
  Free  PE / Size       823847 / 3.14 TiB
  VG UUID               tm4Q7z-LWIL-OUW3-egF0-8UP4-d2MJ-fW1sXX


PE Size is 4 MB

To calculate the new size in extends take the size in bytes from our last sector ( I am not sure if sectors start from 1 or 0, better be safe) from fdisk and add one.

  • 71305217 + 1 = 71305218

 

Round up to the next vg extent boundary:

  • RoundUp( Number of sectors * sectors size / PE Size )
  • 71305218 * 512 / ( 4 * 1024 * 1024 ) = 8704.25
  • RoundUp( 8704.25 ) = 8705

Shrink the logical volume

lvreduce -l 8705 /dev/nebulus-vg/lv_vm_ishpublic
  WARNING: Reducing active logical volume to 34.00 GiB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce lv_vm_ishpublic? [y/n]: y
  Reducing logical volume lv_vm_ishpublic to 34.00 GiB
  Logical volume lv_vm_ishpublic successfully resized

And we are done. Well actually you would want to startup your utility VM again, do the mount of the filesystem and run e2fsck (see above) again to make sure that everything worked.

e2fsck /dev/xvdb1
e2fsck 1.42.10 (18-May-2014)
/dev/xvdb1: recovering journal
Setting free inodes count to 1775009 (was 1775029)
Setting free blocks count to 4183513 (was 4183757)
/dev/xvdb1: clean, 322143/2097152 files, 4205095/8388608 blocks

Bonus points enable swap.

Shutdown util and startup your VM with resized disk and login:

If you configured a swap parition check it is working:

swapon -s

If not you have to add the swap partition. Let’s say it was on xvdb2 when you configured it in util then it probably is in xvda2 (make sure you get it right i.e. check if it exists in /dev isn’t mounted df -k). In the following I assume it is on /dev/xvda2

Now for ubuntu execute the following:

blkid /dev/xvda2

Copy the UUID and open /etc/fstab. Copy the swap line and change it as follows (use the printed UUID instead of the one below).

UUID=7340ea5f-3325-466a-8e2f-52c1cf15ae94 / ext4 errors=remount-ro 0 1
# swap was on /dev/xvda5 during installation
#UUID=75ecaea3-ff0d-4f90-b5e2-ea757bde5399 none swap sw 0 0
UUID=582dae7a-5d2a-4b4c-9685-993fc8454200 /dev/xvda2 swap sw 0 0

shutdown -r now

Log back in:

swapon -s
Filename                                Type            Size    Used    Priority
/dev/xvda2                              partition       1046524 0       -1

If satisfied don’t forget to start Util and cleanup the backups created.

Leave a Reply