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