ImmortalWrt Storage Expansion and Partitioning Guide
This guide answers the three questions that usually get mixed together:
- Are you running an
ext4image or asquashfsimage? - Should you expand the root partition, create a separate data partition, or use
extroot? - Which commands are safe to run directly, and when should you stop and inspect first?
Read this page first if any of these apply:
git clonefails because storage is too small- you plan to install iStore, OpenClash, quickstart, or many other packages
- backup archives, rule files, or repositories keep growing
- you are not sure whether
/overlayshould be touched
Start with the conclusion
On Raspberry Pi, the safe path usually depends on the image type:
- If the system already boots as an
ext4root filesystem and you want many plugins, expand the root partition. - If the system is
squashfs + overlayand you mainly need room for repositories, archives, or large files, create a separate data partition.
extroot is not the default answer. It only makes sense on the squashfs path and only after you confirm that this is really your layout.
Step 1: identify your current system type
Run:
mount
df -h
block info
- If you see an
ext4root filesystem
If the output looks like:
/dev/root on / type ext4
your system is using:
- an
ext4image - a root partition mounted directly on
/ - packages, configs, and plugins written directly to that root partition
In this case, when space is tight, the preferred path is:
expand the root partition, not /overlay and not extroot.
- If you see
squashfs + overlay
If the output looks like:
overlayfs:/overlay on / type overlay
your system is using:
- a
squashfsimage - a read-only system layer
- a writable layer mounted at
/overlay
In this case:
- choose a data partition first if you only need more storage
- choose
extrootonly when/overlayitself is too small for packages
Quick glossary
If terms such as rootfs, /overlay, or extroot slow you down, read this section first. If you already know them, you can jump straight to Step 2.
- Partition
A TF card is one physical storage device. A partition splits it into logical areas, for example p1 for boot files, p2 for the operating system, and p3 for your own data.
- Filesystem
A partition is only a chunk of space until it is formatted. Common filesystems on ImmortalWrt include ext4 and vfat.
- Mounting
Mounting attaches a partition to a directory in the system tree. For example, if you mount /dev/mmcblk0p3 to /srv/storage, then /srv/storage becomes the entry point to that partition.
rootfs
rootfs is the filesystem that provides the root directory /.
/overlay
/overlay is the writable layer commonly used by squashfs images. Many package installs and configuration changes end up there.
extroot
extroot does not simply add another partition. It means moving the writable layer of a squashfs system to a larger ext4 partition, which is why it is more sensitive than creating a separate data partition.
Step 2: choose the route before you run mkfs
| Goal | Current system | Recommended path | Beginner-safe |
|---|---|---|---|
Install many plugins and make / much larger | ext4 root filesystem | Expand root partition p2 | Yes |
| Store repositories, backup archives, and large files | squashfs or ext4 | Create a data partition and mount it at /srv/storage | Yes |
Increase writable package space on a squashfs image | squashfs + overlay | extroot | No, advanced only |
Route A: expand the ext4 root partition
Use this path when:
- you flashed an
ext4image mountshows/dev/root on / type ext4- you plan to install iStore, OpenClash, quickstart, Git, and other packages
In practice, if you are already on an ext4 root filesystem, this is usually the most direct and stable route.
Advantages:
- simpler layout
- easier to reason about during boot
- no need to introduce
extroot - a better fit for plugin-heavy Raspberry Pi setups
Follow this route in order. Do not skip straight to partition changes.
- Back up first, and clear stale mount settings.
Run:
sysupgrade -b /boot/pre-expand-$(date +%F).tar.gz
uci delete fstab.overlay 2>/dev/null
uci commit fstab
/etc/init.d/fstab restart
Why:
- the first command creates a config backup
- the next commands remove stale
extrootsettings so the router does not try to mount/overlayincorrectly on the next boot
- Then install the required tools.
First identify your OpenWrt branch:
OpenWrt 24.10 and earlier stable releases: useopkgOpenWrt 25.12 and newer: useapk
For 24.10 and earlier:
opkg update
opkg install parted losetup resize2fs blkid e2fsprogs
For 25.12 and newer:
apk update
apk add parted losetup resize2fs blkid e2fsprogs
- Then confirm the current partition layout.
parted -l -s
If you see something like:
Number Start End Size Type File system Flags
1 4194kB 71.3MB 67.1MB primary fat16 boot, lba
2 75.5MB 390MB 315MB primary ext4
and the total disk size is much larger than p2, there is unallocated space available for expansion.
- Once you confirm expansion is possible, choose offline or online.
If you can power off and move the TF card to another computer, offline expansion is the safer method.
Recommended flow:
- power off and remove the TF card
- open it in
GParted,DiskGenius, or an equivalent partition tool - select
mmcblk0p2 - extend it to near the end of the card
- apply the change and eject the card safely
- boot the Raspberry Pi again
- then run:
e2fsck -f /dev/mmcblk0p2
resize2fs /dev/mmcblk0p2
df -h
If you must do it online, the OpenWrt official expansion script is the safer software path:
cd /root
wget -U "" -O expand-root.sh "https://openwrt.org/_export/code/docs/guide-user/advanced/expand_root?codeblock=0"
. ./expand-root.sh
sh /etc/uci-defaults/70-rootpt-resize
This normally happens in stages:
70-rootpt-resize: expand the root partition first, then trigger an automatic reboot80-rootfs-resize: after the system comes back, resize the ext4 filesystem, and it may reboot once more if needed
Before you run it, make sure:
- power is stable
- you are not gambling on an unattended remote site
- you already have a backup
There are a few details here that matter a lot:
- If the SSH session drops soon after
sh /etc/uci-defaults/70-rootpt-resize, and the router reboots automatically, that is usually normal. - Do not assume failure just because the first
df -hafter reconnect still shows a few hundred MB. Online expansion is staged, and partition expansion does not always finish at the exact same moment as filesystem expansion. - The safer way to judge the result is: wait for the reboot to finish, log in again, check
parted -l -sfirst, and then checkdf -h. Ifp2has already grown to the end of the card but/dev/rootis still small, run:
sh /etc/uci-defaults/80-rootfs-resize
reboot
- If
70-rootpt-resizedoes not trigger a reboot andparted -l -sstill shows the old partition size, do not guess that it "probably worked". Check dependencies, marker files, and the actual partition state first:
type parted losetup resize2fs blkid
parted -l -s
ls -l /etc/uci-defaults/70-rootpt-resize /etc/uci-defaults/80-rootfs-resize /etc/rootpt-resize /etc/rootfs-resize 2>/dev/null
- Verify the result before moving on.
Run:
mount
df -h
block info
If you used the online method, read the result in this order as well:
parted -l -s: confirm thatmmcblk0p2has grown close to the end of the carddf -h: confirm that/dev/roothas actually become largermountandblock info: confirm that the root partition is still mounted correctly asext4
Success usually looks like:
/dev/root on / type ext4/is now much larger, often close to the full SD card size
Example:
Filesystem Size Used Available Use% Mounted on
/dev/root 29.3G 114.5M 29.2G 0% /
After verification, it is reasonable to continue with:
cd /root
git clone https://github.com/Ronchy2000/Immortalwrt-AutoBackup.git
and then install iStore, OpenClash, quickstart, and similar packages.
Suggested order:
- confirm
df -hshows the larger root filesystem - configure Git and backups first
- install iStore and the rest afterwards
- create a backup before major changes
Route B: create a data partition and mount it at /srv/storage
Use this path when:
- the main shortage is repository space, backup space, or large-file space
- you do not want to change the root filesystem layout
- you want Git repos, archives, and large rule files to live in a separate area
This route is for the case where you want to leave the system layout alone and move repositories, backups, and large files elsewhere.
If your situation looks more like:
git clonedoes not fit- automatic backup archives keep growing
- rules, downloads, or media consume space
this route is usually more stable than extroot.
This route should also be done in order. Do not start by running mkfs.ext4.
- Inspect the current state first.
Run:
mount
df -h
block info
uci show fstab
parted -l -s
If you discover:
mmcblk0p3already exists- or
mkfs.ext4warnscontains a ext4 file system labelled 'overlay'
stop there. Do not format the partition until you confirm whether it is already used by the system.
- Only after that should you install the required tools.
First identify your OpenWrt branch:
OpenWrt 24.10 and earlier stable releases: useopkgOpenWrt 25.12 and newer: useapk
For 24.10 and earlier:
opkg update
opkg install block-mount kmod-fs-ext4 e2fsprogs fdisk cfdisk
For 25.12 and newer:
apk update
apk add block-mount kmod-fs-ext4 e2fsprogs fdisk cfdisk
- Then create the partition.
cfdisk /dev/mmcblk0
Steps:
- select
Free space - choose
[ New ] - enter the size you want
- keep the type as
Linux - choose
[ Write ] - type
yes - choose
[ Quit ]
Assume the new partition is:
/dev/mmcblk0p3
- Format it and test-mount it first.
umount /dev/mmcblk0p3 2>/dev/null
mkfs.ext4 -L storage /dev/mmcblk0p3
e2fsck -f /dev/mmcblk0p3
mkdir -p /srv/storage
mount -t ext4 /dev/mmcblk0p3 /srv/storage
df -h | grep mmcblk0p3
- Once that works, configure boot-time mounting.
UUID="$(block info /dev/mmcblk0p3 | sed -n 's/.*UUID=\"\\([^\"]*\\)\".*/\\1/p')"
echo "$UUID"
If that prints a UUID, continue with:
uci add fstab mount
uci set fstab.@mount[-1].target='/srv/storage'
uci set fstab.@mount[-1].uuid="$UUID"
uci set fstab.@mount[-1].fstype='ext4'
uci set fstab.@mount[-1].enabled='1'
uci commit fstab
/etc/init.d/fstab enable
reboot
- Verify again after reboot.
mount | grep srv/storage
df -h
After that, organize the directory layout:
mkdir -p /srv/storage/repos
mkdir -p /srv/storage/backups
mkdir -p /srv/storage/openclash
Example:
cd /srv/storage/repos
git clone https://github.com/Ronchy2000/Immortalwrt-AutoBackup.git
If you still want the old /root path, create a symlink:
ln -s /srv/storage/repos/Immortalwrt-AutoBackup /root/Immortalwrt-AutoBackup
Route C: only consider extroot under these conditions
Only consider extroot when all of these are true:
- you are certain the router is still on the
squashfs + overlaypath - the actual problem is writable package space in
/overlay - you already have a full backup
- you know how to back out if migration fails
See:
Situations where you should stop and reassess
mkfs.ext4reports an existingoverlay.
Example:
/dev/mmcblk0p3 contains a ext4 file system labelled 'overlay'
That usually means the partition has already been used.
Do not continue formatting. Check first:
mount
df -h
block info
uci show fstab
- You are already on
ext4root but still plan to follow anextroottutorial.
If mount shows:
/dev/root on / type ext4
do not use the extroot guide.
- Installing many packages before verifying the storage state.
Check first:
df -h
Make sure / or /srv/storage is ready before installing iStore, OpenClash, Git, or large rule sets.
If the system behaves abnormally after partition changes, check in this order
Check in this order:
- leftover
/overlaymount settings:uci show fstab - root filesystem mount state:
mount - actual free space:
df -h - partition recognition:
block info - recent logs:
logread | tail -50
If the router no longer boots correctly, the fastest recovery path is usually:
- reflash a known-good image
- restore your backup after the first boot
- return to this guide and re-check which route matches your actual system type
What to read next
- read this guide first to identify the system type and choose a route
- if you only need backup and restore, continue with OpenWrt_Backup_Resotre.md
- for ongoing operations, continue with System_Maintenance.md
- open ExtendOverlaySize.md only after confirming you are on
squashfs + overlay