Shrinking root LV on-line

Nuu.. not so on-line. Any reduction requires unmounting the file system before shrinking. The problem with file systems, such as /, /var, /usr, is that you can not unmount them on a live system, so there's no easy way to reduce them.

The usual solution for this problem is to boot from the Live or Rescue CD, and then resize the LV.

In this example, we will try to do this on a live system without using additional boot media. To do this, we will create an LV mirror, then break it, make the desired changes in the LV clone, rename the result, and finally reboot the computer to start using the corrected LV. Of course, some files will be not up to date on our clone, but this can be ignored, since the system's FS content is almost static. If this is important for you, go to the classic model and boot from Live or Rescue media. Even so, you can follow this procedure to be sure that you have the original untouched LV and you can boot your computer in any case.

Make root LV mirrored

I will reduce the root LV on my laptop to release 2g. This amount will not change the situation with the disk usage on my laptop. It's just to demonstrate this procedure. The initial situation was this:

# df /
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/rootvg-fc26   12G  9.2G  2.5G  79% /

Convert the root LV to be mirrored:

# lvconvert --type mirror --alloc anywhere -m1 -b /dev/rootvg/fc26

It takes some time, you can check progress with the command

# lvs -a
  LV              VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log         Cpy%Sync Convert
 ..
  fc26            rootvg mwi-aom---  12.00g                                [fc26_mlog] 23.83
  [fc26_mimage_0] rootvg Iwi-aom---  12.00g                                                            
  [fc26_mimage_1] rootvg Iwi-aom---  12.00g                                                            
  [fc26_mlog]     rootvg lwa-aom---   4.00m                                                            
 ..

In the meantime, let's check the GRUB configuration.

/boot/grub2/grub.cfg

Most likely, you have /boot as a separate first partition, and your grub.cfg file looks like this:

 ..
menuentry 'Fedora 26 (Workstation Edition)' --class fedora --class gnu-linux --class gnu --class os --unrestricted
$menuentry_id_option 'gnulinux-4.13.10-200.fc26.x86_64-advanced-db8f3983-326e-4126-bb7b-7612e99aa659' {
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_msdos
        insmod ext2
        set root='hd0,msdos1'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1
--hint='hd0,msdos1'  2d303076-6349-4e06-93fa-54e96b757726
        else
          search --no-floppy --fs-uuid --set=root 2d303076-6349-4e06-93fa-54e96b757726
        fi
        linux16 /vmlinuz-4.13.10-200.fc26.x86_64 root=/dev/mapper/rootvg-fc26 ro ipv6.disable=1 rd.shell
        initrd16 /initramfs-4.13.10-200.fc26.x86_64.img
}
 ..

In this case, the GRUB bootloader will look for its files, the kernel itself and the initrd on the first partition, and if it does not find it there, it will scan everything that is available to find the UUID file system. The only thing related to the root LV is the name, and since we will rename it as needed, we do not need any changes to grub.cfg.

However, it is possible that your /boot is part of / (how this can be possible?) , then your grub.cfg may looks like:

 ..
menuentry 'Fedora (4.11.5-200.fc25.x86_64) 25 (Twenty Five)' --class fedora --class gnu-linux
--class gnu --class os --unrestricted $menuentry_id_option
'gnulinux-4.11.5-200.fc25.x86_64-advanced-8a988bbc-ae0c-4031-b494-47ec547fccde' {
        load_video
        set gfxpayload=keep
        insmod gzio
        insmod part_gpt
        insmod lvm
        insmod xfs
        set root='lvmid/tdBs7T-BM2b-A1e1-6hBU-f2ta-deYo-pTJxzB/ejNHG1-VyOb-JKtz-lBCF-BdJs-8jej-tRs4ce'
        if [ x$feature_platform_search_hint = xy ]; then
          search --no-floppy --fs-uuid --set=root
--hint='lvmid/tdBs7T-BM2b-A1e1-6hBU-f2ta-deYo-pTJxzB/ejNHG1-VyOb-JKtz-lBCF-BdJs-8jej-tRs4ce'
8a988bbc-ae0c-4031-b494-47ec547fccde
        else
          search --no-floppy --fs-uuid --set=root 8a988bbc-ae0c-4031-b494-47ec547fccde
        fi
        linux16 /boot/vmlinuz-4.11.5-200.fc25.x86_64 root=/dev/mapper/fedora-root ro
rd.lvm.lv=fedora/root rd.lvm.lv=fedora/swap rhgb quiet LANG=en_US.UTF-8
        initrd16 /boot/initramfs-4.11.5-200.fc25.x86_64.img
}
 ..

As you can see, GRUB will look for FS UUID that resides on the LV UUID belonging to the VG UUID. As a result of the mirror FS UUID will be the same (good). The cloned LV will belong to the same VG (excellent). After the mirror break, we will get a new LV UUID (bad). In this case, you need to fix grub.cfg. Duplicate the entry and correct the LV UUID for what the lvdisplay command will shows.

Breaking mirror and resize

Meanwhile, our mirror becomes completely synchronized

# lvs -a
  LV              VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log         Cpy%Sync Convert
 ..
  fc26            rootvg mwi-aom---  12.00g                                [fc26_mlog] 100.00
  [fc26_mimage_0] rootvg iwi-aom---  12.00g                                                            
  [fc26_mimage_1] rootvg iwi-aom---  12.00g                                                            
  [fc26_mlog]     rootvg lwa-aom---   4.00m                                                            
 ..
and we can begin to break mirror:
# lvconvert --splitmirrors 1 --name fc26small /dev/rootvg/fc26
  Logical volume rootvg/fc26 converted.
# lvs
  LV          VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
 ..
  fc26        rootvg -wi-ao----  12.00g                                                    
  fc26small   rootvg -wi-a-----  12.00g                                                    
 ..

Now that we have a full copy of LV, we can do whatever we want with it

# e2fsck -f /dev/rootvg/fc26small
e2fsck 1.43.4 (31-Jan-2017)
/dev/rootvg/fc26small: recovering journal
Clearing orphaned inode 525211 (uid=0, gid=0, mode=0100644, size=10406312)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
Free blocks count wrong (227043, counted=668193).
Fix<y> yes
Free inodes count wrong (541671, counted=541697).
Fix<y> yes

/dev/rootvg/fc26small: ***** FILE SYSTEM WAS MODIFIED *****
/dev/rootvg/fc26small: 244735/786432 files (0.5% non-contiguous), 2477535/3145728 blocks
# resize2fs /dev/rootvg/fc26small 10000m
resize2fs 1.43.4 (31-Jan-2017)
Resizing the filesystem on /dev/rootvg/fc26small to 2560000 (4k) blocks.
The filesystem on /dev/rootvg/fc26small is now 2560000 (4k) blocks long.
# lvresize -L10g /dev/rootvg/fc26small
  WARNING: Reducing active logical volume to 10.00 GiB.
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce rootvg/fc26small? [y/n]: y
  Size of logical volume rootvg/fc26small changed from 12.00 GiB (3072 extents) to 10.00 GiB (2560 extents).
  Logical volume rootvg/fc26small successfully resized.
# resize2fs /dev/rootvg/fc26small       
resize2fs 1.43.4 (31-Jan-2017)
Resizing the filesystem on /dev/rootvg/fc26small to 2621440 (4k) blocks.
The filesystem on /dev/rootvg/fc26small is now 2621440 (4k) blocks long.

I'm not very good with all this calculation of blocks, so I make the FS a little less than LV, and then expand it to fill the LV till the end.

Renaming and reboot

This is probably the most dangerous part. First, fix grub.conf if necessary. Then rename LVs:

# lvrename /dev/rootvg/fc26 /dev/rootvg/fc26big
  Renamed "fc26" to "fc26big" in volume group "rootvg"
# lvrename /dev/rootvg/fc26small /dev/rootvg/fc26
  Renamed "fc26small" to "fc26" in volume group "rootvg"

Renaming takes place online and is harmless. Now reboot the system. (Sec., I need to save this file and close other windows).

OK, I am back with the following sutiation:

# df /
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/rootvg-fc26  9.8G  9.2G  543M  95% /
# lvs
  LV          VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
 ..
  fc26        rootvg -wi-ao----  10.00g                                                    
  fc26big     rootvg -wi-a-----  12.00g                                                    
 ..

You do not need the old root LV fc26big anymore and it can be removed:

# lvremove /dev/rootvg/fc26big
Do you really want to remove active logical volume rootvg/fc26big? [y/n]: y
  Logical volume "fc26big" successfully removed

HAPPY SHRINKING !!


Updated on Thu Nov 9 20:06:41 IST 2017 More documentations here