How to Move /usr Directory Contents to a Separate LVM Logical Volume
This post describes how to move the contents of /usr directory to a separate LVM Logical Volume (LV). In the following example, the contents of the standard Linux directory /usr, residing beneath the root (/) filesystem of an Oracle Linux 7 (OL) system already using LVM, is moved to a dedicated filesystem on an LVM Logical Volume (LV). Though based on CentOS/RHEL 7, the procedure should similarly work for other releases e.g. CentOS/RHEL 8.
Given the disruptive nature of the procedure, it should only be performed within Linux Rescue Mode.
1. Calculate current /usr directory disk space usage. For example:
# du -sh /usr
2. Check for available space:
# vgdisplay
# fdisk -l
If insufficient space exists within the existing system VG to accommodate a new /usr e.g. LV lv_usr, grow the VG accordingly.
3. Add a new disk or partition to the system, then initialise for use by LVM. For example:
# pvcreate /dev/sda1
4. Create/Extend a volume group:
# vgcreate vg_newVolumeName /dev/sda1
# vgextend vg /dev/sda1
5. Display Volume Group attributes and check the space available Free PE / Size:
# vgdisplay vg_VolumeName
6. Create a logical volume in vg_newVolumeName. The following creates a new 6Gb LV lv_usr within VG (adjust the size accordingly with your needs. In this case we are using 6GB as an example):
# lvcreate -L 6G --name lv_usr vg_newVolumeName
7. Create a new filesystem for LV lv_usr:
# mkfs.xfs /dev/mapper/vg_newVolumeName-lv_usr
8. Mount new LV lv_usr to a temporary directory and copy contents of /usr into it. For example:
# mkdir /tmp/usrtmp
# mount /dev/mapper/vg_newVolumeName-lv_usr /tmp/usrtmp
# rsync -avz /usr/ /tmp/usrtmp/
9. Verify the contents of LV lv_usr matches that of the /usr directory:
# diff /usr/ /tmp/usrtmp/
# ls -la /usr/
# ls -la /tmp/usrtmp/
# du /usr/
# du /tmp/usrtmp/
10. Configure the system to permanently mount LV lv_usr. Use the blkid command to identify the UUID of the new filesystem atop LV lv_usr. For example:
# blkid
Take a note for the output. Add a new mount entry to file /etc/fstab.
# vi /etc/fstab
UUID=[uuid of lv_usr] /usr xfs defaults 0 0
11. Restore SELinux Context:
# restorecon -vvFR /usr
12. Add the new VG/LV names to /etc/default/grub:
# vi /etc/default/grub
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap rd.lvm.lv=rhel/usrlv rhgb quiet"
13. Regenerate the GRUB2 configuration:
For Legacy based machines:
# grub2-mkconfig -o /boot/grub2/grub.cfg
For UEFI based machines:
# grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
14. Rebuild the initial RAM disk image file:
# cp /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.$(date +%m-%d-%H%M%S).bak
# dracut -v -f /boot/initramfs-$(uname -r).img $(uname -r)
15. Reboot the system and verify all services and applications operate correctly.
16. Once verified to work correctly, boot the system into rescue mode and remove the original /usr content.