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