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