Release new version 0.22.0
[grml-autoconfig.git] / autoconfig.functions
index fcbaead..3bab753 100755 (executable)
@@ -13,12 +13,10 @@ KERNEL="$(uname -r)"
 ARCH="$(uname -m)"
 umask 022
 
-# old linuxrc version:
-[ -d /cdrom ]      && export LIVECD_PATH=/cdrom
-# initramfs layout until around December 2012:
-[ -d /live/image ] && export LIVECD_PATH=/live/image
-# initramfs layout since around December 2012:
-[ -d /lib/live/mount/medium ] && export LIVECD_PATH=/lib/live/mount/medium
+# initramfs layout since December 2012, backwards compatibility:
+[ -d /lib/live/mount/medium ] && export LIVECD_PATH='/lib/live/mount/medium'
+# initramfs layout since December 2018:
+[ -d /run/live/medium ] && export LIVECD_PATH='/run/live/medium'
 
 # Ignore these signals in non-interactive mode: INT, TERM, SEGV
 [ -z "$PS1" ] && trap "" 2 3 11
@@ -31,17 +29,22 @@ fi
 
 service_wrapper() {
   if [ "$#" -lt 2 ] ; then
-    echo "Usage: service_wrapper <service> <action>" >&2
+    echo "Usage: service_wrapper <service> <action> [background]" >&2
     return 1
   fi
 
   local service="$1"
   local action="$2"
+  local background="$3"
 
   if $SYSTEMD ; then
     systemctl "$action" "$service"
   else
-    /etc/init.d/"$service" "$action"
+    if [ "${background:-}" = "background" ] ; then
+      /etc/init.d/"$service" "$action" &
+    else
+      /etc/init.d/"$service" "$action"
+    fi
   fi
 }
 
@@ -181,13 +184,18 @@ KVM=false
 VIRTUALBOX=false
 VMWARE=false
 
-if vmware-detect &>/dev/null; then
+if virt-what 2>/dev/null | grep -q 'vmware' || \
+  imvirt 2>/dev/null | grep -iq "vmware" ; then
   VIRTUAL=true; VMWARE=true; VIRTUAL_ENV='VMware'
-elif [ "$(virt-what 2>/dev/null)" = "kvm" ] || \
-   [ "$(imvirt 2>/dev/null)" = "KVM" ] ; then
+fi
+
+if virt-what 2>/dev/null | grep -q 'kvm' || \
+  [ "$(imvirt 2>/dev/null)" = "KVM" ] ; then
   VIRTUAL=true; KVM=true; VIRTUAL_ENV='KVM'
-elif [ "$(virt-what 2>/dev/null)" = "virtualbox" ] || \
-   [ "$(imvirt 2>/dev/null)" = "VirtualBox" ] ; then
+fi
+
+if virt-what 2>/dev/null | grep -q 'virtualbox' || \
+  [ "$(imvirt 2>/dev/null)" = "VirtualBox" ] ; then
   VIRTUAL=true; VIRTUALBOX=true; VIRTUAL_ENV='VirtualBox'
 fi
 # }}}
@@ -205,12 +213,8 @@ fi
 config_log(){
 if checkbootparam 'log' || checkbootparam 'debug' ; then
    export DEBUG="/tmp/grml.log.`date +%Y%m%d`"
-   touch $DEBUG
-   einfo "Bootparameter log found. Log files: ${DEBUG} and /var/log/boot"
-   eindent
-     einfo "Starting bootlogd." # known to be *very* unreliable :(
-     bootlogd -r -c >>$DEBUG 2>&1 ; eend $?
-   eoutdent
+   touch "${DEBUG}"
+   einfo "Bootparameter log found, debug log file from grml-autoconfig available at '${DEBUG}'"
 else
    DEBUG="/dev/null"
 fi
@@ -220,165 +224,190 @@ fi
 ### {{{ language configuration / localization
 config_language(){
 
- einfo "Activating language settings:"
- eindent
 einfo "Activating language settings:"
 eindent
 
- # people can specify $LANGUAGE and $CONSOLEFONT in a config file
- [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
 # people can specify $LANGUAGE and $CONSOLEFONT in a config file
 [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
 
- # check for bootoption which overrides config from /etc/grml/autoconfig
- BOOT_LANGUAGE="$(getbootparam 'lang' 2>>$DEBUG)"
- [ -n "$BOOT_LANGUAGE" ] && LANGUAGE="$BOOT_LANGUAGE"
 # check for bootoption which overrides config from /etc/grml/autoconfig
 BOOT_LANGUAGE="$(getbootparam 'lang' 2>>$DEBUG)"
 [ -n "$BOOT_LANGUAGE" ] && LANGUAGE="$BOOT_LANGUAGE"
 
- # set default to 'en' in live-cd mode iff $LANGUAGE is not set yet
- if [ -z "$INSTALLED" ] ; then
 # set default to 'en' in live-cd mode iff $LANGUAGE is not set yet
 if [ -z "$INSTALLED" ] ; then
     [ -n "$LANGUAGE" ] || LANGUAGE='en'
- fi
 fi
 
- if [ -x /usr/sbin/grml-setlang ] ; then
-   # if bootoption lang is used update /etc/default/locale accordingly
-   if [ -n "$BOOT_LANGUAGE" ] ; then
-     /usr/sbin/grml-setlang "$LANGUAGE"
-   # otherwise default to lang=en
-   else
-     /usr/sbin/grml-setlang "en"
-   fi
- fi
 if [ -x /usr/sbin/grml-setlang ] ; then
+    # if bootoption lang is used update /etc/default/locale accordingly
+    if [ -n "$BOOT_LANGUAGE" ] ; then
+      /usr/sbin/grml-setlang "$LANGUAGE"
+      # otherwise default to lang=en
+    else
+      /usr/sbin/grml-setlang "en"
+    fi
 fi
 
- # set console font
- if [ -z "$CONSOLEFONT" ] ; then
-    if ! checkbootparam 'nodefaultfont' >>$DEBUG 2>&1 ; then
-       if [ -r /usr/share/consolefonts/Uni3-Terminus16.psf.gz ] ; then
+  if ! $SYSTEMD ; then
+    # set console font
+    if [ -z "$CONSOLEFONT" ] ; then
+      if ! checkbootparam 'nodefaultfont' >>$DEBUG 2>&1 ; then
+        if [ -r /usr/share/consolefonts/Uni3-Terminus16.psf.gz ] ; then
           CONSOLEFONT='Uni3-Terminus16'
-       else
-          ewarn "/usr/share/consolefonts/Uni3-Terminus16.psf.gz not available. Please upgrade package console-terminus." ; eend 1
-       fi
-       if ! hasfb ; then
+        else
+          ewarn "/usr/share/consolefonts/Uni3-Terminus16.psf.gz not available. Please upgrade package console-setup-linux." ; eend 1
+        fi
+        if ! hasfb ; then
           CONSOLEFONT='Lat15-Terminus16'
-       fi
+        fi
+      fi
     fi
- fi
+  fi # not running systemd
 
- # export it now, so error messages get translated, too
- [ -r /etc/default/locale ] && . /etc/default/locale
- export LANG LANGUAGE
-
- # configure keyboard layout, read in already set values first:
- [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
-
- # now allow keyboard override by boot commandline for later use:
- KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
- [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
- # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
- [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
- [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
-
- # modify /etc/sysconfig/keyboard only in live-cd mode:
- if [ -z "$INSTALLED" ] ; then
-
-   local LANGUAGE="$BOOT_LANGUAGE"
-   . /etc/grml/language-functions
-   # allow setting xkeyboard explicitly different than console keyboard
-   KXKEYBOARD="$(getbootparam 'xkeyboard' 2>>$DEBUG)"
-   if [ -n "$KXKEYBOARD" ]; then
-      XKEYBOARD="$KXKEYBOARD"
-      KDEKEYBOARD="$KXKEYBOARD"
-   elif [ -n "$KKEYBOARD" ]; then
-      XKEYBOARD="$KKEYBOARD"
-      KDEKEYBOARD="$KKEYBOARD"
-   fi
+  # export it now, so error messages get translated, too
+  [ -r /etc/default/locale ] && . /etc/default/locale
+  export LANG LANGUAGE
 
-   # duplicate of previous code to make sure /etc/grml/language-functions
-   # does not overwrite our values....
-   # now allow keyboard override by boot commandline for later use:
-   KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
-   [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
-   # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
-   [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
-   [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
-
-   # write keyboard related variables to file for later use
-   [ -d /etc/sysconfig ] || mkdir /etc/sysconfig
-   if ! [ -e /etc/sysconfig/keyboard ] ; then
-      echo "KEYTABLE=\"$KEYTABLE\""          > /etc/sysconfig/keyboard
-      echo "XKEYBOARD=\"$XKEYBOARD\""       >> /etc/sysconfig/keyboard
-      echo "KDEKEYBOARD=\"$KDEKEYBOARD\""   >> /etc/sysconfig/keyboard
-      echo "KDEKEYBOARDS=\"$KDEKEYBOARDS\"" >> /etc/sysconfig/keyboard
-   fi
- fi
+  if $SYSTEMD ; then
+    local KEYBOARD
+    KEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
+    [ -n "$KEYBOARD" ] || KEYBOARD="$LANGUAGE"
+    # "symbols/en" doesn't exist, so rewrite to "us"
+    [[ "$KEYBOARD" == 'en' ]] && KEYBOARD="us"
+
+    if [ -r /etc/default/keyboard ] ; then
+      sed -i "s/^XKBLAYOUT=.*/XKBLAYOUT=\"$KEYBOARD\"/" /etc/default/keyboard
+
+      case "$KEYBOARD" in
+       de|at)
+         sed -i "s/^XKBVARIANT=.*/XKBVARIANT=\"nodeadkeys\"/" /etc/default/keyboard
+         ;;
+      esac
 
- [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
+    fi
+    service_wrapper console-setup restart >>$DEBUG 2>&1 ; eend $?
+  else # not running systemd, keeing for backwards compatibility:
+    # configure keyboard layout, read in already set values first:
+    [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
+
+    # now allow keyboard override by boot commandline for later use:
+    KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
+    [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
+    # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
+    [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
+    [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
+
+    # modify /etc/sysconfig/keyboard only in live-cd mode:
+    if [ -z "$INSTALLED" ] ; then
+
+      local LANGUAGE="$BOOT_LANGUAGE"
+      . /etc/grml/language-functions
+      # allow setting xkeyboard explicitly different than console keyboard
+      KXKEYBOARD="$(getbootparam 'xkeyboard' 2>>$DEBUG)"
+      if [ -n "$KXKEYBOARD" ]; then
+        XKEYBOARD="$KXKEYBOARD"
+        KDEKEYBOARD="$KXKEYBOARD"
+      elif [ -n "$KKEYBOARD" ]; then
+        XKEYBOARD="$KKEYBOARD"
+        KDEKEYBOARD="$KKEYBOARD"
+      fi
 
- # activate unicode console if running within utf8 environment
- if [ -r /etc/default/locale ] ; then
-    if grep -q "LANG=.*UTF" /etc/default/locale ; then
-       einfo "Setting up unicode environment."
-       unicode_start >>$DEBUG 2>&1 ; eend $?
+      # duplicate of previous code to make sure /etc/grml/language-functions
+      # does not overwrite our values....
+      # now allow keyboard override by boot commandline for later use:
+      KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
+      [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
+      # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
+      [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
+      [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
+
+      # write keyboard related variables to file for later use
+      [ -d /etc/sysconfig ] || mkdir /etc/sysconfig
+      if ! [ -e /etc/sysconfig/keyboard ] ; then
+        echo "KEYTABLE=\"$KEYTABLE\""          > /etc/sysconfig/keyboard
+        echo "XKEYBOARD=\"$XKEYBOARD\""       >> /etc/sysconfig/keyboard
+        echo "KDEKEYBOARD=\"$KDEKEYBOARD\""   >> /etc/sysconfig/keyboard
+        echo "KDEKEYBOARDS=\"$KDEKEYBOARDS\"" >> /etc/sysconfig/keyboard
+      fi
     fi
- fi
 
- # Set default keyboard before interactive setup
- if [ -n "$KEYTABLE" ] ; then
-    einfo "Running loadkeys for ${WHITE}${KEYTABLE}${NORMAL} in background"
-    loadkeys -q $KEYTABLE &
-    eend $?
- fi
+    [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
+  fi
 
- # we have to set up all consoles, therefore loop it over all ttys:
- NUM_CONSOLES=$(fgconsole --next-available 2>/dev/null)
- if [ -n "$NUM_CONSOLES" ] ; then
-    NUM_CONSOLES=$(expr ${NUM_CONSOLES} - 1)
-    [ ${NUM_CONSOLES} -eq 1 ] && NUM_CONSOLES=6
- fi
- CUR_CONSOLE=$(fgconsole 2>/dev/null)
 
- if [ -x "$(which setfont)" ] ; then
-    use_setfont=true
- elif [ -x "$(which consolechars)" ] ; then
-    use_consolechars=true
- else
-    eerror "Neither setfont nor consolechars tool present, can not set font."
-    eend 1
-    return 1
- fi
+  if ! $SYSTEMD ; then
+    # we have to set up all consoles, therefore loop it over all ttys:
+    NUM_CONSOLES=$(fgconsole --next-available 2>/dev/null)
+    if [ -n "$NUM_CONSOLES" ] ; then
+      NUM_CONSOLES=$(expr ${NUM_CONSOLES} - 1)
+      [ ${NUM_CONSOLES} -eq 1 ] && NUM_CONSOLES=6
+    fi
+    CUR_CONSOLE=$(fgconsole 2>/dev/null)
+
+    if [ -x "$(which setfont)" ] ; then
+      use_setfont=true
+    elif [ -x "$(which consolechars)" ] ; then
+      use_consolechars=true
+    else
+      eerror "Neither setfont nor consolechars tool present, can not set font."
+      eend 1
+      return 1
+    fi
 
- if [ -n "$CHARMAP" ] ; then
-    einfo "Setting font to ${CHARMAP}"
-    RC=0
-    for vc in $(seq 0 ${NUM_CONSOLES}) ; do
   if [ -n "$CHARMAP" ] ; then
+      einfo "Setting font to ${CHARMAP}"
+      RC=0
+      for vc in $(seq 0 ${NUM_CONSOLES}) ; do
         if $use_setfont ; then
           setfont -C /dev/tty${vc} $CHARMAP ; RC=$?
         elif $use_consolechars ; then
           consolechars --tty=/dev/tty${vc} -m ${CHARMAP} ; RC=$?
         fi
-    done
-    if [ -n "$CUR_CONSOLE" ] ; then
-       [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
+      done
+      if [ -n "$CUR_CONSOLE" ] ; then
+        [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
+      fi
+      eend $RC
     fi
-    eend $RC
- fi
 
- if checkbootparam 'noconsolefont' ; then
-    ewarn "Skipping setting console font as requested on boot commandline." ; eend 0
- else
-    if [ -n "$CONSOLEFONT" ] ; then
-       einfo "Setting font to ${CONSOLEFONT}"
-       RC=0
-       for vc in $(seq 0 ${NUM_CONSOLES}) ; do
-           if $use_setfont ; then
-             setfont -C /dev/tty${vc} ${CONSOLEFONT} ; RC=$?
-           elif $use_consolechars ; then
-             consolechars --tty=/dev/tty${vc} -f ${CONSOLEFONT} ; RC=$?
-           fi
-       done
-       if [ -n "$CUR_CONSOLE" ] ; then
   if checkbootparam 'noconsolefont' ; then
+      ewarn "Skipping setting console font as requested on boot commandline." ; eend 0
   else
+      if [ -n "$CONSOLEFONT" ] ; then
+        einfo "Setting font to ${CONSOLEFONT}"
+        RC=0
+        for vc in $(seq 0 ${NUM_CONSOLES}) ; do
+          if $use_setfont ; then
+            setfont -C /dev/tty${vc} ${CONSOLEFONT} ; RC=$?
+          elif $use_consolechars ; then
+            consolechars --tty=/dev/tty${vc} -f ${CONSOLEFONT} ; RC=$?
+          fi
+        done
+        if [ -n "$CUR_CONSOLE" ] ; then
           [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
-       fi
-       eend $RC
+        fi
+        eend $RC
+      fi
+    fi
+
+    # Set default keyboard before interactive setup
+    if [ -n "$KEYTABLE" ] ; then
+      einfo "Running loadkeys for ${WHITE}${KEYTABLE}${NORMAL} in background"
+      loadkeys -q $KEYTABLE &
+      eend $?
     fi
- fi
 
- eoutdent
+    # activate unicode console if running within utf8 environment
+    if [ -r /etc/default/locale ] ; then
+      if grep -q "LANG=.*UTF" /etc/default/locale ; then
+        einfo "Setting up unicode environment."
+        unicode_start ; eend $?
+      fi
+    fi
+  fi # not running systemd
+
+  eoutdent
 }
 # }}}
 
@@ -511,24 +540,41 @@ config_kernel(){
 # }}}
 
 # {{{ secure boot
-config_secureboot(){
-  if [ -x /usr/bin/mokutil ] ; then
-    local secstate=$(mokutil --sb-state 2>/dev/null) # "SecureBoot enabled"
-    if [ -n "$secstate" ] ; then
-      einfo "SecureBoot is enabled" ; eend 0
+# helper function to check whether we're running under (enabled) Secure Boot
+running_under_secureboot() {
+  # systemd does this for us, but if we are not running under systemd then mokutil
+  # doesn't work as needed as it relies on /sys/firmware/efi/efivars (while
+  # /sys/firmware/efi/vars would exist)
+  if ! $SYSTEMD ; then
+    if modprobe efivarfs &>/dev/null ; then
+      mount -t efivarfs efivarfs /sys/firmware/efi/efivars
+    fi
+  fi
+
+  if [[ -x "$(command -v mokutil)" ]] ; then
+    if mokutil --sb-state 2>/dev/null | grep -q 'SecureBoot enabled' ; then
+      return 0
     else
-      einfo "SecureBoot not detected" ; eend 0
+      return 1
     fi
   else
-    if modprobe efivars &>/dev/null ; then
+    if modprobe efivarfs &>/dev/null ; then
       if od -An -t u1 /sys/firmware/efi/vars/SecureBoot-*/data 2>/dev/null | grep -q 1 ; then
-        einfo "SecureBoot is enabled" ; eend 0
+        return 0
       else
-        einfo "SecureBoot not detected" ; eend 0
+        return 1
       fi
     fi
   fi
 }
+
+config_secureboot(){
+  if running_under_secureboot ; then
+      einfo "SecureBoot is enabled" ; eend 0
+  else
+      einfo "SecureBoot not detected" ; eend 0
+  fi
+}
 # }}}
 
 # {{{ timezone
@@ -738,7 +784,8 @@ fi
 # {{{ Start brltty
 config_brltty() {
   if checkbootparam 'brltty' ; then
-    [ -x /lib/brltty/brltty.sh ] && /lib/brltty/brltty.sh
+    einfo "Starting brltty service as requested on boot commandline."
+    service_wrapper brltty start ; eend $?
   fi
 }
 # }}}
@@ -858,76 +905,23 @@ fi # -z $INSTALLED
 
 # {{{ CPU-detection
 config_cpu(){
-if checkbootparam 'nocpu'; then
-  ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
-  return 0
-fi
-
-if [[ $(grep -c processor /proc/cpuinfo) -gt 1 ]] ; then
-   einfo "Found CPU:"
-   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)
-   echo $CPU | sed 's/ \{1,\}/ /g'
-   eend 0
-else
-   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
-fi
-
-# no cpufreq setup inside VirtualBox
-if $VIRTUALBOX ; then
-   einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0
-   return 0
-fi
+  if checkbootparam 'nocpu'; then
+    ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
+    return 0
+  fi
 
-if ! [ -x /etc/init.d/loadcpufreq ] ; then
-  ewarn "loadcpufreq init script not available, ignoring cpu frequency scaling."
-  eend 0
-  return 0
-else
-   einfo "Trying to set up cpu frequency scaling:"
-   eindent
-   SKIP_CPU_GOVERNOR=''
-   LOADCPUFREQ=$(mktemp)
-   /etc/init.d/loadcpufreq start >"$LOADCPUFREQ" 2>&1 ; RC=$?
-   if grep -q FATAL "$LOADCPUFREQ" ; then
-      eindent
-        SKIP_CPU_GOVERNOR=1
-        oldIFS="$IFS"
-        IFS="
-"
-         for line in $(grep FATAL "$LOADCPUFREQ" | sed 's/.*FATAL: //; s/ (.*)//') ; do
-             eerror "$line" ; eend $RC
-         done
-         IFS="$oldIFS"
-      eoutdent
-   elif grep -q done "$LOADCPUFREQ" ; then
-      MODULE=$(grep done "$LOADCPUFREQ" | sed 's/.*done (\(.*\))./\1/')
-      if [ -n "$MODULE" -a "$MODULE" != none ]; then
-         einfo "Loading cpufreq kernel module $MODULE" ; eend 0
-      else
-         SKIP_CPU_GOVERNOR=1
-         ewarn "Could not find an appropriate kernel module for cpu frequency scaling." ; eend 1
-      fi
-   fi
+  if ! [ -x "$(which lscpu)" ] ; then
+    ewarn "Skipping CPU detection due to lack of lscpu."; eend 0
+    return 0
+  fi
 
-   rm -f "$LOADCPUFREQ"
+  local cpu_info num_cpus
 
-   if [ -z "$SKIP_CPU_GOVERNOR" ] ; then
-     if [ -r /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors ] ; then
-       if ! grep -q ondemand /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors ; then
-         einfo "Ondemand governor not available for CPU(s), not modifying governor configuration"
-       else
-         einfo "Setting ondemand governor"
-         RC=0
-         for file in $(find /sys/devices/system/cpu/ -name scaling_governor 2>/dev/null) ; do
-           echo ondemand > $file || RC=1
-         done
-         eend $RC
-       fi
-     fi
-   fi
+  cpu_info="$(lscpu | sed -n '/^Model name:/s/[^:]*:\s*//p')"
+  num_cpus=$(grep -c processor /proc/cpuinfo)
 
-   eoutdent
-fi
+  einfo "Found ${num_cpus} CPU(s): ${cpu_info}"
+  eend 0
 }
 # }}}
 
@@ -962,8 +956,9 @@ if checkbootparam 'ssh' ; then
    fi
 
    einfo "Starting secure shell server in background for root and user $localuser"
+   service_wrapper haveged start >>$DEBUG 2>>$DEBUG
    service_wrapper rmnologin start >>$DEBUG 2>>$DEBUG
-   service_wrapper ssh start >>$DEBUG 2>>$DEBUG &
+   service_wrapper ssh start background >>$DEBUG 2>>$DEBUG
    eend $?
 
 fi
@@ -1155,8 +1150,7 @@ config_mixer () {
 
       CONTROLS=$(amixer -c $card scontrols | awk -F"Simple mixer control " '{print $2}')
       IFSOLD=${IFS:-}
-      IFS='
-      '
+      IFS=$'\n'
       for CONTROL in ${=CONTROLS} ; do
         # such devices can not be controlled with amixer ... unmute
         [[ "$CONTROL" == *Console* ]] && continue
@@ -1193,7 +1187,7 @@ config_syslog(){
     ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
  else
     einfo "Starting rsyslog in background."
-    service_wrapper rsyslog start >>$DEBUG &
+    service_wrapper rsyslog start >>$DEBUG
     eend 0
  fi
 }
@@ -1208,8 +1202,7 @@ config_gpm(){
       eerror "No mouse found - not starting GPM." ; eend 1
     else
       einfo "Starting gpm in background."
-      service_wrapper gpm start >>$DEBUG &
-      # ( while [ ! -e /dev/psaux ]; do sleep 5; done; /etc/init.d/gpm start >>$DEBUG ) &
+      service_wrapper gpm start background >>$DEBUG
       eend 0
     fi
   fi
@@ -1230,7 +1223,7 @@ config_services(){
         service_wrapper "${service}" start >>$DEBUG
       else
         einfo "Starting service ${service} in background."
-        service_wrapper "${service}" start >>$DEBUG &
+        service_wrapper "${service}" start background >>$DEBUG
       fi
     done
     eend $?
@@ -1319,6 +1312,10 @@ if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; t
    einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
    config_userlocal
    if $SYSTEMD ; then
+     if [ -n "$WINDOWMANAGER" ] ; then
+       mkdir -p /var/run/grml-x/
+       echo "$WINDOWMANAGER" > /var/run/grml-x/window-manager
+     fi
      chvt 7
      return
    fi
@@ -1415,7 +1412,7 @@ else
     else
       eindent
       einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
-      DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
+      DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2; exit }}')"
       if [ -n "$DCSDIR" ]; then
         ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
       else
@@ -1591,7 +1588,7 @@ config_swraid(){
        if ! checkbootparam 'swraid' ; then
           eindent
           if $SYSTEMD ; then
-            einfo "Just run 'Start mdmonitor' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
+            einfo "Just run 'mdadm --assemble --scan' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
           else
             einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
           fi
@@ -1600,9 +1597,8 @@ config_swraid(){
           einfo "Bootoption swraid found. Searching for software RAID arrays:"
           eindent
            IFSOLD=${IFS:-}
-           IFS='
-'
-           for line in $(mdadm --assemble --scan --auto=yes --symlink=no 2>&1) ; do
+           IFS=$'\n'
+           for line in $(mdadm --assemble --scan 2>&1) ; do
                case $line in
                  *'No arrays found'*)
                    ewarn "$line" ; eend 0
@@ -1622,8 +1618,7 @@ config_swraid(){
                ewarn "No active arrays found" ; eend 0
             else
                IFSOLD=${IFS:-}
-               IFS='
-'
+               IFS=$'\n'
                for line in $(grep '^md[0-9]' /proc/mdstat) ; do
                    einfo "active arrays: $line" ; eend 0
                done
@@ -1638,76 +1633,6 @@ config_swraid(){
 }
 # }}}
 
-# {{{ dmraid
-config_dmraid(){
-  [ -n "$INSTALLED" ] && return 0
-
-  if checkbootparam 'nodmraid' ; then
-    ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
-    return 0
-  fi
-
-  if ! [ -x /sbin/dmraid ] ; then
-    eerror "dmraid not available, can not execute it." ; eend 1
-    return
-  fi
-
-  dmraid_wrapper() {
-    # usage: dmraid_wrapper <dmraid_option>
-    [ -n "$1" ] || return 1
-
-    IFSOLD=${IFS:-}
-    IFS='
-'
-    eindent
-
-    for line in $(dmraid $1 ; echo errcode:$?); do
-      case $line in
-        *'no block devices found'*)
-          einfo "No block devices found" ; eend 0
-          break
-          ;;
-        *'no raid disks'*)
-          einfo "No active dmraid devices found" ; eend 0
-          break
-          ;;
-        errcode:0)
-          eend 0;
-          ;;
-        errcode:1)
-          eend 1
-          ;;
-        *)
-          einfo "$line"
-          ;;
-      esac
-    done
-
-    eoutdent
-    IFS=$IFSOLD
-  }
-
-  if checkbootparam 'dmraid' ; then
-    local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
-    if [ "$ACTION" = "off" ] ; then
-      # Deactivates all active software RAID sets:
-      einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
-      dmraid_wrapper -an
-    else
-      # Activate all software RAID sets discovered:
-      einfo "Activating present dmraid sets (as requested via dmraid):"
-      dmraid_wrapper -ay
-    fi
-
-    return
-  fi
-
-  # by default (no special bootoptions) discover all software RAID devices:
-  einfo "Searching for any present dmraid sets:"
-  dmraid_wrapper -r
-}
-# }}}
-
 # {{{ LVM (Logical Volumes)
 config_lvm(){
   [ -n "$INSTALLED" ] && return 0
@@ -1722,16 +1647,24 @@ config_lvm(){
           einfo "You seem to have logical volumes (LVM) on your system."
           eindent
           if $SYSTEMD ; then
-            einfo "Just run 'Start lvm2-lvmetad' to activate them or boot using 'lvm' as bootoption for autostart."
+            einfo "Just run 'Start lvm2-pvscan@name' to activate LV or VG 'name' or boot using 'lvm' as bootoption for autostart."
           else
             einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
           fi
           eend 0
           if checkbootparam 'lvm' ; then
-             einfo "Bootoption LVM found. Searching for logical volumes:"
              if $SYSTEMD ; then
-               service_wrapper lvm2-lvmetad start ; eend $?
+               einfo "Bootoption LVM found, enabling related services."
+               if [ -r /etc/init.d/lvm2-lvmetad ] ; then
+                 service_wrapper lvm2-lvmetad start ; eend $?
+               fi
+               if [ -r /etc/init.d/lvm2-lvmpolld ] ; then
+                 service_wrapper lvm2-lvmpolld start ; eend $?
+               fi
+               einfo "Searching for logical volumes and enabling them:"
+               vgchange -ay ; eend $?
              else
+               einfo "Bootoption LVM found. Searching for logical volumes and enabling them:"
                service_wrapper lvm2 start ; eend $?
              fi
           fi
@@ -1854,16 +1787,22 @@ fi # checkbootparam "BOOT_IMAGE=debian2hd
 
 # {{{ virtualbox shared folders
 config_virtualbox_shared_folders() {
-if $VIRTUALBOX ; then
-  einfo "VirtualBox detected, trying to set up Shared Folders."
-  if ! modinfo vboxsf &>/dev/null ; then
-    ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
-    eend 0
-  elif ! [ -x /usr/sbin/VBoxService ] ; then
-    ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
-    eend 0
+  if ! $VIRTUALBOX ; then
+    return
+  fi
+
+  if checkbootparam 'novboxsf' ; then
+    ewarn "Skipping VirtualBox Shared Folders setup as requested on boot commandline." ; eend 0
   else
-    eindent
+    einfo "VirtualBox detected, trying to set up Shared Folders."
+    if ! modinfo vboxsf &>/dev/null ; then
+      ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
+      eend 0
+    elif ! [ -x /usr/sbin/VBoxService ] ; then
+      ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
+      eend 0
+    else
+      eindent
 
       einfo "Loading vboxsf driver."
       lsmod | grep -q vboxsf || modprobe vboxsf
@@ -1876,8 +1815,8 @@ if $VIRTUALBOX ; then
 
       config_userfstab
 
-      einfo "Adding $fstabuser to group vboxsf."
-      adduser grml vboxsf &>/dev/null
+      einfo "Adding user ${fstabuser:-grml} to group vboxsf."
+      adduser "${fstabuser:-grml}" vboxsf >>"${DEBUG}" 2>&1
       eend $?
 
       einfo "Starting VBoxService."
@@ -1889,7 +1828,7 @@ if $VIRTUALBOX ; then
         vbautomation="$(getbootparam 'vbautomation' 2>>$DEBUG)"
       fi
 
-      if ! VBoxControl sharedfolder list | egrep -q "^[0-9]+ - ${vbautomation}$" ; then
+      if ! VBoxControl sharedfolder list | egrep -q "^[0-9]+ - ${vbautomation}(\s+|$)" ; then
         ewarn "No automount shared folder '$vbautomation' available"
         eend 0
       else
@@ -1938,9 +1877,36 @@ if $VIRTUALBOX ; then
         fi
       fi
 
-    eoutdent
+      eoutdent
+    fi
   fi
-fi
+}
+# }}}
+
+# {{{ VirtualBox application
+config_virtualbox_setup() {
+  if checkbootparam 'novbox' ; then
+    ewarn "Skipping VirtualBox setup as requested on boot commandline." ; eend 0
+    return
+  fi
+
+  if ! [ -x /usr/bin/VBox ] ; then
+    return
+  fi
+
+  if running_under_secureboot ; then
+    ewarn "VirtualBox service can not be started as running under enabled Secure Boot." ; eend 0
+    return
+  fi
+
+  einfo "VirtualBox service detected, trying to set up."
+  service_wrapper vboxdrv restart >>"${DEBUG}" 2>&1 ; eend $?
+
+  config_userfstab
+
+  einfo "Adding user ${fstabuser:-grml} to group vboxusers."
+  adduser "${fstabuser:-grml}" vboxusers >>"${DEBUG}" 2>&1
+  eend $?
 }
 # }}}
 
@@ -1957,5 +1923,43 @@ fi
 }
 # }}}
 
+# {{{ Easteregg (for 20 years grml.org)
+display_easteregg() {
+  einfo "You found the birthday easter egg!" ; eend 0
+
+  if [[ -x /bin/toilet && -x /usr/games/lolcat ]] ; then
+    visualize() { printf "%s\n" "$*" | toilet | /usr/games/lolcat ; }
+  elif [[ -x /bin/toilet ]] ; then
+    visualize() { printf "%s\n" "$*" | toilet ; }
+  else
+    visualize() { printf "%s\n" "$*" ; }
+  fi
+
+  visualize "   \o/   "
+  visualize "20 years"
+  visualize "grml.org"
+}
+
+config_easteregg() {
+  checkbootparam 'noeasteregg' && return 0
+
+  zmodload zsh/datetime 2>/dev/null || return 0
+  zmodload zsh/mathfunc 2>/dev/null || return 0
+
+  local birthday=1694822400            # := 2023-09-16 -> TZ=UTC date -d "2023-09-16" +%s
+  local one_month=$[24*30*3600]
+  local pi=3.14159265358979323846
+  local magic=$(( one_month/(pi/2) ))  # normalization factor, used to map the [birthday;birthday+-one_month] range onto [0;+-pi/2]
+
+  if [[ $(( abs(birthday-EPOCHSECONDS) )) -le $one_month ]] ; then
+    if [[ $(( rand48() )) -le $(( cos((birthday-EPOCHSECONDS)/magic) )) ]] ; then
+      display_easteregg
+    fi
+  fi
+
+  return 0
+}
+# }}}
+
 ## END OF FILE #################################################################
 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=2