3 # See the help block at the end for documentation.
5 . /etc/default/functions
9 # The following variables control which directories in /var end up on the rootfs
10 # and which end up in a temporary file system.
11 INRAM_MEMSTICK="/var/cache /var/lock /var/log /var/run /var/tmp /var/lib/ipkg"
12 INRAM_NFS="/var/cache /var/lock /var/run /var/tmp"
15 # force: override certain checks
19 # The type of the file system mounted on "new" Outputs the last
20 # piece of information found, which should be the one for the
21 # currently visible mount!
23 local cwd dev mp type options pass freq result
24 cwd="$(cd "$1"; /bin/pwd)"
26 while read dev mp type options pass freq
29 "$cwd") result="$type";;
36 # Collapses the mount (-o) options into a single list which is
37 # printed on stdout. Accepts an arbitrary list of options and
38 # just joins them together.
67 # get_flash <directory> {mount options}
68 # mount the flash device, writeable, on the given directory
74 test -n "$ffsdir" -a -d "$ffsdir" || {
75 echo "$0: $ffsdir: internal error, flash mount point not a directory" >&2
79 ffsdev="$(mtblockdev Flashdisk)"
80 umountflash "$ffsdev" &&
81 mountflash "$ffsdev" "$ffsdir" "$@"
84 # check_rootfs [-i] <root fs directory>
85 # Make sure the candidate rootfs is empty
95 fcount="$(find "$1" ! -type d -print | wc -l)"
96 test "$fcount" -eq 0 && return 0
98 echo "turnup: $1: partition contains existing files, specify -f to overwrite" >&2
100 *) checkmount "$1" && return 0
102 echo "turnup: $1: partition does not seem to be a valid root partition" >&2
103 if test -f "$1"/.recovery
105 echo " $1/.recovery exists: fix the partition then remove it" >&2
111 # copy_rootfs old new
112 # Make a copy of the given root file system, copying only the
113 # directories needed. The root must be the flash file system
118 test -d "$old" -a -d "$new" || {
119 echo "turnup: rootfs: copy $old $new: not a directory" >&2
123 # There are no problem file names in the flash file system, so
124 # it is possible to use -print, not -print0. The following
125 # files and directories are not copied:
131 echo "turnup: copying root file system" >&2
133 find . -mount -print |
134 sed '\@^./dev/@d;\@^./boot/@d;\@^./boot$@d;\@^./linuxrc@d;\@^./var/@d' |
135 cpio -p -d -m -u "$2"
137 echo "turnup: rootfs: cpio $old $new failed" >&2
144 # setup_dev new device_table
145 # In flash file systems /dev is in ramfs, in disk systems /dev
146 # can be populated permanently. This is done by creating a
147 # single entry '.noram' in /dev - the devices init script will
148 # then populate the directory without overmounting it. The
149 # devices in the passed in device table are also created, but
150 # note that this is insufficient, /etc/init.d/devices must
153 test -n "$1" -a -d "$1"/dev -a -r "$2" || {
154 echo "turnup: setup_dev($1,$2): expected a directory and a file" >&2
157 echo "turnup: initialising dev file system" >&2
158 # init tries to open the following devices:
162 # syslog, and maybe other things, only work if fd 1 is valid, therefore
163 # we must create these devices here...
164 makedevs --root="$1" --devtable="$2"
170 # setup_bootdev new device_table
171 # As above but actually uses the supplied device table - this is possible if
172 # the table is just used for boot because the extra setup is not required.
174 test -n "$1" -a -d "$1"/dev -a -r "$2" || {
175 echo "turnup: setup_bootdev($1,$2): expected a directory and a file" >&2
178 # NOTE: this fails silently with 0 return code(!) when a directory
179 # does not exist yet things are created within it.
180 makedevs -r "$1" -D "$2"
186 # Removes the /var tmpfs entry from /etc/fstab.
187 # Creates links from /var into /media/ram for NFS and Memstick.
190 test -n "$1" -a -d "$1"/var || {
191 echo "turnup: setup_var($1,$2): expected a directory" >&2
196 *) echo "turnup: setup_var($1,$2): expected 'disk', 'nfs' or 'memstick'" >&2
200 # populate /var, there is a shell script to do this, but it uses
201 # absolute path names
202 chroot "$1" /bin/busybox sh /etc/init.d/populate-volatile.sh || {
203 echo "turnup: /var: could not populate directory" >&2
208 disk) RAMTARGETS=${INRAM_DISK};;
209 nfs) RAMTARGETS=${INRAM_NFS};;
210 memstick) RAMTARGETS=${INRAM_MEMSTICK};;
213 for d in ${RAMTARGETS}; do
214 RAMDIR="/media/ram${d}"
216 rm -rf "${1}${REALDIR}"
217 ln -s "${RAMDIR}" "${1}${REALDIR}"
219 # the startup link is left for the moment, this seems safer
220 #rm "$1"/etc/rc?.d/[KS]??populate-var.sh
221 # remove the /var tmpfs entry from the new /etc/fstab
222 sed -i '\@[ ]/var[ ][ ]*tmpfs[ ]@d' "$1"/etc/fstab
223 echo "turnup: tmpfs will no longer be mounted on /var" >&2
225 # Previous versions of turnup removed populate-var.sh from the
226 # startup links, this one doesn't, so /var can be made back into
227 # a tmpfs just by a change to /etc/fstab.
233 # Moves the syslog to a file - appropriate for disk and nfs types, not
236 test -n "$1" -a -d "$1"/etc || {
237 echo "turnup: setup_syslog($1): expected a directory" >&2
241 # if the syslog is to the buffer redirect it to a file
242 if egrep -q '^DESTINATION="buffer"' "$1"/etc/syslog.conf
244 if cp "$1"/etc/syslog.conf "$1"/etc/syslog.conf.sav
246 # the busybox syslog will fail with ROTATESIZE and ROTATEGENS
247 sed -i 's!DESTINATION="buffer"!DESTINATION="file"!
249 /^ROTATEGENS=/d' "$1"/etc/syslog.conf
250 echo "turnup: /etc/syslog.conf: changed to file buffering" >&2
251 echo " Old (buffer) version in /etc/syslog.conf.sav" >&2
252 echo " Log messages will be in /var/log/messages" >&2
254 echo "turnup: /etc/syslog.conf: failed to make a copy" >&2
255 echo " syslog will log to a buffer" >&2
262 # setup_rootfs type new device_table
263 # Populates the /dev and /var directories, alters the startup to
264 # not mount or populate them further. Does the right thing according
272 test -n "$new" -a -d "$new" -a -f "$table" || {
273 echo "turnup: setup_rootfs($type,$new,$table): expected a directory and a file" >&2
279 disk) setup_dev "$new" "$table" &&
280 setup_var "$new" "$type" &&
281 setup_syslog "$new";;
283 setup_bootdev "$new" "$table" &&
284 setup_var "$new" "$type" ;;
285 nfs) setup_dev "$new" "$table" &&
286 setup_var "$new" "$type" &&
287 setup_syslog "$new";;
288 *) echo "turnup: setup_rootfs: $type: unknown rootfs type" >&2
291 # return code of last setup function
295 # setup_fstab new fsdev fstype fsoptions
296 # Alters the /etc/fstab entry for / to refer to the correct device and
297 # have the correct type and options. Essential for checkroot to remount
298 # / with the correct options.
299 # bad, since sed won't fail even if it changes nothing.
301 sed -i '\@^[^ ]*[ ][ ]*/[ ]@s@^.*$@'"$2 / $3 $4 1 1"'@' "$1"/etc/fstab
302 egrep -q "^$2 / $3 $4 1 1\$" "$1"/etc/fstab || {
303 echo "turnup: /etc/fstab: root(/) entry not changed" >&2
304 echo " you probably need to check the options in /etc/fstab" >&2
305 echo " to ensure that the root partition is mounted correctly" >&2
312 # boot_rootfs <boot type> <flash file system> <sleep time> <device> [options]
313 # Change the flash partition (not the current root!) to boot off
314 # the new root file system
316 local type ffs sleep device opt
323 # test this first as the test does not depend on the correctness
324 # of the other arguments
325 test -n "$ffs" -a -d "$ffs" || {
326 echo "turnup: boot_rootfs($type, $ffs, $device): expected directory" >&2
329 test -x "$ffs"/boot/"$type" || {
330 echo "turnup: boot_rootfs($type, $ffs, $device): invalid boot type $type" >&2
337 disk) test -n "$device" -a -b "$device" || {
338 echo "turnup: boot_rootfs($ffs, $type, $device): expected block device" >&2
345 *) echo "turnup: boot_rootfs($type, $ffs, $device): unknown type" >&2
350 # The /linuxrc records the correct options to mount the device,
351 # since we have already mounted if correctly with these options
352 # we can be sure (maybe) that the boot will work. If not /boot/disk
353 # falls back to flash.
355 # This modifies the boot process, until this point no harm has been
356 # done to the system, but at this point the boot rootfs will change
357 rm -f "$ffs"/linuxrc.new || {
358 echo "turnup: boot_rootfs: failed to remove $ffs/linuxrc.new" >&2
362 flash) ln -s "boot/flash" "$ffs"/linuxrc.new || {
363 echo "turnup: boot_rootfs: failed to create $ffs/linuxrc.new" >&2
366 ram) { echo '#!/bin/sh'
367 echo 'rm -f /linuxrc.new'
368 echo 'ln -s boot/flash /linuxrc.new'
369 echo 'mv /linuxrc.new /linuxrc'
370 echo 'exec /boot/ram /dev/ram0'
371 echo 'exec /boot/flash'
372 } >"$ffs"/linuxrc.new &&
373 chmod 744 "$ffs"/linuxrc.new || {
374 echo "turnup: boot_rootfs: failed to write $ffs/linuxrc.new" >&2
377 *) { echo '#!/bin/sh'
378 test "$sleep" -gt 0 && echo -n "sleep='$sleep' "
379 echo -n "exec '/boot/$type' '$device'"
385 echo 'exec /boot/flash'
386 } >"$ffs"/linuxrc.new &&
387 chmod 744 "$ffs"/linuxrc.new || {
388 echo "turnup: boot_rootfs: failed to write $ffs/linuxrc.new" >&2
392 rm -f "$ffs"/linuxrc.sav || {
393 echo "turnup: boot_rootfs: failed to remove $ffs/linuxrc.sav" >&2
396 ln "$ffs"/linuxrc "$ffs"/linuxrc.sav || {
397 echo "turnup: boot_rootfs: failed to save /linuxrc.sav" >&2
400 mv -f "$ffs"/linuxrc.new "$ffs"/linuxrc || {
401 echo "turnup: boot_rootfs: failed to install new /linuxrc" >&2
408 # disk [-m] [-i] [-s<time>] <device> {options}
409 # Carefully copy the flash file system to the named device.
411 local setup_type sleep init device new ffs fst fso
421 -m) setup_type=memstick
433 test -n "$device" -a -b "$device" || {
434 echo "turnup disk: $device: block device required" >&2
439 # make temporary directories for the mount points
441 ffs="/tmp/flashdisk.$$"
442 mkdir "$new" "$ffs" || {
443 echo "turnup: disk: failed to create temporary directories" >&2
447 # make sure we can get to the flash file system first
448 get_flash "$ffs" || {
453 # Now mount the device with the given options, note that specifying
454 # read only is *not* an option, this is important because the boot/disk
455 # script needs a rw file system
458 fso="$(fsoptions "$@")"
459 if mount "$@" "$device" "$new"
461 fst="$(fstype "$new")"
463 echo "turnup disk: $device($new): umount does not seem to work" >&2
466 if test -n "$fst" && mount -t "$fst" -o "$fso" "$device" "$new"
468 if check_rootfs $init "$new" && {
470 copy_rootfs "$ffs" "$new" &&
471 setup_rootfs "$setup_type" "$new" "$ffs"/etc/device_table
475 setup_fstab "$new" "$device" "$fst" "$fso"
479 # clean up the disk. It is worrying if this umount fails!
480 umount "$new" || test "$force" = "-f" || {
481 echo "turnup disk: $device: umount failed" >&2
482 echo " you must unmount this device cleanly yourself, then use" >&2
485 echo " turnup with the -f option to boot from the device" >&2
487 echo " turnup without the -i option to boot from the device" >&2
492 # if everything went ok boot from this disk
493 if test $status -eq 0
495 # memsticks boot like disks, so ignore the -m
496 boot_rootfs disk "$ffs" "$sleep" "$device" -t "$fst" -o "$fso"
499 echo "turnup disk: $device($*): unable to mount device on $new" >&2
500 # If it worked first time
503 echo " options used: -t $fst -o $fso [error in this script]" >&2
507 # clean up the flash file system
515 # Resets the boot type to flash or ram, as appropriate
522 *) echo "turnup: boot_reset($1): invalid type" >&2
526 ffs="/tmp/flashdisk.$$"
528 echo "turnup: $1: failed to create temporary directory" >&2
532 get_flash "$ffs" || {
537 # now try to set the /linuxrc appropriately
538 boot_rootfs "$type" "$ffs"
548 # nfs [-i] <root partition> {options}
549 # Copy the flash file system to the given NFS root partition.
551 local init nfsroot new ffs
566 test -n "$nfsroot" || {
567 echo "turnup nfs: $nfsroot: NFS root file system required" >&2
572 # make temporary directories for the mount points
574 ffs="/tmp/flashdisk.$$"
575 mkdir "$new" "$ffs" || {
576 echo "turnup nfs: failed to create temporary directories" >&2
580 # make sure we can get to the flash file system first
581 get_flash "$ffs" || {
586 # Now mount the device with the given options, note that specifying
587 # read only is *not* an option, this is important because the boot/disk
588 # script needs a rw file system
591 # These settings for for NFS, something better will probably have to
592 # be done to support other network file systems.
593 nfsopt="nolock,noatime,hard,intr,rsize=1024,wsize=1024"
594 fso="$(fsoptions -o "$nfsopt" "$@")"
595 if mount -o "$nfsopt" "$@" "$nfsroot" "$new"
597 fst="$(fstype "$new")"
599 echo "turnup nfs: $nfsroot($new): umount does not seem to work" >&2
602 if test -n "$fst" && mount -t "$fst" -o "$fso" "$nfsroot" "$new"
604 if :>"$new"/ttt && test -O "$new"/ttt && rm "$new"/ttt
606 if check_rootfs $init "$new" && {
608 copy_rootfs "$ffs" "$new" &&
609 setup_rootfs nfs "$new" "$ffs"/etc/device_table
613 setup_fstab "$new" "$nfsroot" "$fst" "$fso"
617 echo "turnup nfs: $nfsroot: partition must be exported no_root_squash" >&2
620 # clean up the disk. It is worrying if this umount fails!
621 umount "$new" || test "$force" = "-f" || {
622 echo "turnup nfs: $nfsroot: umount failed" >&2
623 if test $status -eq 0
625 echo " you must unmount this partition cleanly yourself, then use" >&2
628 echo " turnup with the -f option to boot from the NFS root" >&2
630 echo " turnup without the -i option to boot from the NFS root" >&2
636 # if everything went ok boot from this disk
637 if test $status -eq 0
639 # the options used are exactly those which worked before.
640 boot_rootfs nfs "$ffs" 0 "$nfsroot" -t nfs -o "$fso"
643 echo "turnup nfs: $nfsroot($*): unable to mount device on $new" >&2
644 # If it worked first time
647 echo " options obtained: -t $fst -o $fso" >&2
651 # clean up the flash file system
659 # Called when the configuration is invalid to reset /etc/default/sysconf
661 # first look on the flash disk (ideally this stuff would only
662 # be called from flash, but there is no way of guaranteeing that).
663 local ffsdev ffs mac name force
669 ffsdev="$(mtblockdev Flashdisk)"
670 test -n "$ffsdev" -a -b "$ffsdev" || {
671 echo "turnup init: the flash file system device is missing" >&2
672 echo " The device (typically /dev/mtdblock4) must exist and" >&2
673 echo " it must identify a flash partition called 'Flashdisk'" >&2
674 echo " It may be that the /dev directory has not been initialised." >&2
675 echo " This script cannot correct this problem." >&2
679 test -x /etc/init.d/sysconfsetup || {
680 echo "turnup init: /etc/init.d/sysconfsetup: script not executable" >&2
681 echo " or script not present. turnup init requires this script to" >&2
682 echo " exist to correct the initialisation" >&2
686 # use devio to find out if this *is* the flash disk.
688 if test "$(devio "<<$ffsdev" prd)" -ne "$(devio '<</etc/init.d/sysconfsetup' prd)"
690 # this isn't the flash device
691 ffs="/tmp/flashdisk.$$"
692 # make sure we can get to the flash file system first
693 get_flash "$ffs" || {
699 if test -r "$ffs/etc/default/sysconf"
701 cp "$ffs/etc/default/sysconf"
709 # if the config is still not valid generate sysconf from the slug
711 config valid && test -z "$force" || {
715 echo "turnup init: please find the 'MAC Address' of your NSLU2" >&2
716 echo " The required number is on a label on the bottom of the NSLU2" >&2
717 echo " It will be something like 'LKG1A2B3C'" >&2
718 echo -n "Enter the mac address: " >/dev/tty
721 [Ll][Kk][Gg][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])
722 mac="$(echo "$name" |
723 sed -n 's/^...\(..\)\(..\)\(..\)$/00:0F:66:\1:\2:\3/p')";;
724 [0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f]:[0-9A-Fa-f][0-9A-Fa-f])
729 *) echo "$name: not recognised as a LinkSys mac address" >&2
730 echo " Enter the LinkSys value or a full Ethernet MAC addrress" >&2
734 # Now generate the correct sysconf
737 test -n "$name" && echo "default_server_name=$name"
738 } >/etc/default/sysconf
742 # the configuration should be valid now
743 /etc/init.d/sysconfsetup reload
747 # read_one 'prompt' 'group' 'name'
748 # read a single value
751 o="$(sysval "$2" "$3")"
752 echo -n "$1 [$o]: " >/dev/tty
754 test -z "$n" && n="$o"
759 # Change the network initialisation
761 # fix the root password
762 echo "Please enter a new password for 'root'." >/dev/tty
763 echo "The password must be non-empty for ssh login to succeed!" >/dev/tty
765 # now the network configuration
766 read_one "Host name" network disk_server_name
767 read_one "Domain name" network w_d_name
768 read_one "Boot protocol (dhcp|static)" network bootproto
770 static) read_one "IP address" network ip_addr
771 read_one "IP netmask" network netmask
772 read_one "IP gateway" network gateway
773 read_one "First DNS server" network dns_server1
774 read_one "Second DNS server" network dns_server2
775 read_one "Third DNS server" network dns_server3
776 echo "$ip_addr $disk_server_name" >> /etc/hosts
778 dhcp) sed -i -e "s/localhost\$/localhost $disk_server_name/" /etc/hosts
783 # The other stuff which cannot be changed
784 hw_addr="$(config mac)"
785 lan_interface="$(config iface)"
787 # Write this out to a new sysconf
789 echo "hw_addr=$hw_addr"
790 echo "lan_interface=$lan_interface"
791 test -n "$disk_server_name" && echo "disk_server_name=$disk_server_name"
792 test -n "$w_d_name" && echo "w_d_name=$w_d_name"
793 echo "bootproto=$bootproto"
795 static) echo "ip_addr=$ip_addr"
796 test -n "$netmask" && echo "netmask=$netmask"
797 test -n "$gateway" && echo "gateway=$gateway"
798 test -n "$dns_server1" && echo "dns_server1=$dns_server1"
799 test -n "$dns_server2" && echo "dns_server2=$dns_server2"
800 test -n "$dns_server3" && echo "dns_server3=$dns_server3"
803 } >/etc/default/sysconf
805 # And reload the result
806 /etc/init.d/sysconfsetup reload
808 # The remove the spurious 'init' motd
813 # Basic command switch (this should be the only thing in this
814 # script which actually does anything!)
817 if config valid && test "$1" != -f
821 echo "turnup init: you must reboot the NSLU2 for the changes to take effect" >&2
828 echo "turnup init: you must reboot the NSLU2 for the changes to take effect" >&2
837 disk -m "$@" -o noatime;;
840 flash) boot_reset flash;;
841 ram) boot_reset ram;;
843 usage: turnup command [options]
848 correct errors in network information
849 initialise network information when DHCP is not available
850 change network information
851 disk [-i] [-s<seconds>] <device> [mount options]
852 With -i make <device> a bootable file system then (with or
853 without -i) arrange for the next reboot to use that device.
854 The device must already be formatted as a file system, with
855 -i it must be completely empty, without it must contain an
856 apparently bootable file system. -s (for example -s5)
857 specifies a delay in seconds to wait at boot time before
859 memstick [-i] <device> [mount options]
860 Behaves as disk however options appropriate to a flash memory
861 stick are automatically added
862 nfs [-i] <nfs mount path> [mount options]
863 <nfs mount path> must be a mountable NFS file system. With
864 -i the partition must be empty and is initialised with a
865 bootable file system. Without -i the partition must already
866 contain a bootable file system. In either case the NFS
867 partition must be available to be mounted without root id
868 sqashing (i.e. root must be root) and it will be selected
869 as the root file system for subsequent reboots.
870 A default set of -o options are provided, additional options
871 may be given on the command line (multiple -o options will
872 be combined into a single -o).
874 Revert to booting from the flash disk on next reboot.
876 Boot (once) into a ramdisk, subsequent boots will be to
877 the flash file system.
879 The argument to 'nfs' or 'disk' must be an empty partition
880 of sufficient size to hold the root file system (at least
881 16MByte but more is recommended to allow package installation).
882 An appropriate ext3 partition can be made using the command:
884 mke2fs -j <device> # for example: /dev/sda1
886 An appropriate NFS partition can be emptied using 'rm', but
887 must be set up (exported) on the NFS server." >&2
890 # Exit with return code from command.