DEV Community

Pierre Gradot
Pierre Gradot

Posted on • Edited on

Resizing Partitions on Linux

Sometimes, you need to resize your partitions on Linux. And this may not be as easy as you think...

When I installed Debian on my work computer a few months ago, the wizard suggested creating 2 separate partitions: one for root (with the OS itself), another for home (with my personal data). Alas! The suggested sizes (that I naively accepted) were highly unsuitable and a month later, the root partition (only 40 Go) was full. I had to resize them. It turns out that now, 5 months later, the home is full (I really generate a lot of data for my current project). It's time to resize my partitions again but this time I will keep track of the entire procedure in this article. Who knows when I will have to resize them one more time...

Current State and Goal

My computer as a single encrypted SSD disk:

 % lsblk
NAME                    MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINTS
nvme0n1                 259:0    0  3.6T  0 disk 
├─nvme0n1p1             259:1    0  512M  0 part  /boot/efi
├─nvme0n1p2             259:2    0  488M  0 part  /boot
└─nvme0n1p3             259:3    0  3.6T  0 part 
  └─nvme0n1p3_crypt     253:0    0  3.6T  0 crypt 
    ├─debian--vg-root   253:1    0  2.6T  0 lvm   /
    ├─debian--vg-swap_1 253:2    0  976M  0 lvm   [SWAP]
    └─debian--vg-home   253:3    0    1T  0 lvm   /home
Enter fullscreen mode Exit fullscreen mode

fdisk -l shows similar information.

As I said, my home partition is full. However, the root partition is almost empty:

 % df -h | grep debian
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/debian--vg-root  2.6T  202G  2.3T   8% /
/dev/mapper/debian--vg-home 1007G  937G   19G  99% /home
Enter fullscreen mode Exit fullscreen mode

My goal is to resize the partitions so that root is 1T and home occupies the rest of the disk. This will be a 2-step process: first, shrink root ; second, extend home.

Apparently, I can't do this from the graphical disk utility (note "Edit Partition..." and "Resize..." being greyed out):

disk utility

It's time to open a terminal and input some weird commands!

Shrinking Root

Because I want to resize the root partition, it seems that I can't directly work from my installed Debian. I put my hands back on my bootable USB drive (the one I used to install Debian in the first place) and I reboot my computer on it. It doesn't provide a live Debian mode, so I have to use the rescue mode to get a shell:

advanced option

rescue mode

Yes, I took pictures on my laptop's screen.

Once I have configured my language and keyboard layout, and skipped the network configuration, I can finally enter the rescue mode for real:

rescue mode again

I have to enter my passphrase because my disk is encrypted, and I now have a shell. Hooray!

Resizing a "partition" is not a single-step operation. Indeed, there are in fact a logical volume and a filesystem on top of it. Both need to be resized in the correct order.

First, reduce the filesystem with the resize2fs command. In this first step, I use a temporary size, not the desired size. It must be big enough to hold all the files but smaller that the desired size. The output df -h above shows that 202G are used on root. The desired size is 1T. Hence, 300G seems fine.

resize2fs /dev/mapper/debian--vg-root 300G
Enter fullscreen mode Exit fullscreen mode

I am asked to check the filesystem first with e2fsck -f /dev/mapper/debian--vg-home. Once the check and possible fixes are done, I can call resize2fs again.

Second, reduce the volume to the desired size (1T) with the lvreduce command:

lvreduce -L 1T /dev/vgroot/lvroot
Enter fullscreen mode Exit fullscreen mode

Third (and last), extend the filesystem to use the entire volume. This is done by passing only the volume to resize2fs because if the "size parameter is not specified, it will default to the size of the partition".

resize2fs /dev/vgroot/lvroot
Enter fullscreen mode Exit fullscreen mode

This is how it looks like in real life:

commands in shell

Note that step 3 may be performed directly in step 2, because lvreduce has an option that seems to do it:

-r, --resizefs
Resize underlying filesystem together with the logical volume using fsadm.

To be honest, I wasn't really keen to try on my work computer, I can't afford any data loss. So I stuck a procedure that I knew to work, but I encourage you to test it 😅

Checking Root

Now, I shut down my computer, I remove the USB drive, I reboot to my actual system, and I'm glad to see that it still works 😄

I can check the state of my disk:

 % df -h | grep mapper
/dev/mapper/debian--vg-root 1008G  202G  756G  22% /
/dev/mapper/debian--vg-home 1007G  937G   19G  99% /home

 % lsblk
NAME                    MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINTS
nvme0n1                 259:0    0  3.6T  0 disk  
├─nvme0n1p1             259:1    0  512M  0 part  /boot/efi
├─nvme0n1p2             259:2    0  488M  0 part  /boot
└─nvme0n1p3             259:3    0  3.6T  0 part  
  └─nvme0n1p3_crypt     253:0    0  3.6T  0 crypt 
    ├─debian--vg-root   253:1    0    1T  0 lvm   /
    ├─debian--vg-swap_1 253:2    0  976M  0 lvm   [SWAP]
    └─debian--vg-home   253:3    0    1T  0 lvm   /home
Enter fullscreen mode Exit fullscreen mode

The root partition is fine. Of course, the home partition is unchanged. Let's resize it now.

Extending Home

This time, I don't need to boot on my USB drive.

First, extend the volume with the lvextend command. I don't have to calculate the remaining size, I just ask to add 100% of the free space of the disk to the volume:

 % sudo lvextend -l +100%FREE /dev/mapper/debian--vg-home      
  Size of logical volume debian-vg/home changed from 1.00 TiB (262144 extents) to <2.64 TiB (691219 extents).
  Logical volume debian-vg/home successfully resized.
Enter fullscreen mode Exit fullscreen mode

Note that the option is -l (lowercase) not -L (uppercase), unlike with lvreduce.

Second (and last), resize the filesystem to use the entire volume (same as last operation for root):

 % sudo resize2fs /dev/mapper/debian--vg-home
resize2fs 1.47.0 (5-Feb-2023)
Filesystem at /dev/mapper/debian--vg-home is mounted on /home; on-line resizing required
old_desc_blocks = 128, new_desc_blocks = 338
The filesystem on /dev/mapper/debian--vg-home is now 707808256 (4k) blocks long.
Enter fullscreen mode Exit fullscreen mode

Checking Home

Finally, I have reached my goal:

 % df -h | grep mapper                       
/dev/mapper/debian--vg-root 1008G  202G  756G  22% /
/dev/mapper/debian--vg-home  2.6T  937G  1.6T  37% /home

 % lsblk                                           
NAME                    MAJ:MIN RM  SIZE RO TYPE  MOUNTPOINTS
nvme0n1                 259:0    0  3.6T  0 disk  
├─nvme0n1p1             259:1    0  512M  0 part  /boot/efi
├─nvme0n1p2             259:2    0  488M  0 part  /boot
└─nvme0n1p3             259:3    0  3.6T  0 part  
  └─nvme0n1p3_crypt     253:0    0  3.6T  0 crypt 
    ├─debian--vg-root   253:1    0    1T  0 lvm   /
    ├─debian--vg-swap_1 253:2    0  976M  0 lvm   [SWAP]
    └─debian--vg-home   253:3    0  2.6T  0 lvm   /home
Enter fullscreen mode Exit fullscreen mode

Conclusion

I have to be honest, it was quite scary to resize partitions 😱 Of course, I backed up my important data, but I can't really back up a full system with all the installed tools and settings I have as a software developer on my machine.

At the end of the day, I left this uncomfortable situation:

Before:

 % df -h | grep mapper       
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/debian--vg-root  2.6T  202G  2.3T   8% /
/dev/mapper/debian--vg-home 1007G  937G   19G  99% /home
Enter fullscreen mode Exit fullscreen mode

And I have reached with much more cozy one:

 % df -h | grep mapper                       
/dev/mapper/debian--vg-root 1008G  202G  756G  22% /
/dev/mapper/debian--vg-home  2.6T  937G  1.6T  37% /home
Enter fullscreen mode Exit fullscreen mode

I hope this was the last time I had to resize my partitions on this computer! 😁

Top comments (2)

Collapse
 
ferdnyc profile image
Frank Dana • Edited

A few thoughts.

Root is still way over-allocated

My goal is to resize the partitions so that root is 1T and home occupies the rest of the disk.

...First off: Why? By which I mean, why waste a full terabyte on the root partition? It's only using 202GB right now. How much bigger do you expect it to grow???

Data is consumed on Linux filesystems in the user space — the home partition. The root partition might grow slightly over time, but once the system has been up and running and all of the software you need is installed, it's unlikely to experience significant growth beyond its current size. If your root partition is currently 202GB, 250GB is the maximum I'd allocate to it, because it's unlikely to grow beyond that.

You say, "I hope this was the last time I had to resize my partitions on this computer!", but by continuing to waste almost 800GB of empty space on a root allocation, you're making it more likely that it won't be the last time. Eventually, you'll probably want more of that space for home.

Counter-intuitively, it's a mistake to fully allocate an LVM volume-group up front

As you've seen, shrinking logical volumes is a pain in the neck. But growing them is a simple, convenient, on-demand action that can be performed at any time — online, without even unmounting the partition! Heck, you can grow a logical volume while you're actively hammering it with data transfers, and the only consequence will be that both operations take slightly longer to complete.

Because LVM offers on-demand, near-instant ad-hoc growth, the best way to manage volume allocations is to wait until you need the space. You say,

the wizard suggested to create 2 separate partitions: one for root (with the OS itself), another for home (with my personal data). Alas! the suggested sizes (that I naively accepted) were highly unsuitable and a month later, the root partition (only 40 Go) was full. I had to resize them.

...The mistake you made originally wasn't accepting the wizard's recommendation of a 40GB root partition, it was giving the entire rest of the disk to the home partition.

You're working with a 3.6TB physical volume. If it were me, I'd initially have accepted that 40GB root allocation, and allocated maybe a 1TB home. I'd have left the rest of the space in the volume group completely unallocated.

Then, when the root proved far too small, I'd simply have allocated another 100GB to it with sudo lvresize -r -L +100G debian-vg/root.

When the first 1TB of /home filled up, sudo lvresize -r -L +500G debian-vg/home to give it more wiggle room. When that runs out, just do it again.

If you start with reasonable size allocations and leave yourself lots of unallocated extents in the volume group, you can let the logical volumes grow gradually and organically as they fill up their current allocations.

The absolute worst position to be in is the one you've set up at every point in this process: fully-allocating your volume group so it's depleted of unallocated extents. Until you hit that point (which you should try to hold off as long as humanly possible), LVM's dynamically-allocated extent mapping is incredibly flexible. Once it's fully allocated, you've basically given up almost every advantage LVM has over dumb, pre-LVM static partitioning.

ALWAYS use the -r option to lvresize (or lvextend / lvreduce, but who uses those anymore?)

You say you're wary of it, I'm telling you: Do not be. Rely on it. There's no reason to ever fiddle with manual resize2fs runs to make partitions fit inside logical volumes. Just let LVM resize the partition to fit the logical volume at every step along the way.

And when growing LVs into unallocated extents, it reduces the entire operation to a single, atomic lvresize command.

Collapse
 
pgradot profile image
Pierre Gradot

Hello

Thanks for your enlightening comment.

1/Root is still way over-allocated

How much bigger do you expect it to grow???

I don't know. How could you know? 3 months later, I now have:

 % df -h /dev/mapper/debian--vg-root
Filesystem                   Size  Used Avail Use% Mounted on
/dev/mapper/debian--vg-root 1008G  341G  616G  36% /
Enter fullscreen mode Exit fullscreen mode

I may be able to make some cleanup to regain some space, but I don't want to do this kind of cleanup often if I can afford to do occasionally (or at least, to afford to delay the moment where I will have to understand what this cleanup would be).

1T was probably too much. However, 250G would have been too little. Maybe 500G could be a good point.

2/ Counter-intuitively, it's a mistake to fully allocate an LVM volume-group up front

I like the approach you are showing. Next time I set up a new machine, I will try it.

The mistake you made originally wasn't accepting the wizard's recommendation of a 40GB root partition, it was giving the entire rest of the disk to the home partition.

I have just run Debian installer inside a VM to see again how the wizard proposes to arrange the disk. At some point, you have to choose between "Use entire disk" or "Manual". If you select the first option, you are then asked if you want a separate partition for /home. If you don't know your proposed approach, well, you end up with the rest of the disk for the home partition.

I have been wondering whether having a separate partition for /home was even a good idea. What is your opinion in this?

3/ ALWAYS use the -r option to lvresize

You say you're wary of it, I'm telling you: Do not be. Rely on it.

I was already convinced to use it next time. Thank you for reassuring me, though :D