Skip to content

Instantly share code, notes, and snippets.

@jornane
Created October 23, 2017 12:12
Show Gist options
  • Save jornane/71edf07363706898bc78cf2032b124b2 to your computer and use it in GitHub Desktop.
Save jornane/71edf07363706898bc78cf2032b124b2 to your computer and use it in GitHub Desktop.
How to grow a partition in Linux

How to grow a partition in Linux

This guide will walk you through the steps required to grow a partition in Linux. You will have to reboot through this guide.

  1. If possible, make a snapshot.

Often, you will want to grow the partition table because you made your virtual hard disk too small, and you tried to extend it in your hypervisor, only to find out that your partition is still the same size as it was before.

This process should be completely safe, but just make a snapshot anyway. Since you're probably on a hypervisor, making a snapshot is easy and cheap. Do it.

  1. Use gdisk(8) to grow your partition table (fdisk can't)

     % sudo gdisk /dev/sda
     GPT fdisk (gdisk) version 1.0.1
    
     Partition table scan:
       MBR: protective
       BSD: not present
       APM: not present
       GPT: present
    
     Found valid GPT with protective MBR; using GPT.
    
     Command (? for help): w
     Warning! Secondary header is placed too early on the disk! Do you want to
     correct this problem? (Y/N): Y
     Have moved second header and partition table to correct location.
    
     Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
     PARTITIONS!!
    
     Do you want to proceed? (Y/N): Y
     OK; writing new GUID partition table (GPT) to /dev/sda.
     Warning: The kernel is still using the old partition table.
     The new table will be used at the next reboot or after you
     run partprobe(8) or kpartx(8)
     The operation has completed successfully.
    

You don't have to reboot. Yet...

  1. Take note of your existing partition

     % sudo gdisk /dev/sda
     GPT fdisk (gdisk) version 1.0.1
    
     Partition table scan:
       MBR: protective
       BSD: not present
       APM: not present
       GPT: present
    
     Found valid GPT with protective MBR; using GPT.
    
     Command (? for help): p
     Disk /dev/sda: 629145600 sectors, 300.0 GiB
     Logical sector size: 512 bytes
     Disk identifier (GUID): 81E5985B-444C-4D94-80D5-C5B863B4F400
     Partition table holds up to 128 entries
     First usable sector is 34, last usable sector is 204799966
     Partitions will be aligned on 8-sector boundaries
     Total free space is 2015 sectors (1007.5 KiB)
    
     Number  Start (sector)    End (sector)  Size       Code  Name
        1            2048            4096   1024.5 KiB  EF02  primary
        2            4098       204799966   97.7 GiB    8E00  primary
    
     Command (? for help): d
    

You must write down (or keep in our scrollback) that our partition has Start sector 4098 and Code 8E00. You will need these values later on.

  1. Use gdisk(8) to grow your partition (fdisk can, but gdisk is better)

Here you will remove the partition and re-create it using a new Last sector, which is bigger than the previous.

When being asked for the Last sector, simply press Enter to get the largest value.

WARNING If you get the message Information: Moved requested sector, STOP WHAT YOU ARE DOING, PRESS ^C IMMEDIATELY. Read further ahead.

Command (? for help): d
Partition number (1-2): 2

Command (? for help): n
Partition number (2-128, default 2): 2
First sector (34-629145566, default = 4097) or {+-}size{KMGTP}: 4098
Last sector (4098-629145566, default = 629145566) or {+-}size{KMGTP}: 629143552
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): 8E00
Changed type of partition to 'Linux LVM'

Command (? for help): p
Disk /dev/sda: 629145600 sectors, 300.0 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 81E5985B-444C-4D94-80D5-C5B863B4F400
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 629145566
Partitions will be aligned on 1-sector boundaries
Total free space is 4029 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048            4096   1024.5 KiB  EF02  primary
   2            4098       629143552   300.0 GiB   8E00  Linux LVM

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sda.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.
  1. Reboot your machine

As gdisk already told you, the kernel is still using the old partition table. Since there are mounted filesystems on it, it refuses to reload it, so you'll have to reboot. This is safe to do if you've completed step 4 without writing any number wrong. 😈

  1. Resize your filesystem

When you've booted back into your system, you'll notice that you can't utilize your newly created space. You must tell your filesystem explicitly to do so.

If you use LVM (after this you must still resize the actual filesystem):

pvresize /dev/sda2
lvextend -l 100%VG /dev/mapper/root

If you use ext234 (use the /dev/mapper thingy if it's under LVM):

resize2fs /dev/sda2

If you use XFS (use the /dev/mapper thingy if it's under LVM):

xfs_growfs /dev/sda2

Information: Moved requested sector

If you get the Information: Moved requested sector message, STOP.

Check your numbers. Did you make a typo? That's okay. As long as you don't write using w nothing bad has happened yet. Abort with ^C. Start again.

If your numbers DO match, you have a strange partition setup. This may happen especially if you didn't install Linux by hand, but used some orchestrator to make your life easier. All magic has a price, and now you must pay.

gdisk will not allow you to set the partition back the way it was, because in 99.98% of all cases it would be a REALLY BAD IDEA™ to do so. But you're different. Lucky you. Especially for snowflakes like you, gdisk has so-called extra functionality or expert menu. Here, you can set gdisk's sector alignment value, which really just means that every sector must be dividable by this number. For modern harddisks, this number is 2048.

We will set the sector alignment value to 1 (one), since every integer is dividable by one, it will allow you to set any weird number you want.

% sudo gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.1

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): x

Expert command (? for help): l
Enter the sector alignment value (1-65536, default = 2048): 1

Expert command (? for help): m

Don't quit gdisk now, or you'll have to do these steps again.

From here, you can use gdisk as usual, so now you can continue where step 4 left off. You should NOT get the Information: Moved requested sector message this time.

@Mezzano
Copy link

Mezzano commented Mar 29, 2020

Hi, I read that you say that fdisk can't grow a partition table.
I've indeed been trying to extend my existing physical disk which is divided in 29 partitions, when I try to add a new one I get :
Command (m for help): n
No free partition available!
Any idea how to proceed without installing gdisk?

@jornane
Copy link
Author

jornane commented Apr 2, 2020

Any idea how to proceed without installing gdisk?

I haven't tried this, but one thing I can think of is jotting down the partition table that fdisk shows you, then re-initializing the partition table and creating all partitions anew. This may be especially hard if you have 29 partitions, and even harder if you use MBR style (instead of GPT), because then you use an extended partition as well. You can dig a very deep hole for yourself there. I'd use gdisk.

You may also check out sfdisk, I think I used it to dump the partition table to some text file (using --dump) that I was able to edit and then write back (just pipe it back). I think it doesn't work for GPT, but works for MBR.

@Mezzano
Copy link

Mezzano commented Apr 3, 2020

Thanks jornane but it's a remote upgrade and I need to keep the partition with the rootfs on it. I've used sfdisk but I get same problem, and by the way it does work with GPT. At the moment, I'm using gdisk but need to install it first what I wanted to avoid.

@jstrot
Copy link

jstrot commented Jan 1, 2021

Thanks for the detailed instructions. Personally, I started by making a backup of the partition table to a file using gdisk's b (backup) command. It can be loaded back using the l (load) option from gdisk's recovery menu in case of a snafu.

I ended up not using the gdisk delete/new method as it would have changed my partition's GUID and then it would have required a fixup.

Another method which resizes in place without changing the GUID is possible using the parted utility:

$ sudo parted /dev/sdh
GNU Parted 3.3
Using /dev/sdh
Welcome to GNU Parted! Type 'help' to view a list of commands.

Make sure to set units to sectors to get the most accurate values:

(parted) unit s

Print the partitiion table including free spaces:

(parted) print free
Model: ATA ST4000VN008-2DR1 (scsi)
Disk /dev/sdh: 7814037168s
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start        End          Size         File system  Name        Flags
        34s          2047s        2014s        Free Space
 1      2048s        5860533134s  5860531087s               Linux RAID  raid
        5860533135s  7814037134s  1953504000s  Free Space

Now you can use the end sector of the free space as reference for your new partition end:

(parted) resizepart 1 7814037134s

Check and quit:

(parted) print free
Model: ATA ST4000VN008-2DR1 (scsi)
Disk /dev/sdh: 7814037168s
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start  End          Size         File system  Name        Flags
        34s    2047s        2014s        Free Space
 1      2048s  7814037134s  7814035087s               Linux RAID  raid

(parted) quit
Information: You may need to update /etc/fstab.

Voilà! Partition resized in place.

Cheers

@damag
Copy link

damag commented Apr 12, 2022

Hi, thanks for these instructions. Just wanted to add that you can avoid the reboot by using partprobe to inform the kernel of the partition table changes:

partprobe /dev/sda

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment