Monday July 30, 2007 at 14:41
Subject: Reducing the size of your root partition.
Keywords:
ext2, ext3, resize, Technical
Posted by: Sean Reifschneider
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:
(Post Reply)
[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 (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.
(Post Reply)
| Comment |
Pierfrancesco Marsiaj Subject: You rock! |
Thank you for your post about shrinking root partition. Indeed you saved me from driving 600 km to the place where the server I maintain is. It worked pretty straightforwardly on a Centos 5 with root on LVM.
Great post, great suggestion, very clever. I was about to give up, after almost 10 minutes the machine didn't respond to ping yet. The fact is that I resized from 250Gb to 20Gb and that took a while...
Thanks again!
Pierfrancesco
Pierfrancesco
| Comment |
Skeeter Subject: Awesome! |
This worked great..! I was a little worried to run this on my server that's far far away in another land, but it worked perfectly.
I originally tried this on my Fedora 8 box, but it was saying invalid partition size. It worked fine on my CentOS5 server.
Thanks!
| Comment |
Eric Z Subject: Segmentation fault on resize2fs |
very good idea, but on kernel 2.4 resize2fs doesn't work
[root@linux root]# ./resize2fs FATAL: kernel too old Segmentation fault
| Comment |
Jay Subject: Excellent :) |
Excellent work :) Saved me a lot o heartache!
FYI this is pretty robust, the my DC noc noticed my server down, and rebooted it midway through the process, upon reboot they noticed my rather obvious comments (added to init) spewing across the screen about resizing in progress, and contacted me to see what was going on! The process completed no problem :)
Do you happen to have a patch for resize2fs? I'd like to make a few binaries for various systems I have which have ridiculously large / filesystems.
Cheers!