From 4b72cfb3f2a471ece09a87321a790c92cfe6966f Mon Sep 17 00:00:00 2001 From: John Bowler Date: Mon, 23 May 2005 18:02:35 +0000 Subject: New /linuxrc boot mechanism Use "turnup help" to find out how to do turnup now! BKrev: 42921abbPAuC7JcmxHiVNgYZgCeE5A --- packages/openslug-init/openslug-init-0.10/turnup | 612 +++++++++++++++++++++++ 1 file changed, 612 insertions(+) (limited to 'packages/openslug-init/openslug-init-0.10/turnup') 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