Resize NVME root partition

Hi all,

I got myself one of those x86 mini-PC's with 128GB of NVMe storage. I installed latest OpenWRT on it according to instructions here:

Basically, booted from USB image of "openwrt-22.03.3-x86-64-generic-ext4-combined-efi.img",
then run

dd if=openwrt-21.02.0-x86-64-generic-ext4-combined.img bs=1M of=/dev/nvme0n1

Rebooted from HD and that's it. It works fine except for 100MB root which I would like to expand to full 100GB. .I tried to expand it by running:

parted -s /dev/sda resizepart 2 100%

It finished fine but after reboot I still have 100MB of storage (except my tmp which seems to have grown to 100GB).

DF output here:

root@OpenWrt:~# df
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/root               104788     20920     81740  20% /
tmpfs                  3998908       248   3998660   0% /tmp
/dev/nvme0n1p1           16334      5866     10468  36% /boot
/dev/nvme0n1p1           16334      5866     10468  36% /boot
tmpfs                      512         0       512   0% /dev

lsblk output:


root@OpenWrt:~# lsblk
NAME          MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
nvme0n1       259:0    0 119.2G  0 disk
âânvme0n1p1   259:1    0    16M  0 part /boot
â                                       /boot
âânvme0n1p2   259:2    0 119.2G  0 part /
âânvme0n1p128 259:3    0   239K  0 part

What am I doing wrong?

Boot from the flash drive again, change the partition size,
using fdisk(delete, create, save), then do a resize2fs and fsck.

This post is extremely helpful

OK. I got it working. I booted gparted from USB Linux, it said my partition 2 "needs fixing". I let it "fix it" and presto...100GB of root.

FAQ is not really working for NVME it seems.

There is not a whole lot special about NVME, except the device name, which isn't

but obviously /dev/nvme0n1.

This is just a typo from my side. I resized the partition with correct device. But still, it is not enough to do it, you need to fix file system for partition to be usable. It is not mentioned in FAQ so maybe it needs to be added?

If you see anything that needs to be added to or clarified in @NC1's guide, make sure to post it on the thread @d687r02j8g mentions above so it can be updated!

Indeed. :smile: I am thinking of putting out the next edition in April or maybe May (in other words, whenever I have some time to put into it). Found an interesting issue (that, upon some Googling, has apparently been around for a while), which can be easily avoided by a slightly different resizing routine.

After resizing a UEFI/SquashFS system, the boot partition fails to automount at boot (even though resizing doesn't affect it). Everything still works, routers still boot, but the boot partition is not accessible to the root user unless mounted manually.

The workaround turns out to be pretty simple: rather than edit the grub config to reflect the renaming of the root partition that happened during resizing, we can give the resized and renamed root partition its original UUID back (there are options for that in fdisk) and leave the grub config be... So I am thinking of changing to this approach and throwing out everything grub-related...

And yes, I should probably spell out more explicitly that sda is not the only naming possibility; eMMC and NVMe storage devices do go under different names... After all, I do claim to target less experienced users, for whom this would be good to know...

Guess what. My chinese miniPC NVMe died after three years, forcing me to reinstall everything from zero. And boy are NVMe drives expensive nowadays. I failed expanding ext4 file system twice, until I remembered to read my own thread. gparted "fixed" it again. What do I do with 1TB NVMe OpenWRT drive :grin: (it was all I had lying around).

I made a guide somewhere on here...

Update: Found it

cat > /tmp/resize-nvme.sh << 'EOF'
#!/bin/sh
set -e

apk update
apk add parted losetup resize2fs lsblk partx-utils

# Derive the disk and root partition from the mounted /boot, not from parted -l
BOOT=$(awk '$2=="/boot" {print $1}' /proc/mounts)
[ -n "$BOOT" ] || { echo "No /boot mount found. Aborting."; exit 1; }

DISK="/dev/$(lsblk -no PKNAME "$BOOT")"
BOOTNUM=$(echo "$BOOT" | grep -o '[0-9]*$')
PART=$((BOOTNUM + 1))
ROOT="${DISK}${PART}"
case "$DISK" in *mmcblk*|*nvme*) ROOT="${DISK}p${PART}" ;; esac

FSTYPE=$(lsblk -no FSTYPE "$ROOT" | head -n1)
echo "Disk: $DISK   Partition: $ROOT   Type: ${FSTYPE:-unknown}"
parted -s "$DISK" print || true

case "$FSTYPE" in
    ext4|squashfs) ;;
    *) echo "Unsupported filesystem '${FSTYPE:-none}' on $ROOT. Aborting."; exit 1 ;;
esac

# Bail out if there is nothing to claim (avoids a pointless table rewrite)
FREE=$(parted -sm "$DISK" unit MB print free | awk -F: '/free;$/ {gsub("MB","",$4); f=$4} END {print int(f+0)}')
if [ "${FREE:-0}" -lt 16 ]; then
    echo "Less than 16MB unallocated. Nothing to do."
    exit 0
fi
echo "Unallocated space available: ${FREE}MB"

# Repair the GPT backup header (it sits mid-disk after an image write), then grow
echo fix | parted ---pretend-input-tty "$DISK" print >/dev/null 2>&1 || true
parted -s "$DISK" resizepart "$PART" 100%

# Make the kernel re-read the table without rebooting
partx -u "$DISK" 2>/dev/null || partprobe "$DISK" 2>/dev/null || true
sleep 2

if [ "$FSTYPE" = "ext4" ]; then
    resize2fs "$ROOT"
    df -h /
    echo "Done."
    exit 0
fi

# squashfs: partition 2 is read-only, the writable overlay is a loop device
# backed by the free space inside that same partition.
LOOP=$(losetup -n -O NAME,BACK-FILE 2>/dev/null | awk -v r="$ROOT" '$2==r {print $1}' | head -n1)
if [ -z "$LOOP" ]; then
    echo "Partition grown, but the overlay loop device was not found."
    echo "Reboot and re-run this script to finish the overlay resize."
    exit 0
fi

losetup -c "$LOOP"
OVFS=$(lsblk -no FSTYPE "$LOOP" | head -n1)
echo "Overlay: $LOOP   Type: ${OVFS:-unknown}"

case "$OVFS" in
    ext4)
        resize2fs "$LOOP"
        df -h /overlay
        echo "Done."
        ;;
    f2fs)
        echo "Overlay is f2fs and cannot be grown while mounted."
        echo "Partition resize is complete and persistent."
        echo "Finish offline: boot the initramfs image, then run"
        echo "  resize.f2fs $LOOP"
        ;;
    *)
        echo "Unrecognised overlay filesystem '${OVFS:-none}'. Partition resize is complete;"
        echo "the overlay was left untouched."
        ;;
esac
EOF
chmod +x /tmp/resize-nvme.sh
sh /tmp/resize-nvme.sh