802db3894627721e837bedf9454168f5b75e7908
[grml-autoconfig.git] / autoconfig.functions
1 #!/bin/zsh
2 # Filename:      autoconfig.functions
3 # Purpose:       basic system configuration and hardware setup for grml system
4 # Authors:       grml-team (grml.org), (c) Michael Prokop <mika@grml.org>
5 # Bug-Reports:   see http://grml.org/bugs/
6 # License:       This file is licensed under the GPL v2.
7 ################################################################################
8
9 # {{{ path, variables, signals, umask, zsh
10 export PATH="/bin:/sbin:/usr/bin:/usr/sbin"
11 DEBUG="/dev/null"
12 KERNEL="$(uname -r)"
13 ARCH="$(uname -m)"
14 umask 022
15
16 # old linuxrc version:
17 [ -d /cdrom ]      && export LIVECD_PATH=/cdrom
18 # initramfs layout until around December 2012:
19 [ -d /live/image ] && export LIVECD_PATH=/live/image
20 # initramfs layout since around December 2012:
21 [ -d /lib/live/mount/medium ] && export LIVECD_PATH=/lib/live/mount/medium
22
23 # Ignore these signals in non-interactive mode: INT, TERM, SEGV
24 [ -z "$PS1" ] && trap "" 2 3 11
25
26 if [ "$(cat /proc/1/comm 2>/dev/null)" = "systemd" ] ; then
27   SYSTEMD=true
28 else
29   SYSTEMD=false
30 fi
31
32 service_wrapper() {
33   if [ "$#" -lt 2 ] ; then
34     echo "Usage: service_wrapper <service> <action>" >&2
35     return 1
36   fi
37
38   local service="$1"
39   local action="$2"
40
41   if $SYSTEMD ; then
42     systemctl "$action" "$service"
43   else
44     /etc/init.d/"$service" "$action"
45   fi
46 }
47
48 # zsh stuff
49 iszsh(){
50 if [ -n "$ZSH_VERSION" ] ; then
51   return 0
52 else
53   return 1
54 fi
55 }
56 # avoid 'no matches found: ...'
57 iszsh && setopt no_nomatch # || echo "Warning: not running under zsh!"
58 # }}}
59
60 # {{{ Read in boot parameters
61 if [ -z "$CMDLINE" ]; then
62   # if CMDLINE was set from the outside, we're debugging.
63   # otherwise, take CMDLINE from Kernel and config files.
64   CMDLINE="$(cat /proc/cmdline)"
65   [ -d ${LIVECD_PATH}/bootparams/ ] && CMDLINE="$CMDLINE $(cat ${LIVECD_PATH}/bootparams/* | tr '\n' ' ')"
66   modprobe 9p 2>/dev/null || true
67   if grep -q 9p /proc/filesystems ; then
68       TAG="grml-parameters"
69       if grep -q "$TAG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then
70           MOUNTDIR="$(mktemp -d)"
71           mount -t 9p -o trans=virtio,ro "$TAG" "$MOUNTDIR"
72           CMDLINE="$CMDLINE $(cat "$MOUNTDIR"/* 2>/dev/null | tr '\n' ' ')"
73           umount "$MOUNTDIR"
74           rmdir "$MOUNTDIR"
75       fi
76   fi
77 fi
78 # }}}
79
80 ### {{{ Utility Functions
81
82 # Get a bootoption's parameter: read boot command line and either
83 # echo last parameter's argument or return false.
84 getbootparam(){
85   local line
86   local ws
87   ws='   '
88   line=" $CMDLINE "
89   case "$line" in
90     *[${ws}]"$1="*)
91       result="${line##*[$ws]$1=}"
92       result="${result%%[$ws]*}"
93       echo "$result"
94       return 0 ;;
95     *) # no match?
96       return 1 ;;
97   esac
98 }
99
100 # Check boot commandline for specified option
101 checkbootparam(){
102   [ -n "$1" ] || ( echo "Error: missing argument to checkbootparam()" ; return 1 )
103   local line
104   local ws
105   ws='   '
106   line=" $CMDLINE "
107   case "$line" in
108     *[${ws}]"$1"=*|*[${ws}]"$1"[${ws}]*)
109       return 0 ;;
110     *)
111       return 1 ;;
112   esac
113 }
114
115 # Check if currently using a framebuffer
116 hasfb() {
117     [ -e /dev/fb0 ] && return 0 || return 1
118 }
119
120 # Check wheter a configuration variable (like $CONFIG_TOHD) is
121 # enabled or not
122 checkvalue(){
123   case "$1" in
124     [yY][eE][sS])     return 0 ;; # it's set to 'yes'
125     [tT][rR][uU][eE]) return 0 ;; # it's set to 'true'
126                    *) return 1 ;; # default
127   esac
128 }
129
130 # Are we using grml-small?
131 checkgrmlsmall(){
132   grep -q small /etc/grml_version 2>>$DEBUG && return 0 || return 1
133 }
134
135 # if no password is set return a random password
136 set_passwd() {
137   [ -n "$PASSWD" ] && return 0
138
139   if [ -x /usr/bin/apg ] ; then
140     PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
141   elif [ -x /usr/bin/gpw ] ; then
142     PASSWD="$(gpw 1)"
143   elif [ -x /usr/bin/pwgen ] ; then
144     PASSWD="$(pwgen -1 8)"
145   elif [ -x /usr/bin/hexdump ] ; then
146     PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
147   elif [ -n "$RANDOM" ] ; then
148     PASSWD="grml${RANDOM}"
149   else
150     PASSWD=''
151     eerror "Empty passphrase and neither apg, gpw, pwgen, hexdump nor \$RANDOM available. Skipping."
152     eend 1
153     return 1
154   fi
155 }
156
157 ### }}}
158
159 # {{{ filesystems (proc, pts, sys) and fixes
160 mount_proc(){
161   [ -f /proc/version ] || mount -t proc /proc /proc 2>/dev/null
162 }
163
164 mount_pts(){
165   grep -q "/dev/pts" /proc/mounts || mount -t devpts /dev/pts /dev/pts 2>/dev/null
166 }
167
168 mount_sys(){
169   [ -d /sys/devices ] || mount -t sysfs /sys /sys 2>/dev/null
170 }
171 # }}}
172
173 # {{{ Check if we are running in live mode or from HD
174 INSTALLED=""
175 [ -e /etc/grml_cd ] || INSTALLED="yes"
176 # }}}
177
178 # {{{ provide information about virtual environments
179 VIRTUAL=false # assume physical system by default
180 KVM=false
181 VIRTUALBOX=false
182 VMWARE=false
183
184 if vmware-detect &>/dev/null; then
185   VIRTUAL=true; VMWARE=true; VIRTUAL_ENV='VMware'
186 elif [ "$(virt-what 2>/dev/null)" = "kvm" ] || \
187    [ "$(imvirt 2>/dev/null)" = "KVM" ] ; then
188   VIRTUAL=true; KVM=true; VIRTUAL_ENV='KVM'
189 elif [ "$(virt-what 2>/dev/null)" = "virtualbox" ] || \
190    [ "$(imvirt 2>/dev/null)" = "VirtualBox" ] ; then
191   VIRTUAL=true; VIRTUALBOX=true; VIRTUAL_ENV='VirtualBox'
192 fi
193 # }}}
194
195 # {{{ source lsb-functions , color handling
196 if checkbootparam 'nocolor'; then
197   . /etc/grml/lsb-functions
198   einfo "Disabling colors in bootsequence as requested on commandline." ; eend 0
199 else
200   . /etc/grml/lsb-functions
201 fi
202 # }}}
203
204 # {{{ debug
205 config_debug(){
206  checkbootparam 'debug'            && BOOTDEBUG="yes"
207  checkbootparam "BOOT_IMAGE=debug" && BOOTDEBUG="yes"
208
209  rundebugshell(){
210   if [ -n "$BOOTDEBUG" ]; then
211      einfo "Starting intermediate shell stage $stage as requested by \"debug\" option."
212      if [ grep -q "debug=noscreen" "$CMDLINE" ] ; then
213         einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
214         einfo "Just exit the shell to continue boot process..."
215         /bin/zsh
216      else
217         eindent
218         if [ -r /etc/grml/screenrc ] ; then
219            einfo "Starting GNU screen to be able to use a full featured shell environment."
220            einfo "Just exit the shells (and therefore screen) to continue boot process..."
221            /bin/zsh -c "screen -c /etc/grml/screenrc"
222         else
223            einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!"
224            einfo "Just exit the shell to continue boot process..."
225            /bin/zsh
226         fi
227         eoutdent
228      fi
229   fi
230  }
231 }
232 # }}}
233
234 # {{{ log
235 config_log(){
236 if checkbootparam 'log' || checkbootparam 'debug' ; then
237    export DEBUG="/tmp/grml.log.`date +%Y%m%d`"
238    touch $DEBUG
239    einfo "Bootparameter log found. Log files: ${DEBUG} and /var/log/boot"
240    eindent
241      einfo "Starting bootlogd." # known to be *very* unreliable :(
242      bootlogd -r -c >>$DEBUG 2>&1 ; eend $?
243    eoutdent
244 else
245    DEBUG="/dev/null"
246 fi
247 }
248 # }}}
249
250 ### {{{ language configuration / localization
251 config_language(){
252
253  einfo "Activating language settings:"
254  eindent
255
256  # people can specify $LANGUAGE and $CONSOLEFONT in a config file
257  [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
258
259  # check for bootoption which overrides config from /etc/grml/autoconfig
260  BOOT_LANGUAGE="$(getbootparam 'lang' 2>>$DEBUG)"
261  [ -n "$BOOT_LANGUAGE" ] && LANGUAGE="$BOOT_LANGUAGE"
262
263  # set default to 'en' in live-cd mode iff $LANGUAGE is not set yet
264  if [ -z "$INSTALLED" ] ; then
265     [ -n "$LANGUAGE" ] || LANGUAGE='en'
266  fi
267
268  if [ -x /usr/sbin/grml-setlang ] ; then
269    # if bootoption lang is used update /etc/default/locale accordingly
270    if [ -n "$BOOT_LANGUAGE" ] ; then
271      /usr/sbin/grml-setlang "$LANGUAGE"
272    # otherwise default to lang=en
273    else
274      /usr/sbin/grml-setlang "en"
275    fi
276  fi
277
278  # set console font
279  if [ -z "$CONSOLEFONT" ] ; then
280     if ! checkbootparam 'nodefaultfont' >>$DEBUG 2>&1 ; then
281        if [ -r /usr/share/consolefonts/Uni3-Terminus16.psf.gz ] ; then
282           CONSOLEFONT='Uni3-Terminus16'
283        else
284           ewarn "/usr/share/consolefonts/Uni3-Terminus16.psf.gz not available. Please upgrade package console-terminus." ; eend 1
285        fi
286        if ! hasfb ; then
287           CONSOLEFONT='Lat15-Terminus16'
288        fi
289     fi
290  fi
291
292  # export it now, so error messages get translated, too
293  [ -r /etc/default/locale ] && . /etc/default/locale
294  export LANG LANGUAGE
295
296  # configure keyboard layout, read in already set values first:
297  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
298
299  # now allow keyboard override by boot commandline for later use:
300  KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
301  [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
302  # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
303  [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
304  [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
305
306  # modify /etc/sysconfig/keyboard only in live-cd mode:
307  if [ -z "$INSTALLED" ] ; then
308
309    local LANGUAGE="$BOOT_LANGUAGE"
310    . /etc/grml/language-functions
311    # allow setting xkeyboard explicitly different than console keyboard
312    KXKEYBOARD="$(getbootparam 'xkeyboard' 2>>$DEBUG)"
313    if [ -n "$KXKEYBOARD" ]; then
314       XKEYBOARD="$KXKEYBOARD"
315       KDEKEYBOARD="$KXKEYBOARD"
316    elif [ -n "$KKEYBOARD" ]; then
317       XKEYBOARD="$KKEYBOARD"
318       KDEKEYBOARD="$KKEYBOARD"
319    fi
320
321    # duplicate of previous code to make sure /etc/grml/language-functions
322    # does not overwrite our values....
323    # now allow keyboard override by boot commandline for later use:
324    KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
325    [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
326    # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
327    [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
328    [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
329
330    # write keyboard related variables to file for later use
331    [ -d /etc/sysconfig ] || mkdir /etc/sysconfig
332    if ! [ -e /etc/sysconfig/keyboard ] ; then
333       echo "KEYTABLE=\"$KEYTABLE\""          > /etc/sysconfig/keyboard
334       echo "XKEYBOARD=\"$XKEYBOARD\""       >> /etc/sysconfig/keyboard
335       echo "KDEKEYBOARD=\"$KDEKEYBOARD\""   >> /etc/sysconfig/keyboard
336       echo "KDEKEYBOARDS=\"$KDEKEYBOARDS\"" >> /etc/sysconfig/keyboard
337    fi
338  fi
339
340  [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
341
342  # activate unicode console if running within utf8 environment
343  if [ -r /etc/default/locale ] ; then
344     if grep -q "LANG=.*UTF" /etc/default/locale ; then
345        einfo "Setting up unicode environment."
346        unicode_start >>$DEBUG 2>&1 ; eend $?
347     fi
348  fi
349
350  # Set default keyboard before interactive setup
351  if [ -n "$KEYTABLE" ] ; then
352     einfo "Running loadkeys for ${WHITE}${KEYTABLE}${NORMAL} in background"
353     loadkeys -q $KEYTABLE &
354     eend $?
355  fi
356
357  # we have to set up all consoles, therefore loop it over all ttys:
358  NUM_CONSOLES=$(fgconsole --next-available 2>/dev/null)
359  if [ -n "$NUM_CONSOLES" ] ; then
360     NUM_CONSOLES=$(expr ${NUM_CONSOLES} - 1)
361     [ ${NUM_CONSOLES} -eq 1 ] && NUM_CONSOLES=6
362  fi
363  CUR_CONSOLE=$(fgconsole 2>/dev/null)
364
365  if [ -x "$(which setfont)" ] ; then
366     use_setfont=true
367  elif [ -x "$(which consolechars)" ] ; then
368     use_consolechars=true
369  else
370     eerror "Neither setfont nor consolechars tool present, can not set font."
371     eend 1
372     return 1
373  fi
374
375  if [ -n "$CHARMAP" ] ; then
376     einfo "Setting font to ${CHARMAP}"
377     RC=0
378     for vc in $(seq 0 ${NUM_CONSOLES}) ; do
379         if $use_setfont ; then
380           setfont -C /dev/tty${vc} $CHARMAP ; RC=$?
381         elif $use_consolechars ; then
382           consolechars --tty=/dev/tty${vc} -m ${CHARMAP} ; RC=$?
383         fi
384     done
385     if [ -n "$CUR_CONSOLE" ] ; then
386        [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
387     fi
388     eend $RC
389  fi
390
391  if checkbootparam 'noconsolefont' ; then
392     ewarn "Skipping setting console font as requested on boot commandline." ; eend 0
393  else
394     if [ -n "$CONSOLEFONT" ] ; then
395        einfo "Setting font to ${CONSOLEFONT}"
396        RC=0
397        for vc in $(seq 0 ${NUM_CONSOLES}) ; do
398            if $use_setfont ; then
399              setfont -C /dev/tty${vc} ${CONSOLEFONT} ; RC=$?
400            elif $use_consolechars ; then
401              consolechars --tty=/dev/tty${vc} -f ${CONSOLEFONT} ; RC=$?
402            fi
403        done
404        if [ -n "$CUR_CONSOLE" ] ; then
405           [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
406        fi
407        eend $RC
408     fi
409  fi
410
411  eoutdent
412 }
413 # }}}
414
415 # {{{ Set hostname
416 config_hostname(){
417   if ! checkbootparam 'hostname' ; then
418     return 0
419   fi
420
421   HOSTNAME="$(getbootparam 'hostname' 2>>$DEBUG)"
422   if [ -z "$HOSTNAME" ] && [ -x /usr/bin/random-hostname ] ; then
423     einfo "Generating random hostname as no hostname was specified."
424     HOSTNAME="$(/usr/bin/random-hostname)"
425     eend $?
426   fi
427
428   einfo "Setting hostname to $HOSTNAME as requested."
429   grml-hostname $HOSTNAME >>$DEBUG
430   eend $?
431 }
432 # }}}
433
434 # fstabuser (needed when running from harddisk with username != grml {{{
435 config_userfstab(){
436   # force load of build-in and local config
437   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
438   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig.local
439
440   # 1st. try configured fstab user
441   if [ -n "$CONFIG_FSTAB_USER" ] ; then
442      fstabuser=$(getent passwd $CONFIG_FSTAB_USER | cut -d: -f1)
443   fi
444
445   # 2nd. use standard user id
446   [ -n "$fstabuser" ] || fstabuser=$(getent passwd 1000 | cut -d: -f1)
447
448   # 3rd. use standard user name
449   [ -n "$fstabuser" ] || fstabuser=$(getent passwd grml | cut -d: -f1)
450
451   # if not yet set fall back to 'root' user, avoid bad /etc/fstab
452   [ -n "$fstabuser" ] || fstabuser='root'
453 }
454 # }}}
455
456 # local_user (needed when running with username != grml {{{
457 config_userlocal() {
458
459   # force load of build-in and local config
460   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
461   [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig.local
462
463   # 1st. try id of primary user
464   localuser=$(getent passwd 1000 | cut -d: -f1)
465
466   # 2nd. use name standard user
467   [ -n "$localuser" ] || localuser=$(getent passwd grml | cut -d: -f1)
468 }
469 # }}}
470
471 # {{{ Set clock (Local time is more often used than GMT, so it is default)
472 config_time(){
473  # don't touch the files if running from harddisk:
474  if [ -z "$INSTALLED" ]; then
475     # The default hardware clock timezone is stated as representing local time.
476     UTC="--localtime"
477
478     if [ -f /etc/default/rcS ] ; then
479       grep -q "^UTC=" /etc/default/rcS || echo "UTC=no" >> /etc/default/rcS
480       checkbootparam 'utc'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
481       checkbootparam 'gmt'       >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
482       checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=no|"  /etc/default/rcS
483       grep -q -i "^UTC=yes" /etc/default/rcS && UTC="-u"
484     # recent initscripts package versions don't ship /etc/default/rcS anymore, instead rely on /etc/adjtime
485     elif [ -f /etc/adjtime ] ; then
486       checkbootparam 'utc'       >>$DEBUG 2>&1 && sed -i "s/^LOCAL/UTC/" /etc/adjtime
487       checkbootparam 'gmt'       >>$DEBUG 2>&1 && sed -i "s/^LOCAL/UTC/" /etc/adjtime
488       checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s/^UTC$/LOCAL/" /etc/adjtime
489       grep -q "^UTC$" /etc/adjtime && UTC="-u"
490     fi
491
492     # hwclock uses the TZ variable
493     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
494     [ -z "$KTZ" ] && [ -r /etc/timezone ] && KTZ=$(cat /etc/timezone)
495     if [ ! -f "/usr/share/zoneinfo/$KTZ" ] ; then
496        ewarn "Warning: unknown timezone $KTZ" ; eend 1
497        KTZ="UTC"
498        ewarn "Falling back to timezone $KTZ" ; eend 0
499     fi
500
501     if ! [ -r /dev/rtc ] ; then
502       ewarn "Warning: realtime clock not available, trying to execute hwclock anyway." ; eend 0
503     fi
504
505     ERROR=$(TZ="$KTZ" hwclock $UTC -s 2>&1 | head -1) ; RC=$?
506     if [ -n "$ERROR" ] ; then
507        eindent
508        ERROR=$(TZ="$KTZ" hwclock $UTC -s --directisa 2>&1 | head -1)
509        if [ -n "$ERROR" ] ; then
510           eerror "Problem running hwclock: $ERROR" ; eend 1
511        fi
512        eoutdent
513     fi
514
515  fi
516 }
517 # }}}
518
519 # {{{ print kernel info
520 config_kernel(){
521   if $VIRTUAL && [ -n "$VIRTUAL_ENV" ] ; then
522     einfo "Running Linux Kernel $KERNEL inside $VIRTUAL_ENV" ; eend 0
523   else
524     einfo "Running Linux Kernel $KERNEL" ; eend 0
525   fi
526
527   if [ -r /proc/cpuinfo ] ; then
528     if egrep -q '^flags.*(vmx|svm)' /proc/cpuinfo ; then
529       eindent
530       einfo 'CPU(s) featuring virtualization technology detected' ; eend 0
531       eoutdent
532     fi
533   fi
534
535   if [ -d /proc/xen ] ; then
536     eindent
537     einfo 'Running kernel featuring support for Xen detected' ; eend 0
538     eoutdent
539   fi
540 }
541 # }}}
542
543 # {{{ timezone
544 config_timezone(){
545  # don't touch the files if running from harddisk:
546  if [ -z "$INSTALLED" ]; then
547     KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
548     if [ -n "$KTZ" ] ; then
549        if [ ! -f "/usr/share/zoneinfo/$KTZ" ]
550        then
551           ewarn "Warning: unknown timezone $KTZ"; eend 0
552        else
553           einfo "Setting timezone."
554           # update debconf
555           area=$(echo $KTZ | cut -d '/' -f1)
556           zone=$(echo $KTZ | cut -d '/' -f2)
557           echo "tzdata tzdata/Areas       select $area" | debconf-set-selections
558           echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections
559           # update files
560           echo $KTZ > /etc/timezone
561           rm -f /etc/localtime
562           cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $?
563        fi
564     fi
565  fi
566 }
567 # }}}
568
569 # activate serial console {{{
570 config_console(){
571 if checkbootparam 'console'; then
572   local line
573   local ws
574   ws='   '
575
576   einfo "Bootoption for serial console detected:"
577
578   line="$CMDLINE x "
579   this=""
580   line="${line#*[$ws]}"
581   local telinitq=""
582   while [ -n "$line" ]; do
583     case "$this" in
584       console=*)
585         local serial="$this"
586         local device="${this%%,*}"
587         local device="${device##*=}"
588         if echo $serial | grep -q ttyS ; then
589           local option="${serial##*,}"
590           # default (works for kvm & CO):
591           local speed="115200,57600,38400,19200,9600,4800,2400,1200";
592           # ... unless overriden by command line:
593           case "$option" in
594             115200*) speed=115200 ;;
595              57600*) speed=57600 ;;
596              38400*) speed=38400 ;;
597              19200*) speed=19200 ;;
598               9600*) speed=9600 ;;
599               4800*) speed=4800 ;;
600               2400*) speed=2400 ;;
601               1200*) speed=1200 ;;
602           esac
603           eindent
604             einfo "Activating console login on device ${device} with speed ${speed}."
605             local number="${device#ttyS}"
606             sed -i "/^T$number:/d;/^#grmlserial#/iT$number:23:respawn:/bin/bash -c \"/sbin/getty -L $device -l /usr/share/grml-scripts/run-welcome $speed vt100 || sleep 30\"" /etc/inittab
607             eend $?
608             telinitq="1"
609           eoutdent
610         fi
611         ;;
612     esac
613     this="${line%%[$ws]*}"
614     line="${line#*[$ws]}"
615   done
616
617   if [ -n "$telinitq" ]; then
618     /sbin/telinit q
619   fi
620   eend $?
621 fi
622 }
623 # }}}
624
625 # {{{ CD Checker
626 config_testcd(){
627 if checkbootparam 'testcd' ; then
628   einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
629   eindent
630
631   local ERROR=true
632   local FOUND_FILE=false
633   local logfile='/tmp/md5sum.log'
634
635   rm -f "$logfile"
636
637   for md5 in $(find "${LIVECD_PATH}" -name md5sums) ; do
638     einfo "Checking files against $md5, this may take a while..."
639
640     FOUND_FILE=true
641     OLD_PWD=$(pwd)
642     cd $(dirname "$md5")
643     md5sum -c $(basename "$md5") |& tee -a "${logfile}"
644     if [ $pipestatus[1] -eq 0 ] ; then
645       ERROR=false
646     fi
647     cd "${OLD_PWD}"
648   done
649
650   if ! $FOUND_FILE ; then
651     eerror 'Error: Could not find md5sum file' ; eend 1
652     return
653   fi
654
655   if ! $ERROR ; then
656     einfo "Everything looks OK" ; eend 0
657   else
658     eerror 'Checksum failed for theses files:' ; eend 1
659     egrep -v '(^md5sum:|OK$)' "${logfile}"
660     eerror 'Data on the medium is possibly incomplete/damaged or RAM of your system is broken.' ; eend 1
661     einfon "Hit return to continue, or press the power button to shut down system."
662     read a
663   fi
664
665   eoutdent
666 fi
667 }
668 # }}}
669
670 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
671 config_blacklist(){
672 if checkbootparam 'blacklist' ; then
673  if [ -z "$INSTALLED" ]; then
674   einfo "Bootoption blacklist found."
675   BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
676   BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
677   if [ -n "$BLACK" ] ; then
678     for module in $(echo ${BLACK//,/ }) ; do
679         einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
680         echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
681         echo "blacklist $module"     >> "$BLACKLIST_FILE"
682         echo "alias     $module off" >> "$BLACKLIST_FILE"
683         echo "# end   entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
684     done
685   else
686    eerror "No given module for blacklist found. Blacklisting will not work therefore."
687   fi
688  else
689   ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
690   eindent
691    einfo "Please blacklist the module(s) manually using the 'blacklist' script."
692   eoutdent
693  fi
694 fi
695 }
696 # }}}
697
698 # {{{ ACPI
699 config_acpi(){
700   if $SYSTEMD ; then
701     echo "systemd detected, no acpi(d) stuff needed." >>"$DEBUG"
702     return
703   fi
704
705   if checkbootparam 'noacpi'; then
706     ewarn "ACPI: Not loading modules as requested by boot option \"noacpi\"." ; eend 0
707   elif checkbootparam 'nogrmlacpi' ; then
708     ewarn "ACPI: Not loading modules as requested by boot option \"nogrmlacpi\"." ; eend 0
709   elif [ ! -d /proc/acpi ] ; then
710     ewarn "ACPI: Kernel support not present." ; eend 0
711   else
712     einfo "ACPI: Loading modules (disable with boot option noacpi / nogrmlacpi): "
713     eindent
714     found=""
715     for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
716       basename="${a##*/}"
717       basename="${basename%%.*}"
718       case "$basename" in *_acpi)
719         egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
720     esac
721     modprobe $basename >>$DEBUG 2>&1 && found="yes"
722     local BASE="$BASE $basename"
723   done
724   if [ -n "$found" ] ; then
725     einfo "$BASE"  ; eend 0
726   else
727     ewarn "(none)" ; eend 1
728   fi
729   if ! pgrep acpid >/dev/null ; then
730     einfo "Starting acpi daemon."
731     service_wrapper acpid.socket start >>$DEBUG 2>&1 ; eend $?
732     service_wrapper acpid start >>$DEBUG 2>&1 ; eend $?
733   else
734     ewarn "acpi daemon already running."
735     eend 0
736   fi
737   eoutdent
738 fi
739 }
740 # }}}
741
742 # {{{ Start brltty
743 config_brltty() {
744   if checkbootparam 'brltty' ; then
745     [ -x /lib/brltty/brltty.sh ] && /lib/brltty/brltty.sh
746   fi
747 }
748 # }}}
749
750 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
751 config_fstab(){
752
753 NOSWAP="yes" # we do not use swap by default!
754 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
755    NOSWAP=''
756    checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
757 fi
758
759 # Scan for swap, config, homedir - but only in live-mode
760 if [ -z "$INSTALLED" ] ; then
761    [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
762    GRML_IMG=""
763    GRML_SWP=""
764    HOMEDIR="$(getbootparam 'home')"
765    if [ -n "$partitions" ]; then
766       while read p m f relax; do
767         case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
768         partoptions="users,exec"
769         fnew=""
770         # it's a swap partition?
771         case "$f" in swap)
772           eindent
773           if [ -n "$NOSWAP" ]; then
774              ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
775              eend 0
776           else
777              case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
778                    S1SUSP|S2SUSP|pmdisk|[zZ]*)
779                      if [ -n "$ANYSWAP" ] ; then
780                         einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
781                         swapon $p 2>>$DEBUG ; eend $?
782                      else
783                         ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
784                      fi
785                      ;;
786                    *)
787                      if [[ "$p" == LABEL* ]] ; then
788                         p=$(blkid -t $p | awk -F: '{print $1}')
789                      fi
790                      if grep -q $p /proc/swaps ; then
791                         ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
792                      else
793                         if [ -b "$p" ] ; then
794                         einfo "Using swap partition ${WHITE}${p}${NORMAL}."
795                         swapon $p 2>>$DEBUG ; eend $?
796                         else
797                         ewarn "$p is not a valid block device - not using it therefore." ; eend 0
798                         fi
799                      fi
800                      ;;
801              esac # dd-check
802           fi # -n "$NOSWAP
803           eoutdent
804           continue
805           ;;
806         esac # it's a swap partition?
807
808         # mount read-only
809         MOUNTOPTS="ro"
810         case "$f" in
811           vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
812           ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
813           *) continue ;;
814           # *) NONEFOUND='1'; continue ;;
815         esac
816
817         # use a swapfile
818         if [ -z "$NOSWAP" ] ; then
819            mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
820            # Activate swapfile, if exists
821            SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
822         fi
823         if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
824            mount -o remount,rw $m && MOUNTED=1
825            if swapon "$SWAPFILE" 2>>$DEBUG ; then
826               eindent
827                 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
828               eoutdent
829               fnew="$SWAPFILE swap swap defaults 0 0"
830               grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
831               GRML_SWP="$GRML_SWP $SWAPFILE"
832               eend 0
833            fi
834            mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
835         fi
836
837         # use a image as home
838         IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
839         if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
840            if [ -n "$HOMEDIR" ]; then
841               if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
842                  continue
843               fi
844            fi
845            if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
846               GRML_IMG="$IMAGE"
847               mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
848            fi
849         fi
850         eend 0
851
852         # Umount, if not in use
853         [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
854
855       done <<EOT
856       $(cat /etc/fstab)
857 EOT
858    fi # -n $partitions
859 fi # -z $INSTALLED
860 }
861 # }}}
862
863 # {{{ CPU-detection
864 config_cpu(){
865 if checkbootparam 'nocpu'; then
866   ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
867   return 0
868 fi
869
870 if [[ $(grep -c processor /proc/cpuinfo) -gt 1 ]] ; then
871    einfo "Found CPU:"
872    CPU=$(awk -F: '/^processor/{printf " Processor"$2" is"};/^model name/{printf $2};/^vendor_id/{printf vendor};/^cpu MHz/{printf " %dMHz",int($2)};/^cache size/{printf ","$2" Cache"};/^$/{print ""}' /proc/cpuinfo 2>>$DEBUG)
873    echo $CPU | sed 's/ \{1,\}/ /g'
874    eend 0
875 else
876    einfo "Found CPU: `awk -F: '/^processor/{printf " Processor"$2" is"};/^model name/{printf $2};/^vendor_id/{printf vendor};/^cpu MHz/{printf " %dMHz",int($2)};/^cache size/{printf ","$2" Cache"};/^$/{print ""}' /proc/cpuinfo 2>>$DEBUG` " ; eend 0
877 fi
878
879 # no cpufreq setup inside VirtualBox
880 if $VIRTUALBOX ; then
881    einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0
882    return 0
883 fi
884
885 if ! [ -x /etc/init.d/loadcpufreq ] ; then
886   ewarn "loadcpufreq init script not available, ignoring cpu frequency scaling."
887   eend 0
888   return 0
889 else
890    einfo "Trying to set up cpu frequency scaling:"
891    eindent
892    SKIP_CPU_GOVERNOR=''
893    LOADCPUFREQ=$(mktemp)
894    /etc/init.d/loadcpufreq start >"$LOADCPUFREQ" 2>&1 ; RC=$?
895    if grep -q FATAL "$LOADCPUFREQ" ; then
896       eindent
897         SKIP_CPU_GOVERNOR=1
898         oldIFS="$IFS"
899         IFS="
900 "
901          for line in $(grep FATAL "$LOADCPUFREQ" | sed 's/.*FATAL: //; s/ (.*)//') ; do
902              eerror "$line" ; eend $RC
903          done
904          IFS="$oldIFS"
905       eoutdent
906    elif grep -q done "$LOADCPUFREQ" ; then
907       MODULE=$(grep done "$LOADCPUFREQ" | sed 's/.*done (\(.*\))./\1/')
908       if [ -n "$MODULE" -a "$MODULE" != none ]; then
909          einfo "Loading cpufreq kernel module $MODULE" ; eend 0
910       else
911          SKIP_CPU_GOVERNOR=1
912          ewarn "Could not find an appropriate kernel module for cpu frequency scaling." ; eend 1
913       fi
914    fi
915
916    rm -f "$LOADCPUFREQ"
917
918    if [ -z "$SKIP_CPU_GOVERNOR" ] ; then
919      if [ -r /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors ] ; then
920        if ! grep -q ondemand /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors ; then
921          einfo "Ondemand governor not available for CPU(s), not modifying governor configuration"
922        else
923          einfo "Setting ondemand governor"
924          RC=0
925          for file in $(find /sys/devices/system/cpu/ -name scaling_governor 2>/dev/null) ; do
926            echo ondemand > $file || RC=1
927          done
928          eend $RC
929        fi
930      fi
931    fi
932
933    eoutdent
934 fi
935 }
936 # }}}
937
938 # {{{ autostart of ssh
939 config_ssh(){
940 if checkbootparam 'ssh' ; then
941    local PASSWD
942    PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
943
944    config_userlocal
945    einfo "Bootoption ssh found, trying to set password for root and user $localuser"
946    [ -z "$localuser" ] && eend 1
947
948    eindent
949    if [ -z "$PASSWD" ] ; then
950      set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0
951    fi
952    eoutdent
953
954    if [ -n "$PASSWD" ] ; then
955       chpass_options=""
956       if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
957         chpass_options="-m"
958       fi
959
960       echo "$localuser:$PASSWD" | chpasswd $chpass_options
961       echo "root:$PASSWD" | chpasswd $chpass_options
962
963       eindent
964       ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
965       eoutdent
966    fi
967
968    einfo "Starting secure shell server in background for root and user $localuser"
969    service_wrapper rmnologin start >>$DEBUG 2>>$DEBUG
970    service_wrapper ssh start >>$DEBUG 2>>$DEBUG &
971    eend $?
972
973 fi
974 }
975
976 # }}}
977
978 # {{{ display hostkeys of SSH server
979 config_display_ssh_fingerprints() {
980   if ! ls /etc/ssh/ssh_host_\*_key >/dev/null 2>&1 ; then
981     return 0 # no SSH host keys present
982   fi
983
984   einfo "SSH key fingerprints:"
985   for file in /etc/ssh/ssh_host_*_key ; do
986     einfon
987     ssh-keygen -l -f $file
988   done | column -t
989   eend $?
990 }
991 # }}}
992
993 # {{{ autostart of x11vnc
994 config_vnc(){
995 if checkbootparam 'vnc' ; then
996    config_userlocal
997    VNC_PASSWD=''
998    VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)"
999    einfo "Bootoption vnc found, trying to set password for user $localuser."
1000    eindent
1001    if [ -z "$VNC_PASSWD" ] ; then
1002       if [ -x /usr/bin/apg ] ; then
1003          VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
1004       elif [ -x /usr/bin/gpw ] ; then
1005          VNC_PASSWD="$(gpw 1)"
1006       elif [ -x /usr/bin/pwgen ] ; then
1007          VNC_PASSWD="$(pwgen -1 8)"
1008       elif [ -x /usr/bin/hexdump ] ; then
1009          VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1010       elif [ -n "$RANDOM" ] ; then
1011          VNC_PASSWD="${localuser}${RANDOM}"
1012       else
1013          VNC_PASSWD=''
1014          eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1015          eend 1
1016       fi
1017
1018       if [ -n "$VNC_PASSWD" ] ; then
1019          ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0
1020       fi
1021    fi
1022    eoutdent
1023
1024    # finally check if we have a password we can use:
1025    if [ -n "$VNC_PASSWD" ] ; then
1026
1027       VNCDIR="/home/${localuser}/.vnc"
1028       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1029
1030       if [ ! -x /usr/bin/x11vnc ] ; then
1031          eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package."
1032          eend 1
1033       else
1034          /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $?
1035          /bin/chown -R "$localuser": "$VNCDIR"
1036       fi
1037    fi
1038    if checkbootparam 'vnc_connect' ; then
1039       VNC_CONNECT=''
1040       VNC_CONNECT="$(getbootparam 'vnc_connect' 2>>$DEBUG)"
1041       einfo "Bootoption vnc_connect found, will start vnc with connect to $VNC_CONNECT."
1042       #store the options in a file
1043       VNCDIR="/home/${localuser}/.vnc"
1044       [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1045       echo " --connect $VNC_CONNECT " >> $VNCDIR/options
1046    fi
1047 fi
1048 }
1049 # }}}
1050
1051 # {{{ set password for root and default user
1052 config_passwd(){
1053 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1054   local PASSWD
1055   PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1056
1057   config_userlocal
1058   einfo "Bootoption passwd found, trying to set password for root and user $localuser"
1059   [ -z "$localuser" ] && eend 1
1060
1061   eindent
1062   if [ -z "$PASSWD" ] ; then
1063     set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0
1064   fi
1065   eoutdent
1066
1067   if [ -n "$PASSWD" ] ; then
1068     chpass_options=""
1069     if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1070       chpass_options="-m"
1071     fi
1072
1073     echo "$localuser:$PASSWD" | chpasswd $chpass_options
1074     echo "root:$PASSWD" | chpasswd $chpass_options
1075
1076     eindent
1077     ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
1078     eoutdent
1079   fi
1080
1081 fi
1082
1083 if checkbootparam 'encpasswd' >>$DEBUG 2>&1; then
1084   local PASSWD
1085   PASSWD="$(getbootparam 'encpasswd' 2>>$DEBUG)"
1086
1087   if [ -z "$PASSWD" ] ; then
1088     eerror "No hashed password found, can not set password."
1089     eend 1
1090     return
1091   fi
1092
1093   config_userlocal
1094   einfo "Bootoption encpasswd found, trying to set hashed password for root and user $localuser"
1095   [ -z "$localuser" ] && eend 1
1096
1097   if [ -n "$PASSWD" ] ; then
1098     chpass_options="-e"
1099
1100     echo "$localuser:$PASSWD" | chpasswd $chpass_options
1101     echo "root:$PASSWD" | chpasswd $chpass_options
1102
1103     eindent
1104     ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
1105     eoutdent
1106   fi
1107
1108 fi
1109 }
1110 # }}}
1111
1112 # {{{ Sound
1113 config_mixer () {
1114    if ! [ -x /usr/bin/amixer ] ; then
1115       eerror "amixer binary not available. Can not set sound volumes therefore."
1116       eend 1
1117    else
1118       if ! [ -r /proc/asound/cards ] ; then
1119          ewarn "No soundcard present, skipping mixer settings therefore."
1120          eend 0
1121          return
1122       fi
1123
1124       for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do
1125          einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\""
1126          eindent
1127
1128          if checkbootparam 'vol' ; then
1129             VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1130             if [ -z "$VOL" ] ; then
1131                eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)."
1132                VOL='75'
1133                eend 1
1134             fi
1135          else
1136             VOL='75'
1137          fi
1138
1139          if checkbootparam 'nosound' ; then
1140             einfo "Muting sound devices on request."
1141             ERROR=$(amixer -q set Master mute)
1142             RC=$?
1143             if [ -n "$ERROR" ] ; then
1144                eindent
1145                eerror "Problem muting sound devices: $ERROR"
1146                eoutdent
1147             fi
1148             eend $RC
1149          elif [ -z "$INSTALLED" ] ; then
1150             einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1151
1152             if checkbootparam 'micvol' ; then
1153                MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1154                einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1155             else
1156                MICVOL=0
1157             fi
1158
1159             CONTROLS=$(amixer -c $card scontrols | awk -F"Simple mixer control " '{print $2}')
1160             IFSOLD=${IFS:-}
1161             IFS='
1162 '
1163             for CONTROL in ${=CONTROLS} ; do
1164                # such devices can not be controlled with amixer ... unmute
1165                [[ "$CONTROL" == *Console* ]] && continue
1166
1167                if ! echo "${CONTROL}" | grep -q -i "mic" ; then
1168                    if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*pswitch' ; then
1169                       amixer -c $card -q set "${CONTROL}" unmute
1170                    fi
1171                    if amixer -c $card sget "${CONTROL}" | grep -q -P 'Capabilities:.*(pvolume| volume)' ; then
1172                       amixer -c $card -q set "${CONTROL}" "${VOL}"%
1173                    fi
1174                fi
1175
1176                if [ ${MICVOL} -ne 0 ] ; then
1177                   if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cswitch' ; then
1178                      amixer -c $card -q set "${CONTROL}" unmute
1179                   fi
1180                   if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cvolume' ; then
1181                      amixer -c $card -q set "${CONTROL}" $MICVOL%
1182                   fi
1183                   eend $?
1184                fi
1185             done
1186             IFS=$IFSOLD
1187          fi # checkbootparam 'nosound'
1188          eoutdent
1189       done
1190    fi
1191 }
1192 # }}}
1193
1194 # {{{ syslog service
1195 config_syslog(){
1196  if checkbootparam 'nosyslog'; then
1197     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1198  else
1199     einfo "Starting rsyslog in background."
1200     service_wrapper rsyslog start >>$DEBUG &
1201     eend 0
1202  fi
1203 }
1204 # }}}
1205
1206 # {{{ gpm
1207 config_gpm(){
1208  if checkbootparam 'nogpm'; then
1209   ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1210  else
1211    if ! [ -r /dev/input/mice ] ; then
1212       eerror "No mouse found - not starting GPM." ; eend 1
1213    else
1214       einfo "Starting gpm in background."
1215       service_wrapper gpm start >>$DEBUG &
1216       # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start >>$DEBUG ) &
1217       eend 0
1218    fi
1219  fi
1220 }
1221 # }}}
1222
1223 # {{{ services
1224 config_services(){
1225  if checkbootparam 'services' ; then
1226     SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1227     SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1228     SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1229     for service in $(echo -e $SERVICELIST) ; do
1230       # support running (custom) init scripts in non-blocking mode
1231       # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1232       if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1233         einfo "Starting service ${service}."
1234         service_wrapper "${service}" start >>$DEBUG
1235       else
1236         einfo "Starting service ${service} in background."
1237         service_wrapper "${service}" start >>$DEBUG &
1238       fi
1239     done
1240     eend $?
1241  fi
1242 }
1243 # }}}
1244
1245 # {{{ remote files
1246 get_remote_file() {
1247   [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1248   SOURCE=$(eval echo "$1")
1249   TARGET="$2"
1250   getconfig() {
1251   wget --timeout=10 --dns-timeout=10  --connect-timeout=10 --tries=1 \
1252        --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1253   }
1254   einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1255
1256   if checkbootparam 'getfile.retries' ; then
1257     local counter="$(getbootparam 'getfile.retries' 2>>$DEBUG)"
1258   else
1259     local counter=10
1260   fi
1261
1262   while ! getconfig && [[ "$counter" != 0 ]] ; do
1263     echo -n "Sleeping for 1 second and trying to get config again... "
1264     counter=$(( counter-1 ))
1265     echo "$counter tries left" ; sleep 1
1266   done
1267   if [ -s "$TARGET" ] ; then
1268     einfo "Downloading was successfull." ; eend 0
1269     einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1270     md5sum ${TARGET} ; eend 0
1271     return 0;
1272   else
1273     einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1274     return 1;
1275  fi
1276 }
1277 # }}}
1278
1279 # {{{ config files
1280 config_netconfig(){
1281  if checkbootparam 'netconfig' ; then
1282   CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1283   CONFIGFILE='/tmp/netconfig.grml'
1284
1285   if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1286     cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1287   fi
1288
1289  fi
1290 }
1291 # }}}
1292
1293 # {{{ remote scripts
1294 config_netscript() {
1295  if checkbootparam 'netscript' ; then
1296   CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1297   SCRIPTFILE='/tmp/netscript.grml'
1298
1299   if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1300     chmod +x ${SCRIPTFILE}
1301     einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1302   fi
1303
1304  fi
1305 }
1306 # }}}
1307
1308 # {{{ stats
1309 config_stats() {
1310  if ! checkbootparam 'nostats' ; then
1311    BASE_URL="http://stats.grml.org/report/"
1312    ACTION_NAME=Boot
1313
1314    HOST_ID=$(cat /proc/sys/kernel/random/boot_id)
1315
1316    grep -q " lm " /proc/cpuinfo && HAS_64BIT="1" || HAS_64BIT="0"
1317    DATE_STRING=$(date +'h=%H&m=%M&s=%S')
1318    [ -e /etc/grml_version ] && VERSION=$(cat /etc/grml_version) || \
1319      VERSION=$(lsb_release -d | awk -F: '{gsub(/^[ \t]+/, "", $2); print $2}')
1320
1321    PARAMS="$( echo "$CMDLINE" | sed -e 's/=[^ ]*/=x/g' | tr " " "\n"|sort|tr "\n" " " )"
1322
1323    echo "$CMDLINE" | grep -q -e "fetch" -e "nfsroot" && BOOT="remote"
1324    [ -z "$BOOT" ] && BOOT="local"
1325
1326    ADDITIONAL_PARAMS=""
1327    ( [ -n "$COLUMNS" ] && [ -n "$LINES" ] ) && \
1328      ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS&res=$((COLUMNS * 8))x$((LINES * 16))"
1329
1330    URI='$BASE_URL?action=${ACTION_NAME}\&$DATE_STRING\&unique_id=${HOST_ID}\&support_64bit=$HAS_64BIT\&version=$VERSION\&bootup=$BOOT\&params=$PARAMS$ADDITIONAL_PARAMS'
1331
1332    get_remote_file "$URI" "/dev/null"  >/dev/null 2>&1 &!
1333  fi
1334 }
1335 # }}}
1336
1337 # {{{ start X window system via grml-x
1338 config_x_startup(){
1339
1340   if $SYSTEMD ; then
1341     ewarn "The startx boot option isn't yet supported via systemd, sorry." ; eend 0
1342     return
1343   fi
1344
1345 # make sure we start X only if startx is used *before* a nostartx option
1346 # so it's possible to disable automatic X startup using nostart
1347 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1348  if [ -x "$(which X)" ] ; then
1349   if [ -z "$INSTALLED" ] ; then
1350    WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1351    if [ -z "$WINDOWMANAGER" ] ; then
1352      einfo "No window manager specified. Using default one." && eend 0
1353    else
1354      einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1355    fi
1356    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1357    config_userlocal
1358  cat>|/etc/init.d/xstartup<<EOF
1359 #!/bin/sh
1360 su $localuser -c "/usr/bin/grml-x ${WINDOWMANAGER}"
1361 EOF
1362    chmod 755 /etc/init.d/xstartup
1363
1364    # adjust inittab for xstartup
1365    if grep -q '^6:' /etc/inittab ; then
1366       sed -i 's|^6:.*|6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/share/grml-scripts/run-welcome" >/dev/tty6 2>\&1 </dev/tty6|' /etc/inittab
1367    else # just append tty6 to inittab if no definition is present:
1368       echo '6:2345:respawn:/bin/zsh --login -c "/etc/init.d/xstartup ; /usr/share/grml-scripts/run-welcome" >/dev/tty6 2>&1 < /dev/tty6' >> /etc/inittab
1369    fi
1370
1371    /sbin/telinit q ; eend $?
1372
1373    if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1374       sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1375    else
1376       echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1377    fi
1378
1379   else
1380     eerror "We are not running in live mode - startx will not work, skipping it."
1381     eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1382   fi
1383  else
1384    eerror "/usr/bin/X is not present on this grml flavour."
1385    eerror "  -> Boot parameter startx does not work therefore." ; eend 1
1386  fi
1387 fi
1388 }
1389 # }}}
1390
1391 # {{{ configuration framework
1392 config_extract(){
1393 if checkbootparam 'extract' ; then
1394  EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1395  EXTRACTOPTIONS="-- -x $EXTRACT"
1396 fi
1397 }
1398
1399 config_finddcsdir() {
1400 #  - If no GRMLCFG partition is found and noautoconfig is _not_ given
1401 #    on the command line, nothing is changed and the dcs files are
1402 #    searched within the .iso, $dcs-dir is set to the root directory
1403 #    within the .iso
1404 #  - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1405 #    the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1406 #    set, $dcs-dir is set to the root directory within the .iso.
1407 #  - If myconfig=foo is set on the command line, $dcs-dir is set to
1408 #    foo, even if a GRMLCFG partition is present.
1409 DCSDIR=""
1410 DCSMP="/mnt/grml"
1411 # autoconfig, see issue673
1412 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1413 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1414 if checkbootparam 'noautoconfig' ; then
1415   DCSDIR="${LIVECD_PATH}" # set default so it works for "scripts" boot option as expected
1416   ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1417 else
1418   if [ -z "$INSTALLED" ] ; then
1419     if checkbootparam 'myconfig' ; then
1420       DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1421       if [ -z "$DCSDEVICE" ]; then
1422         eerror "Error: No device for bootoption myconfig provided." ; eend 1
1423       fi # [ -z "$DCSDEVICE" ]
1424     elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1425       einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1426       eindent
1427       DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1428
1429       modprobe 9p 2>/dev/null || true
1430       if [ -z "$DCSDEVICE" ] && grep -q 9p /proc/filesystems ; then
1431           if grep -q "$GRMLCFG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then
1432             einfo "Found 9p-virtio fs with mount_tag $GRMLCFG"
1433             DCSDEVICE="$GRMLCFG"
1434             MOUNTOPTIONS="ro,trans=virtio"
1435             DCSFS="9p"
1436           fi
1437       fi
1438
1439       if [ -n "$DCSDEVICE" ]; then
1440         DCSMP="/mnt/grmlcfg"
1441       fi
1442       eoutdent
1443     fi
1444
1445     # if not specified/present then assume default:
1446     if [ -z "$DCSDEVICE" ]; then
1447       DCSDIR="${LIVECD_PATH}"
1448     else
1449       eindent
1450       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1451       DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1452       if [ -n "$DCSDIR" ]; then
1453         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1454       else
1455         [ -d $DCSMP ] || mkdir $DCSMP
1456         umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1457         mount -o ${MOUNTOPTIONS:-ro} -t ${DCSFS:-auto} $DCSDEVICE  $DCSMP ; RC="$?"
1458         if [[ $RC == 0 ]]; then
1459           einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1460         else
1461           eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1462         fi
1463         DCSDIR="$DCSMP"
1464       fi
1465       eoutdent
1466     fi
1467   fi
1468 fi
1469
1470 if [ -n "$DCSDIR" -a "$DCSDIR" != "${LIVECD_PATH}" ] ; then
1471   einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1472 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1473   einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1474 fi
1475 }
1476
1477
1478 config_partconf() {
1479 if checkbootparam 'partconf' ; then
1480  MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1481  if [ -n "$MOUNTDEVICE" ]; then
1482    [ -d /mnt/grml ] || mkdir /mnt/grml
1483    mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1484     if [[ $RC == 0 ]]; then
1485       einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1486       einfo "Copying files from $MOUNTDEVICE over grml system."
1487       for file in `cat /etc/grml/partconf` ; do
1488         [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1489         [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file}  ${file} && echo "copied: $file"
1490       done && eend 0
1491     else
1492       einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1493     fi # mount $MOUNTDEVICE
1494    grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1495  else
1496    einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1497  fi # [ -n "$MOUNTDEVICE" ]
1498 fi
1499 }
1500 # }}}
1501
1502 # {{{ /cdrom/.*-options
1503 config_debs(){
1504 if checkbootparam 'debs' ; then
1505    iszsh && setopt localoptions shwordsplit
1506    DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1507    if [ -z "$DEBS" ] ; then
1508       DEBS="*.deb"
1509    fi
1510    if ! echo $DEBS | grep -q '/'; then
1511      # backwards compatibility: if no path is given get debs from debs/
1512      DEBS="debs/$DEBS"
1513    fi
1514    einfo "Trying to install Debian package(s) ${DEBS}"
1515    DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1516    dpkg -i $DEBS ; eend $?
1517 fi
1518 }
1519
1520 config_scripts(){
1521 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1522    SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1523    if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1524      SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1525    fi
1526    if ! echo $SCRIPTS | grep -q '/'; then
1527      # backwards compatibility: if no path is given get scripts from scripts/
1528      SCRIPTS="scripts/$SCRIPTS"
1529    fi
1530    if [ -n "$SCRIPTS" ]; then
1531      SCRIPTS="${DCSDIR}/$SCRIPTS"
1532      if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1533        einfo "Trying to execute ${SCRIPTS}"
1534        sh -c $SCRIPTS
1535        eend $?
1536      elif [ -d "$SCRIPTS" ]; then
1537        einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1538        run-parts --regex '.*' $SCRIPTS
1539        eend $?
1540      else
1541        einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1542        sh -c $SCRIPTS
1543        eend $?
1544      fi
1545    fi
1546 fi
1547 }
1548
1549 config_config(){
1550 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1551   CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1552   if [ -z "$CONFIG" ]; then
1553     CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1554   fi
1555   if [ -n "$CONFIG" ]; then
1556     if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1557       einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1558
1559       cp -a ${DCSDIR}/${CONFIG}/* /
1560     elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1561       einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1562
1563       cd /
1564       unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1565     else
1566       ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1567     fi
1568   fi
1569 fi
1570 }
1571 # }}}
1572
1573 # {{{ confing_umount_dcsdir
1574 config_umount_dcsdir(){
1575    # umount $DCSMP if it was mounted by finddcsdir
1576    grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1577 }
1578 # }}}
1579
1580 # {{{ mypath
1581 config_mypath(){
1582 if checkbootparam 'mypath' ; then
1583    MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1584    einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1585    touch /etc/grml/my_path
1586    chmod 644 /etc/grml/my_path
1587    # make sure the directories exist:
1588    eindent
1589    for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1590        if ! [ -d "$i" ] ; then
1591           einfo "Creating directory $i"
1592           mkdir -p "$i" ; eend $?
1593        fi
1594    done
1595    grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1596    eoutdent
1597 fi
1598 }
1599 # }}}
1600
1601 # {{{ SW-RAID
1602 config_swraid(){
1603   [ -n "$INSTALLED" ] && return 0
1604
1605   if checkbootparam 'noraid'   || checkbootparam 'noswraid' || \
1606      checkbootparam 'raid=noautodetect' ; then
1607      ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1608   else
1609     [ -e /proc/mdstat ] || modprobe md_mod
1610     if ! [ -x /sbin/mdadm ] ; then
1611        eerror "mdadm not available, can not execute it." ; eend 1
1612     else
1613
1614        # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1615        # find out whether we have a valid configuration file already
1616        if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1617           einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1618           [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1619           MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1620         else
1621           ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1622        fi
1623
1624        if ! checkbootparam 'swraid' ; then
1625           eindent
1626           einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1627           eoutdent
1628        else
1629           einfo "Bootoption swraid found. Searching for software RAID arrays:"
1630           eindent
1631            IFSOLD=${IFS:-}
1632            IFS='
1633 '
1634            for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
1635                case $line in
1636                  *'No arrays found'*)
1637                    ewarn "$line" ; eend 0
1638                    ;;
1639                  *)
1640                    einfo "$line" ; eend 0
1641                    ;;
1642                esac
1643            done
1644            IFS=$IFSOLD
1645          eoutdent
1646
1647          if [ -r /proc/mdstat ] ; then
1648             eindent
1649             MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1650             if [ -z "$MDSTAT" ] ; then
1651                ewarn "No active arrays found" ; eend 0
1652             else
1653                IFSOLD=${IFS:-}
1654                IFS='
1655 '
1656                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1657                    einfo "active arrays: $line" ; eend 0
1658                done
1659                IFS=$IFSOLD
1660             fi
1661             eoutdent
1662          fi # /proc/mdstat
1663        fi # bootoption swraid
1664
1665      fi # is /sbin/mdadm executable?
1666   fi # check for bootoptions
1667 }
1668 # }}}
1669
1670 # {{{ dmraid
1671 config_dmraid(){
1672   [ -n "$INSTALLED" ] && return 0
1673
1674   if checkbootparam 'nodmraid' ; then
1675     ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1676     return 0
1677   fi
1678
1679   if ! [ -x /sbin/dmraid ] ; then
1680     eerror "dmraid not available, can not execute it." ; eend 1
1681     return
1682   fi
1683
1684   dmraid_wrapper() {
1685     # usage: dmraid_wrapper <dmraid_option>
1686     [ -n "$1" ] || return 1
1687
1688     IFSOLD=${IFS:-}
1689     IFS='
1690 '
1691     eindent
1692
1693     for line in $(dmraid $1 ; echo errcode:$?); do
1694       case $line in
1695         *'no block devices found'*)
1696           einfo "No block devices found" ; eend 0
1697           break
1698           ;;
1699         *'no raid disks'*)
1700           einfo "No active dmraid devices found" ; eend 0
1701           break
1702           ;;
1703         errcode:0)
1704           eend 0;
1705           ;;
1706         errcode:1)
1707           eend 1
1708           ;;
1709         *)
1710           einfo "$line"
1711           ;;
1712       esac
1713     done
1714
1715     eoutdent
1716     IFS=$IFSOLD
1717   }
1718
1719   if checkbootparam 'dmraid' ; then
1720     local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1721     if [ "$ACTION" = "off" ] ; then
1722       # Deactivates all active software RAID sets:
1723       einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1724       dmraid_wrapper -an
1725     else
1726       # Activate all software RAID sets discovered:
1727       einfo "Activating present dmraid sets (as requested via dmraid):"
1728       dmraid_wrapper -ay
1729     fi
1730
1731     return
1732   fi
1733
1734   # by default (no special bootoptions) discover all software RAID devices:
1735   einfo "Searching for any present dmraid sets:"
1736   dmraid_wrapper -r
1737 }
1738 # }}}
1739
1740 # {{{ LVM (Logical Volumes)
1741 config_lvm(){
1742   [ -n "$INSTALLED" ] && return 0
1743
1744   if checkbootparam 'nolvm' ; then
1745      ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1746   else
1747     if ! [ -x /sbin/lvm ] ; then
1748        eerror "LVM not available, can not execute it." ; eend 1
1749     else
1750        if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1751           einfo "You seem to have logical volumes (LVM) on your system."
1752           eindent
1753           einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1754           eend 0
1755           if checkbootparam 'lvm' ; then
1756              einfo "Bootoption LVM found. Searching for logical volumes:"
1757              service_wrapper lvm2 start ; eend $?
1758           fi
1759           eoutdent
1760        fi
1761     fi # check for lvm binary
1762   fi # check for bootoption nolvm
1763 }
1764 # }}}
1765
1766 # {{{ debnet: setup network based on an existing one found on a partition
1767 config_debnet(){
1768 if checkbootparam 'debnet' ; then
1769  einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1770  /usr/sbin/debnet
1771 fi
1772 }
1773 # }}}
1774
1775 # {{{ disable console blanking
1776 config_blanking(){
1777 if checkbootparam 'noblank' ; then
1778   einfo "Bootoption noblank found. Disabling monitor blanking."
1779   setterm -blank 0 ; eend $?
1780 fi
1781 }
1782 # }}}
1783
1784 # {{{ debootstrap: automatic installation
1785 config_debootstrap(){
1786
1787 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
1788
1789 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
1790
1791 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
1792    eindent
1793    eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
1794    eoutdent
1795    exit 1
1796 fi
1797
1798 if checkbootparam 'target' ; then
1799   TARGET=''
1800   TARGET="$(getbootparam 'target' 2>>$DEBUG)"
1801   # notice: the following checks whether the given partition is available, if not the skip
1802   # execution of grml-debootstrap as it might result in data loss...
1803   if ! [ -r "$TARGET" ] ; then
1804      eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
1805   fi
1806 else
1807   eindent
1808   eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
1809   eoutdent
1810   exit 1
1811 fi
1812
1813 if checkbootparam 'grub' ; then
1814   GRUB=''
1815   GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
1816 fi
1817
1818 if checkbootparam 'groot' ; then
1819   GROOT=''
1820   GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
1821 fi
1822
1823 if checkbootparam 'release' ; then
1824   RELEASE=''
1825   RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
1826 fi
1827
1828 if checkbootparam 'mirror' ; then
1829   MIRROR=''
1830   MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
1831 fi
1832
1833 if checkbootparam 'boot_append' ; then
1834   BOOT_APPEND=''
1835   BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
1836 fi
1837
1838 if checkbootparam 'password' ; then
1839   PASSWORD=''
1840   PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
1841 fi
1842
1843 # now check which options are available
1844 if [ -n "TARGET" ] ; then
1845    TARGETCMD="--target $TARGET"
1846 else
1847    TARGETCMD=''
1848    eindent
1849    eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
1850    eoutdent
1851    exit 1
1852 fi
1853 [ -n "$GRUB" ]     && GRUBCMD="--grub $GRUB"               || GRUBCMD=''
1854 [ -n "$GROOT" ]    && GROOTCMD="--groot $GROOT"            || GROOTCMD=''
1855 [ -n "$RELEASE" ]  && RELEASECMD="--release $RELEASE"      || RELEASECMD=''
1856 [ -n "$MIRROR" ]   && MIRRORCMD="--mirror $MIRROR"         || MIRRORCMD=''
1857 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD"   || PASSWORDCMD=''
1858 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
1859
1860 # and finally write script and execute it
1861 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
1862 #!/bin/sh
1863 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
1864 EOF
1865
1866 chmod 750  /usr/bin/grml-debootstrap_noninteractive
1867
1868 screen /usr/bin/grml-debootstrap_noninteractive
1869 einfo "Invoking a shell, just exit to continue booting..."
1870 /bin/zsh
1871
1872 fi # checkbootparam "BOOT_IMAGE=debian2hd
1873 }
1874 # }}}
1875
1876 # {{{ virtualbox shared folders
1877 config_virtualbox_shared_folders() {
1878 if $VIRTUALBOX ; then
1879   einfo "VirtualBox detected, trying to set up Shared Folders."
1880   if ! modinfo vboxsf &>/dev/null ; then
1881     ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
1882     eend 0
1883   elif ! [ -x /usr/sbin/VBoxService ] ; then
1884     ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
1885     eend 0
1886   else
1887     eindent
1888
1889       einfo "Loading vboxsf driver."
1890       lsmod | grep -q vboxsf || modprobe vboxsf
1891       eend $?
1892
1893       einfo "Adjusting /dev/vboxguest."
1894       chown root:vboxsf /dev/vboxguest
1895       chmod 660 /dev/vboxguest
1896       eend $?
1897
1898       config_userfstab
1899
1900       einfo "Adding $fstabuser to group vboxsf."
1901       adduser grml vboxsf &>/dev/null
1902       eend $?
1903
1904       einfo "Starting VBoxService."
1905       VBoxService >/dev/null
1906       eend $?
1907
1908       local vbautomation='automation'
1909       if checkbootparam 'vbautomation'; then
1910         vbautomation="$(getbootparam 'vbautomation' 2>>$DEBUG)"
1911       fi
1912
1913       if ! VBoxControl sharedfolder list | egrep -q "^[0-9]+ - ${vbautomation}$" ; then
1914         ewarn "No automount shared folder '$vbautomation' available"
1915         eend 0
1916       else
1917         einfo "Found automount shared folder '$vbautomation'"
1918         eend 0
1919
1920         local distri="$(getbootparam 'distri' 2>>$DEBUG)"
1921         [ -n "$distri" ] || distri='grml'
1922
1923         local vbox_auto_sf="/media/sf_${vbautomation}"
1924
1925         sleep 1 # ugly but necessary
1926
1927         counter=10
1928         eindent
1929         while ! [ -d "${vbox_auto_sf}" ] && [[ "$counter" != 0 ]]; do
1930           einfo "Waiting another second to retry access to ${vbox_auto_sf}"
1931           sleep 1
1932           counter=$(( counter-1 ))
1933           eend 0
1934         done
1935         eoutdent
1936
1937         if ! [ -d "${vbox_auto_sf}" ] ; then
1938           eerror "Giving up trying to access folder ${vbox_auto_sf} which doesn't seem to exist"
1939           eend 1
1940         else
1941           einfo "Found shared folders automation directory $vbox_auto_sf"
1942           eend 0
1943
1944           eindent
1945           if checkbootparam 'novbautomation' ; then
1946             einfo "Bootoption novbautomation found. Disabling automation script execution."
1947             eend 0
1948           else
1949             if ! [ -x "${vbox_auto_sf}/${distri}" ] ; then
1950               ewarn "Couldn't find an automation script named ${vbox_auto_sf}/${distri}"
1951               eend 1
1952             else
1953               einfo "Executing '${vbox_auto_sf}/${distri}' now:"
1954               "${vbox_auto_sf}/${distri}"
1955               eend $?
1956             fi
1957           fi
1958           eoutdent
1959         fi
1960       fi
1961
1962     eoutdent
1963   fi
1964 fi
1965 }
1966 # }}}
1967
1968 # {{{ Support customization
1969 config_distri(){
1970 if checkbootparam 'distri'; then
1971   DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
1972   if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
1973      [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0
1974      # make sure the desktop.jpg file is not a symlink, so copying does not file then
1975      [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
1976      cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
1977   fi
1978 fi
1979 }
1980 # }}}
1981
1982 ## END OF FILE #################################################################
1983 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=2