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