57

Long story short, I need to perform this all automatically on boot (embedded system).

Our engineers will flash images to production devices. These images will contain a small partition table. On boot, I need to automatically expand the last partition (#3) to use all the available space on the disk.

Here is what I get when I look at the free space on my disk.

> parted /dev/sda print free
Model: Lexar JumpDrive (scsi)
Disk /dev/sda: 32.0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name     Flags
        17.4kB  1049kB  1031kB  Free Space
 1      1049kB  25.3MB  24.2MB  fat16        primary  legacy_boot
        25.3MB  26.2MB  922kB   Free Space
 2      26.2MB  475MB   449MB   ext4         primary
 3      475MB   1549MB  1074MB  ext4         primary
        1549MB  32.0GB  30.5GB  Free Space

I need to expand partition 3 by N (30.5GB) number of bytes

How do I perform this step automatically, with no prompt? This needs to work with a dynamic size of space available after the 3rd partition.

Paul Knopf
  • 1,231
  • Dont expect to receive a ready to go script, without a try! So can you show to us what did you try until now? Another thing the partition that you are resizing must be not mounted during the operation.... – Luciano Andress Martini Jun 23 '17 at 20:22
  • I have tried resizepart command, and it works, but it requires an exact size. I need it to be dynamic. – Paul Knopf Jun 23 '17 at 20:28
  • resize2fs might be what I am looking for. https://linux.die.net/man/8/resize2fs – Paul Knopf Jun 23 '17 at 20:29

10 Answers10

76

Being unable to properly script parted (it asked for confirmation because the partition was mounted and contrary to other answers I found did not understand -1s or 100%), I just found the growpart tool which does exactly this.

Usage is simple: growpart /dev/sda 3 (and then resize2fs /dev/sda3, or another appropriate command for the used filesystem type).

In Debian and Ubuntu it is packaged as cloud-guest-utils.

Ivo Smits
  • 861
  • 11
    This is the most convenient way I could find for this right now. It worked wonderfully. – SebiF Sep 13 '18 at 19:16
  • This was the solution for me - parted didn't like ext4 as the file system, and there seemed to be no way of avoiding it attempting resizing the file system... – Antti Haapala Feb 13 '19 at 14:00
  • 1
    not working for Ubuntu 18.04 – dreamflasher Apr 23 '19 at 12:39
  • @DreamFlasher I can't tell why it did not work for you. As far as I can see you can just install the cloud-guest-utils package and since this is the only function provided by growpart it should work unless there's a bug, it's used incorrectly or something out of its control is going wrong. Note that the last argument (3 in the example) is the partition to be resized, counting from 1, and that sufficient space needs to be available right after the partition to be able to resize it this way. – Ivo Smits Apr 24 '19 at 17:26
  • This is the answer. So simple, and growpart is installed by default on ubuntu 21. – jonesy19 May 31 '21 at 12:19
  • I didn't like piping arguments to fdisk and parted wasn't installed on my image. growpart was installed and I'm in love with it! Thanks for introducing this tool to us. – Pavin Joseph Oct 03 '21 at 17:59
  • I'd guess if this didn't work it's because you're trying to resie an "extended" partition beyond the bounds of its "primary" partition. In my case, I need to grow /dev/sda2 before growing /dev/sda5 – Auspex Mar 10 '22 at 13:00
43

In current versions of parted, resizepart should work for the partition (parted understands 100% or things like -1s, the latter also needs -- to stop parsing options on the cmdline). To determine the exact value you can use unit s, print free. resize2fs comes afterwards for the filesystem.


Old versions of parted had a resize command that would resize both partition and filesystem in one go, it even worked for vfat.

In a Kobo ereader modification I used this to resize the 3rd partition of internal memory to the maximum: (it blindly assumes there to be no 4th partition and msdos table and things)

start=$(cat /sys/block/mmcblk0/mmcblk0p3/start)
end=$(($start+$(cat /sys/block/mmcblk0/mmcblk0p3/size)))
newend=$(($(cat /sys/block/mmcblk0/size)-8))

if [ "$newend" -gt "$end" ]
then
    parted -s /dev/mmcblk0 unit s resize 3 $start $newend
fi

So you can also obtain the values from /sys/block/.../ if the kernel supports it. But parted removed the resize command so you have to do two steps now, resizepart to grow the partition, and whatever tool your filesystem provides to grow that, like resize2fs for ext*.

frostschutz
  • 48,978
  • Side question, what's with the 8 bytes at the end? – Paul Knopf Jun 24 '17 at 23:11
  • Avoid resizing by a single sector... you'd have to change that to -40 or something (GPT backup header at end of disk). – frostschutz Jun 25 '17 at 01:29
  • Does parted not support automatic extension from the command line? Because, it does support it interactively. If run interactively, it'll ask if you want to fix the GPT partition table to match the size of the disk (type fix), and then you can run resizepart 3 -1. I've been trying to figure out how to get it to do that from the command line. – Harvey Oct 09 '17 at 21:10
  • 1
    Not so fast: The resize command has been removed in parted 3.0. Try sfdisk or gparted. – GregD Mar 14 '18 at 02:14
  • Changed this answer script to oneliner: BDn=sda && BDPn=sda2 && GAPin4K=2540 && BD=/sys/block/$BDn && BDP=$BD/$BDPn && BDPs=$(($(cat $BD/size)-$(cat $BDP/start)-$GAPin4K*8)) && [[ $BDPs -gt $(($(cat $BDP/start)+$(cat $BDP/size))) ]] && parted -s /dev/$BDn unit s resizepart $(cat $BDP/partition) $BDPs. First three variables are the parameters (changing 3rd parameter is optional): BDn - device name; BDPn - patition name; GAPin4K - trailing gap size in 4k blocks (default is leaving 10MB unpatitioned). It does exactly what what requested in the question. Tested. – dess Aug 23 '19 at 12:28
  • 7
    For those looking for the actual resizepart command, I think this is what the OP had in mind: sudo parted /dev/mmcblk0 resizepart 3 100% where /dev/mmcblk0 is the drive and 3 is the partition. – Heath Raftery May 12 '20 at 10:48
17

The right way to do this is use the fact that parted has the notion of percentages. So

parted /dev/sda resize 3 100%
10

In Ubuntu 18.04, I am able to resize to fill unallocated space in a script with the following:

sudo parted -s /dev/sdb "resizepart 2 -1" quit
sudo mount -av
sudo umount /dev/sdb2
sudo mount /dev/sdb2 /mnt
sudo resize2fs /dev/sdb2

It may not be necessary to mount before resizing. I did it to suppress a query from resize2fs for user input.

jesse_b
  • 37,005
5

Alternatively, you can do a one liner with sfdisk:

echo ", +" | sfdisk -N 3 /dev/sda

See Karel Zak's blog post for more details.

Mansour
  • 261
1

i know the question mentioned using parted, but here is a bash script using fdisk and resize2fs.

I use it on Raspberry Pi, but you can use it anywhere those 2 tools are available, just change the target disk (sda, sdb, ...).

Always be careful while manipulating partitions: you might end up breaking your system !

#!/bin/bash

This bash script extends the last partition of the specified disk

To the maximum size available.

target disk

disk='mmcblk0'

get last partition

part=$(grep "${disk}" /proc/partitions | tail -1 | awk '{print $4}' | xargs) partN=$(echo $part | tail -c 2)

fdisk: delete and recreate the last partition with the largest size possible.

( echo d # Delete partition echo $partN # Last partition echo n # Add a new partition echo p # Primary partition echo $partN # Last partition echo # First sector (Accept default: 1) echo # Last sector (Accept default: varies) echo w # Write changes ) | fdisk /dev/$disk

update filesystem to match new partition size

resize2fs /dev/$part

maige
  • 11
1

Just to summarize a few of the comments into a method: (for in my case sda2)

parted /dev/sda resizepart 2 100%

resize2fs /dev/sda2

Hayden Thring
  • 242
  • 1
  • 14
1

2023/2024's solution for Ubuntu 22.04 LTS:

# Boot into Ubuntu Live CD
sudo parted /dev/sda print free
sudo parted /dev/sda resizepart 2 100%
sudo e2fsck -f /dev/sda2
sudo resize2fs /dev/sda2
1

The latest version Parted 3.6 released April 2023. To this day the behavior described across all these various stack exchange threads still hasn't been fixed or improved with many examples from the past decade now non-working due to changes over the years.

I frequently find myself increasing the size of virtual disks for virtual machines I support and trying to make parted do this automatically is still very finicky.

Given I have to do this often enough that I don't want to have to type commands into each machine I've come up with the below example to aid me through 2024:

# Set the disk and partition number
export disk=/dev/sda part=3
# Inform the system of the disk's new block count
echo 1 > /sys/class/block/${disk//*\/}/device/rescan
# Have parted update the GUID Partition Table to use all raw disk space
yes Fix | parted --script --fix ${disk} print
# Have parted expand the target partition
yes | parted ---pretend-input-tty ${disk} resizepart ${part} 100%
# Make the filesystem aware of its newfound partition size.
resize2fs ${disk}${part}

The above also works perfectly as a one-liner for ssh'ing into the remote hosts in say, a for-loop. It also seems to work perfectly with Saltstack's cmd.run module against a glob of minions all at once.

Making sure to change the variables a one-liner version of this looks like: export disk=/dev/sda part=3 ; echo 1 > /sys/class/block/${disk//*\/}/device/rescan ; yes Fix | parted --script --fix ${disk} print ; yes | parted ---pretend-input-tty ${disk} resizepart ${part} 100% ; resize2fs ${disk}${part}

iPaq
  • 11
-3

In the short video step-by-step tutorial "How to Resize a Live Filesystem on Linux" is shown, how to achieve this a very simple way. I've just extended the /dev/sda2 on a VirtualBox VM after resizing the VDI (virtual hard drive). It works pretty well:

  1. Back up the data.
  2. Start fdisk: sudo fdisk /dev/sda.
  3. Print the partitions: p.
  4. Delete the partition, you want to resize (it's a kind of unlinking, the data is not removed): d. If you have multiple partitions, you'll be asked, which one should be deleted.
  5. Create a new partition: n. Follow the dialog for setting the partition type, the partition number, the first sector, and the last sector. The last two parameters define the size of the new partition. By default the space between the first and the last sector will cover the complete available free space. The last option: Choose whether the signature should be removed.
  6. See the changes (and compare the result with the state before): p.
  7. Save the changes and quit fdisk: w (use q to exit without saving).
automatix
  • 199