aboutsummaryrefslogtreecommitdiffstats
path: root/recipes/slugos-init/files
diff options
context:
space:
mode:
authorDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
committerDenys Dmytriyenko <denis@denix.org>2009-03-17 14:32:59 -0400
commit709c4d66e0b107ca606941b988bad717c0b45d9b (patch)
tree37ee08b1eb308f3b2b6426d5793545c38396b838 /recipes/slugos-init/files
parentfa6cd5a3b993f16c27de4ff82b42684516d433ba (diff)
downloadopenembedded-709c4d66e0b107ca606941b988bad717c0b45d9b.tar.gz
rename packages/ to recipes/ per earlier agreement
See links below for more details: http://thread.gmane.org/gmane.comp.handhelds.openembedded/21326 http://thread.gmane.org/gmane.comp.handhelds.openembedded/21816 Signed-off-by: Denys Dmytriyenko <denis@denix.org> Acked-by: Mike Westerhof <mwester@dls.net> Acked-by: Philip Balister <philip@balister.org> Acked-by: Khem Raj <raj.khem@gmail.com> Acked-by: Marcin Juszkiewicz <hrw@openembedded.org> Acked-by: Koen Kooi <koen@openembedded.org> Acked-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
Diffstat (limited to 'recipes/slugos-init/files')
-rw-r--r--recipes/slugos-init/files/README49
-rw-r--r--recipes/slugos-init/files/boot/disk83
-rw-r--r--recipes/slugos-init/files/boot/flash29
-rw-r--r--recipes/slugos-init/files/boot/kexec203
-rw-r--r--recipes/slugos-init/files/boot/network41
-rw-r--r--recipes/slugos-init/files/boot/nfs31
-rw-r--r--recipes/slugos-init/files/boot/ram64
-rw-r--r--recipes/slugos-init/files/boot/udhcpc.script17
-rw-r--r--recipes/slugos-init/files/conffiles55
-rw-r--r--recipes/slugos-init/files/functions427
-rw-r--r--recipes/slugos-init/files/initscripts/fixfstab91
-rw-r--r--recipes/slugos-init/files/initscripts/leds_startup11
-rw-r--r--recipes/slugos-init/files/initscripts/loadmodules.sh15
-rw-r--r--recipes/slugos-init/files/initscripts/rmrecovery4
-rw-r--r--recipes/slugos-init/files/initscripts/sysconfsetup46
-rw-r--r--recipes/slugos-init/files/initscripts/syslog.buffer23
-rw-r--r--recipes/slugos-init/files/initscripts/syslog.file23
-rw-r--r--recipes/slugos-init/files/initscripts/syslog.network28
-rw-r--r--recipes/slugos-init/files/initscripts/umountinitrd.sh33
-rw-r--r--recipes/slugos-init/files/initscripts/zleds45
-rw-r--r--recipes/slugos-init/files/leds269
-rw-r--r--recipes/slugos-init/files/links.conf6
-rw-r--r--recipes/slugos-init/files/modulefunctions45
-rw-r--r--recipes/slugos-init/files/modutils.txt1
-rw-r--r--recipes/slugos-init/files/reflash658
-rw-r--r--recipes/slugos-init/files/setup-optware.sh17
-rw-r--r--recipes/slugos-init/files/sysconf796
-rw-r--r--recipes/slugos-init/files/turnup965
-rw-r--r--recipes/slugos-init/files/usb2
29 files changed, 4077 insertions, 0 deletions
diff --git a/recipes/slugos-init/files/README b/recipes/slugos-init/files/README
new file mode 100644
index 0000000000..264d4d8f85
--- /dev/null
+++ b/recipes/slugos-init/files/README
@@ -0,0 +1,49 @@
+OpenSlug-1.x Family Release README
+
+Warning: OpenSlug is not for the faint of heart! In fact, OpenSlug has a
+specific target audience.
+
+Some background first. According to the NSLU2 - Linux developers, there are 4
+specific types ("camps") of NSLU2 - Linux users:
+
+ Camp #1: Users who want full Linksys compatibility (including for future
+ Linksys firmware releases). They can load firmware images via
+ the Linksys web interface and telnet in - to load Optware -
+ Unslung packages with ipkg, but have no idea what RedBoot is or
+ does.
+
+ Camp #2: "Camp #1 Plus users." They can telnet into RedBoot (ability
+ to "self-rescue" a non-working NSLU2), and are comfortable
+ using Linux.
+
+ Camp #3: Power users! Firmware flashing via any interface is a walk
+ in the park. They aren't just *users*, but are developers or
+ administrators of computers and/or computer software.
+ However, they have no JTAG or custom bootloaders.
+
+ Camp #4: Bleeding edge users. They create and use custom bootloaders,
+ certainly having no need or desire for Linksys compatibility,
+ modifying and/or changing the hardware as well.
+
+With those camps in mind, OpenSlug is targetted toward Camp #3 and Camp #4
+users. If you're not in Camps 3 & 4, then you should be looking to use the
+Unslung firmware. If you are a Camp #2 user, and still want to use OpenSlug,
+you need to practice gaining RedBoot access, and be able to recover from bad
+flashes, "drive not formatted" conditions, and other common mistakes/problems
+which are documented in the NSLU2-Linux Wiki at http://www.nslu2-linux.org.
+Once you are comfortable doing those things, then you may consider using
+OpenSlug.
+
+If you're still reading - and still intent on using OpenSlug, click through
+the Intel license, download the latest OpenSlug binary and flash it to your
+NSLU2! (Without any HD attached while flashing!!!) Your next stop should be
+the OpenSlug Turnip page at:
+
+ http://www.nslu2-linux.org/wiki/OpenSlug/OpenSlugTurnUp
+
+Please add your name and information to the OpenSlug database at the yahoo
+NSLU2-Linux group at:
+
+ http://groups.yahoo.com/group/nslu2-linux/
+
+Happy OpenSlugging! \ No newline at end of file
diff --git a/recipes/slugos-init/files/boot/disk b/recipes/slugos-init/files/boot/disk
new file mode 100644
index 0000000000..1829033d4e
--- /dev/null
+++ b/recipes/slugos-init/files/boot/disk
@@ -0,0 +1,83 @@
+#!/bin/sh
+# boot from the hard disk partition "$1" (which
+# must be given) using options from the rest of
+# the command line.
+
+# Use the standard init path (see /etc/init.d/rcS)
+export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+
+# Mount required fileystems if necessary
+[ -e /proc/cpuinfo ] || mount -t proc proc /proc
+[ -e /sys/class ] || mount -t sysfs sysfs /sys
+
+# Load the helper functions
+. /etc/default/functions
+. /etc/default/modulefunctions
+
+leds boot system
+
+if test -n "$1"
+then
+ device="$1"
+ shift
+ # load USB & SCSI storage modules (/proc required!)
+ echo "boot: loading modules required for disk boot"
+ loaddiskmods
+ # waiting for disk
+ if test "$sleep" -gt 0
+ then
+ echo "boot: waiting $sleep seconds for disk"
+ sleep "$sleep"
+ fi
+ # Attempt to assemble the RAID if necessary
+ if (echo $device | grep -q "^/dev/md")
+ then
+ if test -n "$MDUUID"
+ then
+ echo "boot: assembling RAID array (UUID)"
+ mdadm -Acpartitions --auto=md --uuid="$MDUUID" $device
+ else
+ echo "boot: assembling RAID array (config file)"
+ mdadm -As --auto=md $device
+ fi
+ fi
+
+ # fire the boot
+ echo "boot: rootfs: mount $* $device [$UUID]"
+
+ # Mount read-write because before exec'ing init
+ # If a UUID is given (in the environment) this
+ # is used in preference to the device, but if
+ # the UUID mount fails a standard device mount
+ # is attempted.
+ if test -n "$UUID" &&
+ mount "$@" UUID="$UUID" /mnt ||
+ mount "$@" "$device" /mnt
+ then
+ # checkmount checks for sh, chroot, init, /dev
+ # and /mnt (i.e. /mnt/mnt in this case).
+ # minimaldevnodes checks (and creates if required)
+ # a few mandatory /dev nodes we may need.
+ if checkmount /mnt && minimaldevnodes /mnt
+ then
+ # pivot to /initrd if available, else /mnt
+ cd /
+ if test -d /mnt/initrd
+ then
+ swivel mnt initrd
+ else
+ swivel mnt mnt
+ fi
+ # swivel failed
+ fi
+ # Failure: unmount the partition
+ umount /mnt
+ # Remount /proc and /sys if necessary
+ [ -e /proc/cpuinfo ] || mount -t proc proc /proc
+ [ -e /sys/class ] || mount -t sysfs sysfs /sys
+ fi
+fi
+
+# fallback - use the flash boot
+leds beep -f 1000 -r 2
+exec /boot/flash
diff --git a/recipes/slugos-init/files/boot/flash b/recipes/slugos-init/files/boot/flash
new file mode 100644
index 0000000000..01c20e963a
--- /dev/null
+++ b/recipes/slugos-init/files/boot/flash
@@ -0,0 +1,29 @@
+#!/bin/sh
+# boot from the current (flash) root partition
+# nothing need be done apart from setting the
+# system LED status correctly
+
+# Mount required filesystems if necessary
+[ -e /proc/cpuinfo ] || mount -t proc proc /proc
+[ -e /sys/class ] || mount -t sysfs sysfs /sys
+
+leds beep
+. /etc/default/functions
+leds boot system
+
+if [ -x /sbin/init ]
+then
+ umount /proc 2>/dev/null
+ umount /sys 2>/dev/null
+ exec /sbin/init
+fi
+
+# fallback if /sbin/init has been deleted (bad!)
+# Mount required filesystems if necessary
+[ -e /proc/cpuinfo ] || mount -t proc proc /proc
+[ -e /sys/class ] || mount -t sysfs sysfs /sys
+leds boot system panic
+exec <>/dev/console >&0 2>&0
+test -x /sbin/sulogin && exec /sbin/sulogin
+test -x /bin/sh && exec /bin/sh
+exit 1
diff --git a/recipes/slugos-init/files/boot/kexec b/recipes/slugos-init/files/boot/kexec
new file mode 100644
index 0000000000..a60be03142
--- /dev/null
+++ b/recipes/slugos-init/files/boot/kexec
@@ -0,0 +1,203 @@
+#!/bin/sh
+#
+# Loads the specified kernel and kexecs it.
+
+# The access method and path from which to fetch the kernel
+# is specified in "$1" and "$2":
+#
+# flash /boot/zImage-ixp4xxbe
+# nfs spike:/home/slug/vmlinuz
+# wget http://devserv/kernels/vmlinuzbe
+# wget ftp://ftpserv/pub/zImage
+# /dev/sda1 /kernels/zImage-test
+# UUID /kernels/zImage-test
+# tftp server:/pub/kernels/vmlinuz
+#
+# Command-line options for the new kernel are in "$3".
+
+
+# In order to use this, you must exec this script from the /linuxrc file.
+#
+# This sample linuxrc script boots from external disk. The last line of
+# this example (exec /boot/flash) is a fallback; it will not normally be
+# executed unless /boot/kexec is missing or damaged.
+#--------------------
+# #!/bin/sh
+# sleep=8 exec /boot/kexec /dev/sda1 /boot/zImage-ixp4xxbe \
+# "console=ttyS0,115200n8 root=/dev/sda1 rootfstype=ext3 rw init=/linuxrc"
+# exec /boot/flash
+#--------------------
+#
+# This one boots from flash in the normal fashion, except the kernel is
+# loaded using wget. This is common for kernel debugging.
+#--------------------
+# #!/bin/sh
+# exec /boot/kexec wget http://myserver/boot/zImage-ixp4xxbe \
+# "console=ttyS0,115200n8 root=/dev/mtdblock4 rootfstype=jffs2 rw \
+# init=/boot/flash noirqdebug"
+# exec /boot/flash
+#--------------------
+
+
+# Use the standard init path (see /etc/init.d/rcS)
+export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+
+# Wait at least a short while for the disks...
+if [ ! "$sleep" -gt 0 ] ; then
+ sleep=1
+fi
+
+# Load the helper functions
+. /etc/default/functions
+. /etc/default/modulefunctions
+
+# Print a distinctive banner to make it easy to separate the in-flash
+# kernel boot from the kexec'd kernel boot when looking at logs, etc.
+echo '###########################################################'
+echo '###################### KEXEC ######################'
+
+leds boot system
+
+if [ -n "$1" -a -n "$2" ] ; then
+
+ method="$1"
+ shift
+ kpath="$1"
+ shift
+ if [ -n "$1" ] ; then
+ kcmdline="$1"
+ shift
+ fi
+ kexec_image=
+ need_umount=0
+ do_kexec=0
+
+ mount -t proc proc /proc
+
+ case "$method" in
+
+ flash )
+ echo "Loading kexec kernel directly from \"$kpath\"..."
+ kexec_image="$kpath"
+ ;;
+
+ wget )
+ if /boot/network ; then
+ echo "mounting tmpfs partition..."
+ if mount -t tmpfs tmpfs /mnt ; then
+ need_umount=1
+ echo "Loading kexec kernel using wget \"$kpath\"..."
+ wget -P /mnt "$kpath"
+ t=`basename "$kpath"`
+ kexec_image="/mnt/$t"
+ fi
+ fi
+ ;;
+
+ nfs )
+ if /boot/network ; then
+ echo "Loading kexec kernel using nfs \"$kpath\"..."
+ echo "mounting nfs partition..."
+ loadnfsmods
+ if mount -o ro,nolock -t nfs `dirname "$kpath"` /mnt ; then
+ need_umount=1
+ t=`basename "$kpath"`
+ kexec_image="/mnt/$t"
+ fi
+ fi
+ ;;
+
+ /dev/* )
+ echo "Loading kexec kernel using disk \"$kpath\"..."
+ loaddiskmods
+ sleep "$sleep"
+ echo "mounting partition \"$method\"..."
+ if mount -o ro "$method" /mnt ; then
+ need_umount=1
+ kexec_image="/mnt/$kpath"
+ fi
+ ;;
+
+ UUID )
+ echo "Loading kexec kernel using disk UUID \"$kpath\"..."
+ loaddiskmods
+ sleep "$sleep"
+ if [ -n "$UUID" ] ; then
+ echo "mounting partition UUID \"$UUID\"..."
+ if mount -o ro UUID="$UUID" /mnt ; then
+ need_umount=1
+ kexec_image="/mnt/$kpath"
+ fi
+ fi
+ ;;
+
+ tftp )
+ if /boot/network ; then
+ echo "mounting tmpfs partition..."
+ if mount -t tmpfs tmpfs /mnt ; then
+ need_umount=1
+ t=`basename "$kpath"`
+ kexec_image="/mnt/$t"
+ echo "Loading kexec kernel using tftp \"$kpath\"..."
+ tftp -g -l "$kexec_image" -r "${kpath#*:}" "${kpath%%:*}"
+ fi
+ fi
+ ;;
+
+ * )
+ echo "Unrecognized method: \"$method\""
+ ;;
+
+ esac
+
+ if [ -n "$kexec_image" -a -f "$kexec_image" ] ; then
+ if kexec -l "$kexec_image" ; then
+ do_kexec=1
+ fi
+ else
+ echo "Unable to load \"$kexec_image\""
+ fi
+
+ if [ $do_kexec -eq 1 -a -n "$kcmdline" ] ; then
+ echo "Attempting to mount /sys (sysfs)..."
+ if mount -t sysfs sysfs /sys ; then
+ echo "Setting command line:"
+ echo " \"$kcmdline\""
+ echo "$kcmdline" > /sys/kernel/kexec_cmdline
+ echo "unmounting /sys..."
+ umount /sys
+ else
+ do_kexec=0
+ fi
+ fi
+
+ if [ $need_umount -eq 1 ] ; then
+ echo "unmounting /mnt..."
+ umount /mnt
+ fi
+
+ if [ $do_kexec -eq 1 ] ; then
+ echo "Remounting root as read-only..."
+ mount -o remount,ro /
+ echo "Invoking \"kexec -f -e\" ..."
+ kexec -f -e
+ echo "ERROR!"
+ # We should never return here! At this point, things are not
+ # too well. Remount the root as rw, and fallback.
+ echo "Remounting root as read-write..."
+ mount -o remount,rw /
+ fi
+else
+ echo "Usage: $0 flash|nfs|wget|UUID|/dev/<partition> <path-or-URL> [cmdline]"
+fi
+
+# fallback - use the flash boot
+echo "Falling back to flash boot..."
+leds beep -f 1000 -r 2
+exec /boot/flash
+
+# fallback to the fallback
+leds boot system panic
+exec <>/dev/console >&0 2>&0
+test -x /bin/sh && exec /bin/sh
+exit 1 \ No newline at end of file
diff --git a/recipes/slugos-init/files/boot/network b/recipes/slugos-init/files/boot/network
new file mode 100644
index 0000000000..b8054a0056
--- /dev/null
+++ b/recipes/slugos-init/files/boot/network
@@ -0,0 +1,41 @@
+#!/bin/sh
+# bring up the network before boot, used to allow
+# netconsole logging and NFS boot. This runs out
+# of flash, but that's ok because the script doesn't
+# leave any process running.
+
+# NOTE: /etc/default/functions defines ifup as a shell
+# function!
+. /etc/default/functions
+
+# We may need to load the network driver modules here
+. /etc/default/modulefunctions
+loadnetmods
+
+# Now all the information for booting should be in the configuration
+# file. Config the loopback and network interfaces.
+ifconfig lo 127.0.0.1 up
+iface="$(config iface)"
+test -z "$iface" && exit 1
+
+# Fire up a process in the background to load the firmware if necessary.
+# If this system doesn't require the NPE-B firmware, no problem, the
+# background process will simply go away in two seconds. If it requires
+# some other firmware, then modification will be required. We probably
+# should replace this with mdev or some other hotplug-based technique...
+sysf="/sys/class/firmware/$iface"
+(
+ # Wait for the firware to be requested, if required
+ [ -f $sysf/loading ] || sleep 1
+ [ -f $sysf/loading ] || sleep 1
+ if [ -f $sysf/loading ] ; then
+ echo "1" >$sysf/loading
+ cat /lib/firmware/NPE-B >$sysf/data
+ echo "0" >$sysf/loading
+ fi
+) &
+# Trigger the firmware load proactively
+ifconfig "$iface" up
+
+ifup "$iface"
+# exit code is true only if the interface config has succeeded
diff --git a/recipes/slugos-init/files/boot/nfs b/recipes/slugos-init/files/boot/nfs
new file mode 100644
index 0000000000..7f91889315
--- /dev/null
+++ b/recipes/slugos-init/files/boot/nfs
@@ -0,0 +1,31 @@
+#!/bin/sh
+# boot from the nfs partition "$1" (which
+# must be given) using options from the rest of
+# the command line.
+
+# Use the standard init path (see /etc/init.d/rcS)
+export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+
+# Mount required fileystems if necessary
+[ -e /proc/cpuinfo ] || mount -t proc proc /proc
+[ -e /sys/class ] || mount -t sysfs sysfs /sys
+
+# Load the helper functions
+. /etc/default/functions
+. /etc/default/modulefunctions
+
+leds boot system
+
+if /boot/network
+then
+ # load the nfs kernel module
+ loadnfsmods
+
+ # network is up and running, the NFS mount will
+ # now succeed (possibly), use /boot/disk
+ exec /boot/disk "$@"
+fi
+
+# fallback - use the flash boot
+leds beep -f 1000 -r 2
+exec /boot/flash
diff --git a/recipes/slugos-init/files/boot/ram b/recipes/slugos-init/files/boot/ram
new file mode 100644
index 0000000000..0a8fe1d25d
--- /dev/null
+++ b/recipes/slugos-init/files/boot/ram
@@ -0,0 +1,64 @@
+#!/bin/sh
+# boot from the hard disk partition "$1" (which
+# must be given) using options from the rest of
+# the command line.
+
+# Use the standard init path (see /etc/init.d/rcS)
+export PATH=/sbin:/bin:/usr/sbin:/usr/bin
+
+# Mount required fileystems if necessary
+[ -e /proc/cpuinfo ] || mount -t proc proc /proc
+[ -e /sys/class ] || mount -t sysfs sysfs /sys
+
+# Load the helper functions
+. /etc/default/functions
+
+leds beep -r 2
+leds boot system
+
+if test -n "$1"
+then
+ device="$1"
+ shift
+ echo "boot: rootfs: mount $* $device"
+
+ # prepare the device. This uses tmpfs to avoid dependency
+ # on non-built-in file systems and because tmpfs can expand
+ # to bigger than the 10MByte ram0 partition used before.
+ # The 'device' is currently unused.
+ if mount -t tmpfs "$@" tmpfs /mnt
+ then
+ cd /
+ # filter out boot (with zimage), linuxrc and anything
+ # below /var, keep dev or the boot will fail. Take
+ # care that nothing is mounted at this point!
+ umount /proc
+ umount /sys
+ find . -xdev -print |
+ sed '\@^./boot/@d;\@^./boot$@d;\@^./linuxrc@d;\@^./var/@d' |
+ cpio -p -d -m -u /mnt
+ # busybox find with -xdev will not print the name of the
+ # mountpoint, so create the empty dir manually if required.
+ test -d /mnt/mnt || mkdir /mnt/mnt
+ # checkmount checks for sh, chroot, init, /dev
+ # and /mnt (i.e. /mnt/mnt in this case).
+ # minimaldevnodes checks (and creates if required)
+ # a few mandatory /dev nodes we may need.
+ if checkmount /mnt && minimaldevnodes /mnt
+ then
+ # pivot to /mnt
+ cd /
+ swivel mnt mnt
+ # swivel failed
+ fi
+ # Failure: unmount the partition
+ umount /mnt
+ # Remount /proc and /sys if necessary
+ [ -e /proc/cpuinfo ] || mount -t proc proc /proc
+ [ -e /sys/class ] || mount -t sysfs sysfs /sys
+ fi
+fi
+
+# fallback - use the flash boot
+leds beep -f 1000 -r 2
+exec /boot/flash
diff --git a/recipes/slugos-init/files/boot/udhcpc.script b/recipes/slugos-init/files/boot/udhcpc.script
new file mode 100644
index 0000000000..3f437e3143
--- /dev/null
+++ b/recipes/slugos-init/files/boot/udhcpc.script
@@ -0,0 +1,17 @@
+#!/bin/sh
+# executed by udhcpc to do the real work of configuring an interface
+# writes the result (if any) to file descriptor 9
+case "$1" in
+deconfig) # ignored
+ :;;
+renew|bound) # this gives the real information
+ test -n "$ip" && {
+ echo "ip='$ip'"
+ echo "subnet='$subnet'"
+ echo "broadcast='$broadcast'"
+ echo "router='$router'"
+ } >&9;;
+leasefail) # ignore - probably no dhcp server
+ :;;
+*) echo "udhcpc: $*: command not recognised" >&2;;
+esac
diff --git a/recipes/slugos-init/files/conffiles b/recipes/slugos-init/files/conffiles
new file mode 100644
index 0000000000..668f7467a8
--- /dev/null
+++ b/recipes/slugos-init/files/conffiles
@@ -0,0 +1,55 @@
+# conffiles
+# Known SlugOS configuration files. These files are preserved on
+# a flash upgrade. Other configuration files, found from:
+#
+# /usr/lib/opkg/*.conffiles
+# /etc/*.conf
+#
+# are preserved too with an operation of 'diff' if they have been
+# changed since /etc/.configured was created.
+#
+# Lines starting with # are comments, other lines have
+# two fields:
+#
+# operation file
+#
+# The file must *NOT* have a leading /
+#
+# operation may be:
+# ignore Do not preserve this file
+# preserve Preserve this file unconditionally
+# diff Compare file with the new version, ask if different
+#
+preserve linuxrc
+preserve etc/.configured
+preserve etc/TZ
+diff etc/default/conffiles
+diff etc/default/devpts
+preserve etc/default/rcS
+preserve etc/default/sysconf
+diff etc/default/usbd
+preserve etc/defaultdomain
+preserve etc/dropbear/dropbear_dss_host_key
+preserve etc/dropbear/dropbear_rsa_host_key
+preserve etc/ssh/ssh_host_dsa_key
+preserve etc/ssh/ssh_host_dsa_key.pub
+preserve etc/ssh/ssh_host_rsa_key
+preserve etc/ssh/ssh_host_rsa_key.pub
+preserve etc/fstab
+preserve etc/group
+preserve etc/gshadow
+preserve etc/hostname
+preserve etc/hosts
+preserve etc/localtime
+ignore etc/modules
+ignore etc/modules.conf
+preserve etc/motd
+preserve etc/network/interfaces
+preserve etc/ntp.drift
+preserve etc/passwd
+preserve etc/profile
+preserve etc/resolv.conf
+preserve etc/shadow
+preserve etc/syslog.conf
+preserve etc/timezone
+preserve root/.ssh/authorized_keys
diff --git a/recipes/slugos-init/files/functions b/recipes/slugos-init/files/functions
new file mode 100644
index 0000000000..38a3b4d166
--- /dev/null
+++ b/recipes/slugos-init/files/functions
@@ -0,0 +1,427 @@
+#!/bin/sh
+# . this file to load the following utility functions
+#
+# hardware
+# the 'Hardware' string from cpuinfo
+hardware(){
+ sed -n 's!^Hardware *: !!p' /proc/cpuinfo
+}
+#
+# machine
+# outputs an identifier of the current machine - i.e. the board
+# slugos is running on.
+machine(){
+ case "$(hardware)" in
+ *Coyote*) echo coyote;;
+ *IXDPG425*) echo ixdpg425;;
+ *WRV54G*) echo wrv54g;;
+ *IXDP425*) echo ixdp425;;
+ *IXDP465*) echo ixdp465;;
+ *IXCDP1100*) echo ixcdp1100*;;
+ *Avila*) echo avila;;
+ *Loft*) echo loft;;
+ *NAS?100d*) echo nas100d;;
+ *DSM?G600*) echo dsmg600;;
+ *NSLU2*) echo nslu2;;
+ *FSG?3*) echo fsg3;;
+ *) echo unknown;;
+ esac
+}
+#
+# single_user_ok
+# if the machine is capable of single user interaction return
+# true, else return false. The result of this function is
+# preempted by setting SULOGIN to 'yes' or 'ok' in /etc/default/rcS
+single_user_ok() {
+ # list known good machines in the 'case'
+ test "$SULOGIN" = yes -o "$SULOGIN" = ok ||
+ case "$(machine)" in
+ ixdp*|avila|loft)
+ test "$SULOGIN" != never;;
+ *) return 1;;
+ esac
+}
+#
+# load_functions "source"
+# load the functions in '/sbin/source' - relies on /sbin/source being
+# a shell script and having support for this function.
+load_functions(){
+ test -n "$1" -a -x "/sbin/$1" && . "/sbin/$1" || {
+ echo "$0: /sbin/$1: script not found" >&2
+ return 1
+ }
+}
+#
+# mtdev "name"
+# return (output) the character device name for flash parition "name"
+# /proc/mtd has the general form:
+# dev: size erasesize name
+# mtd5: 00020000 00020000 "FIS directory"
+# use this rather than hard-wiring the device because the partition
+# table can change - looking in /proc/mtd is more reliable.
+mtdev(){
+ sed -n 's!^\(mtd[0-9][0-9]*\):[^"]*"'"$1"'"$!/dev/\1!p' /proc/mtd
+}
+#
+# mtblockdev "name"
+# as mtdev but output the name of the block (not character) device
+mtblockdev(){
+ sed -n 's!^mtd\([0-9][0-9]*\):[^"]*"'"$1"'"$!/dev/mtdblock\1!p' /proc/mtd
+}
+#
+# mtsize "name"
+# the size of the partition as a hexadecimal value (with 0x at the front)
+mtsize(){
+ sed -n 's!^mtd[0-9][0-9]*: \([^ ]*\)[^"]*"'"$1"'"$!0x\1!p' /proc/mtd
+}
+#
+# sysvalmatch "section" "name" 'pattern' "configuration file"
+# sysvalof "section" "name" "configuration file"
+# sysval "section" "name"
+# outputs the value of the SysConf variable 'name' from section 'section',
+# if there are multiple definitions only the last is output
+# NOTE: these functions should only be used internally, add entries to 'config'
+# below if necessary. This is because 'config' does the defaulting.
+sysvalmatch(){
+ sed -n '/^\['"$1"'\]$/,/^\[.*\]$/s/^'"$2"'=\('"$3"'\)$/\1/p' "$4" | sed -n '$p'
+}
+sysvalof(){
+ sysvalmatch "$1" "$2" '.*' "$3"
+}
+sysval(){
+ test -r "$config_root/etc/default/sysconf" &&
+ sysvalof "$1" "$2" "$config_root/etc/default/sysconf"
+}
+#
+# syssection "section"
+# outputs all the values from the given section changed to the format "name value"
+# (i.e. the '=' is dropped).
+syssection(){
+ test -r "$config_root/etc/default/sysconf" &&
+ sed -n '/^\['"$1"'\]$/,/^\[.*\]$/s/^\([^=]*\)=\(.*\)$/\1 \2/p' "$config_root/etc/default/sysconf"
+}
+#
+# config "value"
+# convenience callers for specific values to avoid mis-typing in scripts
+# NOTE: this function does the defaulting, 'sysval' does not!
+# config_root: if set this will override the root where config/sysval
+# looks for /etc/default/sysconf
+config(){
+ local mac
+ mac="$(test -r /proc/net/maclist &&
+ sed -n '/^[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]:[0-9A-Za-z][0-9A-Za-z]$/p' /proc/net/maclist |
+ sed -n 1p)"
+ #
+ case "$1" in
+ mac) test -n "$mac" && echo "$mac";;
+ host) if test -n "$(sysval network disk_server_name)"
+ then
+ sysval network disk_server_name
+ elif test -n "$(sysval network default_server_name)"
+ then
+ sysval network default_server_name
+ elif test -n "$mac"
+ then
+ echo "$mac" | sed -n 's/^\(..\):\(..\):\(..\):\(..\):\(..\):\(..\)$/slug\1\2\3\4\5\6/p'
+ else
+ # because we want the name to remain constant:
+ echo "brokenslug"
+ fi;;
+ domain) sysval network w_d_name;;
+ iface) if test -n "$(sysval network lan_interface)"
+ then
+ sysval network lan_interface
+ else
+ echo eth0
+ fi;;
+ ip) if test -n "$(sysval network ip_addr)"
+ then
+ sysval network ip_addr
+ else
+ echo 192.168.1.77
+ fi;;
+ netmask)sysval network netmask;;
+ gateway)sysval network gateway;;
+ dns) sysval network dns_server1;;
+ dns2) sysval network dns_server2;;
+ dns3) sysval network dns_server3;;
+ boot) if test -n "$(sysval network bootproto)"
+ then
+ sysval network bootproto
+ else
+ echo dhcp
+ fi;;
+ valid) test -r "$config_root/etc/default/sysconf" -a -n "$mac";;
+ *) return 1;;
+ esac
+}
+#
+# checkif "iface"
+# Validate an interface name by making sure that it exists
+# in /proc/net/dev (and is not lo). The listing outputs the
+# interface followed by a :, the check function looks for
+# something of the form '$1[a-zA-Z0-9]*:' and outputs the
+# part preceding the ':'
+checkif(){
+ sed -n '/^[ ]*lo:/d;s/^[ ]*\('"$1"'[a-zA-Z0-9]*\):.*$/\1/p;tE;d;:E;q' /proc/net/dev
+}
+#
+# checkmount "mountpoint"
+# tests an already mounted mountpoint to see whether to attempt to
+# boot with this as root. Returns success if it appears ok.
+checkmount(){
+ # basic test for init (the kernel will try to load this)
+ # but require a shell in bin/sh too
+ test \( -d "$1/mnt" \) -a \
+ \( -d "$1/dev" \) -a \
+ \( -x "$1/bin/sh" -o -h "$1/bin/sh" \) -a \
+ \( -x "$1/usr/sbin/chroot" -o -h "$1/usr/sbin/chroot" -o \
+ -x "$1/sbin/chroot" -o -h "$1/sbin/chroot" \) -a \
+ \( -x "$1/sbin/init" -o -h "$1/sbin/init" -o \
+ -x "$1/etc/init" -o -h "$1/etc/init" -o \
+ -x "$1/bin/init" -o -h "$1/bin/init" \)
+}
+#
+# minimaldevnodes "mountpoint"
+# tests an already mounted mountpoint to see if a very minimal
+# set of devices exists or can be created in dev, and returns
+# failure if not. This is required for booting to an nfsroot
+# with an empty dev directory, as commonly occurs when the rootfs
+# is created from a tar.gz image. This is also required for mdev.
+minimaldevnodes(){
+ [ -c "$1/dev/console" ] || mknod -m 600 "$1/dev/console" c 5 1 || return 1
+ [ -c "$1/dev/null" ] || mknod -m 666 "$1/dev/null" c 1 3 || return 1
+ [ -c "$1/dev/tty0" ] || mknod -m 644 "$1/dev/tty0" c 4 0 || return 1
+ return 0
+}
+#
+# swivel "new root" "old root"
+# NOTE: the arguments must be paths relative to /, bad things
+# will happen if the arguments themselves start with /
+# Pivot to a new root. This does all the fancy pivot_root stuff
+# including closing streams and does a umount of /proc and /sys -
+# it doesn't matter if this fails (failure codes are ignored),
+# but if /proc and/or /sys was mounted it must be restored by the
+# caller on return. Normally this function never returns!
+# On return 0,1,2 are connected to /dev/console - this may not
+# have been true before!
+swivel(){
+ cd "$1"
+ exec <&- >&- 2>&-
+ # This is just-in-case the caller mounted either /proc or
+ # /sys, and was unable to close them
+ umount /sys 2>/dev/null
+ umount /proc 2>/dev/null
+ if pivot_root . "$2"
+ then
+ # everything must move out of the old root, this process
+ # is $2/bin/sh so it must die, IO is redirected
+ # just in case - typically it will be to a device so it
+ # won't hold the old root open.
+ # the exec here is the first point at which the old root
+ # is unused - before the exec regardless of the close of
+ # 0,1,2 above ash still has *this* shell script open!
+ # (it's on fd 10).
+ # init closes all file descriptors, there's no point
+ # supplying it with fds.
+ # NOTE: this used to use $2/usr/sbin/chroot, however on
+ # linux / is already . when the command is executed
+ # therefore it is essential to use the local (new root)
+ # chroot to ensure it gets the correct shared libraries.
+ if test -x usr/sbin/chroot -o -h usr/sbin/chroot
+ then
+ chroot=usr/sbin/chroot
+ elif test -x sbin/chroot -o -h sbin/chroot
+ then
+ chroot=sbin/chroot
+ else
+ chroot=chroot
+ fi
+ #
+ exec "$chroot" . bin/sh -c "\
+ test -x sbin/init && exec sbin/init
+ test -x etc/init && exec etc/init
+ test -x bin/init && exec bin/init
+ # Problematic failure! The chroot worked, but the
+ # exec failed. Nothing to do but blink the LEDs.
+ # (Use a wildcard because the LED names depend on
+ # the version of the kernel in use.)
+ mount -t sysfs sysfs /mnt
+ for i in /mnt/class/leds/*[ready\|status]
+ do
+ echo -n timer >$i/trigger
+ echo -n 60 >$i/delay_on
+ echo -n 30 >$i/delay_off
+ done
+ umount /mnt
+ sync;sync;sync
+ exit 1"
+ fi
+ #
+ # recovery - must restore the old root
+ cd "$2"
+ sbin/pivot_root . "$1"
+ # cd is back to $1 - either pivot_root doesn't change it and the
+ # chroot above was not executed, or pivot_root does change it and
+ # has just changed it back!
+ exec <>/dev/console >&0 2>&0
+}
+#
+# ifup "interface"
+# bring that interface up with the configured ip and other
+# information
+ifup(){
+ local ip hostname router subnet iface HOSTNAME NETMASK BROADCAST
+
+ iface="$1"
+ ip="$(config ip)"
+ hostname="$(config host)"
+ router="$(config gateway)"
+ broadcast=
+
+ if test -n "$ip"
+ then
+ # only if an ip was specified
+ subnet="$(config netmask)"
+ else
+ ip=192.168.1.77
+ fi
+
+ # First try udhcpc - note that the /boot/udhcpc.script
+ # simply records the values returned and the udhcpc
+ # is not left running so this will only work for
+ # the lease length time!
+ ifconfig "$iface" up
+ if test "$(config boot)" != static
+ then
+ test -n "$hostname" && HOSTNAME="-H $hostname"
+ # Pause a moment in case link negotiation takes a while
+ sleep 3
+ # The script writes the required shell variable assignments
+ # to file descriptor 9
+ eval $(udhcpc -i "$iface" -n -q -r "$ip" $HOSTNAME -s /boot/udhcpc.script 9>&1 >/dev/null)
+ fi
+
+ test -n "$broadcast" && BROADCAST="broadcast $broadcast"
+ test -n "$subnet" && NETMASK="netmask $subnet"
+
+ if ifconfig "$iface" "$ip" $NETMASK $BROADCAST
+ then
+ for route in $router
+ do
+ route add default gw "$route" dev "$iface"
+ done
+ return 0
+ else
+ ifconfig "$iface" down
+ return 1
+ fi
+}
+#
+# ifdown "interface"
+# take the interface down
+ifdown(){
+ ifconfig "$1" down
+}
+#
+# mountflash "flash device" "flash root directory" {mount options}
+# Finds and mounts the flash file system on the given directory
+mountflash(){
+ local ffsdev ffsdir
+
+ ffsdev="$1"
+ test -n "$ffsdev" -a -b "$ffsdev" || {
+ echo "$0: unable to find flash file system to copy ($ffsdev)" >&2
+ return 1
+ }
+ shift
+
+ ffsdir="$1"
+ test -n "$ffsdir" -a -d "$ffsdir" || {
+ echo "$0: mountflash $ffsdir: not a directory (internal error)" >&2
+ return 1
+ }
+ shift
+
+ mount -t jffs2 "$@" "$ffsdev" "$ffsdir" || {
+ echo "$0: $ffsdev: unable to mount flash file system on $ffsdir" >&2
+ return 1
+ }
+ return 0
+}
+#
+# umountflash [-r] "flash device"
+# unmount any instance of the given flash device, if -r is specified a mount on
+# root is an error, otherwise a mount on root is ignored (and remains).
+umountflash(){
+ local rootok ffsno ffsdev
+ rootok=1
+ case "$1" in
+ -r) rootok=
+ shift;;
+ esac
+ #
+ # The argument is ffsdev
+ ffsdev="$1"
+ ffsno="$(devio "<<$ffsdev" prd)"
+ test -n "$ffsno" -a "$ffsno" -ge 0 || {
+ echo "$0: $ffsdev: device number $ffsno is not valid, cannot continue." >&2
+ return 1
+ }
+ #
+ # Make sure that Flashdisk isn't mounted on /
+ if test -z "$rootok" -a "$(devio "<</etc/init.d/sysconfsetup" prd)" -eq "$ffsno"
+ then
+ echo "$0: $ffsdev is mounted on /, use turnup ram" >&2
+ return 1
+ fi
+ #
+ # The function is currently always used interactively, so output
+ echo "$0: umounting any existing mount of $ffsdev" >&2
+ #
+ # check each mount point, do this last first because otherwise nested
+ # mounts of ffsdev cannot be umounted.
+ ffs_umount() {
+ local device mp type options stuff
+
+ read device mp type options stuff
+ test -z "$device" && return 0
+
+ # handle following entries first
+ ffs_umount || return 1
+
+ # handle this entry, since this is currently only used for unmounting
+ # the flash root partition we know a file which must exist...
+ case "$mp/$type" in
+ //jffs2);; # skip /
+ */jffs2)test "$(devio "<<$mp/etc/init.d/sysconfsetup" prd 2>/dev/null)" -ne "$ffsno" ||
+ umount "$mp" || {
+ echo "$0: $mp: unable to umount $ffsdev" >&2
+ return 1
+ };;
+ esac
+
+ return 0
+ }
+ #
+ ffs_umount </proc/mounts || {
+ echo "$0: umount $ffsdev from all mount points then re-run $0" >&2
+ return 1
+ }
+
+ return 0
+}
+
+#
+# uuid_by_partition
+# output a list of partitions and their UUIDs
+uuid_by_partition() {
+ blkid -c /dev/null -s UUID | sed -n 's/^\([^:]*\): .*UUID="\([^"]*\)".*$/\1 \2/p'
+}
+
+#
+# partition_of uuid
+# return the partition corresponding to the UUID
+partition_of() {
+ sed -n 's/^\([^ ]*\) '"$1"'$/\1/p'
+}
diff --git a/recipes/slugos-init/files/initscripts/fixfstab b/recipes/slugos-init/files/initscripts/fixfstab
new file mode 100644
index 0000000000..67116a12fd
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/fixfstab
@@ -0,0 +1,91 @@
+#!/bin/sh
+# validate /etc/fstab against the current UUID list in
+# /etc/uuid_by_partition
+#
+. /etc/default/functions
+pfile=/etc/uuid_by_partition
+
+#
+# use debug to find out what is going on
+test "$1" = start -o "$1" = debug || exit 0
+
+#
+# obtain the current list of parititions with UUIDs
+newlist="$(uuid_by_partition)"
+
+if test -r "$pfile"
+then
+ # read the old list
+ oldlist="$(cat "$pfile")"
+ #
+ # if it hasn't changed nothing need be done
+ test "$newlist" = "$oldlist" && exit 0
+ #
+ # it has changed, but this only matters if
+ # a previously existing uuid has moved, build
+ # a list of old device vs new device for every
+ # uuid which has moved
+ changedlist="$(
+ { echo "$oldlist"
+ echo "$newlist"
+ } | awk 'device[$2] == ""{device[$2] = $1}
+ device[$2] != $1{print device[$2], $1}')"
+
+ if test -n "$changedlist"
+ then
+ # at least one partition has moved, scan the
+ # current fstab to see if it has a reference
+ # to this partition
+ changedfstab="$(
+ { echo "$changedlist"
+ echo '#fstab'
+ cat /etc/fstab
+ } | awk 'BEGIN{list=1}
+ list==1 && $0=="#fstab"{list=0; continue}
+ list==1{new[$1] = $2; continue}
+ new[$1] != ""{print $1, new[$1]}')"
+
+ # if this list is not empty edit the fstab
+ if test -n "$changedfstab"
+ then
+ rm -f /tmp/fstab.$$
+ # if the edit fails then do not overwrite the old
+ # partition list - just exit with an error
+ { echo "$changedlist"
+ echo '#fstab'
+ cat /etc/fstab
+ } | awk 'BEGIN{list=1}
+ list==1 && $0=="#fstab"{list=0; continue}
+ list==1{new[$1] = $2; continue}
+ new[$1] != ""{$1 = new[$1]}
+ {print}' >/tmp/fstab.$$ || {
+ if test "$1" = start
+ then
+ logger -s "/etc/init.d/fixfstab: /tmp/fstab.$$: awk failed"
+ else
+ echo "debug: awk script failed with:" >&2
+ echo "$changedlist" >&2
+ echo "output in /tmp/fstab.$$" >&2
+ fi
+ exit 1
+ }
+
+ if test "$1" = start
+ then
+ mv /tmp/fstab.$$ /etc/fstab || {
+ logger -s "/etc/init.d/fixfstab: /tmp/fstab.$$: update failed"
+ exit 1
+ }
+ else
+ echo "debug: fstab changed:"
+ diff -u /etc/fstab /tmp/fstab.$$
+ fi
+ fi
+ fi
+fi
+
+# write the new list to the file, only if we
+# are doing something...
+test "$1" = start && echo "$newlist" >"$pfile"
+
+exit 0
diff --git a/recipes/slugos-init/files/initscripts/leds_startup b/recipes/slugos-init/files/initscripts/leds_startup
new file mode 100644
index 0000000000..945d75bd02
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/leds_startup
@@ -0,0 +1,11 @@
+#!/bin/sh
+# Bug fix: during the initial boot sysvinit sets PREVLEVEL to
+# nothing in rcS and to 'N' in the transition from rcS to the
+# user state. This script runs on that transition and, if
+# the PREVLEVEL is 'N', sets 'previous' (as in /etc/init.d/rc)
+# to 'S'
+if test "$PREVLEVEL" = N
+then
+ previous=S exec /etc/init.d/zleds stop
+fi
+exit 0
diff --git a/recipes/slugos-init/files/initscripts/loadmodules.sh b/recipes/slugos-init/files/initscripts/loadmodules.sh
new file mode 100644
index 0000000000..e80f995598
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/loadmodules.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+# This script is used for loading modules required by SlugOS
+# This script may not be necessary if udev is present, but is included
+# for 'backup' purposes in case udev is playing silly buggers
+
+. /etc/default/modulefunctions # Load module loading logic
+
+loadnetmods
+
+loaddiskmods
+
+loadmiscmods
+
+exit 0
diff --git a/recipes/slugos-init/files/initscripts/rmrecovery b/recipes/slugos-init/files/initscripts/rmrecovery
new file mode 100644
index 0000000000..eec822b154
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/rmrecovery
@@ -0,0 +1,4 @@
+#!/bin/sh
+# Run to remove /.recovery if the boot seems to have succeeded
+test -e /.recovery && rm -f /.recovery
+exit 0
diff --git a/recipes/slugos-init/files/initscripts/sysconfsetup b/recipes/slugos-init/files/initscripts/sysconfsetup
new file mode 100644
index 0000000000..a4f9074d9c
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/sysconfsetup
@@ -0,0 +1,46 @@
+#!/bin/sh
+# This script is run once when the system first boots. Its sole
+# purpose is to create /etc/default/sysconf (the overall system
+# configuration file) and other files derived from this.
+#
+# The script runs immediately after S10checkroot.sh - this is the
+# point at which the rootfs will be mounted rw even if the kernel
+# booted with it ro.
+#
+# rm or mv the file (/etc/default/sysconf) to recreate it, run this
+# script with the reload option to overwrite the system files. The
+# configuration files described in sysconf_reload (in
+# /sbin/sysconf) will be overwritten on reload.
+#
+# start: standard startup, do a complete (auto) restore if necessary
+# reinit: always do a complete auto restore
+# reload: just reload sysconf (no config files!)
+#
+# /etc/default/functions contains useful utility functions - it's
+# in a separate file so that it can be loaded by any script
+. /etc/default/functions
+load_functions sysconf || exit 1
+#
+case "$1" in
+start) test -s /etc/default/sysconf || {
+ if sysconf_read
+ then
+ if sysconf_valid
+ then
+ sysconf_restore auto
+ else
+ sysconf_reload
+ fi
+ else
+ sysconf_default
+ sysconf_reload
+ fi
+ };;
+
+reload) test -s /etc/default/sysconf || sysconf_read || sysconf_default
+ sysconf_reload;;
+
+reinit) sysconf_restore auto;;
+
+*) ;;
+esac
diff --git a/recipes/slugos-init/files/initscripts/syslog.buffer b/recipes/slugos-init/files/initscripts/syslog.buffer
new file mode 100644
index 0000000000..9285c02946
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/syslog.buffer
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# Invoke the syslog startup if the configuration
+# uses (only) 'buffer' as the DESTINATION
+DESTINATION=
+test -f /etc/syslog.conf && . /etc/syslog.conf
+doit=
+
+for d in $DESTINATION
+do
+ case "$d" in
+ buffer) doit=1;;
+ file) exit 0;;
+ remote) exit 0;;
+ *) echo "/etc/syslog.conf: $d: unknown destination" >&2
+ exit 1;;
+ esac
+done
+
+test -n "$doit" -a -x /etc/init.d/syslog &&
+ exec /etc/init.d/syslog "$@"
+
+exit 0
diff --git a/recipes/slugos-init/files/initscripts/syslog.file b/recipes/slugos-init/files/initscripts/syslog.file
new file mode 100644
index 0000000000..80ee5f0174
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/syslog.file
@@ -0,0 +1,23 @@
+#!/bin/sh
+#
+# Invoke the syslog startup if the configuration
+# uses 'file' (and, optionally, buffer) as the DESTINATION
+DESTINATION=
+test -f /etc/syslog.conf && . /etc/syslog.conf
+doit=
+
+for d in $DESTINATION
+do
+ case "$d" in
+ buffer) :;;
+ file) doit=1;;
+ remote) exit 0;;
+ *) echo "/etc/syslog.conf: $d: unknown destination" >&2
+ exit 1;;
+ esac
+done
+
+test -n "$doit" -a -x /etc/init.d/syslog &&
+ exec /etc/init.d/syslog "$@"
+
+exit 0
diff --git a/recipes/slugos-init/files/initscripts/syslog.network b/recipes/slugos-init/files/initscripts/syslog.network
new file mode 100644
index 0000000000..3d7f4ab8e6
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/syslog.network
@@ -0,0 +1,28 @@
+#!/bin/sh
+#
+# Invoke the syslog startup if the configuration
+# uses 'remote', or doesn't use 'buffer' or 'file'
+DESTINATION=
+test -f /etc/syslog.conf && . /etc/syslog.conf
+doit=
+doneit=
+
+for d in $DESTINATION
+do
+ case "$d" in
+ buffer) doneit=1;;
+ file) doneit=1;;
+ remote) doit=1;;
+ *) doit=1
+ echo "/etc/syslog.conf: $d: unknown destination" >&2
+ exit 1;;
+ esac
+done
+
+# One of doneit or doit is set unless the DESTINATION value
+# is empty (which is probably an error), let syslog handle
+# the error.
+test \( -n "$doit" -o -z "$doneit" \) -a -x /etc/init.d/syslog &&
+ exec /etc/init.d/syslog "$@"
+
+exit 0
diff --git a/recipes/slugos-init/files/initscripts/umountinitrd.sh b/recipes/slugos-init/files/initscripts/umountinitrd.sh
new file mode 100644
index 0000000000..93f05a00f6
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/umountinitrd.sh
@@ -0,0 +1,33 @@
+#!/bin/sh
+#
+# umount /mnt, which is where the initrd ends up mounted
+# if the directory /initrd is not present, if this fails
+# then the /initrd is mounted and we want to remount that
+# ro - this works round the shutdown -r hang problem
+. /etc/default/functions
+
+case "$(machine)" in
+nslu2)
+ ffspart="Flashdisk";;
+*)
+ ffspart="filesystem";;
+esac
+
+while read device directory remainder
+do
+ case "$directory" in
+ /mnt) echo "InitRD: unmount initrd on /mnt" >&2
+ umount /mnt;;
+ /initrd)# need the device for a remount
+ ffsdev="$(mtblockdev $ffspart)"
+ [ -n "$ffsdev" ] || \
+ ffsdev="$(mtblockdev rootfs)"
+ echo "Remounting $ffsdev read-only on /initrd" >&2
+ if test -n "$ffsdev" -a -b "$ffsdev"
+ then
+ mount -o remount,ro "$ffsdev" /initrd
+ else
+ echo "$ffspart: $ffsdev: flash device not found" >&2
+ fi;;
+ esac
+done </proc/mounts
diff --git a/recipes/slugos-init/files/initscripts/zleds b/recipes/slugos-init/files/initscripts/zleds
new file mode 100644
index 0000000000..4c8277a53d
--- /dev/null
+++ b/recipes/slugos-init/files/initscripts/zleds
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# This script is executed at the start and end of each run-level
+# transition. It is the first 'stop' script and the last 'start'
+# script.
+#
+# 'stop' indicates the start of a runlevel change
+# 'start' at the end of the runlevel change - we are in the new
+# runlevel.
+#
+# state outputs 'system', 'user' etc according the the nature of
+# the runlevel it is passed (the *new* runlevel is used).
+state(){
+ case "$1" in
+ S|N) echo system;;
+ 0|6) echo shutdown;;
+ 1) echo singleuser;;
+ 2|3|4|5) echo user;;
+ *) echo "led change: $runlevel: runlevel unknown" >&2
+ echo system;;
+ esac
+}
+
+# trumpet "beeps" an announcement on systems with such support.
+l=120 # Long beep time
+s=40 # Try to keep a 3:1 ratio
+trumpet(){
+ case "$1" in
+ k) leds beep -l $l; leds beep -l $s; leds beep -l $l;;
+ n) leds beep -l $l; leds beep -l $s;;
+ *) leds beep;;
+ esac
+}
+
+case "$1" in
+start) leds "$(state "$runlevel")"
+ if [ "$(state "$runlevel")" == "user" ]; then
+ trumpet "k"
+ fi
+ ;;
+stop) leds boot "$(state "$runlevel")"
+ ;;
+*) echo "led change: $1: command ignored" >&2
+ ;;
+esac
diff --git a/recipes/slugos-init/files/leds b/recipes/slugos-init/files/leds
new file mode 100644
index 0000000000..b40d5d874e
--- /dev/null
+++ b/recipes/slugos-init/files/leds
@@ -0,0 +1,269 @@
+#!/bin/sh
+# leds
+#
+# utilities to manipulate the settings of the system leds
+#
+# load the utility functions unless this script is being called
+# just to load its own functions.
+case "$1" in
+leds) ;;
+*) . /etc/default/rcS
+ . /etc/default/functions;;
+esac
+
+#
+# led_set led-dir off|on|slow|fast|panic|blink|flash|*
+# set the given LED (expressed as a directory) to the
+# given status.
+#
+led_set(){
+ local setting
+ # expect led-dir state
+ if test -d "$1"
+ then
+ setting="$2"
+ case "$setting" in
+ off|on) echo -n none
+
+ case "$setting" in
+ on) echo -n 255;;
+ off) echo -n 0;;
+ esac >"$1/brightness";;
+
+ slow|fast|panic|blink|flash)
+ echo -n timer
+
+ case "$setting" in
+ flash) echo -n 60;;
+ blink) echo -n 540;;
+ slow) echo -n 500;;
+ fast) echo -n 1500;;
+ panic) echo -n 3000;;
+ esac >"$1/delay_on"
+
+ case "$setting" in
+ flash) echo -n 540;;
+ blink) echo -n 60;;
+ slow) echo -n 500;;
+ fast) echo -n 1500;;
+ panic) echo -n 3000;;
+ esac >"$1/delay_off";;
+
+ *) echo -n "$setting";;
+ esac >"$1/trigger"
+ else
+ echo "leds: $1: no such directory" >&2
+ return 1
+ fi
+}
+
+#
+# sysled [boot] system|user|singleuser|shutdown [error|panic|*]
+# set the system LEDs to indicate the given boot state, the function
+# will temporarily mount sysfs is necessary (using /mnt)
+#
+# the cases for two LEDs (ready+status)
+sysled_readystatus(){
+ local ready status
+ # expect dir [boot](system|user) [error|panic]
+ case "$3" in
+ error) ready=fast; status=off;;
+ panic) ready=fast; status=fast;;
+ *) case "$2" in
+ bootsystem) ready=slow; status=slow;;
+ system) ready=on; status=on;;
+ bootuser) ready=on; status=slow;;
+ user) ready=user; status=off;;
+ bootsingleuser) ready=on; status=slow;;
+ singleuser) ready=user; status=user;;
+ bootshutdown) ready=on; status=slow;;
+ shutdown) ready=slow; status=on;;
+ esac;;
+ esac
+
+ led_set "$1/$ready_led_name" "$ready"
+ led_set "$1/$status_led_name" "$status"
+}
+#
+# the cases for one LED (just ready)
+sysled_ready(){
+ local ready
+ # expect dir [boot](system|user) [error|panic]
+ case "$3" in
+ error) ready=fast;;
+ panic) ready=panic;;
+ *) case "$2" in
+ bootsystem) ready=flash;;
+ system) ready=blink;;
+ bootuser) ready=slow;;
+ user) ready=user;;
+ bootsingleuser) ready=flash;;
+ singleuser) ready=blink;;
+ bootshutdown) ready=slow;;
+ shutdown) ready=blink;;
+ esac;;
+ esac
+
+ led_set "$1/$ready_led_name" "$ready"
+}
+#
+# the cases for one blue flashing LED (just power)
+sysled_power(){
+ local power
+ # expect dir [boot](system|user) [error|panic]
+ case "$3" in
+ error) power=off;;
+ panic) power=off;;
+ *) case "$2" in
+ bootsystem) power=off;; # blinking
+ system) power=off;; # blinking
+ bootuser) power=on;;
+ user) power=on;;
+ bootsingleuser) power=off;; # blinking
+ singleuser) power=off;; # blinking
+ bootshutdown) power=off;; # blinking
+ shutdown) power=off;; # blinking
+ esac;;
+ esac
+
+ led_set "$1/$power_led_name" "$power"
+}
+#
+sysled(){
+ local mp st boot isst
+ mp=/sys
+ st=1
+ boot=
+
+ # validate arguments
+ if test "$1" = boot
+ then
+ shift
+ boot=boot
+ fi
+ case "$1" in
+ system|user|singleuser|shutdown) :;;
+ *) echo "sysled: unknown option '$1'" >&2
+ echo " usage: sysled [boot] system|user|singleuser|shutdown [error|panic|*]" >&2
+ return 1;;
+ esac
+
+ if test ! -d "$mp/class/leds" && mount -t sysfs sysfs /mnt
+ then
+ mp=/mnt
+ fi
+ #
+ # check for the 'ready' LED - otherwise check for a 'power' LED
+ if test -d "$mp/class/leds/$ready_led_name"
+ then
+ if test -d "$mp/class/leds/$status_led_name"
+ then
+ sysled_readystatus "$mp/class/leds" $boot"$@"
+ else
+ sysled_ready "$mp/class/leds" $boot"$@"
+ fi
+ else
+ if test -d "$mp/class/leds/$power_led_name"
+ then
+ sysled_power "$mp/class/leds" $boot"$@"
+ fi
+ fi
+ #
+ # clean up
+ test "$mp" = /mnt && umount /mnt
+ return "$st"
+}
+
+#
+# beep {arguments}
+# emit a beep
+# does nothing if there is no beep executable, is very
+# quiet in the presence of errors
+beep(){
+ local arg devices module
+ arg=
+ test "$1" = beep && shift
+ if test -x /bin/beep
+ then
+ devices=`ls -d /sys/class/input/event* 2>/dev/null`
+ for device in $devices
+ do
+ module=`egrep PHYSDEVDRIVER $device'/uevent' | cut -d '=' -f 2`
+ if test "$module" = "ixp4xx-beeper";
+ then
+ devnode=`echo "$device" | cut -d '/' -f 5`
+ arg="-e /dev/input/"$devnode
+ break
+ fi
+ done
+ /bin/beep $arg "$@" 2>/dev/null
+ fi
+ return 0
+}
+
+#
+# leds_help
+# be helpful
+# leds <led> off|on|slow|fast|panic|blink|flash|user|*
+# leds [boot] system|user|singleuser|shutdown [error|panic|*]
+leds_help(){
+ echo "leds: change the setting of the LEDs" >&2
+ echo " usage:" >&2
+ echo " leds [boot] system|user|singleuser|shutdown [error|panic|*]" >&2
+ echo " set leds during system boot to indicate a particular boot" >&2
+ echo " state. 'boot' means that the system is transitioning to" >&2
+ echo " the new state. 'error' or 'panic' means a (potentially)" >&2
+ echo " recoverable error or an unrecoverable error ('panic') has" >&2
+ echo " occured." >&2
+ echo " <led> off|on|slow|fast|panic|blink|flash" >&2
+ echo " set the named led to the given display." >&2
+ echo " beep {args}" >&2
+ echo " if possible cause the machine to emit a beep" >&2
+}
+
+# Define the LED names based on kernel version.
+version=$(uname -r | cut -c -6)
+if [ "$version" \< "2.6.25" ]; then
+ status_led_name="status"
+ ready_led_name="ready"
+ power_led_name="power"
+else
+ case "$(machine)" in
+ dsmg600)
+ status_led_name="none"
+ ready_led_name="none"
+ power_led_name="dsmg600:green:power"
+ ;;
+ fsg3)
+ status_led_name="none"
+ ready_led_name="fsg:blue:sync"
+ power_led_name="none"
+ ;;
+ nas100d)
+ status_led_name="none"
+ ready_led_name="none"
+ power_led_name="nas100d:blue:power"
+ ;;
+ nslu2)
+ status_led_name="nslu2:red:status"
+ ready_led_name="nslu2:green:ready"
+ power_led_name="none"
+ ;;
+ esac
+fi
+
+# the real command, if required
+case "$1" in
+boot|system|user|singleuser|shutdown)
+ sysled "$@";;
+
+beep) beep "$@";;
+
+""|-*) leds_help;;
+help) leds_help;;
+
+leds) # just load the functions
+ ;;
+
+*) led_set /sys/class/leds/"$@"
+esac
diff --git a/recipes/slugos-init/files/links.conf b/recipes/slugos-init/files/links.conf
new file mode 100644
index 0000000000..fdd1f3ce23
--- /dev/null
+++ b/recipes/slugos-init/files/links.conf
@@ -0,0 +1,6 @@
+# This file does not exist. Please do not ask the debian maintainer about it.
+# You may use it to do strange and wonderful things, at your risk.
+
+# The new RTC class does not create the /dev/rtc symlink, and udev rules don't get run for built-in modules.
+# So it looks like we have to do this here for the moment, until someone comes up with a better idea ...
+L rtc rtc0
diff --git a/recipes/slugos-init/files/modulefunctions b/recipes/slugos-init/files/modulefunctions
new file mode 100644
index 0000000000..02bfccb500
--- /dev/null
+++ b/recipes/slugos-init/files/modulefunctions
@@ -0,0 +1,45 @@
+#!/bin/sh
+# . this file to load the functions for automatically loading modules
+# NB: /proc must be mounted for correct evaluation of "$(machine)".
+
+. /etc/default/functions
+
+loaddiskmods(){
+ case "$(machine)" in
+ nslu2)
+ [ -d /sys/module/ehci_hcd ] || modprobe ehci-hcd
+ [ -d /sys/module/ohci_hcd ] || modprobe ohci-hcd
+ ;;
+ nas100d)
+ [ -d /sys/module/ehci_hcd ] || modprobe ehci-hcd
+ [ -d /sys/module/uhci_hcd ] || modprobe uhci-hcd
+ [ -d /sys/module/pata_artop ] || modprobe pata-artop
+ ;;
+ dsmg600)
+ [ -d /sys/module/ehci_hcd ] || modprobe ehci-hcd
+ [ -d /sys/module/uhci_hcd ] || modprobe uhci-hcd
+ [ -d /sys/module/pata_artop ] || modprobe pata-artop
+ ;;
+
+ esac
+}
+
+loadnetmods(){
+ case "$(machine)" in
+ dsmg600)
+ [ -d /sys/module/via_velocity ] || modprobe via-velocity
+ ;;
+ *)
+ true
+ ;;
+ esac
+}
+
+loadnfsmods(){
+ [ -d /sys/module/nfs ] || modprobe nfs
+}
+
+loadmiscmods(){
+ true
+}
+
diff --git a/recipes/slugos-init/files/modutils.txt b/recipes/slugos-init/files/modutils.txt
new file mode 100644
index 0000000000..a73b480efe
--- /dev/null
+++ b/recipes/slugos-init/files/modutils.txt
@@ -0,0 +1 @@
+# Adding modules to be automatically loaded via update-modules
diff --git a/recipes/slugos-init/files/reflash b/recipes/slugos-init/files/reflash
new file mode 100644
index 0000000000..22a18bb068
--- /dev/null
+++ b/recipes/slugos-init/files/reflash
@@ -0,0 +1,658 @@
+#!/bin/sh
+# reflash
+# ensure the flash disk is not mounted
+# save configuration files
+# update the kernel
+# update the flashdisk
+# restore the saved configuration files
+# the set of configuration files is described by
+# /etc/default/conffiles.
+#
+# /etc/default/functions contains useful utility functions
+. /etc/default/functions
+load_functions sysconf
+#
+# NSLU2 flash layout is non-standard.
+case "$(machine)" in
+nslu2)
+ isnslu2=1
+ isdsmg600=
+ isnas100d=
+ imageok=1
+ apexpart="Loader"
+ usrpart=
+ kpart="Kernel"
+ ffspart="Flashdisk";;
+nas100d)
+ isnslu2=
+ isdsmg600=
+ isnas100d=1
+ imageok=1
+ apexpart=
+ usrpart="usr"
+ kpart="kernel"
+ ffspart="filesystem";;
+dsmg600)
+ isnslu2=
+ isdsmg600=1
+ isnas100d=
+ imageok=1
+ apexpart=
+ usrpart="usr"
+ kpart="kernel"
+ ffspart="filesystem";;
+*)
+ isnslu2=
+ isdsmg600=
+ isnas100d=
+ imageok=
+ apexpart=
+ usrpart=
+ kpart="kernel"
+ ffspart="filesystem";;
+esac
+#
+# CHECKING FOR INPUT (ARGUMENTS ETC)
+# ----------------------------------
+#
+# find the kernel and the new flash file system, an image file can
+# be used to specify both images.
+ffsfile=
+kfile=
+imgfile=
+preserve_config=1
+while test $# -gt 0
+do
+ case "$1" in
+ -n) preserve_config=
+ shift;;
+ -k) shift
+ test $# -gt 0 || {
+ echo "reflash: -k: give the file containing the kernel image" >&2
+ exit 1
+ }
+ kfile="$1"
+ shift;;
+ -[jr]) shift
+ test $# -gt 0 || {
+ echo "reflash: -j: give the file containing the root jffs2 image" >&2
+ exit 1
+ }
+ ffsfile="$1"
+ shift;;
+ -i) shift
+ test -n "$imageok" || {
+ echo "reflash: -i: only supported on the LinkSys NSLU2," >&2
+ echo " Iomega NAS 100d and D-Link DSM-G600 systems; use -k and -j" >&2
+ echo " to specify the kernel and root file system instead." >&2
+ exit 1
+ }
+ test $# -gt 0 || {
+ echo "reflash: -i: give the file containing the complete flash image" >&2
+ exit 1
+ }
+ imgfile="$1"
+ shift;;
+ *) if test -n "$imageok"
+ then
+ echo "reflash: usage: $0 [-n] [-k kernel] [-j rootfs] [-i image]" >&2
+ else
+ echo "reflash: usage: $0 [-n] [-k kernel] [-j rootfs]" >&2
+ fi
+ echo " -n: do not attempt to preserve the configuration" >&2
+ echo " -k file: the new compressed kernel image ('zImage')" >&2
+ echo " -j file: the new root file system (jffs2)" >&2
+ test -n "$imageok" &&
+ echo " -i file: a complete flash image (gives both kernel and jffs2)" >&2
+ echo " The current jffs2 will be umounted if mounted." >&2
+ exit 1;;
+ esac
+done
+#
+# Sanity check on the arguments (note that the first case can only fire
+# on NSLU2 or DSM-G600 because of the check for -i above.)
+if test -n "$imgfile" -a -n "$ffsfile" -a -n "$kfile"
+then
+ echo "reflash: specify at most two files" >&2
+ echo " -i has both a kernel and rootfs, the kernel from -k and" >&2
+ echo " the rootfs from -j override the one in the image (if given)" >&2
+ exit 1
+elif test -z "$imgfile" -a -z "$ffsfile" -a -z "$kfile"
+then
+ echo "reflash: specify at least one file to flash" >&2
+ exit 1
+fi
+#
+# Perform basic checks on the input (must exist, size must be ok).
+if test -n "$imgfile"
+then
+ if test -r "$imgfile" -a -n "$isnslu2"
+ then
+ # read the partition table and from this find the offset
+ # and size of $kpart and $ffspart partitions. The following
+ # devio command just dumps the partition table in a format
+ # similar to /proc/mtd (but it outputs decimal values!)
+ #NOTE: this uses a here document because this allows the while
+ # loop to set the variables, a pipe would put the while in
+ # a sub-shell and the variable settings would be lost. This
+ # works in ash, no guarantees about other shells!
+ while read size base name
+ do
+ if test "$name" = "$apexpart"
+ then
+ imgapexsize="$size"
+ imgapexoffset="$base"
+ elif test "$name" = "$kpart"
+ then
+ imgksize="$size"
+ imgkoffset="$base"
+ elif test "$name" = "$ffspart" -o "$name" = "rootfs"
+ then
+ imgffssize="$size"
+ imgffsoffset="$base"
+ fi
+ done <<EOI
+$(devio "<<$imgfile" '
+ <= $ 0x20000 -
+ L= 0x1000
+ $( 1
+ # 0xff byte in name[0] ends the partition table
+ $? @ 255 =
+ # output size base name
+ <= f15+
+ .= b 0xfffffff &
+ <= f4+
+ .= b
+ pf "%lu %lu "
+ <= f28-
+ cp 16
+ pn
+ <= f240+
+ L= L256-
+ $) L255>')
+EOI
+ # check the result
+ test "$imgksize" -gt 0 -a "$imgkoffset" -ge 0 || {
+ echo "reflash: $imgfile: failed to find $kpart partition in image" >&2
+ exit 1
+ }
+ # the kernel is after a 16 byte header which holds the
+ # values length,0,0,0 Get the true size.
+ ktmp="$(devio "<<$imgfile" "L=$imgksize" "O=$imgkoffset" '
+ $( OL+$>!
+ <= O
+ A= b
+ $( AL>!
+ pr A
+ $) 0
+ $) 0')"
+ test "$ktmp" -gt 0 || {
+ echo "reflash: $imgfile($imgkoffset,$imgksize): invalid kernel offset/size" >&2
+ exit 1
+ }
+ # update the size and offset to these values (the offset is 16+ because
+ # of the header).
+ imgksize="$ktmp"
+ imgkoffset="$(devio "O=$imgkoffset" 'pr O16+')"
+ # just test the size for the rootfs
+ test "$imgffssize" -gt 0 -a "$imgffsoffset" -ge 0 || {
+ echo "reflash: $imgfile: failed to find $ffspart" >&2
+ exit 1
+ }
+ elif test -r "$imgfile" -a \( -n "$isdsmg600" -o -n "$isnas100d" \)
+ then
+ #
+ # For the DSM-G600, this is really easy - the image is just
+ # a tar file. So, extract the contents of the tar file, and
+ # set the kernel and filesystem variables (if not already set)
+ # to point to the extracted content. Content will look like:
+ #
+ # drwxr-xr-x 500/500 0 2006-11-25 23:47:59 firmupgrade
+ # -rw-r--r-- 500/500 4718592 2006-12-02 16:32:51 firmupgrade/rootfs.gz
+ # -rw-r--r-- 500/500 40 2006-11-25 22:15:41 firmupgrade/version.msg
+ # -rw-r--r-- 500/500 0 2006-11-25 23:47:59 firmupgrade/usr.cramfs
+ # -rw-rw-r-- 500/500 1306872 2006-12-02 16:33:37 firmupgrade/ip-ramdisk
+ #
+ # Heuristic: if the size of usr.cramfs is zero, the firmware
+ # is not a D-Link firmware for the device. (The version.msg
+ # file is not useful for this purpose; it describes the hardware,
+ # not the firmware version in the image!)
+ #
+ # TODO: If usr.cramfs is non-zero, we should flash that, too, just
+ # to make sure that it matches the native firmware's kernel
+ # and rootfs that we're now flashing back onto the device.
+
+ echo "reflash: unpacking DSM-G600/NAS-100d image file" >&2
+ tar -x -f "$imgfile" -C /var/tmp || {
+ echo "reflash: unable to unpack image file to be flashed" >&2
+ exit 1
+ }
+
+ if test -z "$kfile"
+ then
+ kfile="/var/tmp/firmupgrade/ip-ramdisk"
+ fi
+
+ if test -z "$ffsfile"
+ then
+ ffsfile="/var/tmp/firmupgrade/rootfs.gz"
+ fi
+
+ if test -s "/var/tmp/firmupgrade/usr.cramfs"
+ then
+ echo "reflash: Native flash being restored" >&2
+ usrfile="/var/tmp/firmupgrade/usr.cramfs"
+ preserve_config=
+ fi
+
+ else
+ echo "reflash: $imgfile: image file not found" >&2
+ exit 1
+ fi
+fi
+if test -n "$kfile"
+then
+ if test ! -r "$kfile"
+ then
+ echo "reflash: $kfile: kernel file not found" >&2
+ exit 1
+ fi
+ # the file values override anything from the image.
+ imgksize="$(devio "<<$kfile" 'pr$')"
+ imgkoffset=0
+else
+ kfile="$imgfile"
+fi
+if test -n "$ffsfile"
+then
+ if test ! -r "$ffsfile"
+ then
+ echo "reflash: $ffsfile: root file system image file not found" >&2
+ exit 1
+ fi
+ # values override those from the image
+ imgffssize="$(devio "<<$ffsfile" 'pr$')"
+ imgffsoffset=0
+else
+ ffsfile="$imgfile"
+fi
+if test -n "$usrfile"
+then
+ if test ! -r "$usrfile"
+ then
+ echo "reflash: $usrfile: usr file system image file not found" >&2
+ exit 1
+ fi
+ # values override those from the image
+ imgusrsize="$(devio "<<$usrfile" 'pr$')"
+ imgusroffset=0
+else
+ usrfile=
+fi
+#
+# INPUTS OK, CHECKING THE ENVIRONMENT
+# -----------------------------------
+# basic setup. This could be parameterised to use different partitions!
+#
+kdev=
+ksize=0
+if test -n "$kfile"
+then
+ # we have a new kernel
+ kdev="$(mtblockdev $kpart)"
+ test -n "$kdev" -a -b "$kdev" || {
+ echo "reflash: $kpart($kdev): cannot find $kpart mtd partition." >&2
+ echo " check /proc/mtd, either the partition does not exist or there is no" >&2
+ echo " corresponding block device." >&2
+ exit 1
+ }
+ ksize="$(devio "<<$kdev" 'pr$')"
+ #
+ # check the input file size
+ test -n "$imgksize" -a "$imgksize" -gt 0 -a "$imgksize" -le "$ksize" || {
+ echo "reflash: $kfile: bad $kpart size ($imgksize, max $ksize)" >&2
+ exit 1
+ }
+fi
+#
+ffsdev=
+ffssize=0
+if test -n "$ffsfile"
+then
+ ffsdev="$(mtblockdev $ffspart)"
+ [ -n "$ffsdev" ] || \
+ ffsdev="$(mtblockdev rootfs)"
+ test -n "$ffsdev" -a -b "$ffsdev" || {
+ echo "reflash: $ffspart($ffsdev): cannot find $ffspart mtd partition." >&2
+ echo " check /proc/mtd, either the partition does not exist or there is no" >&2
+ echo " corresponding block device." >&2
+ exit 1
+ }
+ ffssize="$(devio "<<$ffsdev" 'pr$')"
+ #
+ # check the input file size
+ test -n "$imgffssize" -a "$imgffssize" -gt 0 -a "$imgffssize" -le "$ffssize" || {
+ echo "reflash: $ffsfile: bad $ffspart size ($imgffsize, max $ffssize)" >&2
+ exit 1
+ }
+fi
+#
+usrdev=
+usrsize=0
+if test -n "$usrfile"
+then
+ usrdev="$(mtblockdev $usrpart)"
+ test -n "$usrdev" -a -b "$usrdev" || {
+ echo "reflash: $usrpart($usrdev): cannot find $usrpart mtd partition." >&2
+ echo " check /proc/mtd, either the partition does not exist or there is no" >&2
+ echo " corresponding block device." >&2
+ exit 1
+ }
+ usrsize="$(devio "<<$usrdev" 'pr$')"
+ #
+ # check the input file size
+ test -n "$imgusrsize" -a "$imgusrsize" -gt 0 -a "$imgusrsize" -le "$usrsize" || {
+ echo "reflash: $usrfile: bad $usrpart size ($imgusrsize, max $usrsize)" >&2
+ exit 1
+ }
+fi
+
+#
+# INPUTS OK, ENVIRONMENT OK, UMOUNT ANY EXISTING MOUNT OF THE FLASHDISK
+# ---------------------------------------------------------------------
+# This is only required if the device is going to be used
+if test -n "$ffsdev"
+then
+ # -r causes this to fail if the flash device is mounted on /
+ umountflash -r "$ffsdev" || exit 1
+ #
+ # Everything is umounted, now remount on a temporary directory.
+ ffsdir="/tmp/flashdisk.$$"
+ mkdir "$ffsdir" || {
+ echo "reflash: $ffsdir: failed to create temporary directory" >&2
+ exit 1
+ }
+ #
+ mountflash "$ffsdev" "$ffsdir" -o ro || {
+ rmdir "$ffsdir"
+ exit 1
+ }
+ #
+ # this is a utility function to make the cleanup easier
+ errorexit() {
+ umount "$ffsdir" && rmdir "$ffsdir" ||
+ echo "reflash: $ffsdir: temporary directory cleanup failed" >&2
+ exit 1
+ }
+ #
+ test -r "$ffsdir/etc/default/conffiles" || {
+ echo "reflash: [/initrd]/etc/default/conffiles: file not found" >&2
+ errorexit
+ }
+else
+ errorexit() {
+ exit 1
+ }
+fi
+#
+# PRESERVE EXISTING CONFIGURATION
+# -------------------------------
+# Only required if the flash partition will be written
+if test -n "$ffsdev" -a -n "$preserve_config"
+then
+ echo "reflash: preserving existing configuration file" >&2
+ #
+ # This step produces /tmp/preserve.$$ and /tmp/cpio.$$, the former is
+ # a list of the preserved configuration files together with the processing
+ # option, the latter is a directory tree of the preserved files (a directory
+ # tree makes the restore step easier.)
+ saved=/tmp/cpio.$$
+ list=/tmp/preserve.$$
+ mkdir "$saved" || {
+ echo "reflash: $saved: could not create save directory" >&2
+ errorexit
+ }
+ #
+ # sysconf_save_conffiles <flash-directory> <dest> <list>
+ sysconf_save_conffiles "$ffsdir" "$saved" "$list" || {
+ echo "reflash: $saved: copy of saved configuration files failed" >&2
+ rm -rf "$saved"
+ rm "$list"
+ errorexit
+ }
+ #
+ # If this umount fails do not try to continue...
+ umount "$ffsdir" || {
+ echo "reflash: $ffsdir: temporary mount point umount failed" >&2
+ echo " No changes have been made." >&2
+ rm -rf "$saved"
+ rm "$list"
+ exit 1
+ }
+fi
+#
+# FLASH THE NEW IMAGES
+# --------------------
+echo "reflash: about to flash new image" >&2
+#
+# There are four possibilities here - kernel only, flashdisk only, then
+# kernel&flashdisk in either one or two different files. The code used
+# to attempt to do everything in one step, but this complicates it,
+# so two steps are used (as required). A failure between the two
+# steps is a problem, but then so is a failure in a partial write.
+# Write the flashdisk first because this is larger (most likely to
+# fail).
+#
+# -p causes the progress indicator to be displayed
+progress=-p
+do_kernel() {
+ local cmd
+ if test -n "$isnslu2"
+ then
+ # NSLU2: write length,0,0,0 header, then fill
+ cmd="wb L,4; fb 12,0; cpL"
+ else
+ # Other: just write the kernel bytes
+ cmd="cpL"
+ fi
+ devio $progress "$@" "<<$kfile" ">>$kdev" '
+ # kernel is at imgkoffset[imgksize]
+ ' "<= $imgkoffset" "L=$imgksize" "$cmd" '
+ # fill with 255
+ fb #t-,255'
+}
+#
+do_ffs() {
+ devio $progress "$@" "<<$ffsfile" ">>$ffsdev" '
+ # rootfs is at imgffsoffset[imgffssize]
+ ' "<= $imgffsoffset" "cp $imgffssize" '
+ # fill with 255
+ fb #t-,255'
+}
+#
+do_usr() {
+ devio $progress "$@" "<<$usrfile" ">>$usrdev" '
+ # usrfs is at imgusroffset[imgusrsize]
+ ' "<= $imgusroffset" "cp $imgusrsize" '
+ # fill with 255
+ fb #t-,255'
+}
+#
+# check_status $? type file(offset,size) device
+# check the devio status code (given in $1)
+check_status() {
+ case "$1" in
+ 0) echo " done" >&2;;
+ 1) echo " failed" >&2
+ echo "reflash: $3: flash $2 failed, no changes have been made to $4" >&2
+ if test "$2" = rootfs
+ then
+ rm -rf "$saved"
+ rm "$list"
+ exit 1
+ else
+ echo "reflash: $2: continuing with rootfs changes" >&2
+ echo " NOTE: the old kernel is still in $4!" >&2
+ fi;;
+ 3) echo " failed" >&2
+ echo "reflash: $3: WARNING: partial flash of $2 to $4 the system is unbootable" >&2
+ echo " Reflash from RedBoot or correct the problem here." >&2
+ if test "$2" = rootfs
+ then
+ exit 3
+ else
+ echo "reflash: $2: continuing with rootfs changes" >&2
+ echo " NOTE: the kernel in $4 must be reflashed!" >&2
+ fi;;
+ *) echo " failed" >&2
+ echo "reflash($1): $3: internal error flashing $2 to $4" >&2
+ exit $1;;
+ esac
+}
+#
+if test -n "$usrdev"
+then
+ echo -n "reflash: writing usrfs to $usrdev " >&2
+ do_usr
+ check_status $? usrfs "$usrfile($imgusroffset,$imgusrsize)" "$usrdev"
+fi
+#
+if test -n "$ffsdev"
+then
+ echo -n "reflash: writing rootfs to $ffsdev " >&2
+ do_ffs
+ check_status $? rootfs "$ffsfile($imgffsoffset,$imgffssize)" "$ffsdev"
+fi
+#
+if test -n "$kdev"
+then
+ echo -n "reflash: writing kernel to $kdev " >&2
+ do_kernel
+ check_status $? kernel "$kfile($imgkoffset,$imgksize)" "$kdev"
+fi
+#
+# verify - this just produces a warning
+if test -n "$usrdev"
+then
+ echo -n "reflash: verifying new usr image " >&2
+ if do_usr -v
+ then
+ echo " done" >&2
+ else
+ echo " failed" >&2
+ echo "reflash: WARNING: usrfs flash image verification failed" >&2
+ echo " The system is may be bootable." >&2
+ fi
+fi
+#
+if test -n "$ffsdev"
+then
+ echo -n "reflash: verifying new flash image " >&2
+ if do_ffs -v
+ then
+ echo " done" >&2
+ else
+ echo " failed" >&2
+ echo "reflash: WARNING: rootfs flash image verification failed" >&2
+ echo " The system is probably unbootable." >&2
+ echo " System configuration files will be restored but this may fail" >&2
+ echo " Starting a shell for user recovery (exit to continue)" >&2
+ PS1='badflash$ ' sh -i <>/dev/tty >&0 2>&0
+ fi
+fi
+#
+if test -n "$kdev"
+then
+ echo -n "reflash: verifying new kernel image " >&2
+ if do_kernel -v
+ then
+ echo " done" >&2
+ else
+ echo " failed" >&2
+ echo "reflash: WARNING: kernel flash image verification failed" >&2
+ echo " The system is probably unbootable." >&2
+ echo " System configuration files will be restored in the rootfs." >&2
+ fi
+fi
+#
+# RESTORE THE OLD CONFIGURATION
+# -----------------------------
+# If not write the rootfs none of the following is required - exit now.
+test -n "$ffsdev" -a -n "$preserve_config" || exit 0
+#
+echo "reflash: restoring saved configuration files" >&2
+#
+# the file /etc/.configured is the datestamp file used to ensure that
+# changed configuration files can be recognised. It is created by
+# /etc/rcS.d/S99finish on first boot (if it does not exist). We need
+# a timestamp earlier than any files we create so touch it here, this
+# also acts as a test on the mounted file system
+mountflash "$ffsdev" "$ffsdir" && :>"$ffsdir/etc/.configured" || {
+ rmdir "$ffsdir"
+ echo "reflash: mount of new flash root file system failed" >&2
+ if test -d "$ffsdir/etc"
+ then
+ echo " The file system does not seem to be writeable." >&2
+ echo " The mounted file system is in $ffsdir" >&2
+ fi
+ echo " WARNING: the kernel and root file system have been reflashed," >&2
+ echo " HOWEVER the new root file system seems to be unuseable." >&2
+ echo " Saved configuration files are in $saved" >&2
+ echo " The list of saved configuration files is in $list" >&2
+ echo " You should determine the reason for the failed mount, mount the new" >&2
+ echo " file system and restore the configuration from $saved - it's just a" >&2
+ echo " matter of copying the saved files where required." >&2
+ exit 1
+}
+#
+# sysconf_restore_conffiles <flash-directory> <source-dir> <restore>
+restore="/tmp/restore.$$"
+sysconf_restore_conffiles "$ffsdir" "$saved" "$restore" <"$list" || {
+ echo "reflash: $saved: restore of saved configuration files failed" >&2
+ echo " The new flash file system is mounted on $ffsdir" >&2
+ echo " The saved files are in $saved and the list in $list, the list of" >&2
+ echo " files selected for restore is in $restore" >&2
+ echo " You should restore any required configuration from $saved," >&2
+ echo " then umount $ffsdir and reboot." >&2
+ exit 1
+}
+#
+# remove the copied files (i.e. the ones which were preserved)
+( cd "$saved"
+ exec rm $(cat "$restore")
+)
+rm "$restore"
+#
+# clean up, files left in $saved need to be handled by the user
+files="$(find "$saved" ! -type d -print)"
+if test -n "$files"
+then
+ echo "reflash: the following saved configuration files remain:" >&2
+ echo "$files" >&2
+ echo "The full list of preserved files is in $list. To alter the" >&2
+ echo "new root file system use the command:" >&2
+ echo "" >&2
+ echo " mount -t jffs2 $ffsdev /mnt" >&2
+ echo "" >&2
+ echo "The saved files are in the temporary directory, they will not" >&2
+ echo "be retained across a system boot. Copy them elsewhere if you" >&2
+ echo "are unsure whether they are needed" >&2
+else
+ rm -rf "$saved"
+ rm "$list"
+fi
+#
+# now the final umount
+if umount "$ffsdir"
+then
+ rmdir "$ffsdir"
+ echo "reflash: system upgrade complete. Reboot to continue." >&2
+ exit 0
+else
+ echo "reflash: $ffsdir: temporary mount point umount failed" >&2
+ echo " ALL changes have been made successfully, however the umount of" >&2
+ echo " the new root file system has failed. You should determine the" >&2
+ echo " cause of the failure, umount $ffsdir, then reboot the system (this" >&2
+ echo " will use the upgraded kernel and root file system)" >&2
+ exit 1
+fi
diff --git a/recipes/slugos-init/files/setup-optware.sh b/recipes/slugos-init/files/setup-optware.sh
new file mode 100644
index 0000000000..d4ae619491
--- /dev/null
+++ b/recipes/slugos-init/files/setup-optware.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+if test 0 != `id -u`; then
+ echo 'Please run as root'
+ exit 1
+fi
+
+optware_target=slugos5be
+feed=http://ipkg.nslu2-linux.org/feeds/optware/${optware_target}/cross/unstable
+latest_xsh=`wget -q -O- ${feed} | grep '\.xsh' | sed -e 's/.*xsh">//' -e 's/<.*//'`
+
+if test -n "${latest_xsh}"; then
+ cd /tmp
+ rm -f ${latest_xsh}
+ wget ${feed}/${latest_xsh}
+ sh ${latest_xsh}
+fi
diff --git a/recipes/slugos-init/files/sysconf b/recipes/slugos-init/files/sysconf
new file mode 100644
index 0000000000..8d59d5d6f3
--- /dev/null
+++ b/recipes/slugos-init/files/sysconf
@@ -0,0 +1,796 @@
+#!/bin/sh
+# sysconf
+#
+# utility to manipulate system configuration information help
+# in a RedBoot SysConf partition
+#
+# load the utility functions (unless this is being called just
+# to load these functions!)
+test "$1" != sysconf && . /etc/default/functions
+
+case "$(machine)" in
+nslu2)
+ kpart="Kernel"
+ syspart="SysConf"
+ ffspart="Flashdisk";;
+*)
+ kpart="kernel"
+ syspart="sysconfig"
+ ffspart="filesystem";;
+esac
+#
+# sysconf_valid
+# return true if the SysConf partition exists and seems to be
+# potentially valid (it starts with a reasonable length).
+sysconf_valid(){
+ local sysdev
+ sysdev="$(mtblockdev $syspart)"
+ test -n "$sysdev" -a -b "$sysdev" &&
+ devio "<<$sysdev" '!! b.10>s32768<&!'
+}
+
+#
+# sysconf_read [prefix]
+# read the $syspart partition (if present) writing the result into
+# /etc/default/sysconf, if the result is empty it will be removed.
+sysconf_read(){
+ local sysdev sedcmd mac config_root
+ config_root="$1"
+ rm -f /tmp/sysconf.new
+ sysdev="$(mtblockdev $syspart)"
+ if sysconf_valid
+ then
+ # Read the defined part of $syspart into /etc/default/sysconf.
+ # $syspart has lines of two forms:
+ #
+ # [section]
+ # name=value
+ #
+ # In practice $syspart also contains other stuff, use the command:
+ #
+ # devio '<</dev/mtd1;cpb'
+ #
+ # to examine the current settings. The badly formatted stuff
+ # is removed (to be exact, the sed script selects only lines
+ # which match one of the two above). The lan interface, which
+ # on NSLU2 defaults to ixp0, is changed to the correct value for
+ # slugos, eth0. The bootproto, which LinkSys sets to static in
+ # manufacturing, is reset to dhcp if the IP is still the
+ # original (192.168.1.77)
+ sedcmd='/^\[[^][]*\]$/p;'
+ # only do the ip_addr and lan_interface fixups on NSLU2
+ if test "$(machine)" = nslu2
+ then
+ sedcmd="$sedcmd"'
+ s/^lan_interface=ixp0$/lan_interface=eth0/;
+ /^ip_addr=192\.168\.1\.77$/,/^bootproto/s/^bootproto=static$/bootproto=dhcp/;'
+ fi
+ # always fix up the hardware addr if it is present
+ mac="$(config mac)"
+ if test -n "$mac"
+ then
+ sedcmd="$sedcmd"'
+ s/^hw_addr=.*$/hw_addr='"$mac"'/;'
+ fi
+ # and only print lines of the correct form
+ sedcmd="$sedcmd"'
+ /^[-a-zA-Z0-9_][-a-zA-Z0-9_]*=/p'
+
+ devio "<<$sysdev" cpb fb1,10 | sed -n "$sedcmd" >/tmp/sysconf.new
+ fi
+ #
+ # test the result - sysconf must be non-empty
+ if test -s /tmp/sysconf.new
+ then
+ mv /tmp/sysconf.new "$config_root/etc/default/sysconf"
+ else
+ rm -f /tmp/sysconf.new
+ return 1
+ fi
+}
+
+#
+# sysconf_default [prefix]
+# Provde a default /etc/default/sysconf when there is no $syspart partition,
+# or when it is invalid, this function will read from an existing sysconf,
+# copying the values into the new one.
+# sysconf_line tag config-tag
+# write an appropriate line if the config value is non-empty
+sysconf_line(){
+ config "$2" | {
+ local value
+ read value
+ test -n "$value" && echo "$1"="$value"
+ }
+}
+#
+sysconf_default(){
+ local config_root
+ config_root="$1"
+ { echo '[network]'
+ sysconf_line hw_addr mac
+ sysconf_line disk_server_name host
+ sysconf_line w_d_name domain
+ sysconf_line lan_interface iface
+ sysconf_line ip_addr ip
+ sysconf_line netmask netmask
+ sysconf_line gateway gateway
+ sysconf_line dns_server1 dns
+ sysconf_line dns_server2 dns2
+ sysconf_line dns_server3 dns3
+ sysconf_line bootproto boot
+ } >/tmp/sysconf.new
+ mv /tmp/sysconf.new "$config_root/etc/default/sysconf"
+}
+
+#
+# sysconf_reload [prefix]
+# read the values from /etc/default/sysconf and use these values to set
+# up the following system files:
+#
+# /etc/hostname
+# /etc/defaultdomain
+# /etc/resolv.conf
+# /etc/network/interfaces
+# /etc/motd
+#
+sysconf_reload(){
+ local config_root host domain iface boot ip netmask gateway ifname iftype
+ config_root="$1"
+ host="$(config host)"
+ test -n "$host" && echo "$host" >"$config_root/etc/hostname"
+ domain="$(config domain)"
+ test -n "$domain" && echo "$domain" >"$config_root/etc/defaultdomain"
+ #
+ # The DNS server information gives up to three nameservers,
+ # but this currently only binds in the first.
+ {
+ test -n "$domain" && echo "search $domain"
+ test -n "$(config dns)" && echo "nameserver $(config dns)"
+ test -n "$(config dns2)" && echo "nameserver $(config dns2)"
+ test -n "$(config dns3)" && echo "nameserver $(config dns3)"
+ } >"$config_root/etc/resolv.conf"
+ #
+ # Ethernet information. This goes into /etc/network/interfaces,
+ # however this is only used for static setup (and this is not
+ # the default). With dhcp the slugos udhcp script,
+ # /etc/udhcpc.d/50default, loads the values from sysconf.
+ iface="$(config iface)"
+ boot="$(config boot)"
+ # Only dhcp and static are supported at present - bootp
+ # support requires installation of appropriate packages
+ # dhcp is the fail-safe
+ case "$boot" in
+ dhcp|static) ;;
+ *) boot=dhcp;;
+ esac
+ #
+ ip="$(config ip)"
+ netmask="$(config netmask)"
+ gateway="$(config gateway)"
+ {
+ echo "# /etc/network/interfaces"
+ echo "# configuration file for ifup(8), ifdown(8)"
+ echo "#"
+ echo "# The loopback interface"
+ echo "auto lo"
+ echo "iface lo inet loopback"
+ echo "#"
+ echo "# The interface used by default during boot"
+ echo "auto $iface"
+ echo "# Automatically generated from /etc/default/sysconf"
+ echo "# address, netmask and gateway are ignored for 'dhcp'"
+ echo "# but required for 'static'"
+ echo "iface $iface inet $boot"
+ # The following are ignored for DHCP but are harmless
+ test -n "$ip" && echo " address $ip"
+ test -n "$netmask" && echo " netmask $netmask"
+ test -n "$gateway" && echo " gateway $gateway"
+ #
+ # Now read all the other ARPHRD_ETHER (type=1) interfaces
+ # and add an entry for each.
+ for ifname in $(test -d /sys/class/net && ls /sys/class/net)
+ do
+ if test -r "/sys/class/net/$ifname/type" -a "$ifname" != "$iface"
+ then
+ read iftype <"/sys/class/net/$ifname/type"
+ case "$iftype" in
+ 1) echo "#"
+ echo "# /sys/class/net/$ifname:"
+ echo "auto $ifname"
+ echo "iface $ifname inet dhcp";;
+ esac
+ fi
+ done
+ } >"$config_root/etc/network/interfaces"
+ #
+ # Finally rewrite /etc/motd
+ { echo "Host name: $host"
+ echo "Domain name: $domain"
+ echo "Host MAC: $(config mac)"
+ echo "Network boot method: $boot"
+ case "$boot" in
+ static) echo "Host IP address: $ip";;
+ esac
+ echo "Use 'turnup init' to reset the configuration"
+ echo "Use 'turnup preserve' to save the configuration permanently"
+ echo "Use 'turnup restore' to restore a previously saved configuration"
+ echo "Use 'turnup disk|nfs -i <device> options to initialise a non-flash root"
+ echo "Use 'turnup help' for more information"
+ } >"$config_root/etc/motd"
+}
+
+#
+# sysconf_save_conffiles <flash-directory> <dest> <list>
+# preserve the configuration files in a directory or in a CPIO archive
+# (which is *not* compressed). If <dest> is a directory the files are
+# copied, otherwise a CPIO archive is made with that name. <list> is
+# the listing file giving the preserved files and the processing option.
+sysconf_save_conffiles(){
+ local ffsdir dest list file
+ ffsdir="$1"
+ saved="$2"
+ list="$3"
+ test -n "$ffsdir" -a -r "$ffsdir/etc/default/conffiles" -a -n "$saved" -a -n "$list" || {
+ echo "sysconf_save_conffiles: invalid arguments: '$*'" >&2
+ echo " usage sysconf_save_conffiles <flash-directory> <dest> <list>" >&2
+ return 1
+ }
+ #
+ ( cd "$ffsdir"
+ find etc/*.conf $(sed 's!^/!!' usr/lib/opkg/info/*.conffiles) ! -type d -newer etc/.configured -print |
+ sed 's/^/diff /'
+ exec sed 's/#.*$//;/^[ ]*$/d' etc/default/conffiles
+ ) | sed 's!^/*!!' |
+ awk '{ op=$1; $1=""; file[$0]=op }
+ END{ for (f in file) if (file[f] != "ignore") print file[f] f }' |
+ while read op file
+ do
+ if test -e "$ffsdir/$file"
+ then
+ echo "$op $file" >&3
+ echo "$file"
+ fi
+ done 3>"$list" | (
+ cd "$ffsdir"
+ if test -d "$saved"
+ then
+ exec cpio -p -d -m -u "$saved"
+ else
+ exec cpio -o -H crc >"$saved"
+ fi
+ )
+}
+
+#
+# sysconf_verify file
+# this is called with the name of a 'diff' file which is, indeed,
+# different and with all the std streams connected to the tty. It
+# returns a status code to say whether (0) or not (1) to copy the
+# file over.
+#
+# globals: the following must be defined in the calling context!
+# saved: the directory containing the unpacked saved files
+# ffsdir: the flash directory to which the files are being restored (/)
+#
+sysconf_verify_help() {
+ echo "Please specify how to handle this file or link, the options are as follows,"
+ echo "two character abbreviations may be used:"
+ echo
+ echo " keep: retain the old file, overwrite the new flash image file"
+ echo " upgrade: retain the new file, the old (saved) file is not used"
+ echo " diff: display the differences between the old and the new using diff -u"
+ echo " shell: temporarily start an interactive shell (sh -i), exit to continue"
+ echo " skip: ignore this file for the moment. The file is left in the directory"
+ echo " $saved and many be handled after this script has completed"
+}
+#
+sysconf_verify() {
+ local command file
+
+ # return 1 here causes the file not to be overwritten,
+ # control should never get here!
+ test -n "$sysconf_noninteractive" && {
+ echo "$0: $*: changed file cannot be handled non-interactively" >&2
+ return 1
+ }
+
+ file="$1"
+ echo "$0: $file: configuration file changed."
+ sysconf_verify_help "$file"
+ while :
+ do
+ echo -n "option: "
+ read command
+ case "$command" in
+ ke*) return 0;;
+ up*) rm "$saved/$file"
+ return 1;;
+ di*) echo "DIFF OLD($saved) NEW($ffsdir)"
+ diff -u "$saved/$file" "$ffsdir/$file";;
+ sh*) PS1="$file: " sh -i;;
+ sk*) return 1;;
+ *) sysconf_verify_help "$file";;
+ esac
+ done
+}
+# the same, but for a link
+sysconf_verify_link() {
+ local command link
+
+ # return 1 here causes the file not to be overwritten,
+ # control should never get here!
+ test -n "$sysconf_noninteractive" && {
+ echo "$0: $*: changed link cannot be handled non-interactively" >&2
+ return 1
+ }
+
+ link="$1"
+ echo "reflash: $link: configuration link changed."
+ sysconf_verify_help "$link"
+ while :
+ do
+ echo -n "option: "
+ read command
+ case "$command" in
+ ke*) return 0;;
+ up*) rm "$saved/$link"
+ return 1;;
+ di*) echo "DIFF:"
+ echo "OLD($saved): $link -> $(readlink "$saved/$link")"
+ echo "NEW($ffsdir): $link -> $(readlink "$ffsdir/$link")";;
+ sh*) PS1="$link: " sh -i;;
+ sk*) return 1;;
+ *) sysconf_verify_help "$link";;
+ esac
+ done
+}
+
+#
+# sysconf_restore_conffiles <flash-directory> <source-dir> <restore>
+# restore the configuration files from a directory. 'source-dir'
+# If <source> is a directory of files from sysconf_save_conffiles. The
+# list of files restored is written to the third argument (restore),
+# but is not required (/dev/null would be ok).
+#
+# the list of files to restore is read from stdin, along with the
+# processing option for each file (the format is as produced by
+# sysconf_save_conffiles in the 'list' output).
+sysconf_restore_conffiles(){
+ local ffsdir saved restore
+ # these are the globals used by the above function
+ ffsdir="$1"
+ saved="$2"
+ restore="$3"
+ test -n "$ffsdir" -a -r "$ffsdir/etc/default/conffiles" -a -d "$saved" -a -n "$restore" || {
+ echo "restore_conffiles: invalid arguments: '$*'" >&2
+ echo " usage sysconf_restore_conffiles <flash-directory> <source-dir> <list>" >&2
+ return 1
+ }
+ #
+ # read the list and process each given file
+ while read op file
+ do
+ # handle .configured specially (to preserve the original datestamp)
+ if test "$file" = "etc/.configured"
+ then
+ # this should definately not fail because of the test above!
+ if cp -a "$saved/$file" "$ffsdir/$file"
+ then
+ echo "$file" >&3
+ else
+ echo "sysconf_restore_conffiles: $file: timestamp copy failed (ignored)" >&2
+ fi
+ elif test -h "$saved/$file" -o -h "$ffsdir/$file"
+ then
+ # new or old symbolic link
+ if test -h "$saved/$file" -a -h "$ffsdir/$file" &&
+ test "$(readlink "$saved/$file")" = "$(readlink "$ffsdir/$file")"
+ then
+ # no change
+ echo "$file" >&3
+ else
+ # assume a change regardless
+ case "$op" in
+ preserve)
+ echo "$file"
+ echo "$file" >&3;;
+ diff) # need user input
+ if sysconf_verify_link "$file" </dev/tty >/dev/tty 2>&1
+ then
+ echo "$file"
+ echo "$file" >&3
+ fi;;
+ esac
+ fi
+ else
+ # only overwrite if necessary
+ if test -e "$ffsdir/$file" && cmp -s "$saved/$file" "$ffsdir/$file"
+ then
+ # do not overwrite
+ echo "$file" >&3
+ elif test ! -e "$ffsdir/$file"
+ then
+ # always preserve
+ echo "$file"
+ echo "$file" >&3
+ else
+ case "$op" in
+ preserve)
+ echo "$file"
+ echo "$file" >&3;;
+ diff) # the files are different, get user input
+ if sysconf_verify "$file" </dev/tty >/dev/tty 2>&1
+ then
+ echo "$file"
+ echo "$file" >&3
+ fi;;
+ esac
+ fi
+ fi
+ done 3>"$restore" | (cd "$saved"; exec cpio -p -d -u "$ffsdir")
+}
+
+#
+# sysconf_test_restore <flash-directory> <source-dir>
+# return true only if the restore does not need to do an interactive
+# compare
+sysconf_test_restore(){
+ local ffsdir saved
+ # these are the globals used by the above function
+ ffsdir="$1"
+ saved="$2"
+ # this is an error case, but return 0 so that the error is
+ # detected later
+ test -n "$ffsdir" -a -r "$ffsdir/etc/default/conffiles" -a -d "$saved" ||
+ return 0
+ #
+ # read the list and check each diff file (this is just a copy of the
+ # logic above with all the work removed!)
+ while read op file
+ do
+ # handle .configured specially (to preserve the original datestamp)
+ if test "$op" != diff
+ then
+ : # no diff required
+ elif test "$file" = "etc/.configured"
+ then
+ : # special handling
+ elif test -h "$saved/$file" -o -h "$ffsdir/$file"
+ then
+ # new or old symbolic link
+ if test -h "$saved/$file" -a -h "$ffsdir/$file" &&
+ test "$(readlink "$saved/$file")" = "$(readlink "$ffsdir/$file")"
+ then
+ : # no change
+ else
+ # assume a change regardless
+ return 1
+ fi
+ else
+ # only overwrite if necessary
+ if test -e "$ffsdir/$file" && cmp -s "$saved/$file" "$ffsdir/$file"
+ then
+ : # do not overwrite
+ elif test ! -e "$ffsdir/$file"
+ then
+ : # always preserve
+ else
+ # a change
+ return 1
+ fi
+ fi
+ done
+
+ return 0
+}
+
+#
+# sysconf_save
+# save the system configuration to $syspart - $syspart must exist and
+# there must be a writeable device for it.
+sysconf_save(){
+ local sysdev ffsdev ffsdir saved list size status
+ ffsdev="$(mtblockdev $ffspart)"
+ [ -n "$ffsdev" ] || \
+ ffsdev="$(mtblockdev rootfs)"
+ sysdev="$(mtblockdev $syspart)"
+ status=1
+ if test -n "$sysdev" -a -b "$sysdev" -a -n "$ffsdev" -a -b "$ffsdev"
+ then
+ # this will succeed silently if the flash device is on /
+ umountflash "$ffsdev" || exit 1
+ #
+ # Everything is umounted, now remount on a temporary directory.
+ ffsdir="/tmp/flashdisk.$$"
+ mkdir "$ffsdir" || {
+ echo "$0: $ffsdir: failed to create temporary directory" >&2
+ exit 1
+ }
+ #
+ mountflash "$ffsdev" "$ffsdir" -o ro || {
+ rmdir "$ffsdir"
+ exit 1
+ }
+ # need temporary files for the cpio output and the listing
+ saved=/tmp/cpio.$$
+ list=/tmp/preserve.$$
+ rm -rf "$saved" "$list"
+ sysconf_save_conffiles "$ffsdir" "$saved" "$list" || {
+ echo "$0: $saved: archive of saved configuration files failed" >&2
+ rm -rf "$saved"
+ rm "$list"
+ umount "$ffsdir" && rmdir "$ffsdir" ||
+ echo "$0: $ffsdir: temporary directory cleanup failed" >&2
+ return 1
+ }
+ # ignore the error in this case:
+ umount "$ffsdir" && rmdir "$ffsdir" ||
+ echo "$0: $ffsdir: temporary directory cleanup failed" >&2
+ #
+ # we now have:
+ # /etc/default/sysconf the basic config
+ # /tmp/preserve.$$ the list of saved files
+ # /tmp/cpio.$$ the CPIO archive of those files
+ #
+ # make one big file with the sysconf data followed by the
+ # compressed archive in /tmp/sysconf.$$
+ { { cat /etc/default/sysconf
+ echo '[preserve]'
+ } | sed -n '1,/^\[preserve\]^/p'
+ while read op file
+ do
+ echo "$op"="$file"
+ done <"$list"
+ } >/tmp/sysconf.$$
+ size="$(devio "<</tmp/sysconf.$$" 'pr$')"
+ gzip -9 <"$saved" >>/tmp/sysconf.$$
+ #
+ # more cleanup, then try to write the new sysconf to $syspart
+ # the format is a 4 byte big-endian length then the text data
+ # if the data won't fit exit with error code 7
+ rm "$saved" "$list"
+ devio -p "<</tmp/sysconf.$$" ">>$sysdev" '
+ $( $4+ # >
+ !! 7
+ $) 0
+ wb '"$size"',4
+ cp $'
+ case $? in
+ 0) echo " done" >&2
+ status=0;;
+ 1) echo " failed" >&2
+ echo " $syspart could not be written (no changes made)" >&2;;
+ 3) echo " failed" >&2
+ echo " $syspart partially written, you may want to reset it" >&2;;
+ 7) echo " failed" >&2
+ echo " $syspart is too small: $size bytes required" >&2
+ echo " No change made" >&2;;
+ *) echo " failed" >&2
+ echo " Internal error writing $syspart" >&2;;
+ esac
+ #
+ rm -f /tmp/sysconf.$$
+ else
+ echo "sysconf save: $syspart or $ffspart partition not found" >&2
+ echo " A RedBoot partition named '$syspart' must exist in the system" >&2
+ echo " flash memory for this command to work, and there must be a" >&2
+ echo " block device to access this partition (udev will normally" >&2
+ echo " create this automatically. The flash partition contents must" >&2
+ echo " also be accessible in a partition called '$ffspart'" >&2
+ echo
+ echo " To create the $syspart partition use the 'fis create' command" >&2
+ echo " in the RedBoot boot loader, it is sufficient to make the" >&2
+ echo " partition one erase block in size unless you have substantially" >&2
+ echo " increased the size of the files listed in /etc/default/conffiles" >&2
+ fi
+
+ return $status
+}
+
+#
+# sysconf_restore [auto]
+# restore previously saved configuration information from $syspart
+sysconf_restore_error(){
+ local root
+ root="$1"
+ shift
+ # -------------------------------------------------------------------------------
+ { echo " WARNING: saved configuration files not restored"
+ test -n "$1" && echo "$*"
+ echo
+ echo "The configuration of this machine has been reinitialised using the values"
+ echo "from /etc/default/sysconf, however configuration files saved in the $syspart"
+ echo "partition have not been restored."
+ echo
+ echo "You can restore these files by correcting any reported errors then running"
+ echo
+ echo " sysconf restore"
+ echo
+ echo "from the command line. This will completely reinitialise the configuration"
+ echo "using the information in the $syspart partition."
+ } >"$root/etc/motd"
+ cat "$root/etc/motd" >&2
+}
+#
+sysconf_restore(){
+ local sysdev ffsdev ffsdir saved restore size status sysconf_noninteractive config_root
+
+ # if set this means 'do no diff' - this avoids the code above which
+ # would open /dev/tty and therefore allows this stuff to be done from
+ # an init script
+ sysconf_noninteractive=
+ test "$1" = auto && sysconf_noninteractive=1
+
+ ffsdev="$(mtblockdev $ffspart)"
+ [ -n "$ffsdev" ] || \
+ ffsdev="$(mtblockdev rootfs)"
+ sysdev="$(mtblockdev $syspart)"
+ status=1
+ if test -n "$sysdev" -a -b "$sysdev" -a -n "$ffsdev" -a -b "$ffsdev" &&
+ sysconf_valid
+ then
+ # this will succeed silently if the flash device is on /
+ umountflash "$ffsdev" || exit 1
+ #
+ # Everything is umounted, now remount on a temporary directory.
+ ffsdir="/tmp/flashdisk.$$"
+ config_root="$ffsdir"
+ mkdir "$ffsdir" || {
+ echo "$0: $ffsdir: failed to create temporary directory" >&2
+ exit 1
+ }
+ #
+ mountflash "$ffsdev" "$ffsdir" || {
+ rmdir "$ffsdir"
+ exit 1
+ }
+ #
+ # first restore the $syspart section
+ sysconf_read "$ffsdir" || sysconf_default "$ffsdir"
+ #
+ # now use this to regenerate the system files
+ sysconf_reload "$ffsdir"
+ #
+ # now examine the [preserve] section, if it is there restore
+ # it if possible.
+ if test -n "$(syssection preserve)"
+ then
+ # 'saved' is a directory, 'restore' is a file (which is
+ # used to detect unrestored files). The directory needs
+ # to be populated with files.
+ saved=/tmp/cpio.$$
+ restore=/tmp/restore.$$
+ rm -rf "$saved" "$restore"
+ #
+ mkdir "$saved" || {
+ sysconf_restore_error "$ffsdir" "$saved: failed to create temporary directory"
+ umount "$ffsdir" && rmdir "$ffsdir" ||
+ echo "$0: $ffsdir: temporary directory cleanup failed" >&2
+ return 1
+ }
+ #
+ # the CPIO archive is gzip compressed after the text part
+ # of sysconf, gzip will handle the LZ stream termination
+ # correctly (and break the pipe) so we don't need to know
+ # the real length of the data
+ devio "<<$sysdev" '<=b4+.' 'cp $s-' | gunzip | (
+ cd "$saved"
+ exec cpio -i -d -m -u
+ ) || {
+ rm -rf "$saved"
+ sysconf_restore_error "$ffsdir" "$saved: cpio -i failed"
+ umount "$ffsdir" && rmdir "$ffsdir" ||
+ echo "$0: $ffsdir: temporary directory cleanup failed" >&2
+ return 1
+ }
+ # either there must be no 'diff' files or it must
+ # be possible to interact with a real user.
+ if test -z "$sysconf_noninteractive" ||
+ syssection preserve | sysconf_test_restore "$ffsdir" "$saved"
+ then
+ #
+ # remove the 'init' motd from sysconf_reload
+ rm "$ffsdir/etc/motd"
+ #
+ # now restore from the directory, using the information in
+ # the preserve section, if this fails in a non-interactive
+ # setting the system might not reboot
+ syssection preserve |
+ sysconf_restore_conffiles "$ffsdir" "$saved" "$restore" || {
+ # there is a chance of the user cleaning this up
+#------------------------------------------------------------------------------
+ sysconf_restore_error "$ffsdir" \
+"$0: $saved: restore of saved configuration files failed.
+ The flash file system is mounted on $ffsdir.
+ The saved files are in $saved and the list of files selected for
+ restore is in $restore.
+ You should restore any required configuration from $saved, then umount
+ $ffsdir and reboot."
+ # this prevents cleanup/umount
+ return 1
+ }
+ #
+ # remove the copied files (i.e. the ones which were preserved)
+ ( cd "$saved"
+ exec rm $(cat "$restore")
+ )
+ rm "$restore"
+ #
+ # clean up, files left in $saved need to be handled by the user
+ files="$(find "$saved" ! -type d -print)"
+ if test -n "$files"
+ then
+#------------------------------------------------------------------------------
+ sysconf_restore_error "$ffsdir" \
+"$0: some saved configuration files have not been handled:
+
+$files
+
+These files can be examined in $saved and restored to
+$ffsdir if required. The saved files are in a temporary
+directory and will not be retained across a reboot - copy then elsewhere if
+you are unsure whether they are needed."
+ return 1
+ fi
+ #
+ # so this is safe now (no files, links etc)
+ rm -rf "$saved"
+ else
+ rm -rf "$saved"
+ # non-interactive and some changed diff files
+ sysconf_restore_error "$ffsdir" \
+"$0: some of the saved configuration files must be
+examined before restoration"
+ # but continue to the umount
+ fi
+ fi
+ #
+ # ignore the error in this case:
+ umount "$ffsdir" && rmdir "$ffsdir" ||
+ echo "$0: $ffsdir: temporary directory cleanup failed" >&2
+ status=0
+ else
+ echo "sysconf restore: $syspart or $ffspart partition not found" >&2
+ echo " You must have used 'sysconf save' to save configuration data" >&2
+ echo " into the $syspart partition before using this command. The command" >&2
+ echo " will restore the configuration data to the flash root partition" >&2
+ echo " named '$ffspart' - this must also be accessible." >&2
+ fi
+
+ return $status
+}
+
+#
+# sysconf_help
+# help text
+sysconf_help(){
+ # -------------------------------------------------------------------------------
+ echo "sysconf: usage: sysconf read|default|reload|save|restore" >&2
+ echo " read: the current $syspart partition is read into /etc/default/sysconf" >&2
+ echo " default: a default /etc/default/sysconf is created" >&2
+ echo " reload: system configuration files are recreated from /etc/default/sysconf" >&2
+ echo " save: /etc/default/sysconf and the files listed in /etc/default/conffiles" >&2
+ echo " are written to the $syspart partition" >&2
+ echo " restore: the configuration information in the $syspart partition saved by" >&2
+ echo " 'sysconf save' is restored" >&2
+}
+
+#
+# the real commands
+sysconf_command="$1"
+test $# -gt 0 && shift
+case "$sysconf_command" in
+read) sysconf_read "$@";;
+default)sysconf_default "$@";;
+reload) sysconf_reload "$@";;
+save) sysconf_save "$@";;
+restore)sysconf_restore "$@";;
+valid) sysconf_valid "$@";;
+
+sysconf)# just load the functions
+ ;;
+
+*) # help text
+ sysconf_help "$@";;
+esac
diff --git a/recipes/slugos-init/files/turnup b/recipes/slugos-init/files/turnup
new file mode 100644
index 0000000000..118a57d808
--- /dev/null
+++ b/recipes/slugos-init/files/turnup
@@ -0,0 +1,965 @@
+#!/bin/sh
+# turnup
+# See the help block at the end for documentation.
+#
+. /etc/default/functions
+
+#
+# configuration
+# The following variables control which directories in /var end
+# up on the rootfs and which end up in a temporary file system.
+INRAM_MEMSTICK="\
+### SlugOS from-memory-stick boot.
+d root root 0755 /var/backups none
+d root root 0755 /var/volatile/cache none
+l root root 0755 /var/cache /var/volatile/cache
+d root root 0755 /var/lib none
+d root root 2755 /var/local none
+d root root 1777 /var/volatile/lock none
+l root root 1777 /var/lock /var/volatile/lock
+d root root 0755 /var/volatile/log none
+l root root 0755 /var/log /var/volatile/log
+d root root 0755 /var/volatile/run none
+l root root 0755 /var/run /var/volatile/run
+d root root 0755 /var/spool none
+d root root 1777 /var/volatile/tmp none
+l root root 1777 /var/tmp /var/volatile/tmp
+d root root 0755 /var/lock/subsys none
+d root root 0755 /var/lib/dropbear none
+d root root 0755 /var/lib/misc none
+f root root 0664 /var/log/wtmp none
+f root root 0664 /var/log/lastlog none
+f root root 0664 /var/run/utmp none"
+
+INRAM_NFS="\
+### SlugOS from-NFS boot.
+d root root 0755 /var/backups none
+d root root 0755 /var/volatile/cache none
+l root root 0755 /var/cache /var/volatile/cache
+d root root 0755 /var/lib none
+d root root 2755 /var/local none
+d root root 1777 /var/volatile/lock none
+l root root 1777 /var/lock /var/volatile/lock
+d root root 0755 /var/log none
+d root root 0755 /var/volatile/run none
+l root root 0755 /var/run /var/volatile/run
+d root root 0755 /var/spool none
+d root root 1777 /var/volatile/tmp none
+l root root 1777 /var/tmp /var/volatile/tmp
+d root root 0755 /var/lock/subsys none
+d root root 0755 /var/lib/dropbear none
+d root root 0755 /var/lib/misc none
+d root root 0755 /var/lib/opkg none
+f root root 0664 /var/log/wtmp none
+f root root 0664 /var/log/lastlog none
+f root root 0664 /var/run/utmp none"
+
+INRAM_DISK="\
+### SlugOS from-disk boot.
+d root root 0755 /var/backups none
+d root root 0755 /var/cache none
+d root root 0755 /var/lib none
+d root root 2755 /var/local none
+d root root 1777 /var/lock none
+d root root 0755 /var/log none
+d root root 0755 /var/run none
+d root root 0755 /var/spool none
+d root root 1777 /var/tmp none
+d root root 0755 /var/lock/subsys none
+d root root 0755 /var/lib/dropbear none
+d root root 0755 /var/lib/misc none
+d root root 0755 /var/lib/opkg none
+f root root 0664 /var/log/wtmp none
+f root root 0664 /var/log/lastlog none
+f root root 0664 /var/run/utmp none"
+
+INRAM_HEADER="\
+# This configuration file lists filesystem objects that should get verified
+# during startup and be created if missing.
+#
+# Every line must either be a comment starting with #
+# or a definition of format:
+# <type> <owner> <group> <mode> <path> <linksource>
+# where the items are separated by whitespace !
+#
+# <type> : d|f|l : (d)irectory|(f)ile|(l)ink
+#
+# A linking example:
+# l root root 0777 /var/test /tmp/testfile
+# f root root 0644 /var/test none
+#
+# Understanding links:
+# When populate-volatile is to verify/create a directory or file, it will first
+# check it's existence. If a link is found to exist in the place of the target,
+# the path of the target is replaced with the target the link points to.
+# Thus, if a link is in the place to be verified, the object will be created
+# in the place the link points to instead.
+# This explains the order of \"link before object\" as in the example above, where
+# a link will be created at /var/test pointing to /tmp/testfile and due to this
+# link the file defined as /var/test will actually be created as /tmp/testfile.
+#"
+
+#
+# force: override certain checks
+force=
+
+#
+# pfile: the uuid/partition file
+pfile=/etc/uuid_by_partition
+
+#
+# fstype new
+# The type of the file system mounted on "new" Outputs the last
+# piece of information found, which should be the one for the
+# currently visible mount!
+fstype() {
+ local cwd dev mp type options pass freq result
+ cwd="$(cd "$1"; /bin/pwd)"
+ result=
+ while read dev mp type options pass freq
+ do
+ case "$mp" in
+ "$cwd") result="$type";;
+ esac
+ done </proc/mounts
+ echo "$result"
+}
+
+#
+# fsoptions arguments
+# Collapses the mount (-o) options into a single list which is
+# printed on stdout. Accepts an arbitrary list of options and
+# just joins them together.
+fsoptions() {
+ local options
+ options=
+ while test $# -gt 1
+ do
+ case "$1" in
+ -t) shift;;
+ -o) if test -n "$2"
+ then
+ if test -n "$options"
+ then
+ options="$options,$2"
+ else
+ options="$2"
+ fi
+ fi
+ shift;;
+ esac
+ shift
+ done
+ if test -n "$options"
+ then
+ echo "$options"
+ else
+ echo defaults
+ fi
+}
+
+#
+# get_flash <directory> {mount options}
+# mount the flash device, writeable, on the given directory
+get_flash() {
+ local ffsdir ffspart ffsdev
+
+ ffsdir="$1"
+ shift
+ test -n "$ffsdir" -a -d "$ffsdir" || {
+ echo "$0: $ffsdir: internal error, flash mount point not a directory" >&2
+ return 1
+ }
+
+ case "$(machine)" in
+ nslu2) ffspart="Flashdisk";;
+ *) ffspart="filesystem";;
+ esac
+ ffsdev="$(mtblockdev $ffspart)"
+ [ -n "$ffsdev" ] || \
+ ffsdev="$(mtblockdev rootfs)"
+ umountflash "$ffsdev" &&
+ mountflash "$ffsdev" "$ffsdir" "$@"
+}
+
+#
+# check_rootfs [-i] <root fs directory>
+# Make sure the candidate rootfs is empty
+# Environment: rootdev=device or NFS root path
+check_rootfs() {
+ local fcount
+
+ case "$1" in
+ -i) shift
+ case "$force" in
+ -f) return 0;;
+ esac
+
+ fcount="$(find "$1" ! -type d -print | wc -l)"
+ test "$fcount" -eq 0 && return 0
+
+ echo "turnup: $rootdev: partition contains existing files, specify -f to overwrite" >&2
+ return 1;;
+ *) checkmount "$1" && return 0
+
+ echo "turnup: $rootdev: partition does not seem to be a valid root partition" >&2
+ echo " The partition must contain a full operating system. To ensure that" >&2
+ echo " this is the case it is checked for the following, all of which must" >&2
+ echo " exist for the bootstrap to work:" >&2
+ echo
+ echo " 1) A directory /mnt." >&2
+ echo " 2) A command line interpreter program in /bin/sh." >&2
+ echo " 3) The program chroot in /sbin or /usr/sbin." >&2
+ echo " 4) The program init in /sbin, /etc or /bin." >&2
+ echo
+ echo " One or more of these items is missing. Mount $rootdev on /mnt" >&2
+ echo " and examine its contents. You can use turnup disk|nfs -i -f" >&2
+ echo " to copy this operating system onto the disk, but it may overwrite" >&2
+ echo " files on the disk." >&2
+ return 1;;
+ esac
+}
+
+#
+# copy_rootfs old new
+# Make a copy of the given root file system, copying only the
+# directories needed. The root must be the flash file system
+copy_rootfs() {
+ local old new
+ old="$1"
+ new="$2"
+ test -d "$old" -a -d "$new" || {
+ echo "turnup: rootfs: copy $old $new: not a directory" >&2
+ return 1
+ }
+ #
+ # There are no problem file names in the flash file system, so
+ # it is possible to use -print, not -print0. The following
+ # files and directories are not copied:
+ #
+ # /dev/*
+ # /boot, /boot/*
+ # /linuxrc*
+ # /var/*
+ echo "turnup: copying root file system" >&2
+ ( cd "$1"
+ find . -xdev -print |
+ sed '\@^./dev/@d;\@^./boot/@d;\@^./boot$@d;\@^./linuxrc@d;\@^./var/@d' |
+ cpio -p -d -m -u "$2"
+ ) || {
+ echo "turnup: rootfs: cpio $old $new failed" >&2
+ return 1
+ }
+ echo "done" >&2
+}
+
+#
+# setup_dev new device_table
+# In flash file systems /dev is in ramfs, in disk systems /dev
+# can be populated permanently. This is done by creating a
+# single entry '.noram' in /dev - the devices init script will
+# then populate the directory without overmounting it. The
+# devices in the passed in device table are also created, but
+# note that this is insufficient, /etc/init.d/devices must
+# also run.
+setup_dev() {
+ test -n "$1" -a -d "$1"/dev -a -r "$2" || {
+ echo "turnup: setup_dev($1,$2): expected a directory and a file" >&2
+ return 1
+ }
+ echo "turnup: initialising dev file system" >&2
+ # init tries to open the following devices:
+ # /dev/console
+ # /dev/tty0
+ # /dev/null
+ # syslog, and maybe other things, only work if fd 1 is valid, therefore
+ # we must create these devices here...
+ # (if makedevs is a symlink, it's the busybox version, different syntax)
+ if [ -h /sbin/makedevs ]
+ then
+ makedevs -d "$2" "$1"
+ else
+ makedevs --root="$1" --devtable="$2"
+ fi
+ :>"$1"/dev/.noram
+ return 0
+}
+
+#
+# setup_bootdev new device_table
+# As above but actually uses the supplied device table - this is possible if
+# the table is just used for boot because the extra setup is not required.
+setup_bootdev() {
+ test -n "$1" -a -d "$1"/dev -a -r "$2" || {
+ echo "turnup: setup_bootdev($1,$2): expected a directory and a file" >&2
+ return 1
+ }
+ # NOTE: this fails silently with 0 return code(!) when a directory
+ # does not exist yet things are created within it.
+ # (if makedevs is a symlink, it's the busybox version, different syntax)
+ if [ -h /sbin/makedevs ]
+ then
+ makedevs -d "$2" "$1"
+ else
+ makedevs -r "$1" -D "$2"
+ fi
+}
+
+#
+# setup_var new type
+# Populates /var.
+# Removes the /var tmpfs entry from /etc/fstab.
+# Creates links from /var into /media/ram for NFS and Memstick.
+setup_var() {
+
+ test -n "$1" -a -d "$1"/var || {
+ echo "turnup: setup_var($1,$2): expected a directory" >&2
+ return 1
+ }
+ case "$2" in
+ disk|nfs|memstick);;
+ *) echo "turnup: setup_var($1,$2): expected 'disk', 'nfs' or 'memstick'" >&2
+ return 1;;
+ esac
+
+ # populate /var. We just need to create the /var/volatile mount
+ # point, the populate-volatile script does the work at boot time.
+ #QUIET: echo "turnup: ensuring /var/volatile mountpoint exists" >&2
+ test -d "$1"/var/volatile || mkdir "$1"/var/volatile
+
+ # we need to put in place the correct configuration file for
+ # the populate-volatile script to use at boot time. The config
+ # file is already in place for the flash boot, and it's the same
+ # file for the ram boot.
+ case "$2" in
+ disk) echo "$INRAM_HEADER" > "$1"/etc/default/volatiles/00_core
+ echo "$INRAM_DISK" >>"$1"/etc/default/volatiles/00_core;;
+ nfs) echo "$INRAM_HEADER" > "$1"/etc/default/volatiles/00_core
+ echo "$INRAM_NFS" >>"$1"/etc/default/volatiles/00_core;;
+ memstick) echo "$INRAM_HEADER" > "$1"/etc/default/volatiles/00_core
+ echo "$INRAM_MEMSTICK" >>"$1"/etc/default/volatiles/00_core;;
+ esac
+
+ # remove the /var tmpfs entry from the new /etc/fstab, if it is
+ # present in the first place.
+ sed -i '\@[ ]/var[ ][ ]*tmpfs[ ]@d' "$1"/etc/fstab
+ #QUIET: echo "turnup: ensuring tmpfs will not be mounted on /var" >&2
+ #
+ return 0
+}
+
+#
+# setup_syslog new
+# Moves the syslog to a file - appropriate for disk and nfs types, not
+# otherwise.
+setup_syslog() {
+ test -n "$1" -a -d "$1"/etc || {
+ echo "turnup: setup_syslog($1): expected a directory" >&2
+ return 1
+ }
+ #
+ # if the syslog is to the buffer redirect it to a file
+ if egrep -q '^DESTINATION="buffer"' "$1"/etc/syslog.conf
+ then
+ if cp "$1"/etc/syslog.conf "$1"/etc/syslog.conf.sav
+ then
+ # the busybox syslog will fail with ROTATESIZE and ROTATEGENS
+ sed -i 's!DESTINATION="buffer"!DESTINATION="file"!
+ /^ROTATESIZE=/d
+ /^ROTATEGENS=/d' "$1"/etc/syslog.conf
+ #QUIET: echo "turnup: /etc/syslog.conf: changed to file buffering" >&2
+ #QUIET: echo " Old (buffer) version in /etc/syslog.conf.sav" >&2
+ #QUIET: echo " Log messages will be in /var/log/messages" >&2
+ else
+ echo "turnup: /etc/syslog.conf: failed to make a copy" >&2
+ echo " syslog will log to a buffer" >&2
+ fi
+ fi
+ return 0
+}
+
+#
+# setup_rootfs type new device_table
+# Populates the /dev and /var directories, alters the startup to
+# not mount or populate them further. Does the right thing according
+# to the given $type
+setup_rootfs() {
+ local type new table
+ type="$1"
+ new="$2"
+ table="$3"
+
+ test -n "$new" -a -d "$new" -a -f "$table" || {
+ echo "turnup: setup_rootfs($type,$new,$table): expected a directory and a file" >&2
+ return 1
+ }
+
+ case "$type" in
+ flash) return 0;;
+ disk) setup_dev "$new" "$table" &&
+ setup_var "$new" "$type" &&
+ setup_syslog "$new";;
+ memstick)
+ setup_bootdev "$new" "$table" &&
+ setup_var "$new" "$type" ;;
+ nfs) setup_dev "$new" "$table" &&
+ setup_var "$new" "$type" &&
+ setup_syslog "$new";;
+ *) echo "turnup: setup_rootfs: $type: unknown rootfs type" >&2
+ return 1;;
+ esac
+ # return code of last setup function
+}
+
+#
+# setup_fstab new fsdev fstype fsoptions
+# Alters the /etc/fstab entry for / to refer to the correct device and
+# have the correct type and options. Essential for checkroot to remount
+# / with the correct options. Writes the initial uuid file.
+# bad, since sed won't fail even if it changes nothing.
+setup_fstab() {
+ sed -i '\@^[^ ]*[ ][ ]*/[ ]@s@^.*$@'"$2 / $3 $4 1 1"'@' "$1"/etc/fstab
+ egrep -q "^$2 / $3 $4 1 1\$" "$1"/etc/fstab || {
+ echo "turnup: /etc/fstab: root(/) entry not changed" >&2
+ echo " you probably need to check the options in /etc/fstab" >&2
+ echo " to ensure that the root partition is mounted correctly" >&2
+ return 1
+ }
+ #
+ # build $pfile
+ uuid_by_partition >"$1""$pfile" ||
+ echo "turnup: $pfile: blkid failed (ignored)" >&2
+ return 0
+}
+
+#
+# boot_rootfs <boot type> <flash file system> <sleep time> (<device> <uuid>|<nfsroot>) [options]
+# Change the flash partition (not the current root!) to boot off
+# the new root file system
+boot_rootfs() {
+ local type ffs sleep device uuid opt
+
+ type="$1"
+ ffs="$2"
+ sleep="$3"
+ device="$4"
+ uuid=
+ mduuid=
+
+ # test this first as the test does not depend on the correctness
+ # of the other arguments
+ test -n "$ffs" -a -d "$ffs" || {
+ echo "turnup: boot_rootfs($type, $ffs, $device): expected directory" >&2
+ return 1
+ }
+ test -x "$ffs"/boot/"$type" || {
+ echo "turnup: boot_rootfs($type, $ffs, $device): invalid boot type $type" >&2
+ return 1
+ }
+ shift
+ shift
+
+ case "$type" in
+ disk) test -n "$device" -a -b "$device" || {
+ echo "turnup: boot_rootfs($ffs, $type, $device): expected block device" >&2
+ return 1
+ }
+ uuid="$3"
+ if (echo "$device" | grep -q '^/dev/md')
+ then
+ # FIXME: should use awk to do the below extraction
+ mduuid=`mdadm --detail --brief "$device" | sed 's/^.*UUID=//'`
+ fi
+ shift 3;;
+ nfs) shift 2;;
+ flash) ;;
+ ram) ;;
+ *) echo "turnup: boot_rootfs($type, $ffs, $device): unknown type" >&2
+ return 1;;
+ esac
+
+ #
+ # The /linuxrc records the correct options to mount the device,
+ # since we have already mounted if correctly with these options
+ # we can be sure (maybe) that the boot will work. If not /boot/disk
+ # falls back to flash.
+ #
+ # This modifies the boot process, until this point no harm has been
+ # done to the system, but at this point the boot rootfs will change
+ rm -f "$ffs"/linuxrc.new || {
+ echo "turnup: boot_rootfs: failed to remove $ffs/linuxrc.new" >&2
+ return 1
+ }
+ case "$type" in
+ flash) ln -s "boot/flash" "$ffs"/linuxrc.new || {
+ echo "turnup: boot_rootfs: failed to create $ffs/linuxrc.new" >&2
+ return 1
+ };;
+ ram) { echo '#!/bin/sh'
+ echo 'mount -t proc proc /proc'
+ echo 'mount -t sysfs sysfs /sys'
+ echo 'leds beep'
+ echo 'rm -f /linuxrc.new'
+ echo 'ln -s boot/flash /linuxrc.new'
+ echo 'mv /linuxrc.new /linuxrc'
+ echo 'exec /boot/ram /dev/ram0'
+ echo 'exec /boot/flash'
+ } >"$ffs"/linuxrc.new &&
+ chmod 744 "$ffs"/linuxrc.new || {
+ echo "turnup: boot_rootfs: failed to write $ffs/linuxrc.new" >&2
+ return 1
+ };;
+ *) { echo '#!/bin/sh'
+ echo 'mount -t proc proc /proc'
+ echo 'mount -t sysfs sysfs /sys'
+ echo 'leds beep'
+ test "$sleep" -gt 0 && echo -n "sleep='$sleep' "
+ test -n "$uuid" && echo -n "UUID='$uuid' "
+ test -n "$mduuid" && echo -n "MDUUID='$mduuid' "
+ echo -n "exec '/boot/$type' '$device'"
+ for opt in "$@"
+ do
+ echo -n " '$opt'"
+ done
+ echo
+ echo 'exec /boot/flash'
+ } >"$ffs"/linuxrc.new &&
+ chmod 744 "$ffs"/linuxrc.new || {
+ echo "turnup: boot_rootfs: failed to write $ffs/linuxrc.new" >&2
+ return 1
+ };;
+ esac
+ rm -f "$ffs"/linuxrc.sav || {
+ echo "turnup: boot_rootfs: failed to remove $ffs/linuxrc.sav" >&2
+ return 1
+ }
+ ln "$ffs"/linuxrc "$ffs"/linuxrc.sav || {
+ echo "turnup: boot_rootfs: failed to save /linuxrc.sav" >&2
+ return 1
+ }
+ mv -f "$ffs"/linuxrc.new "$ffs"/linuxrc || {
+ echo "turnup: boot_rootfs: failed to install new /linuxrc" >&2
+ return 1
+ }
+ return 0
+}
+
+#
+# disk [-m] [-i] [-s<time>] <device> {options}
+# Carefully copy the flash file system to the named device.
+disk() {
+ local setup_type sleep init device uuid new ffs fst fso
+
+ setup_type=disk
+ sleep=10
+ init=
+ while test $# -gt 0
+ do
+ case "$1" in
+ -f) force="$1"
+ shift;;
+ -m) setup_type=memstick
+ shift;;
+ -i) init="$1"
+ shift;;
+ -s*) sleep="${1#-s}"
+ sleep="${sleep:-10}"
+ shift;;
+ *) break;;
+ esac
+ done
+
+ device="$1"
+ test -n "$device" -a -b "$device" || {
+ echo "turnup disk: $device: block device required" >&2
+ return 1
+ }
+ shift
+
+ # find the uuid if available
+ uuid="$(blkid -c /dev/null -s UUID -o value "$device")"
+
+ # make temporary directories for the mount points
+ new="/tmp/rootfs.$$"
+ ffs="/tmp/flashdisk.$$"
+ mkdir "$new" "$ffs" || {
+ echo "turnup: disk: failed to create temporary directories" >&2
+ return 1
+ }
+
+ # make sure we can get to the flash file system first
+ get_flash "$ffs" || {
+ rmdir "$new" "$ffs"
+ return 1
+ }
+
+ # Now mount the device with the given options, note that specifying
+ # read only is *not* an option, this is important because the boot/disk
+ # script needs a rw file system
+ status=1
+ fst=
+ fso="$(fsoptions "$@")"
+ if if test -n "$uuid"
+ then
+ mount "$@" UUID="$uuid" "$new"
+ else
+ mount "$@" "$device" "$new"
+ fi
+ then
+ fst="$(fstype "$new")"
+ umount "$new" ||
+ echo "turnup disk: $device($new): umount does not seem to work" >&2
+ fi
+
+ if test -n "$fst" &&
+ if test -n "$uuid"
+ then
+ mount -t "$fst" -o "$fso" UUID="$uuid" "$new"
+ else
+ mount -t "$fst" -o "$fso" "$device" "$new"
+ fi
+ then
+ if rootdev="$device" check_rootfs $init "$new" && {
+ test -z "$init" || {
+ copy_rootfs "$ffs" "$new" &&
+ setup_rootfs "$setup_type" "$new" "$ffs"/etc/device_table
+ }
+ }
+ then
+ setup_fstab "$new" "$device" "$fst" "$fso"
+ status=0
+ fi
+
+ # clean up the disk. It is worrying if this umount fails!
+ umount "$new" || test "$force" = "-f" || {
+ echo "turnup disk: $device: umount failed" >&2
+ echo " you must unmount this device cleanly yourself, then use" >&2
+ if test -z "$init"
+ then
+ echo " turnup with the -f option to boot from the device" >&2
+ else
+ echo " turnup without the -i option to boot from the device" >&2
+ fi
+ status=1
+ }
+
+ # if everything went ok boot from this disk
+ if test $status -eq 0
+ then
+ # memsticks boot like disks, so ignore the -m
+ boot_rootfs disk "$ffs" "$sleep" "$device" "$uuid" -t "$fst" -o "$fso"
+ fi
+ else
+ echo "turnup disk: $device($*): unable to mount device on $new" >&2
+ # If it worked first time
+ if test -n "$fst"
+ then
+ echo " options used: -t $fst -o $fso [error in this script]" >&2
+ test -n "$uuid" &&
+ echo " uuid: $uuid (passed with UUID=<uuid>)" >&2
+ fi
+ fi
+
+ # clean up the flash file system
+ umount "$ffs"
+ rmdir "$new" "$ffs"
+ return $status
+}
+
+#
+# boot_reset <type>
+# Resets the boot type to flash or ram, as appropriate
+boot_reset() {
+ local ffs typ status
+
+ case "$1" in
+ flash|ram)type="$1"
+ shift;;
+ *) echo "turnup: boot_reset($1): invalid type" >&2
+ return 1;;
+ esac
+
+ ffs="/tmp/flashdisk.$$"
+ mkdir "$ffs" || {
+ echo "turnup: $1: failed to create temporary directory" >&2
+ return 1
+ }
+
+ get_flash "$ffs" || {
+ rmdir "$ffs"
+ return 1
+ }
+
+ # now try to set the /linuxrc appropriately
+ boot_rootfs "$type" "$ffs"
+ status=$?
+
+ # clean up
+ umount "$ffs"
+ rmdir "$ffs"
+ return $status
+}
+
+#
+# nfs [-i] <root partition> {options}
+# Copy the flash file system to the given NFS root partition.
+nfs() {
+ local init nfsroot new ffs
+
+ init=
+ while test $# -gt 0
+ do
+ case "$1" in
+ -i) init="$1"
+ shift;;
+ -f) force="$1"
+ shift;;
+ *) break;;
+ esac
+ done
+
+ nfsroot="$1"
+ test -n "$nfsroot" || {
+ echo "turnup nfs: $nfsroot: NFS root file system required" >&2
+ return 1
+ }
+ shift
+
+ # make temporary directories for the mount points
+ new="/tmp/rootfs.$$"
+ ffs="/tmp/flashdisk.$$"
+ mkdir "$new" "$ffs" || {
+ echo "turnup nfs: failed to create temporary directories" >&2
+ return 1
+ }
+
+ # make sure we can get to the flash file system first
+ get_flash "$ffs" || {
+ rmdir "$new" "$ffs"
+ return 1
+ }
+
+ # Now mount the device with the given options, note that specifying
+ # read only is *not* an option, this is important because the boot/disk
+ # script needs a rw file system
+ status=1
+ fst=
+ # These settings for for NFS, something better will probably have to
+ # be done to support other network file systems.
+ nfsopt="nolock,noatime,hard,intr,rsize=1024,wsize=1024"
+ fso="$(fsoptions -o "$nfsopt" "$@")"
+ if mount -o "$nfsopt" "$@" "$nfsroot" "$new"
+ then
+ fst="$(fstype "$new")"
+ umount "$new" ||
+ echo "turnup nfs: $nfsroot($new): umount does not seem to work" >&2
+ fi
+
+ if test -n "$fst" && mount -t "$fst" -o "$fso" "$nfsroot" "$new"
+ then
+ if :>"$new"/ttt && test -O "$new"/ttt && rm "$new"/ttt
+ then
+ if rootdev="$nfsroot" check_rootfs $init "$new" && {
+ test -z "$init" || {
+ copy_rootfs "$ffs" "$new" &&
+ setup_rootfs nfs "$new" "$ffs"/etc/device_table
+ }
+ }
+ then
+ setup_fstab "$new" "$nfsroot" "$fst" "$fso"
+ status=0
+ fi
+ else
+ echo "turnup nfs: $nfsroot: partition must be exported no_root_squash" >&2
+ fi
+
+ # clean up the disk. It is worrying if this umount fails!
+ umount "$new" || test "$force" = "-f" || {
+ echo "turnup nfs: $nfsroot: umount failed" >&2
+ if test $status -eq 0
+ then
+ echo " you must unmount this partition cleanly yourself, then use" >&2
+ if test -z "$init"
+ then
+ echo " turnup with the -f option to boot from the NFS root" >&2
+ else
+ echo " turnup without the -i option to boot from the NFS root" >&2
+ fi
+ status=1
+ fi
+ }
+
+ # if everything went ok boot from this disk
+ if test $status -eq 0
+ then
+ # the options used are exactly those which worked before.
+ boot_rootfs nfs "$ffs" 0 "$nfsroot" -t nfs -o "$fso"
+ fi
+ else
+ echo "turnup nfs: $nfsroot($*): unable to mount device on $new" >&2
+ # If it worked first time
+ if test -n "$fst"
+ then
+ echo " options obtained: -t $fst -o $fso" >&2
+ fi
+ fi
+
+ # clean up the flash file system
+ umount "$ffs"
+ rmdir "$new" "$ffs"
+ return $status
+}
+
+#
+# read_one 'prompt' 'group' 'name'
+# read a single value
+read_one() {
+ local n o
+ o="$(sysval "$2" "$3")"
+ echo -n "$1 [$o]: " >/dev/tty
+ read n </dev/tty
+ test -z "$n" && n="$o"
+ eval "$3='$n'"
+}
+
+#
+# init_network
+# Change the network initialisation
+init_network() {
+ # fix the root password
+ echo "Please enter a new password for 'root'." >/dev/tty
+ echo "The password must be non-empty for ssh login to succeed!" >/dev/tty
+ passwd
+ # now the network configuration
+ read_one "Host name" network disk_server_name
+ read_one "Domain name" network w_d_name
+ read_one "Boot protocol (dhcp|static)" network bootproto
+ case "$bootproto" in
+ static) read_one "IP address" network ip_addr
+ read_one "IP netmask" network netmask
+ read_one "IP gateway" network gateway
+ read_one "First DNS server" network dns_server1
+ read_one "Second DNS server" network dns_server2
+ read_one "Third DNS server" network dns_server3
+ echo "$ip_addr $disk_server_name" >> /etc/hosts
+ ;;
+ dhcp) sed -i -e "s/localhost\$/localhost $disk_server_name/" /etc/hosts
+ ;;
+ *) bootproto=dhcp;;
+ esac
+ #
+ # The other stuff which cannot be changed
+ hw_addr="$(config mac)"
+ lan_interface="$(config iface)"
+ #
+ # Write this out to a new sysconf
+ { echo "[network]"
+ echo "hw_addr=$hw_addr"
+ echo "lan_interface=$lan_interface"
+ test -n "$disk_server_name" && echo "disk_server_name=$disk_server_name"
+ test -n "$w_d_name" && echo "w_d_name=$w_d_name"
+ echo "bootproto=$bootproto"
+ case "$bootproto" in
+ static) echo "ip_addr=$ip_addr"
+ test -n "$netmask" && echo "netmask=$netmask"
+ test -n "$gateway" && echo "gateway=$gateway"
+ test -n "$dns_server1" && echo "dns_server1=$dns_server1"
+ test -n "$dns_server2" && echo "dns_server2=$dns_server2"
+ test -n "$dns_server3" && echo "dns_server3=$dns_server3"
+ ;;
+ esac
+ } >/etc/default/sysconf
+ #
+ # And reload the result
+ sysconf reload
+ #
+ # The remove the spurious 'init' motd
+ rm /etc/motd
+}
+
+#
+# Basic command switch (this should be the only thing in this
+# script which actually does anything!)
+case "$1" in
+init) shift
+ if init_network "$@"
+ then
+ echo "turnup init: you must reboot for the changes to take effect" >&2
+ echo " You may want to run 'turnup preserve' to save these settings," >&2
+ echo " after making any additional configuration changes which you" >&2
+ echo " require." >&2
+ else
+ exit 1
+ fi;;
+disk) shift
+ disk "$@";;
+memstick)
+ shift
+ disk -m "$@" -o noatime;;
+nfs) shift
+ nfs "$@";;
+flash) boot_reset flash;;
+ram) boot_reset ram;;
+preserve)
+ shift
+ sysconf save "$@";;
+restore)
+ shift
+ sysconf restore "$@";;
+*) echo "\
+usage: turnup command [options]
+ commands:
+ help
+ output this help
+ init
+ correct errors in network information
+ initialise network information when DHCP is not available
+ change network information
+ disk [-i] [-s<seconds>] <device>|<uuid> [mount options]
+ With -i make <device> a bootable file system then (with or
+ without -i) arrange for the next reboot to use that device.
+ The device must already be formatted as a file system, with
+ -i it must be completely empty, without it must contain an
+ apparently bootable file system. -s (for example -s5)
+ specifies a delay in seconds to wait at boot time before
+ mounting the device.
+ memstick [-i] <device>|<uuid> [mount options]
+ Behaves as disk however options appropriate to a flash memory
+ stick are automatically added
+ nfs [-i] <nfs mount path> [mount options]
+ <nfs mount path> must be a mountable NFS file system. With
+ -i the partition must be empty and is initialised with a
+ bootable file system. Without -i the partition must already
+ contain a bootable file system. In either case the NFS
+ partition must be available to be mounted without root id
+ sqashing (i.e. root must be root) and it will be selected
+ as the root file system for subsequent reboots.
+ A default set of -o options are provided, additional options
+ may be given on the command line (multiple -o options will
+ be combined into a single -o).
+ flash
+ Revert to booting from the flash disk on next reboot.
+ ram
+ Boot (once) into a ramdisk, subsequent boots will be to
+ the flash file system.
+ preserve
+ Save the system configuration to the SysConf partition, you
+ will need to create the SysConf partition from the boot loader
+ before using this if SysConf does not already exist. This
+ just runs 'sysconf save'.
+ restore
+ Restore a previously saved system configuration. This just
+ runs 'sysconf restore'.
+ disk formatting:
+ The argument to 'nfs' or 'disk' must be an empty partition
+ of sufficient size to hold the root file system (at least
+ 16MByte but more is recommended to allow package installation).
+ An appropriate ext3 partition can be made using the command:
+
+ mke2fs -j <device> # for example: /dev/sda1
+
+ An appropriate NFS partition can be emptied using 'rm', but
+ must be set up (exported) on the NFS server." >&2
+ exit 0;;
+esac
+# Exit with return code from command.
diff --git a/recipes/slugos-init/files/usb b/recipes/slugos-init/files/usb
new file mode 100644
index 0000000000..b641113137
--- /dev/null
+++ b/recipes/slugos-init/files/usb
@@ -0,0 +1,2 @@
+install uhci-hcd /sbin/modprobe ehci-hcd ; /sbin/modprobe -i uhci-hcd
+install ohci-hcd /sbin/modprobe ehci-hcd ; /sbin/modprobe -i ohci-hcd