21

On Linux I used to resize MBR partitions using fdisk, even on live filesystems, and then issue a resize2fs/pvresize/... (depending on fs type) to get the new space allocated.

Lately I've been using Xen and GPT partitions, and I've noticed that unfortunately parted doesn't seem to allow on-the-fly resizing of a mounted partition, in fact it will complain:

Error: Partition XXX is being used. You must unmount it before you modify it with Parted.

I've tried both the resize command and even rm + mkpart combination, but they will both complain about the partition being mounted.

How can I do that?

2
  • A way available out of the box on RHEL/CentOS would be highly appreciated
    – cyberz
    Oct 27, 2013 at 9:23
  • Re "resize": Implied making them larger, not smaller? Mar 5, 2023 at 13:24

8 Answers 8

21
+50

The safest way to do this is to boot using an emergency medium (a live CD or the like) and use GParted, which will resize both the partition and the filesystem it contains. This will work only if the partition is not currently being used, though.

If you can't afford any downtime, though, you could try using gdisk instead of parted. You'll need to delete the partition you want to resize and create a new one in its place with the same start point, much as you'd have done with fdisk. gdisk is willing to work on an in-use disk, although the kernel might not register any changes. In that case, you may need to use partprobe or kpartx to get the kernel to accept the new partition table, or even reboot the computer if that doesn't work. (This should all be pretty similar to using fdisk.)

6
  • Looks nice, but is not included by default on CentOS. Any more standard ways? I mean, a redhat-like system should be able to self resize without relying on external programs
    – cyberz
    Oct 19, 2013 at 15:30
  • 2
    There is no tool that ships with CentOS that will do the job. You must go out of the CentOS repository to do what you want. Note that almost all other distributions (including Fedora) include gdisk in their repositories, and I've heard that gdisk will be included in the next version of RHEL (and therefore of CentOS).
    – Rod Smith
    Nov 3, 2013 at 14:19
  • Thank you for the answer and the comment, it's exactly the information i was looking for
    – cyberz
    Nov 3, 2013 at 14:33
  • 1
    gdisk is available in EPEL.
    – jornane
    Aug 27, 2014 at 17:17
  • I tried both partx and partprobe but eventually had to reboot. Thank you anyway for those tips Jan 7, 2017 at 11:50
23

This usually only works with more recent Linux distributions. Tools needed:

  • partprobe (usually part of parted)
  • gdisk / sgdisk

A GPT partition stores a backup header at the end of the disk. If you have resized the underlying device, the backup header will be somewhere in the middle. The first step is to move the partition header to the end of the disk.

Assuming the disk is /dev/sda and the partition is /dev/sda3 (must also be the last partition):

sgdisk -e /dev/sda

Then delete, the last partition and re-create it:

sgdisk -d 3 /dev/sda
sgdisk -N 3 /dev/sda

You'll usually see a message indicating that the kernel is unable to re-load the partition table. You have to run partprobe so the partition is registered with the new size:

partprobe /dev/sda

If this is unsuccessful, you'll have to reboot the virtual machine. After that you can grow your filesystem with the appropriate tool, for ext4 etc.:

resize2fs /dev/sda3

Caution: running sgdisk can be destructive. Make sure you have proper backup procedures in place.

3
  • Awesome! Thanks especially for the partprobe step - I always thought it is necessary to reboot when altering partition table with any mounted partitions.
    – piit79
    Feb 8, 2018 at 8:40
  • 3
    Keep in mind that destroying and recreating the partition will generate a new PARTUUID for the partition, which is otherwise the only reliable and filesystem-independent way for fstab/GRUB/etc to reliably identify partitions in multi-disk setups. Dec 26, 2018 at 19:22
  • does not work at all. always losing the filesystem, even keeping the uniq GUID. w writes a new partition overwriting the old fs signature
    – sgohl
    Apr 6, 2021 at 23:08
6

Here's an example that an automated tool uses to resize a partition online, in one run:

sgdisk -d 1 -n 1:2048:0 -c 1: -u 1:E485F29F-A1F4-4953-9DD8-799EAEA0119B -t 1:0700 /dev/xvda

Here's list of options to sgdisk command:

  • -d 1 delete's first partition
  • -n 1:2048:0 says create new partition "number 1", with starting sector 2048. End sector = "0" which means "use all available space for this partition
  • -u sets unique guid for that partition (this is specific for GPT partitions); you could use 'R' for GUID to be set to a random value. You could also get current partitions's id through gdisk /dev/xvda; p output to reuse the same uid
  • -t 1:0700 basically means first partition is of typecode '0700'.

/dev/xvda was the disk which we repartitioned.

So it deletes and creates a new partition on its place right away.

PS. A few notes on typecode '0700'. From man SGDISK(8)

   -t, --typecode=partnum:{hexcode|GUID}
          Change a single partition's type  code.  You  enter  the  type  code  using  either  a  two-byte  hexadecimal  number,  as 

described earlier, or a fully-specified GUID value, such as EBD0A0A2-B9E5-4433-87C0-68B6B72699C7.

Found best explanation for what '0700' means here - http://www.rodsbooks.com/gdisk/walkthrough.html

"But wait," you say, "I thought the disk had a FAT partition!" Indeed it does. Windows uses a single GUID code for all its data partitions, be they FAT or NTFS. In the past, the same code has been used in Linux for its data partitions. (More on this shortly....) Thus, in this case several different MBR codes are all translated into a single GPT GUID code. GPT fdisk uses, somewhat arbitrarily, the 0x0700 code (or more precisely, EBD0A0A2-B9E5-4433-87C0-68B6B72699C7) for all of these.

In my case I believe that was a Linux ext4 partition, but partition's typecode doesn't mean filesystem type, so '0700' looks more like a catchall type for sgdisk. At least in cases I've seen.

PPS. You may need to run partprobe for kernel to become aware of the partitioning change without rebooting system.

1
  • 'p' will show you the UUID of the disk. 'i' will show you the UUID of a partition.
    – Keith
    Mar 21, 2019 at 16:22
3

I'm just summarising some answers and comments here:

parted will simply refuse to change any mounted partition. gdisk will do the job for you, but it is not in the standard RHEL or CentOS repository. It is in the EPEL repository, though.

Keep in mind that changing partitions on a disk that is in use might prevent the kernel from registering the changes. If that happens, use partprobe, partx or reboot.

3

This worked for me (Ubuntu 20.04) without data loss:

Extend the GPT to the new drive size

# sgdisk -e /dev/sdX

Rescan the partition tables

# partprobe /dev/sdX

Resize the partition

# cgdisk /dev/sdX

cgdisk has a command-line Curses interface where you can navigate with the arrow keys to the partition you want and select 'Resize'. Then 'Write' the partition table and 'Quit'

Resize the filesystem

# resize2fs /dev/sdX3

if it's partition #3 and used directly or, if it's LVM and you want it to take all the spare space:

# pvresize /dev/sdX3
# lvextend -l 100%VG /dev/mapper/your_vg-lv_name
# resize2fs /dev/mapper/your_vg-lv_name

where your_vg-lv_name is created by the Ubuntu installer by default as ubuntu--vg-ubuntu--lv

2

Are you asking about resizing a logical volume? Here is how I would do it:

vgextend vgname /dev/sdb3
lvextend -L +3T /dev/mapper/location
resize2fs /mount/point

OR (xfs):

xfs_growfs /mount/point -D <bytes>
2
  • he probably not using ext2/ext3/ext4, otherwise resize2fs should work on the fly ?
    – user218473
    Nov 3, 2013 at 3:05
  • 1
    @Antony Lee: if you pass -r to lvextend, then it invokes resize2fs for you.
    – jmtd
    Mar 13, 2015 at 15:02
2

See Expand virtual hard disks on a Linux VM.

In my case, growpart expanded a disk without restarting the VM. My Linux VM is on GCP, its OS is CentOS 7, and the file system is XFS.

I hope this would help GCP users.

  1. Increase the disk size in the GCP console.

  2. Install growpart.

    sudo yum install cloud-utils-growpart
    
  3. Check the partition.

    lsblk -f
    sudo gdisk -l /dev/sda
    
  4. Expand the partition. Use a proper partition number. In my case, I should expand /dev/sda2.

    sudo growpart /dev/sda 2
    
  5. Confirm the partition has been expanded.

    sudo gdisk -l /dev/sda
    
  6. Expand the file system. I should expand root.

    sudo xfs_growfs /
    
  7. Confirm the file system has been expanded.

    df -h
    

With this way, I could expand my file system without stopping my service.

1
  • before using growpart,"echo 1 | tee /sys/class/block/sda/device/rescan" to make os update disk size Jul 27, 2023 at 10:21
1

fdisk is typically still available and can do this, if the partition is the last partition and the start of the partition isn't moving.

However, this is a dangerous operation that should be done with great care. Make a backup!

ec2-user@ip-10-0-20-15 ~]$ sudo fdisk /dev/nvme0n1

Welcome to fdisk (util-linux 2.30.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/nvme0n1: 24 GiB, 25769803776 bytes, 50331648 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 70E4A118-98BD-4BF4-8DF9-6926A964902A

Device           Start      End  Sectors Size Type
/dev/nvme0n1p1    4096 16777182 16773087   8G Linux filesystem
/dev/nvme0n1p128  2048     4095     2048   1M BIOS boot

Partition table entries are not in disk order.

Command (m for help): d
Partition number (1,128, default 128): 1

Partition 1 has been deleted.

Command (m for help): n
Partition number (1-127, default 1): 1
First sector (34-50331614, default 4096):
Last sector, +sectors or +size{K,M,G,T,P} (4096-50331614, default 50331614):

Created a new partition 1 of type 'Linux filesystem' and of size 24 GiB.
Partition #1 contains a xfs signature.

Do you want to remove the signature? [Y]es/[N]o: n

Command (m for help): p

Disk /dev/nvme0n1: 24 GiB, 25769803776 bytes, 50331648 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 70E4A118-98BD-4BF4-8DF9-6926A964902A

Device           Start      End  Sectors Size Type
/dev/nvme0n1p1    4096 50331614 50327519  24G Linux filesystem
/dev/nvme0n1p128  2048     4095     2048   1M BIOS boot

Partition table entries are not in disk order.

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Re-reading the partition table failed.: Device or resource busy

The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8).

[ec2-user@ip-10-0-20-15 ~]$ sudo partprobe

[ec2-user@ip-10-0-20-15 ~]$ sudo fdisk -l
Disk /dev/nvme0n1: 24 GiB, 25769803776 bytes, 50331648 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 70E4A118-98BD-4BF4-8DF9-6926A964902A

Device           Start      End  Sectors Size Type
/dev/nvme0n1p1    4096 50331614 50327519  24G Linux filesystem
/dev/nvme0n1p128  2048     4095     2048   1M BIOS boot

Partition table entries are not in disk order.

[ec2-user@ip-10-0-20-15 ~]$ sudo xfs_growfs /
meta-data=/dev/nvme0n1p1         isize=512    agcount=4, agsize=524159 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1 spinodes=0
data     =                       bsize=4096   blocks=2096635, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 2096635 to 6290939
```

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .