OpenWrt Forum Archive

Topic: [Howto] use usb disk to expand root fs

The content of this topic has been archived on 29 Mar 2018. There are no obvious gaps in this topic, but there may still be some posts missing at the end.

This howto explains how to use mini_fo filesystem to mount the USB disk over the existing root.
Original root would be used read-only and all modifications would be redirected to the USB disk

This has been tested on ASUS WL-500gp with WhiteRussian 0.9.

1. Prepare USB disk with ext3 (For more details see: http://wiki.openwrt.org/UsbStorageHowto )

2. Create file /sbin/inflate_root with following content

# Edit the variables to fit your needs:

DSK_DEV="/dev/scsi/host0/bus0/target0/lun0/part1"  #Device for your disk
DSK_MOUNT="/mnt/dsk007"                                     #Mount point for your disk
OVERLAY_DIR="${DSK_MOUNT}/root_overlay"          #Directory on your disk that would be used by mini_fo to store the modified files
TMP_ROOT="/tmp/inflated_root"                               #Temporary directory used to mount the merged root
OLD_ROOT="/mnt/oldroot"                                       #Where the original root would be saved

ROM=$(awk '/squashfs/ {print $2; exit;}' /proc/mounts)
JFFS=$(awk '/jffs2/ {print $2; exit;}' /proc/mounts)

[ -d "$DSK_MOUNT" ] || mkdir -p "$DSK_MOUNT" || exit 1

mount $DSK_DEV $DSK_MOUNT || exit 2

[ -d "$OVERLAY_DIR" ] || mkdir -p "$OVERLAY_DIR"  || exit 3

#copy the changes from /jffs to my disk if not already done
ls $OVERLAY_DIR/*/META_* 2>/dev/null >&2 || {
    cp -prd $JFFS/* "$OVERLAY_DIR"
}

[ -d "$TMP_ROOT" ] || mkdir -p "$TMP_ROOT" || exit 4

# do the overlay mount
mount -t mini_fo -o "base=$ROM,sto=$OVERLAY_DIR" "$ROM" "$TMP_ROOT" || exit 5

[ -d "${TMP_ROOT}/${OLD_ROOT}" ] || mkdir -p "${TMP_ROOT}/${OLD_ROOT}" || exit 6

# pivot root - unfortunatelly pivot_root needs to be run before init

mount -o move /proc "$TMP_ROOT/proc" && \
pivot_root "$TMP_ROOT" "${TMP_ROOT}/${OLD_ROOT}" && {
    mount -o move "$OLD_ROOT/dev" /dev
    mount -o move "$OLD_ROOT/tmp" /tmp
    mount -o move "$OLD_ROOT/jffs" /jffs 2>&-
    mount -o move "$OLD_ROOT/$DSK_DEV" "$DSK_DEV" 
}

3. Make the file executable

chmod +x /sbin/inflate_root

4. Check if it is working and reboot

/sbin/inflate_root
mount
df
dd if=/dev/zero of=/test bs=1k count=128k
rm /test
reboot

5. Because the pivot_root only changes the root for current process we need to execute the script before init.
So we will prepare our own version of init ;-).

Be careful from now on - if you screw up you'll brick your router !!!

rm /sbin/init

6. Create new /sbin/init

#!/bin/sh

# Make sure we have all required modules loaded
for module in usbcore uhci scsi_mod sd_mod usb-storage jbd ext3; do {
        insmod $module
}; done

sleep 4s  

/sbin/inflate_root

exec /bin/busybox init

7. Make it executable

chmod +x /sbin/init

8. Cross your fingers and reboot ;-)

if you bricked the router - reflash ;-(

C.U. PeZ

Hi, thanks this is really great.
Forgive me for not understanding, but whats the difference from this and the boot configuration guide in the wiki?(http://wiki.openwrt.org/UsbStorageHowto#head-6d1886b78cce38eb5669113e3f4231a8497c9493)
when would you use one over the other?
do you know if this works with kamikaze?

Thanks

Also i am getting an error when trying execute the last mount command (luckily i was running the test....):
mount: mounting /mnt/oldroot//dev/discs/disc0/part2 on /dev/discs/disc0/part2 failed
the line thats calling it is
mount -o move "$OLD_ROOT/$DSK_DEV" "$DSK_DEV"

i tried removing the / in the command but i get the same error, maybe because its a test and not running before preinit, but i would have liked to know that what i should expect..... maybe you could post that?
i am running kamikaze 7.09 on an asus wl500gp

cipherzero wrote:

Forgive me for not understanding, but whats the difference from this and the boot configuration guide in the wiki?(http://wiki.openwrt.org/UsbStorageHowto#head-6d1886b78cce38eb5669113e3f4231a8497c9493)
when would you use one over the other?

With the UsbStorageHowto you end up with pretty much the original ROM. And if you did a lots of modifications to your OpenWRT (as I did) you
will loose them. I just wanted to expand the disk space to install asterisk and other stuff that didn't fit on the original flash. If the solution described
in UsbStorageHowto is sufficient for you, you should probably go that way - it's safer :-)

cipherzero wrote:

do you know if this works with kamikaze?

sorry I only have WhiteRussian installed so far. I'm to lazy to make all that stuff I already configured working again on kamikaze :-)

C.U. PeZ

cipherzero wrote:

Also i am getting an error when trying execute the last mount command (luckily i was running the test....):
mount: mounting /mnt/oldroot//dev/discs/disc0/part2 on /dev/discs/disc0/part2 failed
the line thats calling it is
mount -o move "$OLD_ROOT/$DSK_DEV" "$DSK_DEV"

i tried removing the / in the command but i get the same error, maybe because its a test and not running before preinit, but i would have liked to know that what i should expect..... maybe you could post that?
i am running kamikaze 7.09 on an asus wl500gp

Not sure what could be the problem, maybe "mount -o move" doesn't work on kamikaze. Try to add "set -x" to the begining of the script and try to analyze the output to see what gone wrong.

C.U. PeZ

I've got this to work on a ASUS WL-500gp with kernel 2.6 on Kamikaze 8.09 RC2 with info from here: https://dev.openwrt.org/ticket/3554

I had to make the following modifications:

1.) in /sbin/inflate_root change the line

mount -o move "$OLD_ROOT/$DSK_DEV" "$DSK_DEV"

to

mount -o move "$OLD_ROOT/sys" /sys 2>&-

2.) in /sbin/init hotplug2 has to be started before the insmods and terminated before calling the real init

#!/bin/sh

/sbin/hotplug2 --override --persistent --max-children 1 --no-coldplug &

# Make sure we have all required modules loaded
for module in usbcore ehci-hcd scsi_mod sd_mod usb-storage ext2; do {
        /sbin/insmod $module
}; done


sleep 10s

/sbin/inflate_root

/usr/bin/killall hotplug2

exec /bin/busybox init

I've used ext2 as filesystem change that to your needs ...

-RavenClaw

The discussion might have continued from here.