How To Shrink an XFS Partition on LVM

Shrink XFS Partition on LVM

Most modern Linuxes use LVM and XFS by default. CentOS 7 in particular has a default partition layout that is not all that great. In some cases you may find that you have too much free space on the /home partition and not enough on /.

In situations like this you may want to resize both partitions, removing space from /home and reallocating it to /. However, XFS does not support shrinking filesystems.

This guide explains how to deal with that situation gracefully. The procedure is basically as follows.

  1. Take a backup of /home using xfsdump
  2. Reboot into single user mode
  3. Unmount /home and resize the logical volume
  4. Reformat the /home with mkfs.xfs
  5. Resize the / logical volume to scale up
  6. Reboot
  7. Restore /home with xfsrestore

Backup /home

In a situation where you have a full / partition, and need to reclaim capacity from /home, you cannot backup to the local machine. In these situations, you can pipe the xfsdump over ssh and write it to a file on a remote system.

xfsdump -l 0 - /dev/mapper/centos-home | \
ssh <user>@<host> "cat - > centos-home.dump"

It's recommended to use a host on the LAN as to minimize latency. If the dump gets interrupted you can result it by adding the -R option to the command.

Another tip: use ssh key authorization so you don't have to type in a password.

Reboot Into Single-User Mode

Since you cannot resize a partition while it is mounted, and since we're resizing the /home partition, we need to reboot into single user mode and unmount /home first.

On the latest CentOS 7, you have to edit the grub entry. To do this, press the e key while your desired kernel is selected.

This will allow you to edit the invokation. To start in Single-User Mode, you have to add systemd.unit=single to the linux16 line.

linux16 /vmlinuz-3.10.0-327.4.4.el7.x86_64 root=/dev/mapper/centos-root ro rd.lvm.lv=centos/root rd.lvm.lv=centos/swap crashkernel=auto rhgb quiet LANG=en_US.UTF-8 systemd.debug systemd.log_level=debug systemd.log_target=kmsg systemd.unit=single

You can also use the equivalent parameters: s, 1, and rescue.target.

To start this configuration, press ctrl+x.

Shrink /home

When the system is booted into single-user mode, unmount /home and shrink it's logical volume.

unmount /dev/mapper/centos-home
lvresize -L -62G /dev/centos/home

In this example, we remove 62 Gigs from /home.

Reformat /home

Next, reformat the /home partition because shrinking it's logical volume actually broke the filesystem.

mkfs.xfs -f /dev/mapper/centos-home

Grow /

Now, use lvresize to grow /'s logical volume, reallocating that 62Gigs.

lvresize -l +100%FREE /dev/centos/root
xfs_growfs /

Here we simply reallocate all available extents to /. Then we grow the overlying filesystem.

Reboot

Now it is safe to reboot.

reboot

If you have a GUI installed, switch over to a different ptty by pressing ctrl+alt+F2.

Restore /home

Finally, we can restore the dump of /home we took previously. Again, we'll do it over ssh.

ssh <user>@<host> "cat centos-home.dump" | xfsrestore - /home

Now, switch back to your GUI session by pressing ctrl+alt+F1 and enjoy your new free capacity on /.