From 6c4b1cc13597e84ac7921d5372855329d65dbd36 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 17 Nov 2006 03:07:10 +0000 Subject: [PATCH] add failsafe mode and mini_fo mounting support for brcm-2.4 and brcm-2.6 SVN-Revision: 5544 --- package/base-files/brcm/bin/firstboot | 80 ++++++++++++++----- package/base-files/brcm/etc/diag.sh | 28 +++++++ package/base-files/brcm/etc/init.d/done | 15 ++++ package/base-files/brcm/etc/preinit | 72 +++++++++++++++-- package/base-files/brcm/sbin/hotplug.failsafe | 4 + package/base-files/brcm/sbin/mount_root | 10 +-- 6 files changed, 175 insertions(+), 34 deletions(-) create mode 100644 package/base-files/brcm/etc/diag.sh create mode 100644 package/base-files/brcm/etc/init.d/done create mode 100755 package/base-files/brcm/sbin/hotplug.failsafe diff --git a/package/base-files/brcm/bin/firstboot b/package/base-files/brcm/bin/firstboot index b65d3ee98b..c3d9a64b87 100755 --- a/package/base-files/brcm/bin/firstboot +++ b/package/base-files/brcm/bin/firstboot @@ -1,5 +1,9 @@ #!/bin/sh -# Copyright (C) 2006 OpenWrt.org +# $Id$ +. /etc/functions.sh + +partname="OpenWrt" +mtdpart="$(find_mtd_part $partname)" rom=$(awk '/squashfs/ {print $2}' /proc/mounts) jffs=$(awk '/jffs2/ {print $2}' /proc/mounts) @@ -10,7 +14,7 @@ dupe() { # { cd $2 find . -xdev -type d - echo "./dev ./jffs ./mnt ./proc ./tmp ./sys" + echo "./dev ./jffs ./mnt ./proc ./tmp" # xdev skips mounted directories cd $1 } | xargs mkdir -p @@ -21,7 +25,6 @@ dupe() { # case "$file" in ./rom/note) ;; #nothing ./etc/config*|\ - ./etc/resolv.conf|\ ./usr/lib/ipkg/info/*) cp -af $2/$file $file;; *) ln -sf /rom/${file#./*} $file;; esac @@ -37,24 +40,37 @@ pivot() { # pivot_root $1 $1$2 && { mount -o move $2/dev /dev mount -o move $2/tmp /tmp - mount -o move $2/sys /sys + mount -o move $2/jffs /jffs 2>&- return 0 } } -mountdp() { # - dev=$1; mnt=$2; shift 2; opt=$* - mount $dev $mnt $opt - dupe $mnt $rom - pivot $mnt /rom +fopivot() { # + root=$1 + { + mount -t mini_fo -o base=/,sto=$1 $1 /mnt 2>&- && root=/mnt + } || { + [ "$3" = "1" ] && { + mount | grep "on $1 type" 2>&- 1>&- || mount -o bind $1 $1 + dupe $1 $rom + } + } + pivot $root $2 } ramoverlay() { mkdir -p /tmp/root - mountdp /tmp/root /mnt -o bind + fopivot /tmp/root /rom 1 } +# invoked as an executable [ "${0##*/}" = "firstboot" ] && { + + [ -z "$mtdpart" ] && { + echo "MTD partition not found." + exit 1 + } + [ -z "$rom" ] && { echo "You do not have a squashfs partition; aborting" echo "(firstboot cannot be run on jffs2 based firmwares)" @@ -62,17 +78,31 @@ ramoverlay() { } [ "$1" = "switch2jffs" ] && { - mtd erase OpenWrt - mount -o remount,ro none / # try to avoid fs changing while copying - mount -o bind / /mnt - mount /dev/mtdblock/4 /rom/jffs -t jffs2 + mtd erase "$partname" + + # try to avoid fs changing while copying + mount -o remount,ro none / 2>&- + + # copy ramoverlay to jffs2 + mount "$mtdpart" /rom/jffs -t jffs2 echo -n "copying files ... " - cp -a /mnt/* /rom/jffs - umount /mnt + cp -a /tmp/root/* /rom/jffs 2>&- echo "done" + + # switch back to squashfs (temporarily) + # and park the ramdisk ontop of /tmp/root pivot /rom /mnt mount -o move /mnt /tmp/root - pivot /jffs /rom + + # /jffs is the overlay + # /rom is the readonly + fopivot /jffs /rom + + # try to get rid of /tmp/root + # this will almost always fail + umount /tmp/root 2>&- + + # fs is clean jffs2root --clean exit 0 } @@ -81,10 +111,18 @@ ramoverlay() { [ \! -z "$jffs" ] && { echo "firstboot has already been run" echo "jffs2 partition is mounted, only resetting files" - dupe $jffs $rom - exit 0 + grep mini_fo /proc/filesystems >&- + [ $? != 0 ] && { + dupe $jffs $rom + exit 0 + } || { + rm -rf $jffs/* 2>&- + mount -o remount $jffs / 2>&- + exit 0 + } } - mtd erase OpenWrt - mountdp /dev/mtdblock/4 /jffs -t jffs2 + mtd erase "$partname" + mount "$mtdpart" /jffs -t jffs2 + fopivot /jffs /rom 1 } diff --git a/package/base-files/brcm/etc/diag.sh b/package/base-files/brcm/etc/diag.sh new file mode 100644 index 0000000000..3b08554c64 --- /dev/null +++ b/package/base-files/brcm/etc/diag.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# Copyright (C) 2006 OpenWrt.org + +set_led() { + local led="$1" + local state="$2" + [ -f "/proc/diag/led/$1" ] && echo "$state" > "/proc/diag/led/$1" +} + +set_state() { + case "$1" in + preinit) + set_led dmz 1 + set_led diag 1 + set_led power 0 + ;; + failsafe) + set_led diag f + set_led power f + set_led dmz f + ;; + done) + set_led dmz 0 + set_led diag 0 + set_led power 1 + ;; + esac +} diff --git a/package/base-files/brcm/etc/init.d/done b/package/base-files/brcm/etc/init.d/done new file mode 100644 index 0000000000..0640b61938 --- /dev/null +++ b/package/base-files/brcm/etc/init.d/done @@ -0,0 +1,15 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org + +START=95 +boot() { + [ -d /tmp/root ] && { + lock /tmp/.switch2jffs + firstboot switch2jffs + lock -u /tmp/.switch2jffs + } + + # set leds to normal state + . /etc/diag.sh + set_state done +} diff --git a/package/base-files/brcm/etc/preinit b/package/base-files/brcm/etc/preinit index fb13e107e5..9c7f9448c9 100755 --- a/package/base-files/brcm/etc/preinit +++ b/package/base-files/brcm/etc/preinit @@ -1,13 +1,73 @@ #!/bin/sh # Copyright (C) 2006 OpenWrt.org +. /etc/functions.sh +. /etc/diag.sh + +failsafe() { + lock /tmp/.failsafe + + echo "0 1 2 3 4 5u*" > /proc/switch/eth0/vlan/0/ports + + set_state failsafe + [ -x "/usr/sbin/nvram" ] && { + [ "$(nvram get boot_wait)" != "on" ] && { + nvram set boot_wait=on + nvram commit + } + } + + netmsg 192.168.1.255 "Entering Failsafe!" + telnetd -l /bin/login <> /dev/null 2>&1 + + ash --login + lock -u /tmp/.failsafe +} + export PATH=/bin:/sbin:/usr/bin:/usr/sbin mount none /proc -t proc +size=$(awk '/Mem:/ {l=5242880;print((s=$2/2) /proc/sys/kernel/hotplug - telnetd -l /bin/login <> /dev/null 2>&1 -} -mount_root ${FAILSAFE:+failsafe} +insmod diag +set_state preinit +trap 'FAILSAFE=true' USR1 +echo '/sbin/hotplug.failsafe' > /proc/sys/kernel/hotplug + +ifname=eth0 + +# hardware specific overrides +case "$(cat /proc/diag/model)" in + "Linksys WAP54G V1") ifname=eth1;; + "ASUS WL-HDD") ifname=eth1;; + "ASUS WL-300g") ifname=eth1;; + "ASUS (unknown, BCM4702)") ifname=eth1;; +esac + +insmod switch-core +insmod switch-robo || insmod switch-adm || rmmod switch-core + +ifconfig $ifname 192.168.1.1 netmask 255.255.255.0 broadcast 192.168.1.255 up + +[ -d /proc/switch/eth0 ] && { + echo 1 > /proc/switch/eth0/reset + + # this would be easier if we blasted the message across all ports + # but we don't want packets leaking across interfaces + for port in $(seq 0 4); do { + echo "$port 5u*" > /proc/switch/eth0/vlan/0/ports + netmsg 192.168.1.255 "Press reset now, to enter Failsafe!" + }; done +} || netmsg 192.168.1.255 "Press reset now, to enter Failsafe!" + +sleep 2 + +eval ${FAILSAFE:+failsafe} + +lock -w /tmp/.failsafe +echo /sbin/hotplug > /proc/sys/kernel/hotplug + +ifconfig $ifname 0.0.0.0 down + +mount_root exec /sbin/init diff --git a/package/base-files/brcm/sbin/hotplug.failsafe b/package/base-files/brcm/sbin/hotplug.failsafe new file mode 100755 index 0000000000..0544339de8 --- /dev/null +++ b/package/base-files/brcm/sbin/hotplug.failsafe @@ -0,0 +1,4 @@ +#!/bin/sh +case "$1" in + button) kill -USR1 1;; +esac diff --git a/package/base-files/brcm/sbin/mount_root b/package/base-files/brcm/sbin/mount_root index e73afdc886..ffa6072c66 100755 --- a/package/base-files/brcm/sbin/mount_root +++ b/package/base-files/brcm/sbin/mount_root @@ -7,9 +7,6 @@ is_dirty() { return $(hexdump -v /dev/mtdblock/1 -s $OFFSET -n 1 -e '"%d"') } -size=$(awk '/Mem:/ {l=5242880;print((s=$2/2)&- @@ -21,15 +18,14 @@ if [ "$1" != "failsafe" ]; then [ $? != 0 ] && { echo "switching to jffs2" mount /dev/mtdblock/4 /jffs -t jffs2 - pivot /jffs /rom + fopivot /jffs /rom } || { - echo "jffs2 unusable; using ramdisk" + echo "jffs2 not ready yet; using ramdisk" ramoverlay } fi fi -mount none /tmp -t tmpfs -o remount,nosuid,nodev,mode=1777 mkdir -p /dev/pts -mount none /dev/pts -t devpts +mount none /dev/pts -t devpts 2>&- grep sysfs /proc/filesystems >/dev/null && mount -t sysfs none /sys 2>&-