From: John Bowler Date: Mon, 23 May 2005 18:02:35 +0000 (+0000) Subject: New /linuxrc boot mechanism X-Git-Tag: Release-2010-05/1~14110 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4b72cfb3f2a471ece09a87321a790c92cfe6966f;p=openembedded.git New /linuxrc boot mechanism Use "turnup help" to find out how to do turnup now! BKrev: 42921abbPAuC7JcmxHiVNgYZgCeE5A --- diff --git a/packages/busybox/busybox-1.00/openslug/udhcpscript.patch b/packages/busybox/busybox-1.00/openslug/udhcpscript.patch new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/busybox/busybox_1.00.bb b/packages/busybox/busybox_1.00.bb index a532168095..0ae99d0b58 100644 --- a/packages/busybox/busybox_1.00.bb +++ b/packages/busybox/busybox_1.00.bb @@ -10,7 +10,7 @@ HOMEPAGE = "http://www.busybox.net" LICENSE = "GPL" SECTION = "base" PRIORITY = "required" -PR = "r19" +PR = "r20" SRC_URI = "http://www.busybox.net/downloads/busybox-${PV}.tar.gz \ file://add-getkey-applet.patch;patch=1 \ diff --git a/packages/meta/openslug-image.bb b/packages/meta/openslug-image.bb index 5dc3fc4327..8e50c1b40a 100644 --- a/packages/meta/openslug-image.bb +++ b/packages/meta/openslug-image.bb @@ -1,4 +1,4 @@ -PR = "r10" +PR = "r11" IMAGE_BASENAME = "openslug" @@ -19,6 +19,7 @@ DEPENDS = "virtual/kernel base-files base-passwd \ # NOTE: file system kernel modules are defined in openslug.conf # (OPENSLUG_EXTRA_FILESYSTEMS, included in OPENSLUG_EXTRA_INSTALL) +# kernel-module-af-packet must be in the image for DHCP to work IPKG_INSTALL = "base-files base-passwd \ busybox dropbear hotplug-ng initscripts netbase \ update-modules sysvinit tinylogin lrzsz portmap \ @@ -27,6 +28,8 @@ IPKG_INSTALL = "base-files base-passwd \ ipkg-collateral ipkg ipkg-link diffutils \ cpio findutils e2fsprogs-mke2fs \ e2fsprogs-fsck e2fsprogs-e2fsck \ + kernel-module-af-packet \ + kernel-module-netconsole \ ${OPENSLUG_EXTRA_INSTALL}" inherit image_ipk diff --git a/packages/openslug-init/openslug-init-0.10/leds_rs_green b/packages/openslug-init/openslug-init-0.10/leds_rs_green index e69de29bb2..5483d67202 100644 --- a/packages/openslug-init/openslug-init-0.10/leds_rs_green +++ b/packages/openslug-init/openslug-init-0.10/leds_rs_green @@ -0,0 +1,38 @@ +#!/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' sets the correct colour power LED to flash between the +# two colours of the previous and next runlevel. +# 'start' sets the LED to steady +# +# 'red' is the initial setting on kernel boot +# +# 'amber' is used for run levels S (from /linuxrc), 0 (halt), +# 1 (single user) and 6 (reboot). halt and reboot do not +# terminate therefore the LED remains flashing until the +# kernel terminates. +# +# 'green' is used for run levels 2-5 - the normal user run levels. +# +# colours are 'g' (green), 'r' (red) or 'gr' (amber). +colour() { + case "$1" in + S|0|1|6) echo gr;; + 2|3|4|5) echo g;; + N) echo gr;; # apparently used for S as well + *) echo "led change: $runlevel: runlevel unknown" >&2 + echo r;; + esac +} + +# leds syntax is -A + / +case "$1" in +start) leds -A +"$(colour "$runlevel")";; +stop) leds -A +"$(colour "$previous")" /"$(colour "$runlevel")";; +*) echo "led change: $1: command ignored" >&2;; +esac + +exit 0 diff --git a/packages/openslug-init/openslug-init-0.10/sysconfsetup b/packages/openslug-init/openslug-init-0.10/sysconfsetup index 83b8d34648..4ed4e10162 100644 --- a/packages/openslug-init/openslug-init-0.10/sysconfsetup +++ b/packages/openslug-init/openslug-init-0.10/sysconfsetup @@ -1,63 +1,143 @@ #!/bin/sh -if [ ! -e /etc/linksysconf ] +# 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 to run this again. If this is done the +# following configuration files will be rewritten: +# +# /etc/default/sysconf +# /etc/hostname +# /etc/defaultdomain +# /etc/network/interfaces +# /etc/resolv.conf +# +test -r /etc/default/sysconf && exit 0 +# +# /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 +# +# Utility to deal with absence of DNS configuration +echodns(){ + local dns + if test $# -gt 0 + then + for dns in "$@" + do + echo "nameserver $dns" + done + fi +} +# +# The SysConf device must exist in /dev at this point for this script +# to work. +# +# It is important not to hard-wire the name of the device because of +# the posibility of changing the flash partition layout. +sysdev="$(mtdev SysConf)" +if test -n "$sysdev" -a -c "$sysdev" then - -# Ok this may be a little hack for now -# but Make sure the kernel module info is updated -# So the driver can actually load the first time - /usr/sbin/update-modules - -# Set the default root password so ppl can ssh in - sed -i -e 's/root::/root:uf8TRGX9WDuH2:/' /etc/passwd - - dd if=/dev/mtdblock1 of=/etc/linksysconf - cat < /etc/original-network-settings -# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8) - -# The loopback interface -auto lo -iface lo inet loopback - -auto eth0 -iface eth0 inet static -EOF - - # Use the bootproto key to set "static" or "dhcp", then do other stuff based on that. - # strings /etc/linksysconf | grep bootproto >> /etc/original-network-settings - # sed -i -e 's/bootproto=//' /etc/original-network-settings - - strings /etc/linksysconf | grep ip_addr >> /etc/original-network-settings - strings /etc/linksysconf | grep ^netmask >> /etc/original-network-settings - strings /etc/linksysconf | grep ^gateway=. >> /etc/original-network-settings - strings /etc/linksysconf | grep hw_addr >> /etc/original-network-settings - sed -i -e 's/ip_addr=/ address /' /etc/original-network-settings - sed -i -e 's/netmask=/ netmask /' /etc/original-network-settings - sed -i -e 's/gateway=/ gateway /' /etc/original-network-settings - sed -i -e 's/hw_addr=/ hwaddress ether /' /etc/original-network-settings - - mv /etc/network/interfaces /etc/network/interfaces.old - cp /etc/original-network-settings /etc/network/interfaces - - echo "Configured /etc/network/interfaces from /etc/linksysconf" - - strings /etc/linksysconf | grep disk_server_name >> /tmp/hostname - sed -i -e 's/disk_server_name=//' /tmp/hostname - - if [ -s /tmp/hostname ] ; then - mv /etc/hostname /etc/hostname.old - mv /tmp/hostname /etc/hostname - echo "Configured /etc/hostname from /etc/linksysconf" - fi - - strings /etc/linksysconf | grep dns_server1 >> /tmp/resolv.conf - sed -i -e 's/dns_server1=/nameserver /' /tmp/resolv.conf - - if [ -s /tmp/resolv.conf ] ; then - mv /etc/resolv.conf /etc/resolv.conf.old - mv /tmp/resolv.conf /etc/resolv.conf - echo "Configured /etc/resolv.conf from /etc/linksysconf" - fi - + # Read the defined part of SysConf into /etc/default/sysconf. + # SysConf has lines of two forms: + # + # [section] + # name=value + # + # In practice SysConf also contains other stuff, use the command: + # + # devio '</etc/default/sysconf + # + # Now take the result and set up the 'standard' files in the + # root file system (these couldn't be set up before because + # they depend on stuff which RedBoot puts into SysConf from the + # ID info on the specific machine - in particular the hardware + # address of eth0, which must be the one assigned for *this* + # box!) + # + # HOSTNAME: defaults to LGK i.e. something derived from + # the ethernet hardware. LinkSys documentation explains how + # to determine this. Set by the user in linksys setup software. + # DOMAINNAME: LinkSys puts this in w_d_name. + test -n "$(config host)" && config host >/etc/hostname + domain="$(config domain)" + test -n "$domain" && echo "$domain" >/etc/defaultdomain + # + # 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 openslug udhcp script, + # /etc/udhcpc.d/50default, loads the values from sysconf. The + # lan_interface config value must exist for the file to be + # overwritten here. + iface="$(config iface)" + if test -n "$iface" + then + 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 + # + mac="$(config mac)" + 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 NSLU2 built-in ethernet" + echo "auto eth0" + echo "# Automatically generated from /etc/default/sysconf" + if test -n "$mac" + then + echo "# The pre-up option must always be supplied, regardless" + echo "# of configuration, to set the hardware correctly." + echo "# Severe network problems may result if this option is" + echo "# removed." + c= + else + echo "# WARNING: improperly configured network interface." + echo "# WARNING: the pre-up line must be corrected or severe" + echo "# WARNING: network problems may result." + c='#' + mac='' + fi + echo "iface $iface inet $boot" + echo "${c} pre-up ifconfig $iface hw ether $mac" + # 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" + } >/etc/network/interfaces + fi + # + # The DNS server information gives up to three nameservers, but this + # currently only binds in the first. + { + test -n "$domain" && echo "search $domain" + echodns $(config dns) $(config dns1) $(config dns2) + } >/etc/resolv.conf fi -# Module loading handled more properly by update-modules and modprobe.conf +exit 0 diff --git a/packages/openslug-init/openslug-init-0.10/turnup b/packages/openslug-init/openslug-init-0.10/turnup index e69de29bb2..b688bc3051 100644 --- a/packages/openslug-init/openslug-init-0.10/turnup +++ b/packages/openslug-init/openslug-init-0.10/turnup @@ -0,0 +1,612 @@ +#!/bin/sh +# turnup +# See the help block at the end for documentation. +# +. /etc/default/functions + +# +# force: override certain checks +force= +# +# check_rootfs [-i] +# Make sure the candidate rootfs is empty +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: $1: partition contains existing files, specify -f to overwrite" >&2 + return 1;; + *) checkmount "$1" && return 0 + + echo "turnup: $1: partition does not seem to be a valid root partition" >&2 + if test -f "$1"/.recovery + then + echo " $1/.recovery exists: fix the partition then remove it" >&2 + fi + 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 . -mount -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 +# Populates the /dev directory, removes the ramfs mount of /dev by +# removing the links to the devices startup file. +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 + } + # at present the device_table is not used because it is incomplete, + # /etc/init.d/devices adds extra stuff. So this script copies the + # existing /dev. FIXME. + echo "turnup: copying dev file system" >&2 + ( cd / + find dev -print0 | cpio -p -0 -d -m -u "$1" + ) || { + echo "turnup: rootfs: cpio /dev $1 failed" >&2 + return 1 + } + echo "done" >&2 + # now remove the startup links which mount the ramfs on /dev + rm "$1"/etc/rc?.d/[KS]??devices + 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. + makedevs -r "$1" -D "$2" +} + +# +# setup_var new type +# Populates /var. Should only be called for true disk systems and NFS - +# it's a waste on USB memory sticks! Removes the /var tmpfs setting +# for disks, sets it to /var/tmp for NFS. +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);; + *) echo "turnup: setup_var($1,$2): expected 'disk' or 'nfs'" >&2 + return 1;; + esac + # + # populate /var, there is a shell script to do this, but it uses + # absolute path names + chroot "$1" /bin/busybox sh /etc/init.d/populate-var.sh || { + echo "turnup: /var: could not populate directory" >&2 + return 1 + } + # and remove the startup links + rm "$1"/etc/rc?.d/[KS]??populate-var.sh + # remove the /var tmpfs entry from the new /etc/fstab + case "$2" in + disk) sed -i '\@\s/var\s\s*tmpfs\s@d' "$1"/etc/fstab + echo "turnup: tmpfs will no longer be mounted on /var" >&2;; + nfs) sed -i '\@\s/var\s\s*tmpfs\s@s@\s/var@&/tmp@' "$1"/etc/fstab + echo "turnup: tmpfs /var mount moved to /var/tmp" >&2;; + esac + # + # warn the user - it's not enough to put the /var mount back, it + # is necessary to reinsert the populate-var.sh links! + echo " If you remount tmpfs on /var it must be populated at boot, use:" >&2 + echo " update-rc.d populate-var.sh start 37 S ." >&2 + return 0 +} + +# +# setup_files new +# At present just puts the rmrecovery links in. +setup_files() { + test -n "$1" -a -d "$1"/etc || { + echo "turnup: setup_files($1): expected a directory" >&2 + return 1 + } + # + # add the script to remove .recovery + update-rc.d -r "$1" rmrecovery start 99 1 2 3 4 5 . + 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 + echo "turnup: /etc/syslog.conf: changed to file buffering" >&2 + echo " Old (buffer) version in /etc/syslog.conf.sav" >&2 + 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" disk && + setup_files "$new" && + setup_syslog "$new";; + memstick) + setup_bootdev "$new" "$table" && + setup_files "$new";; + nfs) setup_dev "$new" "$table" && + setup_var "$new" nfs && + setup_files "$new" && + setup_syslog "$new";; + *) echo "turnup: setup_rootfs: $type: unknown rootfs type" >&2 + return 1;; + esac + # return code of last setup function +} + +# +# boot_rootfs [options] +# Change the flash partition (not the current root!) to boot off +# the new root file system +boot_rootfs() { + local type ffs sleep device opt + + type="$1" + ffs="$2" + sleep="$3" + device="$4" + + # 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 + } + shift 2;; + 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 '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' + test "$sleep" -gt 0 && echo -n "sleep='$sleep' " + 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 +} + +# +# mountflash +# Finds and mounts the flash file system +mountflash() { + local ffsdev + + ffsdev="$(mtblockdev Flashdisk)" + test -n "$ffsdev" -a -b "$ffsdev" || { + echo "turnup disk: unable to find flash file system to copy ($ffsdev)" >&2 + return 1 + } + mount -t jffs2 "$ffsdev" "$1" || { + echo "turnup disk: $ffsdev: unable to mount flash file system on $1" >&2 + return 1 + } + return 0 +} + +# +# disk [-m] [-i] [-s