Subversion Repositories livecd

Rev

Rev 177 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 177 Rev 185
1
#!/bin/ash
1
#!/bin/ash
2
#
2
#
3
# Functions library :: for Linux Live scripts 5.x.y
3
# Functions library :: for Linux Live scripts 5.x.y
4
# Author: Tomas M. <http://www.linux-live.org>
4
# Author: Tomas M. <http://www.linux-live.org>
5
#
5
#
6
# modified by Urs Beyerle
6
# modified by Urs Beyerle
7
# - to allow LiveCD mounted over nfs
7
# - to allow LiveCD mounted over nfs
8
# - add scsi_mod, sd_mod for usb-storage module
8
# - add scsi_mod, sd_mod for usb-storage module
9
# - only with boot option "automount", all devices in fstab are rw automounted
9
# - only with boot option "automount", all devices in fstab are rw automounted
10
# - remove detect of CD and Floppy (done by fstab-sync)
10
# - remove detect of CD and Floppy (done by fstab-sync)
11
# - add sr_mod (USB CDROM support)
11
# - add sr_mod (USB CDROM support)
12
# - add SATA to modprobe_usb_modules -> modprobe_usb_sata_modules
12
# - add SATA to modprobe_usb_modules -> modprobe_usb_sata_modules
13
# - add fscache (for SL5) 
13
# - add fscache (for SL5) 
14
# - add ide-cd, sr_mod, cdrom (for SL5 cdrom support)
14
# - add ide-cd, sr_mod, cdrom (for SL5 cdrom support)
15
# - add aufs (unionfs replacement)
15
# - add aufs (unionfs replacement)
16
# - to allow LiveCD mounted over NFS (for diskless client)
16
# - to allow LiveCD mounted over NFS (for diskless client)
17
# - add functions get_dhcp_lease() and load_network_modules()
17
# - add functions get_dhcp_lease() and load_network_modules()
18
# - add ata_piix to modprobe_usb_sata_modules
18
# - add ata_piix to modprobe_usb_sata_modules
19
# - works with unionfs 2.x
19
# - works with unionfs 2.x
20
# - better detection of network card in case of diskless client
20
# - better detection of network card in case of diskless client
21
# - add sg, sata_nv module
21
# - add sg, sata_nv module
22
# - to allow LiveCD mounted over CIFS (for diskless client)
22
# - to allow LiveCD mounted over CIFS (for diskless client)
23
# - add function find_changes
23
# - add function find_changes
24
#
24
#
25
 
25
 
26
# ===========================================================
26
# ===========================================================
27
# user interface functions
27
# user interface functions
28
# ===========================================================
28
# ===========================================================
29
 
29
 
30
# echolog
30
# echolog
31
# $1 = text to show and to write to /var/log/messages
31
# $1 = text to show and to write to /var/log/messages
32
#
32
#
33
echolog()
33
echolog()
34
{
34
{
35
   echo "LIVECD:" "$@" >>/var/log/livedbg
35
   echo "LIVECD:" "$@" >>/var/log/livedbg
36
   echo "$@"
36
   echo "$@"
37
}
37
}
38
 
38
 
39
# debug
39
# debug
40
# commands executed when debug boot parameter is present
40
# commands executed when debug boot parameter is present
41
#
41
#
42
debug()
42
debug()
43
{
43
{
44
   echo
44
   echo
45
   echo "====="
45
   echo "====="
46
   echo ": Debugging started. Here is the root shell for you."
46
   echo ": Debugging started. Here is the root shell for you."
47
   echo ": Type your desired command or hit Ctrl+D to continue booting."
47
   echo ": Type your desired command or hit Ctrl+D to continue booting."
48
   echo
48
   echo
49
   ash
49
   ash
50
}
50
}
51
 
51
 
52
# header
52
# header
53
# $1 = text to show
53
# $1 = text to show
54
#
54
#
55
header()
55
header()
56
{
56
{
57
   echolog "$1"
57
   echolog "$1"
58
}
58
}
59
 
59
 
60
fatal()
60
fatal()
61
{
61
{
62
   header "Fatal error occured - $1"
62
   header "Fatal error occured - $1"
63
   echolog "Something went wrong and we can't continue booting :("
63
   echolog "Something went wrong and we can't continue booting :("
64
   echolog "You may explore the system by using simple commands like ls, lsmod, mount, etc."
64
   echolog "You may explore the system by using simple commands like ls, lsmod, mount, etc."
65
   echolog "You may also try to hit Ctrl+D. Booting will continue. Use at your own risk."
65
   echolog "You may also try to hit Ctrl+D. Booting will continue. Use at your own risk."
66
   echolog "To be safe, hit Ctrl+Alt+Delete to reboot."
66
   echolog "To be safe, hit Ctrl+Alt+Delete to reboot."
67
   echolog
67
   echolog
68
   ash
68
   ash
69
}
69
}
70
 
70
 
71
# ===========================================================
71
# ===========================================================
72
# text processing functions
72
# text processing functions
73
# ===========================================================
73
# ===========================================================
74
 
74
 
75
# egrep_o is a replacement for "egrep -o". It prints only the last
75
# egrep_o is a replacement for "egrep -o". It prints only the last
76
# matching text
76
# matching text
77
# $1 = regular expression
77
# $1 = regular expression
78
#
78
#
79
egrep_o()
79
egrep_o()
80
{
80
{
81
   cat | egrep "$1" | sed -r "s/.*($1).*/\\1/"
81
   cat | egrep "$1" | sed -r "s/.*($1).*/\\1/"
82
}
82
}
83
 
83
 
84
# look into cmdline and echo $1 back if $1 is set
84
# look into cmdline and echo $1 back if $1 is set
85
# $1 = value name, case sensitive, for example livecd_subdir
85
# $1 = value name, case sensitive, for example livecd_subdir
86
# $2 = file to use instead /proc/cmdline, optional
86
# $2 = file to use instead /proc/cmdline, optional
87
#
87
#
88
cmdline_parameter()
88
cmdline_parameter()
89
{
89
{
90
   CMDLINE=/proc/cmdline
90
   CMDLINE=/proc/cmdline
91
   if [ "$2" != "" ]; then CMDLINE="$2"; fi
91
   if [ "$2" != "" ]; then CMDLINE="$2"; fi
92
   cat "$CMDLINE" | egrep_o "(^|[[:space:]]+)$1(\$|=|[[:space:]]+)" | egrep_o "$1"
92
   cat "$CMDLINE" | egrep_o "(^|[[:space:]]+)$1(\$|=|[[:space:]]+)" | egrep_o "$1"
93
}
93
}
94
 
94
 
95
# look into cmdline and echo value of $1 option
95
# look into cmdline and echo value of $1 option
96
# $1 = value name, case sensitive, for example livecd_subdir
96
# $1 = value name, case sensitive, for example livecd_subdir
97
# $2 = file to use instead /proc/cmdline, optional
97
# $2 = file to use instead /proc/cmdline, optional
98
#
98
#
99
cmdline_value()
99
cmdline_value()
100
{
100
{
101
   CMDLINE=/proc/cmdline
101
   CMDLINE=/proc/cmdline
102
   if [ "$2" != "" ]; then CMDLINE="$2"; fi
102
   if [ "$2" != "" ]; then CMDLINE="$2"; fi
103
   cat "$CMDLINE" | egrep_o "(^|[[:space:]]+)$1=([^[:space:]]+)" | egrep_o "=.*" | cut -b 2- | tail -n 1
103
   cat "$CMDLINE" | egrep_o "(^|[[:space:]]+)$1=([^[:space:]]+)" | egrep_o "=.*" | cut -b 2- | tail -n 1
104
}
104
}
105
 
105
 
106
# ===========================================================
106
# ===========================================================
107
# system functions
107
# system functions
108
# ===========================================================
108
# ===========================================================
109
 
109
 
110
# modprobe module $1, including all dependencies, suppress all messages
110
# modprobe module $1, including all dependencies, suppress all messages
111
# (own function because modprobe in busybox doesn't work with gzipped modules)
111
# (own function because modprobe in busybox doesn't work with gzipped modules)
112
# $1 = module name, eg. ehci-hcd
112
# $1 = module name, eg. ehci-hcd
113
# $2 = optional argument
113
# $2 = optional argument
114
#
114
#
115
modprobe_module()
115
modprobe_module()
116
{
116
{
117
  if [ "$1" = "" ]; then return 1; fi
117
  if [ "$1" = "" ]; then return 1; fi
118
  PRINTK=`cat /proc/sys/kernel/printk`
118
  PRINTK=`cat /proc/sys/kernel/printk`
119
  echo "0" >/proc/sys/kernel/printk
119
  echo "0" >/proc/sys/kernel/printk
120
 
120
 
121
  KERNEL="`uname -r`"; LSMOD=/tmp/lsmod
121
  KERNEL="`uname -r`"; LSMOD=/tmp/lsmod
122
  MODULEDEPS="`cat /lib/modules/$KERNEL/modules.dep | egrep \"$1\\.ko(\\.gz)?:\"`"
122
  MODULEDEPS="`cat /lib/modules/$KERNEL/modules.dep | egrep \"$1\\.ko(\\.gz)?:\"`"
123
 
123
 
124
  for MODULE in `echo $MODULEDEPS | cut -d ":" -f 2-` `echo $MODULEDEPS | cut -d ":" -f 1`; do
124
  for MODULE in `echo $MODULEDEPS | cut -d ":" -f 2-` `echo $MODULEDEPS | cut -d ":" -f 1`; do
125
     MODULE=${MODULE%%:};   # remove : at the end, a bug 
125
     MODULE=${MODULE%%:};   # remove : at the end, a bug 
126
     TMPMOD="/tmp/`basename $MODULE .gz`";
126
     TMPMOD="/tmp/`basename $MODULE .gz`";
127
     # if the module is not loaded already
127
     # if the module is not loaded already
128
     if [ "`cat $LSMOD 2>/dev/null | egrep \"^$TMPMOD\\\$\"`" = "" ]; then
128
     if [ "`cat $LSMOD 2>/dev/null | egrep \"^$TMPMOD\\\$\"`" = "" ]; then
129
        gunzip -c $MODULE 2>/dev/null >$TMPMOD
129
        gunzip -c $MODULE 2>/dev/null >$TMPMOD
130
        if [ $? -ne 0 ]; then cp $MODULE $TMPMOD; fi # can't gunzip? copy
130
        if [ $? -ne 0 ]; then cp $MODULE $TMPMOD; fi # can't gunzip? copy
131
        insmod $TMPMOD $2; err=$?
131
        insmod $TMPMOD $2; err=$?
132
        ### insmod $TMPMOD $2 >/dev/null 2>/dev/null; err=$?
132
        ### insmod $TMPMOD $2 >/dev/null 2>/dev/null; err=$?
133
        if [ "$err" -eq 0 ]; then echo $TMPMOD >>$LSMOD; fi # module log
133
        if [ "$err" -eq 0 ]; then echo $TMPMOD >>$LSMOD; fi # module log
134
        rm $TMPMOD
134
        rm $TMPMOD
135
     fi
135
     fi
136
  done
136
  done
137
 
137
 
138
  echo "$PRINTK" >/proc/sys/kernel/printk
138
  echo "$PRINTK" >/proc/sys/kernel/printk
139
  if [ "$err" -ne 0 ]; then echolog "error inserting module $1 ($err)"; fi
139
  if [ "$err" -ne 0 ]; then echolog "error inserting module $1 ($err)"; fi
140
  return $err
140
  return $err
141
}
141
}
142
 
142
 
143
# Mount device $1 to $2
143
# Mount device $1 to $2
144
# $1 = /dev device to mount, eg. /dev/hda1
144
# $1 = /dev device to mount, eg. /dev/hda1
145
# $2 = mountpoint, eg. /mnt/hda1
145
# $2 = mountpoint, eg. /mnt/hda1
146
# $3 = mount options, for example "loop", "ro", or "remount,rw"
146
# $3 = mount options, for example "loop", "ro", or "remount,rw"
147
#
147
#
148
mount_device()
148
mount_device()
149
{
149
{
150
  mkdir -p $2
150
  mkdir -p $2
151
  if [ "$3" != "" ]; then OPTIONS="-o $3"; else OPTIONS=""; fi
151
  if [ "$3" != "" ]; then OPTIONS="-o $3"; else OPTIONS=""; fi
152
 
152
 
153
  PRINTK=`cat /proc/sys/kernel/printk`
153
  PRINTK=`cat /proc/sys/kernel/printk`
154
  echo "0" >/proc/sys/kernel/printk
154
  echo "0" >/proc/sys/kernel/printk
155
 
155
 
156
  mount -t auto $1 $2 $OPTIONS >/dev/null 2>/dev/null
156
  mount -t auto $1 $2 $OPTIONS >/dev/null 2>/dev/null
157
  err=$?
157
  err=$?
158
 
158
 
159
  if [ "$err" -ne 0 ]; then rmdir $2 2>/dev/null; fi
159
  if [ "$err" -ne 0 ]; then rmdir $2 2>/dev/null; fi
160
  echo "$PRINTK" >/proc/sys/kernel/printk
160
  echo "$PRINTK" >/proc/sys/kernel/printk
161
  return $err
161
  return $err
162
}
162
}
163
 
163
 
164
# ===========================================================
164
# ===========================================================
165
# live module functions
165
# live module functions
166
# ===========================================================
166
# ===========================================================
167
 
167
 
168
# Create module
168
# Create module
169
# call mksquashfs with apropriate arguments
169
# call mksquashfs with apropriate arguments
170
# $1 = directory which will be compressed to squashfs module
170
# $1 = directory which will be compressed to squashfs module
171
# $2 = output .mo file
171
# $2 = output .mo file
172
# $3 = optional -keep-as-directory argument
172
# $3 = optional -keep-as-directory argument
173
#
173
#
174
create_module()
174
create_module()
175
{
175
{
176
   mksquashfs $1 $2 $3 >/dev/null
176
   mksquashfs $1 $2 $3 >/dev/null
177
   if [ $? -ne 0 ]; then return 1; fi
177
   if [ $? -ne 0 ]; then return 1; fi
178
   chmod oga-x $2 # remove execute attrib
178
   chmod oga-x $2 # remove execute attrib
179
}
179
}
180
 
180
 
181
# Mount .mo module to destination directory
181
# Mount .mo module to destination directory
182
# $1 = path to .mo livecd compressed module
182
# $1 = path to .mo livecd compressed module
183
# $2 = destination folder
183
# $2 = destination folder
184
#
184
#
185
mount_module()
185
mount_module()
186
{
186
{
187
   mount -t squashfs -o loop,ro $1 $2
187
   mount -t squashfs -o loop,ro $1 $2
188
}
188
}
189
 
189
 
190
# Insert a directory tree $2 to an union specified by $1
190
# Insert a directory tree $2 to an union specified by $1
191
# Top-level read-write branch is specified by it's index 0
191
# Top-level read-write branch is specified by it's index 0
192
# $1 = union absolute path (starting with /)
192
# $1 = union absolute path (starting with /)
193
# $2 = path to data directory
193
# $2 = path to data directory
194
#
194
#
195
union_insert_dir()
195
union_insert_dir()
196
{
196
{
197
   which unionctl >/dev/null 2>&1
197
   which unionctl >/dev/null 2>&1
198
   if [ $? -eq 0 ]; then
198
   if [ $? -eq 0 ]; then
199
       # unionfs 1.x or aufs
199
       # unionfs 1.x or aufs
200
       unionctl "$1" --add --after 0 --mode ro "$2"
200
       unionctl "$1" --add --after 0 --mode ro "$2"
201
   else
201
   else
202
       # unionfs 2.x
202
       # unionfs 2.x
203
       mount -t unionfs -o remount,add=:${2}=ro none "$1"
203
       mount -t unionfs -o remount,add=:${2}=ro none "$1"
204
   fi
204
   fi
205
}
205
}
206
 
206
 
207
# List all modules in all directories (base, modules, optional)
207
# List all modules in all directories (base, modules, optional)
208
# and filter out unneeded optional modules (not specified by load= kernel parameter)
208
# and filter out unneeded optional modules (not specified by load= kernel parameter)
209
# $1 = root directory of mounted DATAdir
209
# $1 = root directory of mounted DATAdir
210
#
210
#
211
list_modules()
211
list_modules()
212
{
212
{
213
   LOAD="`cmdline_value load`"
213
   LOAD="`cmdline_value load`"
214
   ls -A1d $1/*.mo $1/*/*.mo 2>/dev/null | while read LINE; do
214
   ls -A1d $1/*.mo $1/*/*.mo 2>/dev/null | while read LINE; do
215
      MODNAME="`basename $LINE .mo`"
215
      MODNAME="`basename $LINE .mo`"
216
      if [ "$LOAD" != "*" -a "`echo $LINE | grep optional`" != "" -a "`echo $LOAD | egrep \"(^|,)$MODNAME(\\\$|,)\"`" = "" ]; then continue
216
      if [ "$LOAD" != "*" -a "`echo $LINE | grep optional`" != "" -a "`echo $LOAD | egrep \"(^|,)$MODNAME(\\\$|,)\"`" = "" ]; then continue
217
        else echo $LINE; fi
217
        else echo $LINE; fi
218
   done
218
   done
219
}
219
}
220
 
220
 
221
# Insert one single .mo module to the union
221
# Insert one single .mo module to the union
222
# $1 = union absolute path (starting with /)
222
# $1 = union absolute path (starting with /)
223
# $2 = module.mo full path
223
# $2 = module.mo full path
224
# $3 = destination folder, where images will be mounted to
224
# $3 = destination folder, where images will be mounted to
225
#
225
#
226
union_insert_module()
226
union_insert_module()
227
{
227
{
228
   TARGET="$3/`basename $2`"
228
   TARGET="$3/`basename $2`"
229
   while [ -e $TARGET ]; do TARGET=$TARGET.X; done
229
   while [ -e $TARGET ]; do TARGET=$TARGET.X; done
230
   mkdir -p $TARGET
230
   mkdir -p $TARGET
231
   mount_module $2 $TARGET
231
   mount_module $2 $TARGET
232
   if [ $? -ne 0 ]; then echo "can't read module data"; return 1; fi
232
   if [ $? -ne 0 ]; then echo "can't read module data"; return 1; fi
233
   union_insert_dir $1 $TARGET; 
233
   union_insert_dir $1 $TARGET; 
234
}
234
}
235
 
235
 
236
# Insert all .mo modules, in $2 directory and subdirectories, to the union
236
# Insert all .mo modules, in $2 directory and subdirectories, to the union
237
# $1 = union absolute path (starting with /)
237
# $1 = union absolute path (starting with /)
238
# $2 = LiveCD data dir (with directories /base, /modules, etc.)
238
# $2 = LiveCD data dir (with directories /base, /modules, etc.)
239
# $3 = destination folder, where images will be mounted to
239
# $3 = destination folder, where images will be mounted to
240
#
240
#
241
union_insert_modules()
241
union_insert_modules()
242
{
242
{
243
   PRINTK=`cat /proc/sys/kernel/printk`
243
   PRINTK=`cat /proc/sys/kernel/printk`
244
   echo "0" >/proc/sys/kernel/printk
244
   echo "0" >/proc/sys/kernel/printk
245
 
245
 
246
   list_modules $2 | while read MODULE; do
246
   list_modules $2 | while read MODULE; do
247
      echo " -> `basename $MODULE`"
247
      echo " -> `basename $MODULE`"
248
      union_insert_module $1 $MODULE $3
248
      union_insert_module $1 $MODULE $3
249
   done
249
   done
250
 
250
 
251
   echo "$PRINTK" >/proc/sys/kernel/printk
251
   echo "$PRINTK" >/proc/sys/kernel/printk
252
}
252
}
253
 
253
 
254
# Copy modules to RAM directory
254
# Copy modules to RAM directory
255
# $1 = data directory
255
# $1 = data directory
256
# $2 = target directory in RAM
256
# $2 = target directory in RAM
257
#
257
#
258
copy_to_ram()
258
copy_to_ram()
259
{
259
{
260
   cp -R $1/* $2
260
   cp -R $1/* $2
261
   if [ $? -ne 0 ]; then fatal "can't copy to RAM, not enough memory?"; fi
261
   if [ $? -ne 0 ]; then fatal "can't copy to RAM, not enough memory?"; fi
262
}
262
}
263
 
263
 
264
# Copy content of "rootcopy" directory on the CD to $2 (union, usually)
264
# Copy content of "rootcopy" directory on the CD to $2 (union, usually)
265
# $1 = source
265
# $1 = source
266
# $2 = destination
266
# $2 = destination
267
#
267
#
268
copy_rootchanges()
268
copy_rootchanges()
269
{
269
{
270
   cp -a $1/rootcopy/* $2 2>/dev/null # could be empty
270
   cp -a $1/rootcopy/* $2 2>/dev/null # could be empty
271
}
271
}
272
 
272
 
273
# ===========================================================
273
# ===========================================================
274
# discovery functions
274
# discovery functions
275
# ===========================================================
275
# ===========================================================
276
 
276
 
277
# List all CD-ROMs
277
# List all CD-ROMs
278
# by using /proc entries
278
# by using /proc entries
279
#
279
#
280
list_cdrom_devices()
280
list_cdrom_devices()
281
{
281
{
282
   if [ "`cmdline_parameter nocd`" != "" ]; then return 1; fi
282
   if [ "`cmdline_parameter nocd`" != "" ]; then return 1; fi
283
   for CDDEVICE in `cat /proc/sys/dev/cdrom/info | head -n 3 | tail -n 1 | cut -d ":" -f 2`; do
283
   for CDDEVICE in `cat /proc/sys/dev/cdrom/info | head -n 3 | tail -n 1 | cut -d ":" -f 2`; do
284
      echo "/dev/$CDDEVICE"
284
      echo "/dev/$CDDEVICE"
285
   done
285
   done
286
}
286
}
287
 
287
 
288
# List all partition devices
288
# List all partition devices
289
# take list of all partitions and output unique disks.
289
# take list of all partitions and output unique disks.
290
# Return empty result when nohd parameter was given.
290
# Return empty result when nohd parameter was given.
291
#
291
#
292
list_partition_devices()
292
list_partition_devices()
293
{
293
{
294
   if [ "`cmdline_parameter nohd`" != "" ]; then return 1; fi
294
   if [ "`cmdline_parameter nohd`" != "" ]; then return 1; fi
295
   cat /proc/partitions | grep -v loop | sed -r "s/^[0-9[:space:]]+/\/dev\//" | grep /dev/
295
   cat /proc/partitions | grep -v loop | sed -r "s/^[0-9[:space:]]+/\/dev\//" | grep /dev/
296
}
296
}
297
 
297
 
298
# List all disk devices
298
# List all disk devices
299
#
299
#
300
list_disk_devices()
300
list_disk_devices()
301
{
301
{
302
   list_partition_devices | egrep -v "[0-9]"
302
   list_partition_devices | egrep -v "[0-9]"
303
}
303
}
304
 
304
 
305
# List all block devices
305
# List all block devices
306
#
306
#
307
list_block_devices()
307
list_block_devices()
308
{
308
{
309
   list_cdrom_devices
309
   list_cdrom_devices
310
   list_partition_devices
310
   list_partition_devices
311
}
311
}
312
 
312
 
313
# Try to mount all disks, partitions and cdroms and Find where the LiveCD is.
313
# Try to mount all disks, partitions and cdroms and Find where the LiveCD is.
314
# If LiveCD found in the device, echo dirname of it's directory,
314
# If LiveCD found in the device, echo dirname of it's directory,
315
# and leave the device mounted. Mounting is not ro, but without any argument.
315
# and leave the device mounted. Mounting is not ro, but without any argument.
316
# $1 = directory where devices will be mounted
316
# $1 = directory where devices will be mounted
317
# added: mount $NFSROOT to /$1/nfs if NFSROOT is set. and search there for LiveCD
317
# added: mount $NFSROOT to /$1/nfs if NFSROOT is set. and search there for LiveCD
318
#
318
#
319
find_live_data_dir()
319
find_live_data_dir()
320
{
320
{
321
   if [ "$NFSROOT" != "" ]; then 
321
   if [ "$NFSROOT" != "" ]; then 
322
      DIR="/$1/nfs"
322
      DIR="/$1/nfs"
323
      mkdir -p $DIR
323
      mkdir -p $DIR
324
      # try to mount nfs dir
324
      # try to mount nfs dir
325
      mount -t nfs -o $NFSOPT $NFSROOT $DIR
325
      mount -t nfs $NFSROOT $DIR -o $NFSOPTS 
326
   fi
326
   fi
327
 
327
 
328
   if [ "$CIFSROOT" != "" ]; then
328
   if [ "$CIFSROOT" != "" ]; then
329
      DIR="/$1/cifs"
329
      DIR="/$1/cifs"
330
      mkdir -p $DIR
330
      mkdir -p $DIR
331
      # try to mount cifs dir
331
      # try to mount cifs dir
332
      mount -t cifs $CIFSROOT $DIR -o ro,$CIFSOPTS
332
      mount -t cifs $CIFSROOT $DIR -o ro,$CIFSOPTS
333
   fi
333
   fi
334
 
334
 
335
   if [ "$DIR" = "" ]; then
335
   if [ "$DIR" = "" ]; then
336
       list_block_devices | while read DEVICE; do
336
       list_block_devices | while read DEVICE; do
337
	   DIR="/$1/`basename $DEVICE`"
337
	   DIR="/$1/`basename $DEVICE`"
338
	   mount_device $DEVICE $DIR
338
	   mount_device $DEVICE $DIR
339
	   if [ $? -ne 0 ]; then continue; fi
339
	   if [ $? -ne 0 ]; then continue; fi
340
	   # FOUND=`find $DIR -name livecd.sgn -type f | head -n 1`
340
	   # FOUND=`find $DIR -name livecd.sgn -type f | head -n 1`
341
	   FOUND=`ls -A1d $DIR/livecd.sgn $DIR/*/livecd.sgn 2>/dev/null | head -n 1`
341
	   FOUND=`ls -A1d $DIR/livecd.sgn $DIR/*/livecd.sgn 2>/dev/null | head -n 1`
342
	   if [ "$FOUND" = "" ]; then umount $DIR 2>/dev/null; rmdir $DIR 2>/dev/null
342
	   if [ "$FOUND" = "" ]; then umount $DIR 2>/dev/null; rmdir $DIR 2>/dev/null
343
	   else dirname "$FOUND"; return 1; fi
343
	   else dirname "$FOUND"; return 1; fi
344
       done
344
       done
345
   else
345
   else
346
       # FOUND=`find $DIR -name livecd.sgn -type f | head -n 1`
346
       # FOUND=`find $DIR -name livecd.sgn -type f | head -n 1`
347
       FOUND=`ls -A1d $DIR/livecd.sgn $DIR/*/livecd.sgn 2>/dev/null | head -n 1`
347
       FOUND=`ls -A1d $DIR/livecd.sgn $DIR/*/livecd.sgn 2>/dev/null | head -n 1`
348
       if [ "$FOUND" != "" ]; then 
348
       if [ "$FOUND" != "" ]; then 
349
	   dirname "$FOUND"
349
	   dirname "$FOUND"
350
       fi
350
       fi
351
   fi
351
   fi
352
}
352
}
353
 
353
 
354
# ===========================================================
354
# ===========================================================
355
# hardware preparation functions
355
# hardware preparation functions
356
# ===========================================================
356
# ===========================================================
357
 
357
 
358
# Create block devices to /dev described by /sys entries
358
# Create block devices to /dev described by /sys entries
359
#
359
#
360
create_block_devices()
360
create_block_devices()
361
{
361
{
362
   echolog "creating /dev entries for block devices"
362
   echolog "creating /dev entries for block devices"
363
   ls -A1d /sys/block/*/dev /sys/block/*/*/dev 2>/dev/null | grep -v loop | while read BLOCK; do
363
   ls -A1d /sys/block/*/dev /sys/block/*/*/dev 2>/dev/null | grep -v loop | while read BLOCK; do
364
      DEVICE="/dev/`basename \`dirname $BLOCK\``"
364
      DEVICE="/dev/`basename \`dirname $BLOCK\``"
365
      if [ ! -b $DEVICE ]; then
365
      if [ ! -b $DEVICE ]; then
366
         MINORMAJOR="`head -n 1 $BLOCK | tr ':' ' '`"
366
         MINORMAJOR="`head -n 1 $BLOCK | tr ':' ' '`"
367
         mknod $DEVICE b $MINORMAJOR
367
         mknod $DEVICE b $MINORMAJOR
368
      fi
368
      fi
369
   done
369
   done
370
}
370
}
371
 
371
 
372
# modprobe kernel modules needed for the LiveCD
372
# modprobe kernel modules needed for the LiveCD
373
#
373
#
374
modprobe_essential_modules()
374
modprobe_essential_modules()
375
{
375
{
376
   echolog "starting loop device support"
376
   echolog "starting loop device support"
377
   modprobe_module loop max_loop=32
377
   modprobe_module loop max_loop=32
378
   echolog "starting cdrom support"
378
   echolog "starting cdrom support"
379
   modprobe_module ide_cd
379
   modprobe_module ide_cd
380
   modprobe_module ide-cd
380
   modprobe_module ide-cd
381
   modprobe_module sr_mod
381
   modprobe_module sr_mod
382
   modprobe_module cdrom
382
   modprobe_module cdrom
383
   echolog "starting cdrom filesystem support"
383
   echolog "starting cdrom filesystem support"
384
   modprobe_module isofs
384
   modprobe_module isofs
385
   echolog "starting squashfs support"
385
   echolog "starting squashfs support"
386
   modprobe_module squashfs
386
   modprobe_module squashfs
387
   echolog "starting unionfs/aufs support"
387
   echolog "starting unionfs/aufs support"
388
   modprobe_module unionfs
388
   modprobe_module unionfs
389
   modprobe_module aufs
389
   modprobe_module aufs
390
   echolog "starting vfat support"
390
   echolog "starting vfat support"
391
   # modprobe_module nls_cp437
391
   # modprobe_module nls_cp437
392
   # modprobe_module nls_iso8859-1
392
   # modprobe_module nls_iso8859-1
393
   # modprobe_module nls_iso8859-2
393
   # modprobe_module nls_iso8859-2
394
   modprobe_module vfat
394
   modprobe_module vfat
395
   echolog "starting ntfs support"
395
   echolog "starting ntfs support"
396
   modprobe_module ntfs
396
   modprobe_module ntfs
397
   modprobe_module nls_utf8
397
   modprobe_module nls_utf8
398
   create_block_devices
398
   create_block_devices
399
}
399
}
400
 
400
 
401
 
401
 
402
# modprobe kernel modules needed for USB masstorage devices
402
# modprobe kernel modules needed for USB masstorage devices
403
#
403
#
404
modprobe_usb_sata_modules()
404
modprobe_usb_sata_modules()
405
{
405
{
406
   echolog "starting USB and SATA support"
406
   echolog "starting USB and SATA support"
407
   modprobe_module ehci-hcd
407
   modprobe_module ehci-hcd
408
   modprobe_module ohci-hcd
408
   modprobe_module ohci-hcd
409
   modprobe_module uhci-hcd
409
   modprobe_module uhci-hcd
410
   modprobe_module scsi_mod
410
   modprobe_module scsi_mod
411
 
411
 
412
   modprobe_module libata
412
   modprobe_module libata
413
   modprobe_module ata_piix
413
   modprobe_module ata_piix
414
   modprobe_module ahci
414
   modprobe_module ahci
415
   modprobe_module sata_nv
415
   modprobe_module sata_nv
416
   modprobe_module sg
416
   modprobe_module sg
417
 
417
 
418
   modprobe_module sd_mod
418
   modprobe_module sd_mod
419
   modprobe_module sr_mod
419
   modprobe_module sr_mod
420
   modprobe_module usb-storage
420
   modprobe_module usb-storage
421
   echolog "waiting for USB devices, max 8 seconds"
421
   echolog "waiting for USB devices, max 8 seconds"
422
   sleep 8
422
   sleep 8
423
   create_block_devices
423
   create_block_devices
424
}
424
}
425
 
425
 
426
# modprobe nfs kernel modules
426
# modprobe nfs kernel modules
427
#
427
#
428
modprobe_nfs_modules()
428
modprobe_nfs_modules()
429
{
429
{
430
   echolog "starting nfs support"
430
   echolog "starting nfs support"
431
   modprobe_module lockd
431
   modprobe_module lockd
432
   modprobe_module fscache
432
   modprobe_module fscache
433
   modprobe_module nfs_acl
433
   modprobe_module nfs_acl
434
   modprobe_module nfs
434
   modprobe_module nfs
435
}
435
}
436
 
436
 
437
# modprobe cifs kernel module
437
# modprobe cifs kernel module
438
#
438
#
439
modprobe_cifs_modules()
439
modprobe_cifs_modules()
440
{
440
{
441
  echolog "starting cifs support"
441
  echolog "starting cifs support"
442
  modprobe_module cifs
442
  modprobe_module cifs
443
}
443
}
444
 
444
 
445
# enable/disable CD autoejecting when unmounted
445
# enable/disable CD autoejecting when unmounted
446
# $1 = 1|0 ... enable|disable
446
# $1 = 1|0 ... enable|disable
447
#
447
#
448
cd_autoeject()
448
cd_autoeject()
449
{
449
{
450
   echo $1 >/proc/sys/dev/cdrom/autoeject
450
   echo $1 >/proc/sys/dev/cdrom/autoeject
451
}
451
}
452
 
452
 
453
# Disable DMA if nodma boot parameter is present
453
# Disable DMA if nodma boot parameter is present
454
#
454
#
455
setup_dma()
455
setup_dma()
456
{
456
{
457
   if [ ! "`cmdline_parameter nodma`" = "" ]; then
457
   if [ ! "`cmdline_parameter nodma`" = "" ]; then
458
      for DEVICE in `list_cdrom_devices` `list_disk_devices`; do
458
      for DEVICE in `list_cdrom_devices` `list_disk_devices`; do
459
         echolog "setting DMA support off for $DEVICE"
459
         echolog "setting DMA support off for $DEVICE"
460
         hdparm -d 0 $DEVICE
460
         hdparm -d 0 $DEVICE
461
      done
461
      done
462
   fi
462
   fi
463
}
463
}
464
 
464
 
465
# create correct fstab file in $1/etc/fstab and create apropriate
465
# create correct fstab file in $1/etc/fstab and create apropriate
466
# mount directories in $1
466
# mount directories in $1
467
# $1 = root directory (union)
467
# $1 = root directory (union)
468
#
468
#
469
activate_fstab()
469
activate_fstab()
470
{
470
{
471
   mkdir -p $1/etc
471
   mkdir -p $1/etc
472
   FSTAB="$1/etc/fstab"
472
   FSTAB="$1/etc/fstab"
473
   echo "tmpfs            /                tmpfs       defaults         0   0" >$FSTAB
473
   echo "tmpfs            /                tmpfs       defaults         0   0" >$FSTAB
474
   echo "devpts           /dev/pts         devpts      gid=5,mode=620   0   0" >>$FSTAB
474
   echo "devpts           /dev/pts         devpts      gid=5,mode=620   0   0" >>$FSTAB
475
   echo "proc             /proc            proc        defaults         0   0" >>$FSTAB
475
   echo "proc             /proc            proc        defaults         0   0" >>$FSTAB
476
 
476
 
477
   # all the rest will be done by runlast or by fstab-sync
477
   # all the rest will be done by runlast or by fstab-sync
478
   # search for SWAP done later in /etc/rc.sysinit
478
   # search for SWAP done later in /etc/rc.sysinit
479
}
479
}
480
 
480
 
481
 
481
 
482
# find partition and/or folder that stores the changes
482
# find partition and/or folder that stores the changes
483
# return false, if changes not set or changes folder/partition not found
483
# return false, if changes not set or changes folder/partition not found
484
# Urs Beyerle
484
# Urs Beyerle
485
#
485
#
486
find_changes()
486
find_changes()
487
{
487
{
488
    echolog "looking for changes in $CHANGESVAL"
488
    echolog "looking for changes in $CHANGESVAL"
489
 
489
 
490
    CHANGESDEV="`echo "$CHANGESVAL" | egrep -o "^/dev/[^/]+"`"
490
    CHANGESDEV="`echo "$CHANGESVAL" | egrep -o "^/dev/[^/]+"`"
491
    CHANGESFOLDER="`echo "$CHANGESVAL" | sed -r 's:^/dev/[^/]+(.*):\1:'`"
491
    CHANGESFOLDER="`echo "$CHANGESVAL" | sed -r 's:^/dev/[^/]+(.*):\1:'`"
492
    # (re-)define CHANGES if CHANGESFOLDER is set
492
    # (re-)define CHANGES if CHANGESFOLDER is set
493
    if [ "$CHANGESFOLDER" != "" ]; then CHANGES=$MEMORY/$CHANGESFOLDER; fi
493
    if [ "$CHANGESFOLDER" != "" ]; then CHANGES=$MEMORY/$CHANGESFOLDER; fi
494
 
494
 
495
    # we may need usb and sata support
495
    # we may need usb and sata support
496
    modprobe_usb_sata_modules
496
    modprobe_usb_sata_modules
497
 
497
 
498
    # device defined?
498
    # device defined?
499
    if [ "$CHANGESDEV" != "" ]; then
499
    if [ "$CHANGESDEV" != "" ]; then
500
	mount_device $CHANGESDEV $MEMORY
500
	mount_device $CHANGESDEV $MEMORY
501
	if [ $? -eq 0 ]; then 
501
	if [ $? -eq 0 ]; then 
502
	    echolog "mounted $CHANGESDEV to $MEMORY"
502
	    echolog "mounted $CHANGESDEV to $MEMORY"
503
	else
503
	else
504
	    echolog "WARNING: device $CHANGESDEV could not be mounted! Continue booting in 10 sec. ..."
504
	    echolog "WARNING: device $CHANGESDEV could not be mounted! Continue booting in 10 sec. ..."
505
	    CHANGESVAL=""
505
	    CHANGESVAL=""
506
	    sleep 10
506
	    sleep 10
507
	fi
507
	fi
508
	return
508
	return
509
    fi
509
    fi
510
    
510
    
511
    # if no device is specified, search all devices for folder CHANGESFOLDER
511
    # if no device is specified, search all devices for folder CHANGESFOLDER
512
    list_block_devices | while read DEVICE; do
512
    list_block_devices | while read DEVICE; do
513
	mount_device $DEVICE $MEMORY
513
	mount_device $DEVICE $MEMORY
514
	if [ $? -ne 0 ]; then continue; fi
514
	if [ $? -ne 0 ]; then continue; fi
515
	FOUND_FOLDER=`ls -1d $MEMORY/$CHANGESFOLDER 2>/dev/null`
515
	FOUND_FOLDER=`ls -1d $MEMORY/$CHANGESFOLDER 2>/dev/null`
516
	if [ "$FOUND_FOLDER" = "" ]; then 
516
	if [ "$FOUND_FOLDER" = "" ]; then 
517
	    umount $MEMORY 2>/dev/null
517
	    umount $MEMORY 2>/dev/null
518
	else
518
	else
519
	    echolog "found folder $CHANGESFOLDER on $DEVICE"
519
	    echolog "found folder $CHANGESFOLDER on $DEVICE"
520
	    break
520
	    break
521
	fi
521
	fi
522
    done
522
    done
523
 
523
 
524
    FOUND_FOLDER=`ls -1d $MEMORY/$CHANGESFOLDER 2>/dev/null`
524
    FOUND_FOLDER=`ls -1d $MEMORY/$CHANGESFOLDER 2>/dev/null`
525
 
525
 
526
    if [ "$FOUND_FOLDER" = "" ]; then 
526
    if [ "$FOUND_FOLDER" = "" ]; then 
527
	echolog "WARNING: changes=$CHANGESVAL not found! Continue booting in 10 sec. ..."
527
	echolog "WARNING: changes=$CHANGESVAL not found! Continue booting in 10 sec. ..."
528
	CHANGESVAL=""
528
	CHANGESVAL=""
529
	sleep 10
529
	sleep 10
530
    fi
530
    fi
531
 
531
 
532
}
532
}
533
 
533
 
534
 
534
 
535
# ===========================================================
535
# ===========================================================
536
# functions used for LiveCD on NFS 
536
# functions used for LiveCD on NFS 
537
# ===========================================================
537
# ===========================================================
538
 
538
 
539
# load network modules, if NFSROOT is set
539
# load network modules, if NFSROOT is set
540
# Urs Beyerle
540
# Urs Beyerle
541
#
541
#
542
 
542
 
543
# network devices found ?
543
# network devices found ?
544
#
544
#
545
found_nic()
545
found_nic()
546
{
546
{
547
    found="1"
547
    found="1"
548
    for iface in eth0 eth1 eth2 eth3 eth4 eth5; do
548
    for iface in eth0 eth1 eth2 eth3 eth4 eth5; do
549
	# nic already found ?
549
	# nic already found ?
550
	echo $FOUND_IFACE | grep -q $iface 
550
	echo $FOUND_IFACE | grep -q $iface 
551
	if [ $? -ne 0 ]; then
551
	if [ $? -ne 0 ]; then
552
	    ifconfig $iface > /dev/null 2>&1
552
	    ifconfig $iface > /dev/null 2>&1
553
	    if [ $? -eq 0 ]; then 
553
	    if [ $? -eq 0 ]; then 
554
		FOUND_IFACE="$FOUND_IFACE $iface"
554
		FOUND_IFACE="$FOUND_IFACE $iface"
555
		found="0"
555
		found="0"
556
	    fi
556
	    fi
557
	fi
557
	fi
558
    done
558
    done
559
    return $found
559
    return $found
560
}
560
}
561
 
561
 
562
# 1. load network driver defined by kernel parameter nic
562
# 1. load network driver defined by kernel parameter nic
563
#
563
#
564
load_network_module_nic()
564
load_network_module_nic()
565
{
565
{
566
    NIC="`cmdline_value nic`"
566
    NIC="`cmdline_value nic`"
567
    if [ -n "$NIC" ]; then
567
    if [ -n "$NIC" ]; then
568
	echolog "load module $NIC"
568
	echolog "load module $NIC"
569
	modprobe_module $NIC
569
	modprobe_module $NIC
570
    fi
570
    fi
571
}
571
}
572
 
572
 
573
 
573
 
574
# 2. auto probe for network card drivers
574
# 2. auto probe for network card drivers
575
#
575
#
576
load_network_module_auto()
576
load_network_module_auto()
577
{
577
{
578
    echolog "auto-detection of network driver ..."
578
    echolog "auto-detection of network driver ..."
579
    FOUND_NICS=""
579
    FOUND_NICS=""
580
    KERNEL="`uname -r`"
580
    KERNEL="`uname -r`"
581
    NETDRIVERS="`find /lib/modules/$KERNEL/kernel/drivers/net | grep -v mii | grep .ko | cut -d"/" -f8 | cut -d"." -f1 | uniq`"
581
    NETDRIVERS="`find /lib/modules/$KERNEL/kernel/drivers/net | grep -v mii | grep .ko | cut -d"/" -f8 | cut -d"." -f1 | uniq`"
582
    for driver in $NETDRIVERS; do
582
    for driver in $NETDRIVERS; do
583
       	modprobe_module $driver > /dev/null 2>&1
583
       	modprobe_module $driver > /dev/null 2>&1
584
	found_nic
584
	found_nic
585
	if [ $? -eq 0 ]; then
585
	if [ $? -eq 0 ]; then
586
	    echolog "found network card $driver"
586
	    echolog "found network card $driver"
587
	    echolog "load module $driver"
587
	    echolog "load module $driver"
588
	    FOUND_NICS="$FOUND_NICS $driver"
588
	    FOUND_NICS="$FOUND_NICS $driver"
589
	else
589
	else
590
	    rmmod $driver > /dev/null 2>&1
590
	    rmmod $driver > /dev/null 2>&1
591
	fi
591
	fi
592
    done
592
    done
593
 
593
 
594
    # clean up: remove unused modules until driver "mii"
594
    # clean up: remove unused modules until driver "mii"
595
    LOADED_DRIVERS="`lsmod | grep -v Module | cut -d" " -f1`"
595
    LOADED_DRIVERS="`lsmod | grep -v Module | cut -d" " -f1`"
596
    for driver in $LOADED_DRIVERS; do
596
    for driver in $LOADED_DRIVERS; do
597
	[ "$driver" = "mii" ]  && break
597
	[ "$driver" = "mii" ]  && break
598
	[ "$driver" = "ntfs" ] && break
598
	[ "$driver" = "ntfs" ] && break
599
	[ "$driver" = "vfat" ] && break
599
	[ "$driver" = "vfat" ] && break
600
	do_not_remove=""
600
	do_not_remove=""
601
	for nic in $FOUND_NICS; do
601
	for nic in $FOUND_NICS; do
602
	    echo $driver | grep -q $nic 
602
	    echo $driver | grep -q $nic 
603
	    [ $? -eq 0 ] && do_not_remove="$driver"
603
	    [ $? -eq 0 ] && do_not_remove="$driver"
604
	done
604
	done
605
	[ ! $do_not_remove ] && rmmod $driver > /dev/null 2>&1
605
	[ ! $do_not_remove ] && rmmod $driver > /dev/null 2>&1
606
    done
606
    done
607
}
607
}
608
 
608
 
609
# 3. detecting network card from pcitable list
609
# 3. detecting network card from pcitable list
610
#
610
#
611
load_network_module_pcitable()
611
load_network_module_pcitable()
612
{
612
{
613
    PCITABLE=/bin/pcitable
613
    PCITABLE=/bin/pcitable
614
    NICS=`lspci -n | awk '/Class 0200/ {print $4}' | tr ':' ' ' \
614
    NICS=`lspci -n | awk '/Class 0200/ {print $4}' | tr ':' ' ' \
615
	| while read x y ; do grep "0x$x.*0x$y" $PCITABLE \
615
	| while read x y ; do grep "0x$x.*0x$y" $PCITABLE \
616
	| awk '$3 !~ /"unknown"/ {print $3}' | tr -d '"' ; done`
616
	| awk '$3 !~ /"unknown"/ {print $3}' | tr -d '"' ; done`
617
    
617
    
618
    if [ -n "$NICS" ]; then
618
    if [ -n "$NICS" ]; then
619
	echolog "found network card(s): $NICS"
619
	echolog "found network card(s): $NICS"
620
	for driver in $NICS; do
620
	for driver in $NICS; do
621
	    echolog "load module $driver"
621
	    echolog "load module $driver"
622
	    modprobe_module $driver
622
	    modprobe_module $driver
623
	done
623
	done
624
    fi
624
    fi
625
}
625
}
626
 
626
 
627
# 4. ask the user for a network driver
627
# 4. ask the user for a network driver
628
#
628
#
629
load_network_module_ask()
629
load_network_module_ask()
630
{
630
{
631
    echo "ERROR: No network card detected!"
631
    echo "ERROR: No network card detected!"
632
    echo "Type in your network card driver (e.g. tg3, e1000). "
632
    echo "Type in your network card driver (e.g. tg3, e1000). "
633
    echo "Or ask your system administrator for help."
633
    echo "Or ask your system administrator for help."
634
    echo -n "Network card driver: "
634
    echo -n "Network card driver: "
635
    read driver
635
    read driver
636
    echo "load module $driver"
636
    echo "load module $driver"
637
    modprobe_module $driver
637
    modprobe_module $driver
638
}
638
}
639
 
639
 
640
# Try to find a network driver
640
# Try to find a network driver
641
#
641
#
642
load_network_modules()
642
load_network_modules()
643
{
643
{
644
    echolog "load network modules"
644
    echolog "load network modules"
645
 
645
 
646
    # mii maybe need by NIC driver
646
    # mii maybe need by NIC driver
647
    modprobe_module mii
647
    modprobe_module mii
648
 
648
 
649
    FOUND_IFACE=""
649
    FOUND_IFACE=""
650
    load_network_module_nic
650
    load_network_module_nic
651
    found_nic          || load_network_module_auto
651
    found_nic          || load_network_module_auto
652
    [ "$FOUND_IFACE" ] || load_network_module_pcitable
652
    [ "$FOUND_IFACE" ] || load_network_module_pcitable
653
    [ "$FOUND_IFACE" ] || load_network_module_ask
653
    [ "$FOUND_IFACE" ] || load_network_module_ask
654
 
654
 
655
    # remove mii, if not needed
655
    # remove mii, if not needed
656
    rmmod mii > /dev/null 2>&1
656
    rmmod mii > /dev/null 2>&1
657
}
657
}
658
 
658
 
659
 
659
 
660
# get DHCP lease
660
# get DHCP lease
661
# Urs Beyerle
661
# Urs Beyerle
662
#
662
#
663
get_dhcp_lease()
663
get_dhcp_lease()
664
{
664
{
665
    # create /dev/urandom (needed by udhcpc)
665
    # create /dev/urandom (needed by udhcpc)
666
    mknod /dev/urandom c 1 9
666
    mknod /dev/urandom c 1 9
667
 
667
 
668
    for iface in eth0 eth1 eth2 eth3 eth4 eth5; do
668
    for iface in eth0 eth1 eth2 eth3 eth4 eth5; do
669
	# interface up ?
669
	# interface up ?
670
	ifconfig $iface > /dev/null 2>&1
670
	ifconfig $iface > /dev/null 2>&1
671
	if [ $? -eq 0 ]; then
671
	if [ $? -eq 0 ]; then
672
	    # get dhcp lease
672
	    # get dhcp lease
673
	    echolog "try to get DHCP lease on $iface"
673
	    echolog "try to get DHCP lease on $iface"
674
	    udhcpc --now --quit --interface=$iface --script=/bin/udhcpc.script
674
	    udhcpc --now --quit --interface=$iface --script=/bin/udhcpc.script
675
	    [ $? -eq 0 ] && return
675
	    [ $? -eq 0 ] && return
676
	    echo "ERROR: couldn't get DHCP lease on $iface."
676
	    echo "ERROR: couldn't get DHCP lease on $iface."
677
	fi
677
	fi
678
    done
678
    done
679
}
679
}