update linuxrc (aufs stuff)
[grml-live.git] / rewrite / linuxrc
1 #!/static/sh
2 # Filename: /linuxrc
3 # Purpose:  minirt for kernel 2.6 running on grml live-cd
4 # Authors:  (c) Klaus Knopper <knoppix@knopper.net>, (c) Michael Prokop <mika@grml.org>
5 # Latest change: Sun Feb 25 20:02:36 CET 2007 [mika]
6 #######################################################################################
7
8 # hardcoded configurable options
9 # Default maximum size of dynamic ramdisk in kilobytes
10 RAMSIZE=1000000
11 # End of options
12
13 # Don't allow interrupt signals
14 trap "" 1 2 3 15
15
16 # Misc functions
17 INSMOD="/static/insmod"
18 # [ -x /modules/insmod ] && INSMOD="/modules/insmod"
19
20 RMMOD="/static/rmmod"
21 # [ -x /modules/rmmod ] && RMMOD="/modules/rmmod"
22
23 # Builin filesystems
24 # BUILTIN_FS="iso9660 ext2 vfat"
25 BUILTIN_FS="iso9660 ext2 ext3 reiserfs vfat xfs jfs reiser4"
26
27 mountit(){
28 # Usage: mountit src dst "options"
29 for fs in $BUILTIN_FS; do
30  if test -b $1; then
31   options="$3"
32   case "$fs" in vfat)
33    # We REALLY need this for Knoppix on DOS-filesystems
34    shortname="shortname=winnt"
35    [ -n "$options" ] && options="$options,$shortname" || options="-o $shortname"
36   ;;
37   esac
38   mount -t $fs $options $1 $2 >/dev/null 2>&1 && return 0
39  fi
40 done
41 return 1
42 }
43
44 FOUND_SCSI=""
45 FOUND_GRML=""
46 INTERACTIVE=""
47
48 # Clean input/output
49 exec >/dev/console </dev/console 2>&1
50
51 # Mount /proc and /dev/pts
52 mount -t proc /proc /proc
53
54 # Disable kernel messages while probing modules in autodetect mode
55 echo "0" > /proc/sys/kernel/printk
56
57 mount -t devpts /dev/pts /dev/pts
58 # Kernel 2.6
59 mount -t sysfs /sys /sys >/dev/null 2>&1
60
61 # Read boot command line with builtin cat command (shell read function fails in Kernel 2.4.19-rc1)
62 CMDLINE="$(cat /proc/cmdline)"
63
64 # Simple shell grep
65 stringinfile(){
66   case "$(cat $2)" in *$1*) return 0;; esac
67   return 1
68 }
69
70 # same for strings
71 stringinstring(){
72   case "$2" in *$1*) return 0;; esac
73   return 1
74 }
75
76 # Reread boot command line; echo last parameter's argument or return false.
77 getbootparam(){
78   stringinstring " $1=" "$CMDLINE" || return 1
79   result="${CMDLINE##*$1=}"
80   result="${result%%[   ]*}"
81   echo "$result"
82   return 0
83 }
84
85 # Check boot commandline for specified option
86 checkbootparam(){
87   stringinstring " $1" "$CMDLINE"
88   return "$?"
89 }
90
91 if checkbootparam "nocolor" ; then
92   echo "Disabling colors in bootsequence as requested on commandline."
93   # Reset fb color mode
94   RESET="\e]R"
95   # ANSI COLORS
96   # Erase to end of line
97   CRE="\r\e[K"
98   # Clear and reset Screen
99   CLEAR="\ec"
100 else
101   # Reset fb color mode
102   RESET="\e]R"
103   # ANSI COLORS
104   # Erase to end of line
105   CRE="\r\e[K"
106   # Clear and reset Screen
107   CLEAR="\ec"
108   # Normal color
109   NORMAL="\e[0;39m"
110   # RED: Failure or error message
111   RED="\e[1;31m"
112   # GREEN: Success message
113   GREEN="\e[1;32m"
114   # YELLOW: Descriptions
115   YELLOW="\e[1;33m"
116   # BLUE: System mesages
117   BLUE="\e[1;34m"
118   # MAGENTA: Found devices or drivers
119   MAGENTA="\e[1;35m"
120   # CYAN: Questions
121   CYAN="\e[1;36m"
122   # BOLD WHITE: Hint
123   WHITE="\e[1;37m"
124 fi
125
126 # don't output anything if running with bootsplash feature
127 if checkbootparam "splash" ; then
128   echo ""
129   echo "${WHITE}Welcome to"
130   echo ""
131   echo "${RED}   ____ ____  __  __ _     "
132   echo "${RED}  / ___|  _ \|  \/  | |    "
133   echo "${RED} | |  _| |_) | |\/| | |    "
134   echo "${RED} | |_| |  _ <| |  | | |___ "
135   echo "${RED}  \____|_| \_\_|  |_|_____|"
136   echo ""
137   echo "${WHITE}grml.org - Linux for users of texttools and sysadmins."
138   echo "${NORMAL}"
139   exec >/dev/null </dev/null 2>&1
140 fi
141
142 # helper functions {{{
143 #log_success_msg () {
144 #  echo " * $@"
145 #}
146
147 log_failure_msg () {
148   echo " ${RED}*${NORMAL} $@"
149 }
150
151 #log_warning_msg () {
152 # echo " ${BLUE}*${NORMAL} $@"
153 #}
154
155 # int log_begin_message (char *message)
156 log_begin_msg () {
157   echo -n " ${GREEN}*${NORMAL} $@"
158 }
159
160 log_warn_msg () {
161   echo -n " ${YELLOW}*${NORMAL} $@"
162 }
163
164 # int log_end_message (int exitstatus)
165 SUCCESS=" ${BLUE}[ ${GREEN}ok ${BLUE}]${NORMAL}"
166 FAILED=" ${NORMAL}[${RED}fail${NORMAL}]"
167 # }}}
168
169 # Clear screen with colormode reset
170 # echo "$CLEAR$RESET"
171 # echo "$CLEAR"
172 # Just go to the top of the screen
173 # echo -n "\e[H\e[J"
174 echo ""
175 echo "${WHITE}Welcome to"
176 echo ""
177 echo "${RED}   ____ ____  __  __ _     "
178 echo "${RED}  / ___|  _ \|  \/  | |    "
179 echo "${RED} | |  _| |_) | |\/| | |    "
180 echo "${RED} | |_| |  _ <| |  | | |___ "
181 echo "${RED}  \____|_| \_\_|  |_|_____|"
182 echo ""
183 echo "${WHITE}grml.org - Linux for users of texttools and sysadmins."
184 echo "${NORMAL}"
185
186 # We only need the builtin commands and /static at this point
187 PATH=/static
188 export PATH
189
190 umask 022
191
192 case "$CMDLINE" in *debuglinuxrc*) set -x; echo "linuxrc debugging activated"; DEBUG="yes"; ;; esac
193 case "$CMDLINE" in *BOOT_IMAGE=expert\ *) INTERACTIVE="yes"; :>/interactive; ;; esac
194 case "$CMDLINE" in *BOOT_IMAGE=vmware\ *) VMWARE="yes"; ;; esac
195 case "$CMDLINE" in *modules-disk*) INTERACTIVE="yes"; ;; esac
196 case "$CMDLINE" in *BOOT_IMAGE=debug\ *|*\ debug\ *) DEBUG="yes"; ;; esac
197 case "$CMDLINE" in *secure*) SECURE=",nosuid"; ;; esac
198 # Does the user want to skip scsi detection?
199 NOSCSI=""
200 NOUSB=""
201 NOFIREWIRE=""
202 case "$CMDLINE" in *noscsi*|*nobootscsi*) NOSCSI="yes"; ;; esac
203 case "$CMDLINE" in *nousb\ *|*nobootusb*) NOUSB="yes"; ;; esac
204 case "$CMDLINE" in *nofirewire*|*nobootfirewire*) NOFIREWIRE="yes"; ;; esac
205 NOCD=""
206 case "$CMDLINE" in *fromhd*) NOCD="yes"; ;; esac
207 case "$CMDLINE" in *fromdvd*) FROMDVD="yes"; ;; esac
208 case "$CMDLINE" in *idecd*|*atapicd*) IDECD="yes"; ;; esac
209 case "$CMDLINE" in *noideraid*) NOIDERAID="yes"; ;; esac
210 USB2="ehci-hcd.ko"
211 case "$CMDLINE" in *nousb2*) USB2="" NOUSB2="yes"; ;; esac
212 case "$CMDLINE" in *\ usb*) USB="yes"; ;; esac
213
214 GRML_DIR="GRML"
215 GRML_NAME="GRML"
216 case "$CMDLINE" in *grml_dir=*) GRML_DIR="$grml_dir"; ;; esac
217 case "$CMDLINE" in *grml_name=*) GRML_NAME="$grml_name"; ;; esac
218
219 if [ -n "$DEBUG" ]; then
220    log_begin_msg "Bootoption debug detected. Printing kernel command line:"
221    echo ""
222    cat /proc/cmdline
223 fi
224
225 # Run a shell if in debug mode
226 # echo "${BLUE}Dropping you to a busybox shell for debugging.${NORMAL}"
227 stage=1
228 rundebugshell(){
229  if [ -n "$DEBUG" ]; then
230   log_begin_msg "Starting intermediate shell stage $stage as requested by \"debug\" option."
231   echo ""
232   echo "   ${GREEN}-${NORMAL} Just exit the shell to continue boot process...${NORMAL}"
233   if [ -x /static/sh ]; then
234     /static/sh
235   else
236     /bin/bash
237   fi
238  fi
239 }
240 rundebugshell
241
242 # Mount module disk
243 mountmodules(){
244 TYPE="$1"; shift
245 echo -n "${CRE}Please insert ${TYPE} modules disk and hit Return."
246 read a
247 echo -n "${CRE}Mounting ${TYPE} modules disk... "
248 # We always mount over /modules/scsi (because it's there ;-)
249 if mountit /dev/fd0 /modules/scsi "-o ro"; then
250 echo "${GREEN}OK.${NORMAL}"
251 return 0
252 fi
253 echo "${RED}NOT FOUND.${NORMAL}"
254 return 1
255 }
256
257 # Unmount module disk
258 umountmodules(){
259 TYPE="$1"; shift
260 echo -n "${CRE}Unmounting ${TYPE} modules disk... "
261 umount /modules/scsi 2>/dev/null
262 echo "${GREEN}DONE.${NORMAL}"
263 }
264
265 # Ask user for modules
266 askmodules(){
267  TYPE="$1"; shift
268  echo "${TYPE} modules available:${WHITE}"
269  c=""
270  for m in "$@"; do
271   if test -f "/modules/scsi/$m"; then
272    test -z "$c"  && { echo -n " $m"; c="1"; } || { echo "               $m"; c=""; }
273   fi
274  done
275  [ -n "$c" ] && echo ""
276  echo "Load ${TYPE} Modules?"
277  echo "[Enter full filename(s) (space-separated), Return for autoprobe, n for none] "
278  echo -n "insmod module(s)> "
279  read MODULES
280  case "$MODULES" in n|N) MODULES=""; ;; y|"")  MODULES="$*"; ;; esac
281 }
282
283 # Try to load the given modules (full path or current directory)
284 loadmodules(){
285  TYPE="$1"; shift
286  test -n "$INTERACTIVE" && echo "6" > /proc/sys/kernel/printk
287  echo ""
288  for i in "$@"; do
289   echo -n "   Probing ${TYPE}... ${WHITE}$i${NORMAL}: "
290    if test -f /modules/scsi/$i.ko && $INSMOD -f /modules/scsi/$i.ko >/dev/null 2>&1 && echo "  $SUCCESS" || echo " failed " ; then
291      case "$TYPE" in scsi|SCSI) FOUND_SCSI="yes"; ;; esac
292    fi
293  done
294  test -n "$INTERACTIVE" && echo "0" > /proc/sys/kernel/printk
295  echo -n "${CRE}"
296 }
297
298 # Check for SCSI, use modules on bootfloppy first
299 # Trying to do kind of /proc/pci hardware detection
300 if checkbootparam oldscsi ; then
301   PROCPCI="`cat /proc/pci 2>/dev/null`"
302   case "$PROCPCI" in *[Aa][Ii][Cc]-*|*[Aa][Hh][Aa]-*) SCSI_PROBE="$SCSI_PROBE aic7xxx" ;; esac
303   case "$PROCPCI" in *[Bb][Uu][Ss][Ll][Oo][Gg][Ii][Cc]*) SCSI_PROBE="$SCSI_PROBE BusLogic" ;; esac
304   case "$PROCPCI" in *[Tt][Rr][Mm]-[Ss]1040*|*[Dd][Cc]395*|*[Dd][Cc]315*) SCSI_PROBE="$SCSI_PROBE dc395x" ;; esac
305   case "$PROCPCI" in *53[Cc]8*) SCSI_PROBE="$SCSI_PROBE sym53c8xx" ;; esac
306   case "$PROCPCI" in *53[Cc]9*) SCSI_PROBE="$SCSI_PROBE NCR53C9x" ;; esac
307   case "$PROCPCI" in *53[Cc]406*) SCSI_PROBE="$SCSI_PROBE NCR53c406a" ;; esac
308   case "$PROCPCI" in *[Ii][Nn][Ii][Tt][Ii][Oo]\ *|*[Ii][Nn][Ii]-[Aa]100[Uu]2[Ww]*) SCSI_PROBE="$SCSI_PROBE initio" ;; esac
309   case "$PROCPCI" in *[Mm][Pp][Tt]*[Ss][Cc][Ss][Ii]*) SCSI_PROBE="$SCSI_PROBE mptbase mptscsih" ;; esac
310   case "$PROCPCI" in *[Aa][Dd][Vv][Aa][Nn][Cc][Ee][Dd]\ [Ss][Yy][Ss]*) SCSI_PROBE="$SCSI_PROBE advansys" ;; esac
311   case "$PROCPCI" in *[Aa][Tt][Pp]8*|*[Aa][Ee][Cc]6*) SCSI_PROBE="$SCSI_PROBE atp870u" ;; esac
312   case "$PROCPCI" in *[Dd][Tt][Cc]*) SCSI_PROBE="$SCSI_PROBE dtc" ;; esac
313   case "$PROCPCI" in *[Ee][Aa][Tt][Aa]*) SCSI_PROBE="$SCSI_PROBE eata" ;; esac
314   case "$PROCPCI" in *[Ff]*[Dd][Oo][Mm][Aa][Ii][Nn]*) SCSI_PROBE="$SCSI_PROBE fdomain" ;; esac
315   case "$PROCPCI" in *[Gg][Dd][Tt]\ *) SCSI_PROBE="$SCSI_PROBE gdth" ;; esac
316   case "$PROCPCI" in *[Mm][Ee][Gg][Aa][Rr][Aa][Ii][Dd]*) SCSI_PROBE="$SCSI_PROBE megaraid_mm megaraid_mbox" ;; esac
317   case "$PROCPCI" in *[Qq][Ll][Oo][Gg][Ii][Cc]*) SCSI_PROBE="$SCSI_PROBE qlogicfas408 qlogicfas qlogicfc" ;; esac
318   case "$PROCPCI" in *53[Cc]974*) SCSI_PROBE="$SCSI_PROBE tmscsim" ;; esac
319   case "$PROCPCI" in *[Uu][Ll][Tt][Rr][Aa][Ss][Tt][Oo][Rr]*) SCSI_PROBE="$SCSI_PROBE ultrastor" ;; esac
320   case "$PROCPCI" in *3[Ww][Aa][Rr][Ee]*) SCSI_PROBE="$SCSI_PROBE 3w-xxxx" ;; esac
321 fi
322
323 # New sysfs based SCSI detection (thanks, Jörg Schirottke)
324 sysfsscsi(){
325 SYS=$(for x in $(find /sys/devices/ -name modalias); do grep pci: $x; done|cut -f2 -d:)
326 while read id driver; do
327  for sysid in $SYS; do
328   case $sysid in $id)
329    if [ -z "$SCSI_PROBE" ]; then
330     SCSI_PROBE="$driver"
331    else
332     SCSI_PROBE="$SCSI_PROBE $driver"
333    fi
334    ;;
335   esac
336  done
337 done <<EOF
338 $(cat /modules/scsi/scsi-modules.txt)
339 EOF
340 }
341
342 if test -n "$INTERACTIVE"; then
343 # Let the user select interactively
344   askmodules SCSI $(cd /modules/scsi; echo *.ko)
345 else
346 # these are the autoprobe-safe modules
347   sysfsscsi
348   MODULES="$SCSI_PROBE"
349 fi
350
351 if test -z "$NOSCSI" ; then
352  log_begin_msg "Scanning for SCSI devices."
353  $INSMOD -f /modules/scsi/firmware_class.ko 1>/dev/null
354  test -n "$MODULES" && loadmodules SCSI $MODULES &&  echo -n "" || echo "           ${BLUE}[${NORMAL} none found ${BLUE}]${NORMAL} (try bootoption scsi=probe)"
355 else
356   log_warn_msg "Not scanning for SCSI devices as requested on commandline." && echo " $SUCCESS"
357 fi
358
359 if checkbootparam scsi ; then
360   MODULE="$(getbootparam 'scsi' 2>/dev/null)"
361   if test "$MODULE" = "probe" ; then
362     log_begin_msg "Bootoption scsi=probe found. Trying to autoprobe SCSI modules:"
363     echo ""
364     echo -n "   Trying to load scsi_debug: " ; $INSMOD -f /modules/scsi/scsi_debug.ko 1>/dev/null && echo "           $SUCCESS" || echo " [ failed ]"
365     for module in /modules/scsi/*.ko ; do
366       echo -n "   Probing ${WHITE}${module}${NORMAL}..."
367       $INSMOD -f ${module} >/dev/null 2>&1 && echo " $SUCCESS" || echo " [ failed ]"
368     done
369   elif test "$MODULE" = "ask" ; then
370     askmodules SCSI $(cd /modules/scsi; echo *.ko)
371     test -z "$NOSCSI" && test -n "$MODULES" && loadmodules SCSI $MODULES
372   else
373     [ -n "$MODULE" ] || echo "   ${RED}Neither a specific module nor option probe nor option ask for SCSI module given. Skipping.${NORMAL}"
374     [ -n "$MODULE" ] && echo -n "   Trying to load module ${WHITE}${MODULE}${NORMAL}:" ; \
375       $INSMOD -f "/modules/scsi/${MODULE}.ko" 1>/dev/null && echo "  $SUCCESS" || echo " [ failed ]"
376   fi
377 fi
378 # End of SCSI check
379
380 if test -n "$VMWARE" ; then
381   log_begin_msg "Bootoption VMware detected. Trying to load SCSI modules:"
382   echo ""
383   for module in mptbase mptscsih mptspi BusLogic ; do
384     echo -n "   Trying to load ${WHITE}${module}${NORMAL}: "
385     $INSMOD -f /modules/scsi/${module}.ko >/dev/null 2>&1 && echo " $SUCCESS" || echo " [ failed ]"
386   done
387 fi
388
389 # Check for USB, use modules on bootfloppy first
390 if test -z "$NOUSB"; then
391   log_begin_msg "Checking for USB."
392   if test -f /modules/div/usbcore.ko; then
393     $INSMOD /modules/div/usbcore.ko >/dev/null 2>&1
394     FOUNDUSB=""
395     for i in $USB2 uhci-hcd.ko ohci-hcd.ko usbhid.ko ; do
396       test -f /modules/div/$i && $INSMOD /modules/div/$i >/dev/null 2>&1 && FOUNDUSB="yes"
397     done
398     if test -n "$FOUNDUSB"; then
399       test -f /modules/div/usb-storage.ko && $INSMOD /modules/div/usb-storage.ko >/dev/null 2>&1
400       echo "                   $SUCCESS"
401     else
402       echo "                   ${BLUE}[${NORMAL} not found ${BLUE}]${NORMAL}"
403       true
404     fi
405     if [ -n "$NOUSB2" ] ; then
406       echo "   Not loading usb2 module ehci-hcd as requested on commandline."
407       echo "   Notice: to skip loading of USB in initrd at all use bootoption nousb"
408     fi
409   fi
410 else
411   log_warn_msg "Not scanning for USB devices as requested on commandline." && echo " $SUCCESS"
412   echo "   Notice that bootoption nousb affects initrd only, it does *not*"
413   echo "   avoid loading of usb modules in userspace afterwards"
414   echo "   Boot using something like 'nousb blacklist=uhci-hcd' to avoid loading of usb modules at all"
415 fi
416 # End of USB check
417
418 # Check for Firewire, use modules on bootfloppy first
419 if test -z "$NOFIREWIRE" ; then
420   log_begin_msg "Checking for Firewire."
421   if test -f /modules/div/ieee1394.ko ; then
422     $INSMOD /modules/div/ieee1394.ko > /dev/null 2>&1
423     FOUNDFIREWIRE=""
424     test -f /modules/div/ohci1394.ko && $INSMOD /modules/div/ohci1394.ko > /dev/null 2>&1 && FOUNDFIREWIRE="yes"
425     if test -n "$FOUNDFIREWIRE" ; then
426       test -f /modules/div/sbp2.ko && $INSMOD /modules/div/sbp2.ko > /dev/null 2>&1
427       echo "              $SUCCESS"
428     else
429       echo "               ${BLUE}[${NORMAL} not found ${BLUE}]${NORMAL}"
430       true
431     fi
432   fi
433 else
434   log_warn_msg "Not scanning for firewire devices as requested on commandline." && echo " $SUCCESS"
435   echo "   Notice that bootoption nofirewire affects initrd only, it does *not*"
436   echo "   avoid loading of firewire modules in userspace afterwards"
437   echo "   Boot with something like 'nofirewire blacklist=ohci1394' to avoid loading of firewire modules at all"
438 fi
439 # End of FIREWIRE check
440
441 # Unfortunately, hotpluggable devices tend to need some time in order to register
442 if test -n "$FOUNDUSB" -o -n "$FOUNDFIREWIRE"; then
443   log_begin_msg "Scanning for USB/Firewire devices."
444   sleep 4
445   if test -n "$USB"; then
446     sleep 10
447   fi
448  echo "  $SUCCESS"
449 fi
450
451 if checkbootparam scandelay ; then
452   DELAY="$(getbootparam 'scandelay' 2>/dev/null)"
453   [ -z $DELAY ] && DELAY='10'
454   log_begin_msg "Delaying bootsequence as requested for ${WHITE}${DELAY}${NORMAL} seconds."
455   sleep $DELAY && echo "  $SUCCESS"
456 fi
457
458 # boot via pcmcia
459 if checkbootparam bootpcmcia ; then
460   log_begin_msg "Bootoption bootpcmcia found. Trying to load ${WHITE}PCMCIA${NORMAL} modules..."
461   if $INSMOD -f /modules/div/pcmcia_core.ko 1>/dev/null ; then
462      $INSMOD -f /modules/div/firmware_class.ko 1>/dev/null && \
463      $INSMOD -f /modules/div/pcmcia.ko         1>/dev/null && \
464      $INSMOD -f /modules/div/rsrc_nonstatic.ko 1>/dev/null && \
465      $INSMOD -f /modules/div/yenta_socket.ko   1>/dev/null && echo " $SUCCESS"
466   else
467     echo " [ failed ]"
468   fi
469 fi
470
471 # Check for misc modules in expert mode
472 if test -n "$INTERACTIVE" ; then
473   another=""
474   answer=""
475   while test "$answer" != "n" -a "$answer" != "N" ; do
476     echo -n "${CYAN}Do you want to load additional modules from$another floppy disk? [${WHITE}Y${CYAN}/n] ${NORMAL}"
477     another=" another"
478     read answer
479     case "$answer" in n*|N*) break; ;; esac
480     if mountmodules new ; then
481        askmodules new $(cd /modules/scsi; echo *.ko)
482        test -n "$MODULES" && loadmodules new $MODULES
483        umountmodules current
484     fi
485   done
486 fi
487 # All interactively requested modules should be loaded now.
488
489 # Check for ide-scsi supported CD-Roms et al.
490 test -f /proc/scsi/scsi && FOUND_SCSI="yes"
491
492 # Disable kernel messages again
493 echo "0" > /proc/sys/kernel/printk
494
495 # We now enable DMA right here, for faster reading/writing from/to IDE devices
496 # in FROMHD or TORAM mode
497 case "$CMDLINE" in *\ nodma*) ;; *)
498  for d in $(cd /proc/ide 2>/dev/null && echo hd[a-z]); do
499   if test -d /proc/ide/$d; then
500     MODEL="$(cat /proc/ide/$d/model 2>/dev/null)"
501     test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]"
502     log_begin_msg "Enabling DMA acceleration for: ${MAGENTA}$d   ${YELLOW}[${MODEL}]${NORMAL}"
503     echo "using_dma:1" >/proc/ide/$d/settings && echo ""
504   fi
505  done
506  ;;
507 esac
508
509 stage=2
510 rundebugshell
511 # NFS
512 for i in $cmdline; do case "$i" in nfsdir=*|NFSDIR=*) eval $i;; esac; done
513 [ -n "$nfsdir" ] && NFS="$nfsdir"
514 if [ -n "$NFS" ]; then
515   tmp_="$(getbootparam nfsdir)"
516   log_begin_msg "Bootoption NFS found." ; echo "$SUCCESS"
517
518   # put the mylibs into /lib for discover and udhcpc
519   cdir
520
521   # starting hw-detection for network card - currently broken, so don't use it
522   #  echo "Starting hw-detection"
523   #  kernel_version_=`uname -r`
524   #  modules_to_load=$(/static/discover --disable-bus all --enable-bus pci --type network --normalize-whitespace --data-path=linux/module/name --data-version=$kernel_version_ | grep -v '^ $' | uniq)
525   #  echo "trying to load the following network modules:  \"$modules_to_load\""
526
527   KERNELVER=`uname -r`
528   for mod in `find /lib/modules/$KERNELVER/kernel/drivers/net/ -name \*.ko` ; do
529       echo `basename $mod | sed -e 's/\.ko$//'` >> /modules.load
530   done
531   modules_to_load=`cat /modules.load | xargs`
532
533   # FIXME modprobe is buggy from busybox
534   log_begin_msg "Trying to load network driver(s)." ; echo
535   modLoad()
536   {
537     for mod in $@ ; do
538       tmp_="`modprobe -vn $mod 2>/dev/null`"
539       if [ $? -ne 0 ]; then
540          continue
541       fi
542       # be quiet by default, be verbose only with bootoption debuglinuxrc
543       [ -n "$DEBUG" ] && eval "$tmp_" || eval "$tmp_" 1>/dev/null 2>/dev/null
544     done
545   }
546   modLoad "$modules_to_load"
547   rm -f /modules.load
548
549   # loading additional modules
550   modLoad sunrpc lockd af_packet nfs
551
552   for INTERFACE in `ifconfig -a | grep '^eth' | sed 's/\ .*//'` ; do
553       log_begin_msg "Requesting network configuration using udhcp for ${INTERFACE}:" ; echo
554       /static/timeout 10 /static/udhcpc --interface="${INTERFACE}" --foreground --quit --script=/static/udhcp-config.sh
555       # echo "press <enter> to start a system shell and configure your system"
556       # sh
557   done
558
559   # recreate the old dir structures
560   rdir
561   #rm -rf /myusr /mylib
562
563   log_begin_msg "Looking for GRML in: ${MAGENTA}$NFS${NORMAL}" ; echo "$SUCCESS"
564   if mount -t nfs "$NFS" -o "async,ro,nolock" /cdrom #>/dev/null 2>&1
565     then
566     if test -f /cdrom/$GRML_DIR/$GRML_NAME
567       then
568       log_begin_msg "Accessing grml CDROM at ${MAGENTA}$NFS${NORMAL}" ; echo "$SUCCESS"
569       FOUND_GRML="$NFS"
570       break
571     fi
572   fi
573 fi
574
575 # Now that the right SCSI driver is (hopefully) loaded, try to find CD-ROM
576 if test -z $NFS ; then
577   DEVICES="/dev/hd?"
578   test -n "$FOUND_SCSI" -a -z "$NOCD" && DEVICES="/dev/scd? /dev/scd?? $DEVICES"
579   # New: Also try parallel port CD-Roms [for Mike].
580   DEVICES="$DEVICES /dev/pcd?"
581   # New: also check HD partitions for a GRML/GRML image
582   # notice: use /dev/sd? for usb-sticks without partition(s)
583   test -n "$FOUND_SCSI" -a -z "$NOSCSI" && DEVICES="$DEVICES /dev/sd?[1-9] /dev/sd?[1-9][0-9] /dev/sd?"
584   DEVICES="$DEVICES /dev/hd?[1-9] /dev/hd?[1-9][0-9]"
585   case "$CMDLINE" in *fromhd=/dev/*) DEVICES="$fromhd"; ;; esac
586   for i in $DEVICES
587   do
588   log_begin_msg "${CRE} ${GREEN}*${NORMAL} Looking for CD-ROM in:    ${MAGENTA}$i${NORMAL}"
589   if mountit $i /cdrom "-o ro" >/dev/null 2>&1
590     then
591     echo "  $SUCCESS"
592     if test -f /cdrom/$GRML_DIR/$GRML_NAME
593       then
594       log_begin_msg "Accessing grml CD-ROM at: ${MAGENTA}$i${NORMAL}" ; echo "  $SUCCESS"
595       FOUND_GRML="$i"
596       break
597     fi
598     umount /cdrom
599   fi
600   done
601 fi
602
603 # Harddisk-installed script part version has been removed
604 # (GRML can be booted directly from HD now).
605 mount_grml()
606 {
607   if test -n "$FOUND_GRML" -a -f $1/$GRML_DIR/$GRML_NAME; then
608     # echo "6" > /proc/sys/kernel/printk
609     mount -t squashfs $1/$GRML_DIR/$GRML_NAME /GRML -o loop,ro$SECURE || FOUND_GRML=""
610   fi
611 }
612
613 remount_grml()
614 {
615   if test -f $TARGET/$GRML_DIR/$GRML_NAME; then
616     umount /GRML # unmount it
617     umount $SOURCE  # unmount CD
618     [ -n "$SOURCE2" ] && umount $SOURCE2  # umount possible loop-device
619     mount_grml $TARGET
620   else
621     log_failure_msg "Warning: Changing to $TARGET failed."
622     return 1
623   fi
624
625   return 0
626 }
627
628 boot_from()
629 {
630   # preparations
631   /bin/mkdir $TARGET
632
633   SOURCE_DEV=$(echo $CMDLINE | /usr/bin/tr ' ' '\n' | /bin/sed -n '/bootfrom=/s/.*=//p' | /usr/bin/tail -1)
634
635   LOOP_DEV=$(echo $SOURCE_DEV | /usr/bin/gawk -F/ '{ print $1 "/" $2 "/" $3 }')
636   ISO_PATH=$(echo $SOURCE_DEV | /bin/sed "s|$LOOP_DEV||g" )
637   case "$ISO_PATH" in /*.[iI][sS][oO]) ;; *) ISO_PATH="" ;; esac
638   LOOP_SOURCE=""
639
640   # load filesystems
641   /GRML/sbin/modprobe fuse
642   /GRML/sbin/modprobe ntfs
643   $INSMOD -f /modules/div/ntfs.ko 1>/dev/null
644
645   if [ -n "$ISO_PATH" ]; then
646      LOOP_SOURCE="$TARGET.loop"
647      LOOP_SOURCE2="$LOOP_SOURCE"
648      TARGET_DEV="$LOOP_SOURCE$ISO_PATH"
649      /bin/mkdir $LOOP_SOURCE
650      /bin/mount -o ro $LOOP_DEV $LOOP_SOURCE || LOOP_SOURCE=""
651      /bin/mount -n -o loop $LOOP_SOURCE2$ISO_PATH $TARGET
652   else
653      TARGET_DEV="$SOURCE_DEV"
654     /bin/mount -n -o ro $SOURCE_DEV $TARGET
655   fi
656   if [ $? -ne 0 ]; then
657      [ -n "$LOOP_SOURCE" ] && /bin/umount $LOOP_SOURCE
658      log_failure_msg "Accessing grml CD-ROM failed. ${MAGENTA}$TARGET_DEV${NORMAL} is not mountable."
659      sleep 2
660      return 1
661   fi
662
663   if [ -f $TARGET/$GRML_DIR/$GRML_NAME ]; then
664     log_begin_msg "Accessing grml CD-ROM at ${MAGENTA}$TARGET_DEV${NORMAL}." ; echo "  $SUCCESS"
665   else
666     log_failure_msg "Accessing grml CD-ROM failed. Could not find $GRML_DIR/$GRML_NAME on ${MAGENTA}$TARGET_DEV${RED}.${NORMAL}"
667     [ -n "$LOOP_SOURCE" ] && /bin/umount $LOOP_SOURCE
668     umount $TARGET
669     sleep 2
670     return 1
671   fi
672   # remount the CD
673   remount_grml
674 }
675
676 copy_to()
677 {
678   # preparations
679   /bin/mkdir $TARGET
680   COPY="$SOURCE/$GRML_DIR"
681
682   # look if we copy to hd or to ram
683   SIZE="$(/usr/bin/du -s $COPY | /usr/bin/gawk '{print int($1*1.1)}')"
684   test -n "$SIZE" || SIZE="800000"
685
686   case "$1" in
687     ram)
688       TARGET_DEV="/dev/shm"
689       TARGET_DEV_DESC="ramdisk"
690       FOUNDSPACE="$(/usr/bin/gawk '/MemTotal/{print $2}' /proc/meminfo)"
691       /bin/mount -n -t tmpfs -o size=${SIZE}k $TARGET_DEV $TARGET
692     ;;
693     hd)
694       TARGET_DEV=$(echo $CMDLINE | /usr/bin/tr ' ' '\n' | /bin/sed -n '/tohd=/s/.*=//p' | /usr/bin/tail -1)
695       TARGET_DEV_DESC="$TARGET_DEV"
696       # load filesystems
697       /GRML/sbin/modprobe fuse
698       /GRML/sbin/modprobe ntfs
699       FS="ext3 ext2 reiserfs reiser4 vfat ntfs"
700
701       MOUNTED=""
702       for i in $FS; do
703        if /GRML/bin/mount -o rw -t "$i" "$TARGET_DEV" "$TARGET"; then
704         MOUNTED="true"
705         break
706        fi
707       done
708       if test -z "$MOUNTED"; then
709         log_failure_msg "Copying grml CD-ROM failed. ${MAGENTA}$TARGET_DEV_DESC${NORMAL} is not mountable."
710         sleep 2
711         return 1
712       fi
713       # check for enough free space
714       USED_SPACE=0
715       [ -f $TARGET/$GRML_DIR/$GRML_NAME ] && USED_SPACE=$(/usr/bin/du -s $TARGET/$GRML_DIR/$GRML_NAME | /usr/bin/gawk '{ print $1 }')
716       FOUNDSPACE="$(/bin/df -k $TARGET | /usr/bin/tail -1 | /usr/bin/gawk '{ print $4+int('$USED_SPACE') }')"
717    ;;
718    *)
719      return 1
720    ;;
721   esac
722
723   # sanity check
724
725   if [ $FOUNDSPACE -lt $SIZE ]
726   then
727     log_failure_msg "Copying grml CD-ROM failed. Not enough free space on ${MAGENTA}${TARGET_DEV_DESC}${NORMAL}. Found: ${MAGENTA}${FOUNDSPACE}k${NORMAL} Need: ${MAGENTA}${SIZE}k${NORMAL}"
728     sleep 2
729     umount $TARGET
730     return 1
731   fi
732
733   # do the real copy
734
735   log_begin_msg "Copying grml CD-ROM to ${TARGET_DEV_DESC}... Please be patient."
736   echo
737   if [ -z "$use_cp" -a -x /usr/bin/rsync ]
738   then
739     # first cp the small files
740     /usr/bin/rsync -a --exclude="$GRML_DIR/$GRML_NAME" $COPY $TARGET # Copy grml to $TARGET
741     # then the big file with nice progress meter
742     [ -f $TARGET/$GRML_DIR/$GRML_NAME ] && /bin/rm -f $TARGET/$GRML_DIR/$GRML_NAME
743     /usr/bin/rsync -a --progress --include="$GRML_DIR/$GRML_NAME" --include="$GRML_DIR/" --exclude="*" $COPY $TARGET # Copy grml to $TARGET
744     #/usr/bin/rsync -avP $COPY $TARGET # Copy grml to $TARGET
745     # make sure to support directories from http://grml.org/config/
746     for dir in scripts bootparams config debs ; do
747         if [ -d "/cdrom/$dir" ] ; then
748            log_begin_msg "Customization directory $dir found, copying to $TARGET"
749            cp -a /cdrom/$dir $TARGET/ && echo "$SUCCESS" || echo "$FAILED"
750         fi
751     done
752   else
753     /bin/cp -a -f $COPY $TARGET # Copy grml to $TARGET
754   fi
755   if [ $? -ne 0 ]
756   then
757     log_failure_msg "Copying grml CD-ROM failed. ${MAGENTA}$TARGET_DEV_DESC${NORMAL} possibly has not enough space left."
758     sleep 2
759     return 1
760   fi
761   # remount r/o
762   /bin/mount -n -o remount,ro $TARGET 1>/dev/null 2>&1
763   remount_grml
764 }
765
766 mount_grml /cdrom
767
768 COPYTO=""
769 BOOTFROM=""
770 DO_REMOUNT=""
771 REAL_TARGET=""
772 UNIONFS=""
773
774 case "$CMDLINE" in *toram*) DO_REMOUNT="yes"; COPYTO="ram"; ;; esac
775 case "$CMDLINE" in *tohd=*) DO_REMOUNT="yes"; COPYTO="hd"; ;; esac
776 case "$CMDLINE" in *bootfrom=*) DO_REMOUNT="yes"; BOOTFROM="yes" ;; esac
777
778 # Remount later after copying/isoloading/driverloading?
779 # pre-test if everything succeeded
780 if  test -n "$DO_REMOUNT" -a -n "$FOUND_GRML" ; then
781   # copy library cache
782   cat /GRML/etc/ld.so.cache > /etc/ld.so.cache
783   echo ""
784
785   SOURCE="/cdrom"
786   TARGET="/cdrom2"
787
788   # first copy_to, then boot_from
789   if [ -n "$COPYTO" ]; then
790      copy_to $COPYTO && REAL_TARGET="$TARGET"
791   fi
792   if [ -n "$BOOTFROM" ]; then
793      boot_from
794      if [ "$?" -eq "0" ]; then
795         # set new source / target paths
796         REAL_TARGET="$TARGET"
797         SOURCE2="$LOOP_SOURCE"
798         SOURCE="/cdrom2"
799         TARGET="/cdrom3"
800     fi
801   fi
802 fi
803
804 # Final test if everything succeeded.
805 if test -n "$FOUND_GRML"
806 then
807 # copy library cache
808 cat /GRML/etc/ld.so.cache > /etc/ld.so.cache
809
810 UNIONFS=""
811 if checkbootparam "unionfs" ; then
812    $INSMOD /modules/unionfs.ko 1>/dev/null
813    grep -q unionfs /proc/filesystems && UNIONFS=yes
814    unionfs='unionfs'
815    UNIONFS_FILETYPE='unionfs'
816    AUFS=''
817 else
818    $INSMOD /modules/aufs.ko 1>/dev/null
819    grep -q aufs /proc/filesystems && UNIONFS=yes
820    unionfs='unionfs (using aufs)'
821    UNIONFS_FILETYPE='aufs'
822    AUFS='yes'
823 fi
824
825 # Set paths
826 log_begin_msg "Setting paths"
827 PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/X11R6/bin:."
828 export PATH
829
830 # Make space: We don't need the modules anymore from here.
831 /GRML/bin/rm -rf /modules
832 # Debian weirdness
833 /GRML/bin/cp -a /GRML/etc/alternatives /etc/ 2>/dev/null
834
835 # Replace /sbin
836 /GRML/bin/rm -f /sbin
837 /GRML/bin/ln -sf /GRML/sbin /sbin
838
839 # From here, we should have all essential commands available.
840 hash -r
841
842 # Did we remount the source media?
843 if  test -n "$REAL_TARGET"; then
844   /bin/mount -n --move $REAL_TARGET /cdrom # move it back and go on to normal boot
845 fi
846
847 # Clean up /etc/mtab (and - just in case - make a nice entry for looped ISO)
848 egrep " /GRML | /cdrom " /proc/mounts 2>/dev/null | sed 's|/dev/loop0 /cdrom \(.*\) 0 0|'$LOOP_SOURCE$ISO_PATH' /cdrom/ \1,loop=/dev/loop0 0 0|g' >> /etc/mtab
849
850 # Clean up /
851 /GRML/bin/rm -rf /modules /static
852 echo "                       $SUCCESS"
853
854 # New in Kernel 2.4.x: tempfs with variable ramdisk size.
855 # We check for available memory anyways and limit the ramdisks
856 # to a reasonable size.
857 FOUNDMEM="$(awk '/MemTotal/{print $2}' /proc/meminfo)"
858 TOTALMEM="$(awk 'BEGIN{m=0};/MemFree|Cached/{m+=$2};END{print m}' /proc/meminfo)"
859
860 # Be verbose
861 if [ -n "$FOUNDMEM" ] ; then
862    log_begin_msg "Total memory found: $FOUNDMEM kB" ; echo "       $SUCCESS"
863 else
864    log_failure_msg "Could not fetch memory information." ; echo "     $FAILED"
865 fi
866
867 # Now we need to use a little intuition for finding a ramdisk size
868 # that keeps us from running out of space, but still doesn't crash the
869 # machine due to lack of Ram
870
871 # Minimum size of additional ram partitions
872 MINSIZE=20000
873 # At least this much memory minus 30% should remain when home and var are full.
874 MINLEFT=16000
875 # Maximum ramdisk size
876 [ -n "$TOTALMEM" ] && MAXSIZE="$(expr $TOTALMEM - $MINLEFT)"
877 # Default ramdisk size for ramdisk
878 [ -n "$TOTALMEM" ] && RAMSIZE="$(expr $TOTALMEM / 5)"
879
880 # Create additional dynamic ramdisk.
881 test -z "$RAMSIZE" -o "$RAMSIZE" -lt "$MINSIZE" && RAMSIZE="$MINSIZE"
882 mkdir -p /ramdisk
883 # tmpfs/varsize version, can use swap
884 RAMSIZE=$(expr $RAMSIZE \* 4)
885 log_begin_msg "Creating /ramdisk (dynamic size=${RAMSIZE}k) on shared memory"
886 # We need /bin/mount here for the -o size= option
887 /bin/mount -t tmpfs -o "size=${RAMSIZE}k" /ramdisk /ramdisk  && echo "$SUCCESS"
888 mkdir -p /ramdisk/tmp /ramdisk/home/grml && chmod 1777 /ramdisk/tmp && chown grml.grml /ramdisk/home/grml && ln -snf /ramdisk/home /home && mv /tmp /tmp.old && ln -s /ramdisk/tmp /tmp && rm -rf /tmp.old
889
890 stage=3
891 rundebugshell
892 # unionfs
893 log_begin_msg "Creating $unionfs and symlinks on ramdisk"
894 mkdir -p /UNIONFS
895 if test -n "$UNIONFS" && /bin/mount -t $UNIONFS_FILETYPE -o noatime${SECURE},dirs=/ramdisk=rw:/GRML=ro /UNIONFS /UNIONFS ; then
896  # We now have unionfs, copy some data from the initial ramdisk first
897  cp -a /etc/fstab /etc/auto.mnt /etc/filesystems /etc/mtab /UNIONFS/etc/
898  for i in bin boot etc sbin var lib opt root usr; do # Move directories to unionfs
899   if test -d /$i; then
900    mv /$i /$i.old && \
901    /GRML/lib/ld-linux.so.2 --library-path /GRML/lib /GRML/bin/ln -snf /UNIONFS/$i /$i && \
902    rm -rf /$i.old
903   else
904    ln -snf /UNIONFS/$i /$i
905   fi
906  done
907  [ -n "$AUFS" ] && echo "    $SUCCESS" || echo "                 $SUCCESS"
908  log_begin_msg "Merging read-only system with read-writeable /ramdisk."
909  for i in $(cd /UNIONFS; echo *); do # Create links for new stuff on /UNIONFS
910    test "$i" = "home" -o "$i" = "tmp" && continue
911    test -L "/$i" || test -d "/$i" || test -f "/$i" || ln -snf "/UNIONFS/$i" /$i
912  done && echo "   $SUCCESS" || echo "   $FAILED"
913 else
914  echo ""
915  log_failure_msg "ERROR: CANNOT UNITE READ-ONLY MEDIA AND INITIAL RAMDISK!"
916  echo "$FAILED"
917  sleep 2
918  echo "Can not continue booting, dropping you to a busybox shell."
919  stage=4
920  rundebugshell
921 fi
922
923 chown grml.grml /home/grml
924 # old:
925 # chmod 1777 /var/tmp
926 # new:
927 rm -rf /var/tmp/ ; mkdir /var/tmp ; chown root.root /var/tmp ; chmod 1777 /var/tmp
928
929 # Create empty utmp and wtmp
930 :> /var/run/utmp
931 :> /var/run/wtmp
932
933 # Make SURE that these are files, not links!
934 rm -rf /etc/ftpusers /etc/passwd /etc/shadow /etc/group \
935        /etc/ppp /etc/isdn /etc/ssh /etc/ioctl.save \
936        /etc/inittab /etc/network /etc/sudoers \
937        /etc/init /etc/localtime /etc/dhcpc /etc/pnm2ppa.conf 2>/dev/null
938 cp -a /GRML/etc/ftpusers /GRML/etc/passwd /GRML/etc/shadow /GRML/etc/group \
939       /GRML/etc/ppp /GRML/etc/isdn /GRML/etc/ssh \
940       /GRML/etc/inittab /GRML/etc/network /GRML/etc/sudoers \
941       /GRML/sbin/init /GRML/etc/dhcpc /etc/ 2>/dev/null
942
943 # Extremely important, init crashes on shutdown if this is only a link
944 :> /etc/ioctl.save
945 :> /etc/pnm2ppa.conf
946 # Must exist for samba to work
947 [ -d /var/lib/samba ] && :> /var/lib/samba/unexpected.tdb
948 # Diet libc bug workaround
949 # cp -f /GRML/etc/localtime /etc/localtime
950 # echo "${BLUE}Done.${NORMAL}"
951
952 # Now tell kernel where the real modprobe lives
953 echo "/sbin/modprobe" > /proc/sys/kernel/modprobe
954
955 # Change root device from /dev/fd0 to /dev/ram0
956 echo "0x100" > /proc/sys/kernel/real-root-dev
957
958 umount /sys # (remount in grml-autoconfig)
959
960 stage=4
961 rundebugshell
962 # Give control to the init process.
963 log_begin_msg "Starting init process. "
964 [ -r /mountit ] && rm -f /mountit
965 rm -f /linuxrc
966 exit 0
967
968 else
969  log_failure_msg "Error: Can't find grml filesystem, sorry."
970  echo "
971 Are you booting via USB or firewire?
972 ====================================
973 Try to boot with bootparam scandelay which delays the
974 bootup sequence so modules should have enough time
975 to initialize devices.
976
977 Usage examples on bootprompt of grml-iso:
978
979 grml scandelay       -> adds the default delay of 10 seconds
980 grml scandelay=13    -> adds a delay of 13 seconds
981
982 Are you booting via SCSI?
983 ====================================
984 Use the bootparam scsi.
985 Usage examples on bootprompt of grml-iso:
986
987 grml scsi=probe      -> autoprobing of scsi modules
988 grml scsi=ask        -> list modules and prompt for module which should be loaded
989 grml scsi=modulename -> loads specified module (without .ko extension)
990 expert               -> activate expert mode, similar to scsi=ask
991
992 Are you getting SquashFS/zlib errors?
993 =====================================
994 Try to boot with \"grml nodma\"
995
996 Still problems?
997 ===============
998 Make sure the ISO itself is ok.
999 Check the md5sum of downloaded ISO.
1000 Used a CD-RW? Make sure the medium is ok!
1001
1002 Please report any problems you notice to the grml-team!
1003 http://grml.org/contact/
1004 "
1005  echo "${RED}Now dropping you to the busybox shell.${NORMAL}"
1006  echo "${RED}Press reset button to quit.${NORMAL}"
1007  echo ""
1008  PS1="grml# "
1009  export PS1
1010  echo "6" > /proc/sys/kernel/printk
1011  # Allow signals
1012  trap 1 2 3 15
1013  exec /static/sh
1014 fi
1015 # EOF