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