Bookmark

Expand OpenWrt Overlay with Extroot: USB, ext4, and Recovery Paths

extroot uses external storage as a writable overlay, giving OpenWrt room for packages and persistent data without replacing the router's internal flash. This article follows the OpenWrt documentation from device discovery and partitioning through the post-reboot checks, recovery paths, and advanced options.1

Warning: This procedure touches partitions and filesystems. Back up the configuration, identify the correct /dev/sdX, and treat the parted example below as a destructive command. Never run it unchanged on a disk containing data.

1. What extroot does and where it applies

On many devices, OpenWrt combines a read-only rootfs with writable rootfs_data or ubifs as an overlay. The documentation's conceptual table is:

ComponentMount pointCompressedWritable
rootfs/romYesNo
rootfs_data or ubifs/overlay, /rom/overlayNoYes
overlay/Depends on the filesystemYes

Extroot adds an overlay on USB, SATA, an SD card, or another block device and mounts it during boot. If the external device is removed, the router still has its internal overlay and can fall back to its pre-extroot state.1

Some firmware without an overlay partition in /proc/mtd may ignore fstab configuration; the source describes using / as the mount point in that special case. Do not make that the default—first inspect the actual layout of the model.

2. Preparation

The source assumes that I can reach a shell through SSH or a UART console. LuCI can edit many of these settings, but shell work makes the device name and command output explicit.1

  • Devices with at least 8 MiB of flash generally have enough room for the required packages. Devices with 4 MiB or less should use the Custom image path instead of trying to squeeze packages into the current overlay.
  • The block tooling supports ext2/3/4, f2fs, btrfs, ntfs, and ubifs; the documentation says that FAT16/FAT32 cannot be used for extroot.
  • The example below uses a USB flash drive, one GPT partition, and ext4. A USB SSD may also need kmod-usb-storage-uas.
  • If the internal flash is nearly full, remove unnecessary packages first. Install the standard packages:
1
2
3
4
opkg update
opkg install block-mount kmod-fs-ext4 e2fsprogs parted kmod-usb-storage
# For a USB SSD, add:
opkg install kmod-usb-storage-uas

Find the disk instead of guessing from the example:

1
ls -l /sys/block

Distinguish a disk such as /dev/sda from a partition such as /dev/sda1. Record the output and confirm that the USB device is visible before moving to the destructive step.

3. Partition and format the USB drive

This is the source's GPT-plus-ext4 method:

1
2
3
4
DISK="/dev/sda"
parted -s ${DISK} -- mklabel gpt mkpart extroot 2048s -2048s
DEVICE="${DISK}1"
mkfs.ext4 -L extroot ${DEVICE}

The parted command erases the partition table on ${DISK}. If the disk is not new or contains data, stop and identify the correct disk. Other supported filesystems are possible, but their formatting commands and packages must change; do not keep mkfs.ext4 while intending to use f2fs or btrfs.

4. Create the extroot mount entry

Before writing fstab, confirm that OpenWrt sees the UUID of ${DEVICE} and the current overlay mount point:

1
2
echo $(block info ${DEVICE} | grep -o -e 'UUID="\S*"')
echo $(block info | grep -o -e 'MOUNT="\S*/overlay"')

If either command returns nothing, stop and check the device, filesystem module, and block info output. Once the output is correct, use the source's UCI sequence:

1
2
3
4
5
6
7
eval $(block info ${DEVICE} | grep -o -e 'UUID="\S*"')
eval $(block info | grep -o -e 'MOUNT="\S*/overlay"')
uci -q delete fstab.extroot
uci set fstab.extroot="mount"
uci set fstab.extroot.uuid="${UUID}"
uci set fstab.extroot.target="${MOUNT}"
uci commit fstab

${UUID} comes from the external partition and ${MOUNT} from the existing overlay layout. Do not replace /overlay with another path without understanding the firmware's layout.

Keep the original overlay reachable

The source's next method mounts the old overlay at /rwm. This is useful when the original rootfs_data/ubifs must be inspected or its fstab adjusted after the external device owns /overlay:

1
2
3
4
5
6
ORIG="$(block info | sed -n -e '/MOUNT="\S*\/overlay"/s/:\s.*$//p')"
uci -q delete fstab.rwm
uci set fstab.rwm="mount"
uci set fstab.rwm.device="${ORIG}"
uci set fstab.rwm.target="/rwm"
uci commit fstab

The old overlay may then be available at /rwm; the corresponding upper-layer fstab is /rwm/upper/etc/config/fstab. Use the layout returned by block info.

5. Transfer the data and apply the change

Temporarily mount the external partition at /mnt, then copy the current overlay with the source's pipeline:

1
2
mount ${DEVICE} /mnt
tar -C ${MOUNT} -cvf - . | tar -C /mnt -xf -

Reboot when the copy is complete:

1
reboot

Do not remove the USB device before the router has completed the reboot. When configuring over Wi-Fi, use Ethernet or a console so a transient disconnect does not interrupt the operation.

6. Verify after reboot

LuCI

  • Open System → Mount Points: the USB partition should be mounted as overlay.
  • Open System → Software: free overlay space should reflect the external partition.

Command line

The external partition should be mounted at /overlay, while / is an overlayfs using it as the upper layer:

1
2
grep -e /overlay /etc/mtab
df /overlay /

A successful result shows /dev/sda1 mounted at /overlay and the available space for / matching /overlay; device names and values will differ on the real router.

7. Troubleshooting and recovery boundaries

If boot has a problem, inspect block discovery, fstab, and the preinit stage:

1
2
3
block info
uci show fstab
logread | sed -n -e "/- preinit -/,/- init -/p"

UUID mismatch after an upgrade

If the log reports block: extroot: UUID mismatch, mount the partition and remove the two markers named by the source:

1
2
3
mount /dev/sda1 /mnt
rm -f /mnt/.extroot-uuid /mnt/etc/.extroot-uuid
umount /mnt

Replace /dev/sda1 with the real device. Do not remove files from another partition.

FAT/FAT32 is not supported

vfat and FAT32 do not work for extroot. If a USB drive is preformatted as FAT, reformat it as ext4 after installing e2fsprogs:

1
mkfs.ext4 /dev/sda1

This also erases data on /dev/sda1.

The USB device appears too late

If the partition mounts manually but not during boot, the source suggests increasing delay_root, for example to 15 seconds:

1
2
uci set fstab.@global[0].delay_root="15"
uci commit fstab

Use a delay only when logs and testing indicate that storage becomes ready late; it is not a universal fix.

Pre-25.xx and post-25.xx firmware

For pre-25.xx releases, the older source material includes a way to permit packages larger than the free space in /rom:

1
echo option force_space >> /etc/opkg.conf

This is not a replacement for extroot and should not be applied blindly. For post-25.xx releases, the source points to the expand_root guide; follow the release-appropriate mechanism instead of mixing both.

On very old systems where only an /etc/rc.local workaround works, the source also records:

1
2
export PREINIT=1
mount_root

This is a historical compatibility branch with possible side effects. Prefer standard extroot or the current release's expand_root method.

Extroot on MMC/SD

For a non-USB block device, modules required to make it visible early must be placed in /etc/modules-boot.d. For SDHCI on MT7688/MT7628, the source gives /etc/modules-boot.d/mmc with:

1
2
3
4
mmc_core
mmc_block
sdhci
mtk_sd

The correct modules depend on the SoC and driver; this is the source's example, not a universal list.

8. Useful additions after extroot

Keep package lists out of RAM

To make package lists survive reboot and reduce RAM use, move the list directory from /var/opkg-lists to /usr/lib/opkg/lists.

In LuCI, open System → Software → Configuration, change lists_dir to /usr/lib/opkg/lists, then open System → Software → Actions → Update lists.

Or run:

1
2
sed -i -e "/^lists_dir\s/s:/var/opkg-lists$:/usr/lib/opkg/lists:" /etc/opkg.conf
opkg update

Create swap on extroot

If a router with roughly 32 MB of RAM cannot read package lists, the source presents a 100 MiB swap file on extroot:

1
2
3
4
5
6
7
8
9
DIR="$(uci -q get fstab.extroot.target)"
dd if=/dev/zero of=${DIR}/swap bs=1M count=100
mkswap ${DIR}/swap
uci -q delete fstab.swap
uci set fstab.swap="swap"
uci set fstab.swap.device="${DIR}/swap"
uci commit fstab
service fstab boot
cat /proc/swaps

Swap increases writes to the USB/flash device and does not turn a router into a high-memory server. Use reliable storage, monitor I/O errors, and never put secrets in a swap file.

USB dongles and usb-modeswitch

The source allows adding usb-modeswitch to an image, but warns about dongles combining a CD-ROM, modem, and card reader: if /overlay is on the dongle's memory card, switching modes can make the filesystem disappear. A safer option is a dongle preconfigured to enable the modem/network adapter and card reader at power-on without switching modes on the router.

The source demonstrates inspecting ports with an AT command:

1
2
3
at^setport?
^SETPORT:A1,A2;1,3,2,A1,A2
OK

Query port meanings with:

1
at^setport=?

In the source example, 1 is the modem, 2 is PCUI, 3 is DIAG, 16 is NCM, and A2 is the SD card. Do not disable PCUI (2) or you may lock yourself out of the dongle. A sample configuration sequence is:

1
2
3
4
5
6
7
at^setport="ff;1,2,3,a2"
OK
at^reset
OK
at^setport?
^SETPORT:;1,2,3,A2
OK

This applies only to a dongle compatible with that AT command set, not to any modem with similarly named ports. The source lists a pre-configuration example for Huawei E3131s-2 firmware v21.158.47.00.1094.

Remote filesystems

The source only links to a guide for fstab failing to mount CIFS at boot; it does not provide a complete CIFS procedure in this article. I do not turn that reference into a generic mount command. Check credentials, network availability, and boot ordering for the actual model and release.

9. LUKS encrypted extroot: advanced branch

The source says that OpenWrt 22.03 does not support opening LUKS reliably before the extroot check. Before starting, create a LUKS container using the disk-encryption documentation, and make sure rootfs_data has room for cryptsetup and its dependencies. Once the volume is unlocked, follow the extroot procedure inside it and copy the data from /overlay.1

Preferred PREINIT method

The source describes a cleaner method: during PREINIT, mount_root looks for block on ROM/overlay and calls block extroot. A wrapper can therefore open the encrypted device before invoking the real binary.

Do not skip these conditions:

  1. Install block-mount and cryptsetup.
  2. Install the executable decrypt.sh script from the disk-encryption documentation.
  3. Move the real /sbin/block binary to /sbin/block.bin.
  4. Place the wrapper at /upper/sbin/block on a UBIFS overlay, or /sbin/block when already on overlayfs, and make it executable.
  5. Use /.use_crypt_extroot on overlayfs or /upper/.use_crypt_extroot on /overlay as the enable marker.
  6. Set up /etc/crypttab before rebooting.

When the marker is absent, encrypted extroot remains disabled, which provides a way to turn it off from failsafe. The source includes the complete wrapper code, but it changes PREINIT behavior, creates device nodes, and loads kernel crypto modules; it should be checked against the actual kernel rather than copied into another model without review.

Fallback /etc/rc.local method

The source gives a more side-effect-prone alternative: normal boot fails to find extroot, then /etc/rc.local opens LUKS at the end of boot and calls mount_root again. Its keyfile example is /root/extroot.key:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# Only set up encrypted extroot when the marker exists on rootfs_data.
mkdir -p /mnt/tmp
if [ -e /.use_crypt_extroot ]; then
    cryptsetup open -d /root/extroot.key /dev/sda1 cextroot
    umount /overlay
    mount --bind /tmp /mnt/tmp
    sleep 5
    PREINIT=1 mount_root
    umount -l /tmp
    mount --bind /rom/mnt/tmp /tmp
    block mount
    rpcd reload
fi

This method does not read an interactive password in /etc/rc.local; the source expects a keyfile and asks the operator to consider the threat model of storing it at /root/extroot.key. The web interface may take another 20–30 seconds to appear, while SSH is not necessarily delayed. Use it only when the PREINIT path fails and a failsafe route is ready.

10. System upgrades and custom images

Do not use opkg upgrade for a blind system upgrade

The source warns against blindly using opkg upgrade on snapshots: the uClibc ABI may change, /rom or /rwm UUIDs may change and break extroot, a kernel/module mismatch can brick the router, and upgrading every package except the kernel/modules can leave packages broken.1

For a stable release, sysupgrade to a coherent image. Afterward, you may need to repeat the mount-entry steps and reinstall packages—especially kernel modules—while checking UUIDs before the next reboot.

Custom image for 4 MiB devices

For routers with 4 MiB or less, the source uses the Image Builder on 64-bit Linux or WSL:

  1. Download the Image Builder for the correct target.
  2. Extract it and run:
1
make info
  1. Find the correct profile, for example:
1
tl-wr1043nd-v1: TP-LINK TL-WR1043N/ND v1 Packages: kmod-usb-core kmod-usb2 kmod-ledtrig-usbdev
  1. Build an image with the profile and required packages:
1
make image PROFILE=tl-wr1043nd-v1 PACKAGES="block-mount kmod-fs-ext4 kmod-usb-storage kmod-usb-ohci kmod-usb-uhci"
  1. Open bin/target/<device-type>/generic/, select the matching factory or sysupgrade image, and install it.
  2. Format the USB drive as ext4 with Linux LiveCD or GParted because, in the source example, e2fsprogs is too large for a 4 MiB device.

Automated setup and automated upgrade

  • openwrt-auto-extroot is an Image Builder frontend that can automatically format and configure a plugged-in storage device that has not been set up.
  • The source's automated-upgrade branch combines Hotplug extras and Opkg extras; packages needed by extroot are stored in the init profile and restored after the upgrade.
  • Its restore script uses /etc/uci-defaults/90-extroot-restore, checks fstab.extroot and /etc/opkg-restore-init, mounts temporarily, moves etc/upper, then reboots. This is an upgrade pipeline for operators who understand the layout; do not run it on a router without a backup.

Conclusion

Extroot is not just “plug in USB and mount it.” The critical parts are identifying the correct ${DEVICE}, keeping the old overlay reachable through /rwm, copying all data, verifying /overlay after reboot, and preparing recovery for UUID mismatches or late storage discovery. USB mode switching, LUKS, custom images, and automated upgrades each have their own limits; when uncertain, stop at standard extroot and keep the backup outside the router.

Sources


  1. OpenWrt Wiki – Extroot configuration , updated 2026-07-30. This is an independent adaptation; it does not rehost the source's HTML, images, or binary assets. ↩︎ ↩︎ ↩︎ ↩︎ ↩︎


0 Bình luận

Góp Ý / Bình Luận / Đánh giá