#!/bin/sh usage="Usage: $0 [-nopw] disk1|disk2" nopw=0 if [ $# -gt 1 ] ; then if [ "$1" = "-nopw" ] ; then nopw=1 shift fi fi # Set target disk if [ $# -eq 1 ] ; then if [ "$1" = "disk1" ] ; then mtch="/dev/sdb1 /share/hdd/data ext3 rw 0 0" targ=/share/hdd/data targconf=/share/hdd/conf flag=.sdb1root htmlinfo="disk1, /dev/sdb1" fixconf=0 elif [ "$1" = "disk2" ] ; then mtch="/dev/sda1 /share/flash/data ext3 rw 0 0" targ=/share/flash/data targconf=/share/flash/conf flag=.sda1root htmlinfo="disk2, /dev/sda1" fixconf=1 else echo $usage exit 1 fi else echo $usage exit 1 fi # MJW - The new "tar" method of unslinging does not care if the device # has already been unslung. The following test has been removed. # # Check that we can unsling at all! An unsling operation creates a new # rootfs, but it also marks the flash rootfs (with a flag file such as # ".sda1root") so that subsequent boots do not create the "var.state" # and "dev.state" mounts. Without those mounts, though, an attempt to # unsling will write a new rootfs on the target with an empty /dev # directory, which doesnt' work really well. So this check is all about # making sure that we are in a state in which we are capable of # performing the unsling operation. #echo "Checking if able to unsling..." #echo #m1="/dev/root /dev.state jffs2 rw 0 0" #m2="/dev/root /var.state jffs2 rw 0 0" #if ! grep "$m1" /proc/mounts >/dev/null 2>&1 || ! grep "$m2" /proc/mounts >/dev/null 2>&1 ; then # echo "Error: This system is unable to properly unsling because certain" # echo "required mounts (dev.state and/or var.state) are not available." # echo "This is most probably because you have already unslung this system." # echo # # if [ -f /.sda1root ] ; then # rm -f /.sda1root # elif [ -f /.sdb1root ] ; then # rm -f /.sdb1root # elif [ -f /.sda2root ] ; then # rm -f /.sda2root # elif [ -f /.sdb2root ] ; then # rm -f /.sdb2root # else # echo "However, in this case, the flags that indicate an already-unslung" # echo "system seem to be missing. Try restarting your NSLU2 to correct," # echo "but if the problem persists, try re-flashing your NSLU2." # exit 1 # fi # echo "The flags that indicate an already-unslung system have now been" # echo "removed and the required mounts should now become present after" # echo "reboot of the NSLU2." # echo # echo "1) Please unplug all drives from the NSLU2," # echo "2) reboot," # echo "3) and retry the unslinging process." # exit 1 #fi # Check it's a real mount point echo "Waiting for $targ ..." CNT=120 while [ $CNT -gt 0 ] do if grep "$mtch" /proc/mounts >/dev/null 2>&1 ; then echo echo "Target disk is $targ" CNT=-1 else echo -ne "\r$CNT " sleep 1 CNT=`expr $CNT - 1` fi done if [ $CNT -eq 0 ] ; then echo echo "Error: $targ ($htmlinfo) is not a mounted disk" exit 1 fi # Do a quick sanity check to make sure we're unslinging to a disk that's been # formatted by the Linksys code. echo "Checking that $targ has been properly formatted..." if ! [ -d $targ/public ] || ! [ -f $targconf/.dongle ] || ! [ -f $targconf/passwd ] ; then echo echo "Error: $targ does not appear to have been formatted by the" echo "Linksys formatting utility. Please go to the web interface," echo "and format the drive before unslinging." exit 1 fi echo "Checking that $targ is clean..." if [ -f $targ/.unslung ] ; then echo echo "Error: $targ appears to have already been unslung to:" cat $targ/.unslung echo "Please go to the web interface, and format the drive before" echo "unslinging." echo echo "(Or, if you wish to unsling without removing the current root" echo "filesystem, simply remove the file $targ/.unslung and retry" echo "the unsling -- but beware, you enter uncharted territory!)" exit 1 fi # Change the root password if [ "$nopw" -eq 0 ] ; then echo echo "Please enter the new root password. This will be the new root" echo "password used when the NSLU2 boots up with or without disks" echo passwd if [ $? -ne 0 ] ; then echo "Error setting password." exit 1 fi # Quick sanity check, something may have gone wrong while we were # waiting at the passwd prompt... if ! [ -d $targ/public ] || ! [ -f $targconf/.dongle ] || ! [ -f $targconf/passwd ] ; then echo echo "Error: $targ appears to have vanished into thin air." echo "This would indicate some type of problem with the USB cable," echo "the device, or the formatting of the device." exit 1 fi cp /etc/passwd /usr/local/passwd grep "^root:" /etc/passwd >$targconf/passwd.new grep -v "^root:" $targconf/passwd >>$targconf/passwd.new mv $targconf/passwd $targconf/passwd.save mv $targconf/passwd.new $targconf/passwd chmod 644 $targconf/passwd fi # Start at the root directory cd / # Save the existing ipkg database. rm -rf $targ/usr/lib/ipkg.old if [ -f $targ/usr/lib/ipkg/status ] ; then mv $targ/usr/lib/ipkg $targ/usr/lib/ipkg.old fi # Copy the complete rootfs to the target. echo echo "Copying the complete rootfs from / to $targ ... " echo " (this will take just a couple of minutes)" # Quick sanity check to avoid filling the flash... if ! [ -d $targ/public ] || ! [ -f $targconf/.dongle ] || ! [ -f $targconf/passwd ] ; then echo echo "Error: $targ appears to have vanished into thin air." echo "This would indicate some type of problem with the USB cable," echo "the device, or the formatting of the device." exit 1 fi # /usr/bin/find / -xdev -print | /usr/bin/cpio -p -d -m -u $targ # rm -rf $targ/dev ; mv $targ/dev.state $targ/dev # rm -rf $targ/var ; mv $targ/var.state $targ/var echo "./var/tmp" > /tmp/xfile echo "./dev.state" >> /tmp/xfile echo "./var.state" >> /tmp/xfile mkdir -p /tmp/tmprootfs /bin/mount /dev/mtdblock4 /tmp/tmprootfs /bin/tar -c -C /tmp/tmprootfs -X /tmp/xfile -f - . | (cd $targ; /bin/tar -x -f -) /bin/umount /tmp/tmprootfs echo "Copy complete ..." echo # Copy over the existing ipkg database. if [ -f $targ/usr/lib/ipkg.old/status ] ; then echo "Preserving existing ipkg database on target disk." ( cd $targ/usr/lib/ipkg.old ; tar cf - . ) | ( cd $targ/usr/lib/ipkg ; tar xf - ) fi echo "Linking /usr/bin/ipkg executable on target disk." rm -f $targ/usr/bin/ipkg ; ln -s /usr/bin/ipkg-cl $targ/usr/bin/ipkg echo "Linking /etc/motd to the unslung motd on target disk." rm -f $targ/etc/motd ; ln -s /etc/motd-un $targ/etc/motd echo "Updating /home/httpd/html/home.htm with target disk info." sedcommand="s#Running.from.Internal.Flash#Unslung to $htmlinfo#" rm -f $targ/home/httpd/html/home.htm_bak cp $targ/home/httpd/html/home.htm $targ/home/httpd/html/home.htm_bak sed "$sedcommand" $targ/home/httpd/html/home.htm_bak > $targ/home/httpd/html/home.htm chmod 644 $targ/home/httpd/html/home.htm # Create a few empty files that are expected to be present touch $targ/var/log/wtmp chmod 644 $targ/var/log/wtmp touch $targ/var/run/utmp chmod 644 $targ/var/run/utmp mkdir -p $targ/var/tmp chmod 777 $targ/var/tmp # The "user password" Linksys utility is hard-coded to /share/hdd; also the # QuickSet utility seems to have some difficulty as well. Ugly fix is to # add symlinks if we are unslinging to /share/flash. It might seem more # reasonable to point to /etc/passwd, for example, but this approach seems to # be more likely to avoid looping symlinks. if [ "$fixconf" -eq 1 ] ; then ln -s ../../flash/conf/.htpasswd $targ/share/hdd/conf/.htpasswd ln -s ../../flash/conf/backup_sh.conf $targ/share/hdd/conf/backup_sh.conf ln -s ../../flash/conf/config $targ/share/hdd/conf/config ln -s ../../flash/conf/group $targ/share/hdd/conf/group ln -s ../../flash/conf/passwd $targ/share/hdd/conf/passwd ln -s ../../flash/conf/server.log $targ/share/hdd/conf/server.log ln -s ../../flash/conf/share $targ/share/hdd/conf/share ln -s ../../flash/conf/share.info $targ/share/hdd/conf/share.info ln -s ../../flash/conf/smb.conf $targ/share/hdd/conf/smb.conf ln -s ../../flash/conf/smbpasswd $targ/share/hdd/conf/smbpasswd ln -s ../../flash/conf/tmp $targ/share/hdd/conf/tmp ln -s ../../flash/conf/upgrade $targ/share/hdd/conf/upgrade ln -s ../../flash/conf/usrgrp.info $targ/share/hdd/conf/usrgrp.info fi # Create the boot flag file. rm -f /.sd??root $targ/.sd??root echo "Creating /$flag to direct switchbox to boot from $targ." echo > /$flag echo > $targ/$flag # Done echo echo "Unsling complete." echo echo "Leave the device $htmlinfo, plugged in and reboot (using" echo "either the Web GUI, or the command \"DO_Reboot\") in order to boot" echo "this system up into unslung mode." exit 0