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