Subversion Repositories livecd

Rev

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

Rev 175 Rev 176
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 -o $NFSOPT $NFSROOT $DIR
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
-
 
485
#
484
find_changes()
486
find_changes()
485
{
487
{
486
    echolog "looking for changes on $CHANGESVAL"
488
    echolog "looking for changes in $CHANGESVAL"
487
 
489
 
488
    CHANGESDEV="`echo "$CHANGESVAL" | egrep -o "^/dev/[^/]+"`"
490
    CHANGESDEV="`echo "$CHANGESVAL" | egrep -o "^/dev/[^/]+"`"
489
    CHANGESFOLDER="`echo "$CHANGESVAL" | sed -r 's:^/dev/[^/]+(.*):\1:'`"
491
    CHANGESFOLDER="`echo "$CHANGESVAL" | sed -r 's:^/dev/[^/]+(.*):\1:'`"
490
    # (re-)define CHANGES if CHANGESFOLDER is set
492
    # (re-)define CHANGES if CHANGESFOLDER is set
491
    if [ "$CHANGESFOLDER" != "" ]; then CHANGES=$MEMORY/$CHANGESFOLDER; fi
493
    if [ "$CHANGESFOLDER" != "" ]; then CHANGES=$MEMORY/$CHANGESFOLDER; fi
492
 
494
 
493
    # we may need usb and sata support
495
    # we may need usb and sata support
494
    modprobe_usb_sata_modules
496
    modprobe_usb_sata_modules
495
 
497
 
496
    # device defined?
498
    # device defined?
497
    if [ "$CHANGESDEV" != "" ]; then
499
    if [ "$CHANGESDEV" != "" ]; then
498
	mount_device $CHANGESDEV $MEMORY
500
	mount_device $CHANGESDEV $MEMORY
499
	return
501
	return
500
    fi 
502
    fi 
501
    
503
    
502
    # if no device is specified, search all devices for folder CHANGESFOLDER
504
    # if no device is specified, search all devices for folder CHANGESFOLDER
503
    list_block_devices | while read DEVICE; do
505
    list_block_devices | while read DEVICE; do
504
	mount_device $DEVICE $MEMORY
506
	mount_device $DEVICE $MEMORY
505
	if [ $? -ne 0 ]; then continue; fi
507
	if [ $? -ne 0 ]; then continue; fi
506
	FOUND_FOLDER=`ls -1d $MEMORY/$CHANGESFOLDER 2>/dev/null`
508
	FOUND_FOLDER=`ls -1d $MEMORY/$CHANGESFOLDER 2>/dev/null`
507
	if [ "$FOUND_FOLDER" = "" ]; then 
509
	if [ "$FOUND_FOLDER" = "" ]; then 
508
	    umount $MEMORY 2>/dev/null
510
	    umount $MEMORY 2>/dev/null
509
	else
511
	else
510
	    echolog "found folder $CHANGESFOLDER on $DEVICE"
512
	    echolog "found folder $CHANGESFOLDER on $DEVICE"
511
	    return
513
	    return
512
	fi
514
	fi
513
    done
515
    done
514
 
516
 
515
    echolog "WARNING: $CHANGESVAL not found! Continue booting in 10 seconds..."
517
    echolog "WARNING: changes=$CHANGESVAL not found! Continue booting in 10 seconds..."
516
    # unset CHANGESVAL
518
    # unset CHANGESVAL
517
    CHANGESVAL=""
519
    CHANGESVAL=""
518
    sleep 10
520
    sleep 10
519
 
521
 
520
}
522
}
521
 
523
 
522
 
524
 
523
# ===========================================================
525
# ===========================================================
524
# functions used for LiveCD on NFS 
526
# functions used for LiveCD on NFS 
525
# ===========================================================
527
# ===========================================================
526
 
528
 
527
# load network modules, if NFSROOT is set
529
# load network modules, if NFSROOT is set
528
# Urs Beyerle
530
# Urs Beyerle
529
#
531
#
530
 
532
 
531
# network devices found ?
533
# network devices found ?
532
#
534
#
533
found_nic()
535
found_nic()
534
{
536
{
535
    found="1"
537
    found="1"
536
    for iface in eth0 eth1 eth2 eth3 eth4 eth5; do
538
    for iface in eth0 eth1 eth2 eth3 eth4 eth5; do
537
	# nic already found ?
539
	# nic already found ?
538
	echo $FOUND_IFACE | grep -q $iface 
540
	echo $FOUND_IFACE | grep -q $iface 
539
	if [ $? -ne 0 ]; then
541
	if [ $? -ne 0 ]; then
540
	    ifconfig $iface > /dev/null 2>&1
542
	    ifconfig $iface > /dev/null 2>&1
541
	    if [ $? -eq 0 ]; then 
543
	    if [ $? -eq 0 ]; then 
542
		FOUND_IFACE="$FOUND_IFACE $iface"
544
		FOUND_IFACE="$FOUND_IFACE $iface"
543
		found="0"
545
		found="0"
544
	    fi
546
	    fi
545
	fi
547
	fi
546
    done
548
    done
547
    return $found
549
    return $found
548
}
550
}
549
 
551
 
550
# 1. load network driver defined by kernel parameter nic
552
# 1. load network driver defined by kernel parameter nic
551
#
553
#
552
load_network_module_nic()
554
load_network_module_nic()
553
{
555
{
554
    NIC="`cmdline_value nic`"
556
    NIC="`cmdline_value nic`"
555
    if [ -n "$NIC" ]; then
557
    if [ -n "$NIC" ]; then
556
	echolog "load module $NIC"
558
	echolog "load module $NIC"
557
	modprobe_module $NIC
559
	modprobe_module $NIC
558
    fi
560
    fi
559
}
561
}
560
 
562
 
561
 
563
 
562
# 2. auto probe for network card drivers
564
# 2. auto probe for network card drivers
563
#
565
#
564
load_network_module_auto()
566
load_network_module_auto()
565
{
567
{
566
    echolog "auto-detection of network driver ..."
568
    echolog "auto-detection of network driver ..."
567
    FOUND_NICS=""
569
    FOUND_NICS=""
568
    KERNEL="`uname -r`"
570
    KERNEL="`uname -r`"
569
    NETDRIVERS="`find /lib/modules/$KERNEL/kernel/drivers/net | grep -v mii | grep .ko | cut -d"/" -f8 | cut -d"." -f1 | uniq`"
571
    NETDRIVERS="`find /lib/modules/$KERNEL/kernel/drivers/net | grep -v mii | grep .ko | cut -d"/" -f8 | cut -d"." -f1 | uniq`"
570
    for driver in $NETDRIVERS; do
572
    for driver in $NETDRIVERS; do
571
       	modprobe_module $driver > /dev/null 2>&1
573
       	modprobe_module $driver > /dev/null 2>&1
572
	found_nic
574
	found_nic
573
	if [ $? -eq 0 ]; then
575
	if [ $? -eq 0 ]; then
574
	    echolog "found network card $driver"
576
	    echolog "found network card $driver"
575
	    echolog "load module $driver"
577
	    echolog "load module $driver"
576
	    FOUND_NICS="$FOUND_NICS $driver"
578
	    FOUND_NICS="$FOUND_NICS $driver"
577
	else
579
	else
578
	    rmmod $driver > /dev/null 2>&1
580
	    rmmod $driver > /dev/null 2>&1
579
	fi
581
	fi
580
    done
582
    done
581
 
583
 
582
    # clean up: remove unused modules until driver "mii"
584
    # clean up: remove unused modules until driver "mii"
583
    LOADED_DRIVERS="`lsmod | grep -v Module | cut -d" " -f1`"
585
    LOADED_DRIVERS="`lsmod | grep -v Module | cut -d" " -f1`"
584
    for driver in $LOADED_DRIVERS; do
586
    for driver in $LOADED_DRIVERS; do
585
	[ "$driver" = "mii" ]  && break
587
	[ "$driver" = "mii" ]  && break
586
	[ "$driver" = "ntfs" ] && break
588
	[ "$driver" = "ntfs" ] && break
587
	[ "$driver" = "vfat" ] && break
589
	[ "$driver" = "vfat" ] && break
588
	do_not_remove=""
590
	do_not_remove=""
589
	for nic in $FOUND_NICS; do
591
	for nic in $FOUND_NICS; do
590
	    echo $driver | grep -q $nic 
592
	    echo $driver | grep -q $nic 
591
	    [ $? -eq 0 ] && do_not_remove="$driver"
593
	    [ $? -eq 0 ] && do_not_remove="$driver"
592
	done
594
	done
593
	[ ! $do_not_remove ] && rmmod $driver > /dev/null 2>&1
595
	[ ! $do_not_remove ] && rmmod $driver > /dev/null 2>&1
594
    done
596
    done
595
}
597
}
596
 
598
 
597
# 3. detecting network card from pcitable list
599
# 3. detecting network card from pcitable list
598
#
600
#
599
load_network_module_pcitable()
601
load_network_module_pcitable()
600
{
602
{
601
    PCITABLE=/bin/pcitable
603
    PCITABLE=/bin/pcitable
602
    NICS=`lspci -n | awk '/Class 0200/ {print $4}' | tr ':' ' ' \
604
    NICS=`lspci -n | awk '/Class 0200/ {print $4}' | tr ':' ' ' \
603
	| while read x y ; do grep "0x$x.*0x$y" $PCITABLE \
605
	| while read x y ; do grep "0x$x.*0x$y" $PCITABLE \
604
	| awk '$3 !~ /"unknown"/ {print $3}' | tr -d '"' ; done`
606
	| awk '$3 !~ /"unknown"/ {print $3}' | tr -d '"' ; done`
605
    
607
    
606
    if [ -n "$NICS" ]; then
608
    if [ -n "$NICS" ]; then
607
	echolog "found network card(s): $NICS"
609
	echolog "found network card(s): $NICS"
608
	for driver in $NICS; do
610
	for driver in $NICS; do
609
	    echolog "load module $driver"
611
	    echolog "load module $driver"
610
	    modprobe_module $driver
612
	    modprobe_module $driver
611
	done
613
	done
612
    fi
614
    fi
613
}
615
}
614
 
616
 
615
# 4. ask the user for a network driver
617
# 4. ask the user for a network driver
616
#
618
#
617
load_network_module_ask()
619
load_network_module_ask()
618
{
620
{
619
    echo "ERROR: No network card detected!"
621
    echo "ERROR: No network card detected!"
620
    echo "Type in your network card driver (e.g. tg3, e1000). "
622
    echo "Type in your network card driver (e.g. tg3, e1000). "
621
    echo "Or ask your system administrator for help."
623
    echo "Or ask your system administrator for help."
622
    echo -n "Network card driver: "
624
    echo -n "Network card driver: "
623
    read driver
625
    read driver
624
    echo "load module $driver"
626
    echo "load module $driver"
625
    modprobe_module $driver
627
    modprobe_module $driver
626
}
628
}
627
 
629
 
628
# Try to find a network driver
630
# Try to find a network driver
629
#
631
#
630
load_network_modules()
632
load_network_modules()
631
{
633
{
632
    echolog "load network modules"
634
    echolog "load network modules"
633
 
635
 
634
    # mii maybe need by NIC driver
636
    # mii maybe need by NIC driver
635
    modprobe_module mii
637
    modprobe_module mii
636
 
638
 
637
    FOUND_IFACE=""
639
    FOUND_IFACE=""
638
    load_network_module_nic
640
    load_network_module_nic
639
    found_nic          || load_network_module_auto
641
    found_nic          || load_network_module_auto
640
    [ "$FOUND_IFACE" ] || load_network_module_pcitable
642
    [ "$FOUND_IFACE" ] || load_network_module_pcitable
641
    [ "$FOUND_IFACE" ] || load_network_module_ask
643
    [ "$FOUND_IFACE" ] || load_network_module_ask
642
 
644
 
643
    # remove mii, if not needed
645
    # remove mii, if not needed
644
    rmmod mii > /dev/null 2>&1
646
    rmmod mii > /dev/null 2>&1
645
}
647
}
646
 
648
 
647
 
649
 
648
# get DHCP lease
650
# get DHCP lease
649
# Urs Beyerle
651
# Urs Beyerle
650
#
652
#
651
get_dhcp_lease()
653
get_dhcp_lease()
652
{
654
{
653
    # create /dev/urandom (needed by udhcpc)
655
    # create /dev/urandom (needed by udhcpc)
654
    mknod /dev/urandom c 1 9
656
    mknod /dev/urandom c 1 9
655
 
657
 
656
    for iface in eth0 eth1 eth2 eth3 eth4 eth5; do
658
    for iface in eth0 eth1 eth2 eth3 eth4 eth5; do
657
	# interface up ?
659
	# interface up ?
658
	ifconfig $iface > /dev/null 2>&1
660
	ifconfig $iface > /dev/null 2>&1
659
	if [ $? -eq 0 ]; then
661
	if [ $? -eq 0 ]; then
660
	    # get dhcp lease
662
	    # get dhcp lease
661
	    echolog "try to get DHCP lease on $iface"
663
	    echolog "try to get DHCP lease on $iface"
662
	    udhcpc --now --quit --interface=$iface --script=/bin/udhcpc.script
664
	    udhcpc --now --quit --interface=$iface --script=/bin/udhcpc.script
663
	    [ $? -eq 0 ] && return
665
	    [ $? -eq 0 ] && return
664
	    echo "ERROR: couldn't get DHCP lease on $iface."
666
	    echo "ERROR: couldn't get DHCP lease on $iface."
665
	fi
667
	fi
666
    done
668
    done
667
}
669
}