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
|
#!/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
# 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
cp /etc/passwd /usr/local/passwd
# cp /etc/passwd $targconf/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 ..."
/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
# 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
# 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"
echo "in order to boot this system up into unslung mode."
exit 0
|