summaryrefslogtreecommitdiff
path: root/recipes/nslu2-binary-only/unslung-rootfs/unsling
blob: 539a1d2b5881aabfbf006f7819af86826e88f834 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
#!/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

echo "./var/tmp" > /tmp/xfile
echo "./dev.state" >> /tmp/xfile
echo "./var.state" >> /tmp/xfile
echo "./lost+found" >>/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