Subversion Repositories livecd

Rev

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

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