I recently had a system that is quite a long distance from me that I needed to reduce the root file-system size on. To make matters worse, the IP KVM is having more than a few issues, so booting into rescue mode was not really an option. I wanted to just put “e2fsck” and “resize2fs” into the init scripts, but the system init scripts are called after the partition is mounted. Here's what I did…
resize2fs can increase the size of a mounted partition, but not reduce it. Shrinking a file-system must be done while the file-system is unmounted. This is pretty common restriction.
The initrd is run extremely early on in the boot process, and is responsible for the initial mounting of the root partition. This can be modified to run the file-system resize before mounting the partition. However, there are a few tricks.
First of all, I first set up a staging system that mimics the remote system, and ran all of my testing on that. My first attempts didn't quite work out, though none of them left the system dead in the water.
The first thing you have to do is make a backup copy of the initrd, and then extract the initrd so you can make changes to it:
[root@trac1 ~]# cp /boot/initrd-2.6.18-8.1.8.el5.img \ /boot/initrd-2.6.18-8.1.8.el5.img.orig [root@trac1 ~]# cd /tmp [root@trac1 tmp]# mkdir init [root@trac1 tmp]# cd init [root@trac1 init]# gunzip </boot/initrd-2.6.18-8.1.8.el5.img | cpio -id cpio: : No such file or directory 14968 blocks [root@trac1 init]# cp /sbin/e2fsck bin [root@trac1 init]#
The last step copies “e2fsck” into the “bin” directory.
You will also need “resize2fs”, but there are a couple of problems with the system resize2fs. First of all, it is not built static. Worst though, it is unhappy running from the initrd because it can't find out of the file-system you are trying to resize is mounted. I grabbed the SRPM for resize2fs and made a modified resize2fs that's built static and skips the mounted partition check (No longer available for download).
Once you have that extracted, you need to look at the “init” file in the top level directory. You will need to insert some lines after the “mkrootdev” command, before the “Mounting root filesystem” line. The device you use should be the same as that used in the “mkrootdev” line, and probably will be different from here:
[...] echo Creating root device. mkrootdev -t ext3 -o defaults,ro /dev/vg00/sys_root # ADD THE FOLLOWING LINES echo Resizing root device. e2fsck -fy /dev/vg00/sys_root resize2fs -p /dev/vg00/sys_root 20G echo sleeping... sleep 30 # END OF ADDED LINES echo Mounting root filesystem. mount /sysroot [...]
In this case we are asking for the file-system to be resized down to 20GB. Change “20G” to whatever you would like. The “sleep” command will make it easier to see any output if it errors out.
Now, re-create the initrd file with the following command:
find ./ | cpio -H newc -o | \ gzip -9 >/boot/initrd-2.6.18-8.1.8.el5.img
Use the correct name of the initrd file which you backed up above. Note that this will overwrite the existing initrd file.
Now reboot, and during the boot it should run an fsck, then run the resize.
After the system boots the root device should be around the size you specified in the resize2fs above. You will need to move the .orig initrd file back over the one that you created above, or it will run the fsck and resize on every subsequent reboot.
Finally, resize the partition the file-system is on. If this was a regular partition, you will probably have to delete it and create it smaller. If it's an LVM as above, you can just use “lvreduce” to shrink it. I always shrink the partition to well above the size of the file-system, then use the online ext2 resize to increase it back up. This way I never have to worry about incorrect math resulting in the end of the file-system getting cut off. In my example above, I then resized the partition to 22GB, then ran “resize2fs /dev/vg00/sys_root” and it will figure out the real partition size and expand the file-system to fill the partition.
Note that if you are using a real partition you probably want to reboot after changing the partition size but before telling ext2resize to expand the file-system. Unlike with LVM, the kernel may still have an idea of the size of the partition which is much larger than it is after a reboot.comments powered by Disqus