Why XFS File System Cannot be Shrunk Directly?
Why cannot we just lvreduce XFS file system? A quote from Red Hat official document talking about XFS space management may explain the whole thing.
XFS is a highly scalable, high-performance file system which was originally designed at Silicon Graphics, Inc. XFS is the default file system for Red Hat Enterprise Linux 7....
After an XFS file system is created, its size cannot be reduced. However, it can still be enlarged using the xfs_growfs command (refer to Section 6.4, “Increasing the Size of an XFS File System”).
lvreduce XFS?
It's true, but the scalability of XFS is only for scaling up, not for scaling down. What if we need to shrink a mount point which was mis-allocated with too much space (I know this would rarely happen on most production environments). Can we just reclaim some space back? The answer is No and Yes.
The "No" is that we cannot reduce XFS logical volume (LV) directly just by handy lvreduce or something else. The "Yes" is that we can work around it, but the approach might be a little tricky.
If your file systems are formatted as any of legacy ext series, you may refer to the post below for resolutions: How to Reduce Logical Volume Size on Linux
Steps to Shrink XFS File System
Let's start our tutorial.
1. Create a file for verifying after reducing XFS size
Log in server as a normal user, i.e. scott in this case.
[scott@test ~]$ pwd
/home/scott
[scott@test ~]$ vi Hello
Hello, world!
[scott@test ~]$ ll
total 4
-rw-rw-r--. 1 scott scott 14 Mar 24 00:03 Hello
[scott@test ~]$ exit
2. Check current status
Let's see the space usage.[root@test ~]# df -h | grep home
/dev/mapper/centos_example-home 188G 33M 188G 1% /home
[root@test ~]# vgs
VG #PV #LV #SN Attr VSize VFree
centos_example 1 3 0 wz--n- 239.51g 64.00m
[root@test ~]# lvdisplay
...
--- Logical volume ---
LV Path /dev/centos_example/home
LV Name home
VG Name centos_example
LV UUID
LV Write Access read/write
LV Creation host, time test.com, 2016-03-21 08:27:22 -0400
LV Status available
# open 1
LV Size 187.45 GiB
Current LE 47986
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:2
You can see that /home is taking too much free space without using it. We need to shrink this XFS logical volume /dev/centos_example/home.
[root@test ~]# mount | grep home
/dev/mapper/centos_example-home on /home type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
See? It's a XFS LV mounted. Since XFS does not allow to shrink its size, so we need a strategy to workaround this. Of course, we don't want to reinstall OS. Here is my plan in short:
- Backup the data
- Remove current LV
- Create a smaller LV
- Restore the data
Let's see how far we can go.
3. Install XFS backup utilities
The best tool to backup XFS file system is xfsdump. Since there's no xfsdump in CentOS 7.2 minimal, so we have to install it by ourselves. First of all, let's see what is xfsdump.
[root@test ~]# yum info xfsdump
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: ftp.ksu.edu.tw
* epel: mirror01.idc.hinet.net
* extras: ftp.ksu.edu.tw
* updates: centos.cs.nctu.edu.tw
* webtatic: sp.repo.webtatic.com
Available Packages
Name : xfsdump
Arch : x86_64
Version : 3.1.4
Release : 1.el7
Size : 307 k
Repo : base/7/x86_64
Summary : Administrative utilities for the XFS filesystem
URL : http://oss.sgi.com/projects/xfs/
License : GPL+
Description : The xfsdump package contains xfsdump, xfsrestore and a number of
: other utilities for administering XFS filesystems.
:
: xfsdump examines files in a filesystem, determines which need to
: be backed up, and copies those files to a specified disk, tape or
: other storage medium. It uses XFS-specific directives for
: optimizing the dump of an XFS filesystem, and also knows how to
: backup XFS extended attributes. Backups created with xfsdump are
: "endian safe" and can thus be transfered between Linux machines of
: different architectures and also between IRIX machines.
:
: xfsrestore performs the inverse function of xfsdump; it can
: restore a full backup of a filesystem. Subsequent incremental
: backups can then be layered on top of the full backup. Single
: files and directory subtrees may be restored from full or partial
: backups.
Install xfsdump package which also includes xfsrestore
[root@test ~]# yum -y install xfsdump
Loaded plugins: fastestmirror
base | 3.6 kB 00:00
epel/x86_64/metalink | 5.2 kB 00:00
extras | 3.4 kB 00:00
mysql-connectors-community | 2.5 kB 00:00
mysql-tools-community | 2.5 kB 00:00
mysql57-community | 2.5 kB 00:00
updates | 3.4 kB 00:00
webtatic | 3.6 kB 00:00
updates/7/x86_64/primary_db | 3.2 MB 00:20
Loading mirror speeds from cached hostfile
* base: ftp.ksu.edu.tw
* epel: mirror01.idc.hinet.net
* extras: ftp.ksu.edu.tw
* updates: centos.cs.nctu.edu.tw
* webtatic: us-east.repo.webtatic.com
Resolving Dependencies
--> Running transaction check
---> Package xfsdump.x86_64 0:3.1.4-1.el7 will be installed
--> Processing Dependency: attr >= 2.0.0 for package: xfsdump-3.1.4-1.el7.x86_64
--> Running transaction check
---> Package attr.x86_64 0:2.4.46-12.el7 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
xfsdump x86_64 3.1.4-1.el7 base 307 k
Installing for dependencies:
attr x86_64 2.4.46-12.el7 base 66 k
Transaction Summary
================================================================================
Install 1 Package (+1 Dependent package)
Total download size: 373 k
Installed size: 1.1 M
Downloading packages:
(1/2): attr-2.4.46-12.el7.x86_64.rpm | 66 kB 00:00
(2/2): xfsdump-3.1.4-1.el7.x86_64.rpm | 307 kB 00:02
--------------------------------------------------------------------------------
Total 145 kB/s | 373 kB 00:02
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : attr-2.4.46-12.el7.x86_64 1/2
Installing : xfsdump-3.1.4-1.el7.x86_64 2/2
Verifying : attr-2.4.46-12.el7.x86_64 1/2
Verifying : xfsdump-3.1.4-1.el7.x86_64 2/2
Installed:
xfsdump.x86_64 0:3.1.4-1.el7
Dependency Installed:
attr.x86_64 0:2.4.46-12.el7
Complete!
4. Backup the XFS file system
We backup the XFS file system to a regular file in the root directory / which will stay everything unchanged in this tutorial. The -l option specifies a dump level (0-9). To perform a full backup, use 0. The -f option specifies the destination of target and source, the format is:
[root@test ~]# xfsdump -l 0 -f /home.image /dev/centos_example/home
xfsdump: using file dump (drive_simple) strategy
xfsdump: version 3.1.4 (dump format 3.0) - type ^C for status and control
============================= dump label dialog ==============================
please enter label for this dump session (timeout in 300 sec)
-> 20160324-dump
session label entered: "20160324-dump"
--------------------------------- end dialog ---------------------------------
xfsdump: level 0 dump of test.com:/home
xfsdump: dump date: Thu Mar 24 00:06:49 2016
xfsdump: session id: 7fe1566a-de11-45f2-93c5-85a9b4725a27
xfsdump: session label: "20160324-dump"
xfsdump: ino map phase 1: constructing initial dump list
xfsdump: ino map phase 2: skipping (no pruning necessary)
xfsdump: ino map phase 3: skipping (only one dump stream)
xfsdump: ino map construction complete
xfsdump: estimated dump size: 20800 bytes
xfsdump: /var/lib/xfsdump/inventory created
============================= media label dialog =============================
please enter label for media in drive 0 (timeout in 300 sec)
-> home-old
media label entered: "home-old"
--------------------------------- end dialog ---------------------------------
xfsdump: creating dump session media file 0 (media 0, file 0)
xfsdump: dumping ino map
xfsdump: dumping directories
xfsdump: dumping non-directory files
xfsdump: ending media file
xfsdump: media file size 21352 bytes
xfsdump: dump size (non-dir files) : 0 bytes
xfsdump: dump complete: 20 seconds elapsed
xfsdump: Dump Summary:
xfsdump: stream 0 /home.image OK (success)
xfsdump: Dump Status: SUCCESS
Let's see the dump file.
[root@test ~]# ll /home.image
-rw-r--r--. 1 root root 21352 Mar 24 00:07 /home.image
5. Remove the source LV
We should umount the file system before doing anything on the LV.
[root@test ~]# umount /dev/centos_example/home
Use lvremove to delete the LV.
[root@test ~]# lvremove /dev/centos_example/home
Do you really want to remove active logical volume home? [y/n]: y
Logical volume "home" successfully removed
[root@test ~]# vgs
VG #PV #LV #SN Attr VSize VFree
centos_example 1 2 0 wz--n- 239.51g 187.51g
As you can see, the space is released.
6. Create a new LV
Use lvcreate to create a 10GB with the same name.
[root@test ~]# lvcreate -L 10G -n home centos_example
WARNING: xfs signature detected on /dev/centos_example/home at offset 0. Wipe it? [y/n]: y
Wiping xfs signature on /dev/centos_example/home.
Logical volume "home" created.
The signature is replaced with the new one. Let's see the current status of VG and LV.
[root@test ~]# vgs
VG #PV #LV #SN Attr VSize VFree
centos_example 1 3 0 wz--n- 239.51g 177.51g
[root@test ~]# lvdisplay
...
--- Logical volume ---
LV Path /dev/centos_example/home
LV Name home
VG Name centos_example
LV UUID
LV Write Access read/write
LV Creation host, time test.com, 2016-03-24 00:10:45 -0400
LV Status available
# open 0
LV Size 10.00 GiB
Current LE 2560
Segments 1
Allocation inherit
Read ahead sectors auto
- currently set to 8192
Block device 253:2
There's a 10GB taken by the new LV. Now, we have to format the new LV in XFS by mkfs.xfs before actually mounting on /home.
[root@test ~]# mkfs.xfs /dev/centos_example/home
meta-data=/dev/centos_example/home isize=256 agcount=4, agsize=655360 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0
data = bsize=4096 blocks=2621440, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
Mount the LV to /home.
[root@test ~]# mount /dev/centos_example/home /home
List the content of /home.
[root@test ~]# ll /home
total 0
Of course, nothing in the /home, because we have not restored the data yet.
7. Restore data back to the new and smaller XFS file system
[root@test ~]# xfsrestore -f /home.image /home
xfsrestore: using file dump (drive_simple) strategy
xfsrestore: version 3.1.4 (dump format 3.0) - type ^C for status and control
xfsrestore: searching media for dump
xfsrestore: examining media file 0
xfsrestore: dump description:
xfsrestore: hostname: test.com
xfsrestore: mount point: /home
xfsrestore: volume: /dev/mapper/centos_example-home
xfsrestore: session time: Thu Mar 24 00:06:49 2016
xfsrestore: level: 0
xfsrestore: session label: "20160324-dump"
xfsrestore: media label: "home-old"
xfsrestore: file system id: 091dc119-8bae-42ac-a725-4a79196398c9
xfsrestore: session id: 7fe1566a-de11-45f2-93c5-85a9b4725a27
xfsrestore: media id: d07cadad-8e5e-4767-bf52-e256dc060e5d
xfsrestore: using online session inventory
xfsrestore: searching media for directory dump
xfsrestore: reading directories
xfsrestore: 1 directories and 0 entries processed
xfsrestore: directory post-processing
xfsrestore: restore complete: 1 seconds elapsed
xfsrestore: Restore Summary:
xfsrestore: stream 0 /home.image OK (success)
xfsrestore: Restore Status: SUCCESS
Check the /home.
[root@test ~]# ll /home
total 0
drwx------. 2 scott scott 71 Mar 24 00:01 scott
[root@test ~]# df -h | grep home
/dev/mapper/centos_example-home 10G 33M 10G 1% /home
[root@test ~]# mount | grep home
/dev/mapper/centos_example-home on /home type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
So far so good, we have the content back to /home. But I have a question now: Can it survive through reboots? Let's continue.
[root@test ~]# init 6
8. Verify the data after reducing XFS LV size
Log in server as scott and verify the file.
[scott@test ~]$ ll
total 4
-rw-rw-r--. 1 scott scott 14 Mar 24 00:03 Hello
[scott@test ~]$ cat Hello
Hello, world!
We did it!
Thank a lot, this article helped me solve my swap size issue.
You’re welcome!
Thanks, Ed. Great article
My pleasure!
This is a perfect example of how to document something. Successfully resized /home and / on RHEL 8 with this. Thank you very much.
Thank you! I’m glad it’s helpful.
Totally agree, very well written. Are you able to advise how you resized the root / ? Did you need to do this from a rescue image?
Thank you! I haven’t resized root directories before, but I think it could be more complicated than the above case.
I reduced the size of the / with the help of this article and some adaptations, I used a CentOS7. Here are commands without details:
Add a new disk (or use a disk with free space, I’m using a VM)
Boot in Rescue Mode com access to shell
vgchange -ay
Obs: Identify the name of the VG and LV that we will use in the next steps
pvcreate /dev/”new device” (step 1)
vgcreate vg_backup /dev/”new device 1″
lvcreate -L 10GB -n lv_backup vg_backup
mkdir /mnt/root_old
mkdir /mnt/root_new
mkfs.xfs /dev/vg_backup/lv_backup
mount /dev/”namevgOld”/”namelvOld-root” /mnt/root_old
mount /dev/vg_backup/lv_backup /mnt/root_new
echo “Arquivo teste OK” > /mnt/root_old/teste
xfsdump -l 0 -f /mnt/root_new/root.image /dev/”namevgOld”/”namelvOld-root”
ls -lh /mnt/root_new/root.image (check size of file…)
umount /mnt/root_old
lvremove /dev/”namevgOld”/”namelvOld-root”
lvcreate -L “10GB” -n root NameVgOld
mkfs.xfs /dev/NameVgOld/root
mount /dev/”namevgOld”/”namelvOld”-root /mnt/root_old
xfsrestore -f /mnt/root_new/root.image /mnt/root_old
cat /mnt/root_old/teste to check restore sucess
reboot
Finish
Very valuable information. Thanks a lot!
masterful work. straight forward.
Thanks! I’m so glad it’s helpful to you.
Hi,
How did you unmount the /?
Thanks, I had to resize a CentOS 7 partition to make it accessible from CentOS 6, and this guide was perfect 🙂
You’re welcome, I’m glad it’s helpful.
This article helped me resize my xfs lv.
Thanks very much
Hi, Its a Nice Article. Its Helped Me!!!
Thank You So Much!!!:)
You’re welcome.
Hello,
do you have any idea how to do something similar for /usr partition?
Very nicely explained and perfect. Thank you.
My pleasure!
Thank a lot, Great article! I joined the procedures you mentioned with rescue mode and managed to reduce /.
My pleasure!
Hi Ed,
I have reduced an xfs file system using xfsdump, lvreduce and xfsrestore.
Now, I am trying to create a new volume and xfs file system in the same volume group (using the space freed up by earlier steps), and get a warning similar to following:
WARNING: xfs signature detected on /dev/centos_example/home at offset 0. Wipe it? [y/n]: y
What will be the impact of y or n answer on existing LV and file system? Pl. note that I need to ensure that creating a new LV and xfs file system doesn’t destroy existing xfs on a different LV in the same VG.
Thank you in advance.
I don’t know about that, I think you can try this in lab.
Ed,
Thanks for the help. Beautifully documented. Take the rest of the day off. Tell them I said it was ok! 😉
I once worked with an Ed Chen, in Oundle. I don’t suppose the world is so small that you’re him?
Anyway. Thanks for the help!
I might not be the one you thought. Anyway, it’s truly a small world.
Great !! This article is very simple and precise explained. Thank you very much!
It’s my pleasure!
Thank-you Ed Chen. If i could put a wizard’s hat on you, I would. Not only do you know the tech, but you can teach too. A *rare* combination indeed. A superb job documenting the steps to accomplish the objective!
Thanks, that’s really kind of you.