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 ################################################################################
9 # {{{ path, variables, signals, umask, zsh
10 export PATH="/bin:/sbin:/usr/bin:/usr/sbin"
16 # initramfs layout since December 2012, backwards compatibility:
17 [ -d /lib/live/mount/medium ] && export LIVECD_PATH='/lib/live/mount/medium'
18 # initramfs layout since December 2018:
19 [ -d /run/live/medium ] && export LIVECD_PATH='/run/live/medium'
21 # Ignore these signals in non-interactive mode: INT, TERM, SEGV
22 [ -z "$PS1" ] && trap "" 2 3 11
24 if [ "$(cat /proc/1/comm 2>/dev/null)" = "systemd" ] ; then
31 if [ "$#" -lt 2 ] ; then
32 echo "Usage: service_wrapper <service> <action> [background]" >&2
41 systemctl "$action" "$service"
43 if [ "${background:-}" = "background" ] ; then
44 /etc/init.d/"$service" "$action" &
46 /etc/init.d/"$service" "$action"
53 if [ -n "$ZSH_VERSION" ] ; then
59 # avoid 'no matches found: ...'
60 iszsh && setopt no_nomatch # || echo "Warning: not running under zsh!"
63 # {{{ Read in boot parameters
64 if [ -z "$CMDLINE" ]; then
65 # if CMDLINE was set from the outside, we're debugging.
66 # otherwise, take CMDLINE from Kernel and config files.
67 CMDLINE="$(cat /proc/cmdline)"
68 [ -d ${LIVECD_PATH}/bootparams/ ] && CMDLINE="$CMDLINE $(cat ${LIVECD_PATH}/bootparams/* | tr '\n' ' ')"
69 modprobe 9p 2>/dev/null || true
70 if grep -q 9p /proc/filesystems ; then
72 if grep -q "$TAG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then
73 MOUNTDIR="$(mktemp -d)"
74 mount -t 9p -o trans=virtio,ro "$TAG" "$MOUNTDIR"
75 CMDLINE="$CMDLINE $(cat "$MOUNTDIR"/* 2>/dev/null | tr '\n' ' ')"
83 ### {{{ Utility Functions
85 # Get a bootoption's parameter: read boot command line and either
86 # echo last parameter's argument or return false.
94 result="${line##*[$ws]$1=}"
95 result="${result%%[$ws]*}"
103 # Check boot commandline for specified option
105 [ -n "$1" ] || ( echo "Error: missing argument to checkbootparam()" ; return 1 )
111 *[${ws}]"$1"=*|*[${ws}]"$1"[${ws}]*)
118 # Check if currently using a framebuffer
120 [ -e /dev/fb0 ] && return 0 || return 1
123 # Check wheter a configuration variable (like $CONFIG_TOHD) is
127 [yY][eE][sS]) return 0 ;; # it's set to 'yes'
128 [tT][rR][uU][eE]) return 0 ;; # it's set to 'true'
129 *) return 1 ;; # default
133 # Are we using grml-small?
135 grep -q small /etc/grml_version 2>>$DEBUG && return 0 || return 1
138 # if no password is set return a random password
140 [ -n "$PASSWD" ] && return 0
142 if [ -x /usr/bin/apg ] ; then
143 PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
144 elif [ -x /usr/bin/gpw ] ; then
146 elif [ -x /usr/bin/pwgen ] ; then
147 PASSWD="$(pwgen -1 8)"
148 elif [ -x /usr/bin/hexdump ] ; then
149 PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
150 elif [ -n "$RANDOM" ] ; then
151 PASSWD="grml${RANDOM}"
154 eerror "Empty passphrase and neither apg, gpw, pwgen, hexdump nor \$RANDOM available. Skipping."
162 # {{{ filesystems (proc, pts, sys) and fixes
164 [ -f /proc/version ] || mount -t proc /proc /proc 2>/dev/null
168 grep -q "/dev/pts" /proc/mounts || mount -t devpts /dev/pts /dev/pts 2>/dev/null
172 [ -d /sys/devices ] || mount -t sysfs /sys /sys 2>/dev/null
176 # {{{ Check if we are running in live mode or from HD
178 [ -e /etc/grml_cd ] || INSTALLED="yes"
181 # {{{ provide information about virtual environments
182 VIRTUAL=false # assume physical system by default
187 if virt-what 2>/dev/null | grep -q 'vmware' || \
188 imvirt 2>/dev/null | grep -iq "vmware" ; then
189 VIRTUAL=true; VMWARE=true; VIRTUAL_ENV='VMware'
192 if virt-what 2>/dev/null | grep -q 'kvm' || \
193 [ "$(imvirt 2>/dev/null)" = "KVM" ] ; then
194 VIRTUAL=true; KVM=true; VIRTUAL_ENV='KVM'
197 if virt-what 2>/dev/null | grep -q 'virtualbox' || \
198 [ "$(imvirt 2>/dev/null)" = "VirtualBox" ] ; then
199 VIRTUAL=true; VIRTUALBOX=true; VIRTUAL_ENV='VirtualBox'
203 # {{{ source lsb-functions , color handling
204 if checkbootparam 'nocolor'; then
205 . /etc/grml/lsb-functions
206 einfo "Disabling colors in bootsequence as requested on commandline." ; eend 0
208 . /etc/grml/lsb-functions
214 if checkbootparam 'log' || checkbootparam 'debug' ; then
215 export DEBUG="/tmp/grml.log.`date +%Y%m%d`"
217 einfo "Bootparameter log found, debug log file from grml-autoconfig available at '${DEBUG}'"
224 ### {{{ language configuration / localization
227 einfo "Activating language settings:"
230 # people can specify $LANGUAGE and $CONSOLEFONT in a config file
231 [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
233 # check for bootoption which overrides config from /etc/grml/autoconfig
234 BOOT_LANGUAGE="$(getbootparam 'lang' 2>>$DEBUG)"
235 [ -n "$BOOT_LANGUAGE" ] && LANGUAGE="$BOOT_LANGUAGE"
237 # set default to 'en' in live-cd mode iff $LANGUAGE is not set yet
238 if [ -z "$INSTALLED" ] ; then
239 [ -n "$LANGUAGE" ] || LANGUAGE='en'
242 if [ -x /usr/sbin/grml-setlang ] ; then
243 # if bootoption lang is used update /etc/default/locale accordingly
244 if [ -n "$BOOT_LANGUAGE" ] ; then
245 /usr/sbin/grml-setlang "$LANGUAGE"
246 # otherwise default to lang=en
248 /usr/sbin/grml-setlang "en"
254 if [ -z "$CONSOLEFONT" ] ; then
255 if ! checkbootparam 'nodefaultfont' >>$DEBUG 2>&1 ; then
256 if [ -r /usr/share/consolefonts/Uni3-Terminus16.psf.gz ] ; then
257 CONSOLEFONT='Uni3-Terminus16'
259 ewarn "/usr/share/consolefonts/Uni3-Terminus16.psf.gz not available. Please upgrade package console-setup-linux." ; eend 1
262 CONSOLEFONT='Lat15-Terminus16'
266 fi # not running systemd
268 # export it now, so error messages get translated, too
269 [ -r /etc/default/locale ] && . /etc/default/locale
274 KEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
275 [ -n "$KEYBOARD" ] || KEYBOARD="$LANGUAGE"
276 # "symbols/en" doesn't exist, so rewrite to "us"
277 [[ "$KEYBOARD" == 'en' ]] && KEYBOARD="us"
279 if [ -r /etc/default/keyboard ] ; then
280 sed -i "s/^XKBLAYOUT=.*/XKBLAYOUT=\"$KEYBOARD\"/" /etc/default/keyboard
284 sed -i "s/^XKBVARIANT=.*/XKBVARIANT=\"nodeadkeys\"/" /etc/default/keyboard
289 service_wrapper console-setup restart >>$DEBUG 2>&1 ; eend $?
290 else # not running systemd, keeing for backwards compatibility:
291 # configure keyboard layout, read in already set values first:
292 [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
294 # now allow keyboard override by boot commandline for later use:
295 KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
296 [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
297 # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
298 [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
299 [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
301 # modify /etc/sysconfig/keyboard only in live-cd mode:
302 if [ -z "$INSTALLED" ] ; then
304 local LANGUAGE="$BOOT_LANGUAGE"
305 . /etc/grml/language-functions
306 # allow setting xkeyboard explicitly different than console keyboard
307 KXKEYBOARD="$(getbootparam 'xkeyboard' 2>>$DEBUG)"
308 if [ -n "$KXKEYBOARD" ]; then
309 XKEYBOARD="$KXKEYBOARD"
310 KDEKEYBOARD="$KXKEYBOARD"
311 elif [ -n "$KKEYBOARD" ]; then
312 XKEYBOARD="$KKEYBOARD"
313 KDEKEYBOARD="$KKEYBOARD"
316 # duplicate of previous code to make sure /etc/grml/language-functions
317 # does not overwrite our values....
318 # now allow keyboard override by boot commandline for later use:
319 KKEYBOARD="$(getbootparam 'keyboard' 2>>$DEBUG)"
320 [ -n "$KKEYBOARD" ] && KEYTABLE="$KKEYBOARD"
321 # notce: de/at is a bad choice, so take de-latin1-nodeadkeys instead:
322 [[ "$KKEYBOARD" == 'de' ]] && KEYTABLE=de-latin1-nodeadkeys
323 [[ "$KKEYBOARD" == 'at' ]] && KEYTABLE=de-latin1-nodeadkeys
325 # write keyboard related variables to file for later use
326 [ -d /etc/sysconfig ] || mkdir /etc/sysconfig
327 if ! [ -e /etc/sysconfig/keyboard ] ; then
328 echo "KEYTABLE=\"$KEYTABLE\"" > /etc/sysconfig/keyboard
329 echo "XKEYBOARD=\"$XKEYBOARD\"" >> /etc/sysconfig/keyboard
330 echo "KDEKEYBOARD=\"$KDEKEYBOARD\"" >> /etc/sysconfig/keyboard
331 echo "KDEKEYBOARDS=\"$KDEKEYBOARDS\"" >> /etc/sysconfig/keyboard
335 [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard
340 # we have to set up all consoles, therefore loop it over all ttys:
341 NUM_CONSOLES=$(fgconsole --next-available 2>/dev/null)
342 if [ -n "$NUM_CONSOLES" ] ; then
343 NUM_CONSOLES=$(expr ${NUM_CONSOLES} - 1)
344 [ ${NUM_CONSOLES} -eq 1 ] && NUM_CONSOLES=6
346 CUR_CONSOLE=$(fgconsole 2>/dev/null)
348 if [ -x "$(which setfont)" ] ; then
350 elif [ -x "$(which consolechars)" ] ; then
351 use_consolechars=true
353 eerror "Neither setfont nor consolechars tool present, can not set font."
358 if [ -n "$CHARMAP" ] ; then
359 einfo "Setting font to ${CHARMAP}"
361 for vc in $(seq 0 ${NUM_CONSOLES}) ; do
362 if $use_setfont ; then
363 setfont -C /dev/tty${vc} $CHARMAP ; RC=$?
364 elif $use_consolechars ; then
365 consolechars --tty=/dev/tty${vc} -m ${CHARMAP} ; RC=$?
368 if [ -n "$CUR_CONSOLE" ] ; then
369 [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
374 if checkbootparam 'noconsolefont' ; then
375 ewarn "Skipping setting console font as requested on boot commandline." ; eend 0
377 if [ -n "$CONSOLEFONT" ] ; then
378 einfo "Setting font to ${CONSOLEFONT}"
380 for vc in $(seq 0 ${NUM_CONSOLES}) ; do
381 if $use_setfont ; then
382 setfont -C /dev/tty${vc} ${CONSOLEFONT} ; RC=$?
383 elif $use_consolechars ; then
384 consolechars --tty=/dev/tty${vc} -f ${CONSOLEFONT} ; RC=$?
387 if [ -n "$CUR_CONSOLE" ] ; then
388 [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE
394 # Set default keyboard before interactive setup
395 if [ -n "$KEYTABLE" ] ; then
396 einfo "Running loadkeys for ${WHITE}${KEYTABLE}${NORMAL} in background"
397 loadkeys -q $KEYTABLE &
401 # activate unicode console if running within utf8 environment
402 if [ -r /etc/default/locale ] ; then
403 if grep -q "LANG=.*UTF" /etc/default/locale ; then
404 einfo "Setting up unicode environment."
405 unicode_start ; eend $?
408 fi # not running systemd
416 if ! checkbootparam 'hostname' ; then
420 HOSTNAME="$(getbootparam 'hostname' 2>>$DEBUG)"
421 if [ -z "$HOSTNAME" ] && [ -x /usr/bin/random-hostname ] ; then
422 einfo "Generating random hostname as no hostname was specified."
423 HOSTNAME="$(/usr/bin/random-hostname)"
427 einfo "Setting hostname to $HOSTNAME as requested."
428 grml-hostname $HOSTNAME >>$DEBUG
433 # fstabuser (needed when running from harddisk with username != grml {{{
435 # force load of build-in and local config
436 [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
437 [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig.local
439 # 1st. try configured fstab user
440 if [ -n "$CONFIG_FSTAB_USER" ] ; then
441 fstabuser=$(getent passwd $CONFIG_FSTAB_USER | cut -d: -f1)
444 # 2nd. use standard user id
445 [ -n "$fstabuser" ] || fstabuser=$(getent passwd 1000 | cut -d: -f1)
447 # 3rd. use standard user name
448 [ -n "$fstabuser" ] || fstabuser=$(getent passwd grml | cut -d: -f1)
450 # if not yet set fall back to 'root' user, avoid bad /etc/fstab
451 [ -n "$fstabuser" ] || fstabuser='root'
455 # local_user (needed when running with username != grml {{{
458 # force load of build-in and local config
459 [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig
460 [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig.local
462 # 1st. try id of primary user
463 localuser=$(getent passwd 1000 | cut -d: -f1)
465 # 2nd. use name standard user
466 [ -n "$localuser" ] || localuser=$(getent passwd grml | cut -d: -f1)
470 # {{{ Set clock (Local time is more often used than GMT, so it is default)
472 # don't touch the files if running from harddisk:
473 if [ -z "$INSTALLED" ]; then
474 # The default hardware clock timezone is stated as representing local time.
477 if [ -f /etc/default/rcS ] ; then
478 grep -q "^UTC=" /etc/default/rcS || echo "UTC=no" >> /etc/default/rcS
479 checkbootparam 'utc' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
480 checkbootparam 'gmt' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS
481 checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=no|" /etc/default/rcS
482 grep -q -i "^UTC=yes" /etc/default/rcS && UTC="-u"
483 # recent initscripts package versions don't ship /etc/default/rcS anymore, instead rely on /etc/adjtime
484 elif [ -f /etc/adjtime ] ; then
485 checkbootparam 'utc' >>$DEBUG 2>&1 && sed -i "s/^LOCAL/UTC/" /etc/adjtime
486 checkbootparam 'gmt' >>$DEBUG 2>&1 && sed -i "s/^LOCAL/UTC/" /etc/adjtime
487 checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s/^UTC$/LOCAL/" /etc/adjtime
488 grep -q "^UTC$" /etc/adjtime && UTC="-u"
491 # hwclock uses the TZ variable
492 KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
493 [ -z "$KTZ" ] && [ -r /etc/timezone ] && KTZ=$(cat /etc/timezone)
494 if [ ! -f "/usr/share/zoneinfo/$KTZ" ] ; then
495 ewarn "Warning: unknown timezone $KTZ" ; eend 1
497 ewarn "Falling back to timezone $KTZ" ; eend 0
500 if ! [ -r /dev/rtc ] ; then
501 ewarn "Warning: realtime clock not available, trying to execute hwclock anyway." ; eend 0
504 ERROR=$(TZ="$KTZ" hwclock $UTC -s 2>&1 | head -1) ; RC=$?
505 if [ -n "$ERROR" ] ; then
507 ERROR=$(TZ="$KTZ" hwclock $UTC -s --directisa 2>&1 | head -1)
508 if [ -n "$ERROR" ] ; then
509 eerror "Problem running hwclock: $ERROR" ; eend 1
518 # {{{ print kernel info
520 if $VIRTUAL && [ -n "$VIRTUAL_ENV" ] ; then
521 einfo "Running Linux Kernel $KERNEL inside $VIRTUAL_ENV" ; eend 0
523 einfo "Running Linux Kernel $KERNEL" ; eend 0
526 if [ -r /proc/cpuinfo ] ; then
527 if egrep -q '^flags.*(vmx|svm)' /proc/cpuinfo ; then
529 einfo 'CPU(s) featuring virtualization technology detected' ; eend 0
534 if [ -d /proc/xen ] ; then
536 einfo 'Running kernel featuring support for Xen detected' ; eend 0
543 # helper function to check whether we're running under (enabled) Secure Boot
544 running_under_secureboot() {
545 # systemd does this for us, but if we are not running under systemd then mokutil
546 # doesn't work as needed as it relies on /sys/firmware/efi/efivars (while
547 # /sys/firmware/efi/vars would exist)
549 if modprobe efivarfs &>/dev/null ; then
550 mount -t efivarfs efivarfs /sys/firmware/efi/efivars
554 if [[ -x "$(command -v mokutil)" ]] ; then
555 if mokutil --sb-state 2>/dev/null | grep -q 'SecureBoot enabled' ; then
561 if modprobe efivarfs &>/dev/null ; then
562 if od -An -t u1 /sys/firmware/efi/vars/SecureBoot-*/data 2>/dev/null | grep -q 1 ; then
572 if running_under_secureboot ; then
573 einfo "SecureBoot is enabled" ; eend 0
575 einfo "SecureBoot not detected" ; eend 0
582 # don't touch the files if running from harddisk:
583 if [ -z "$INSTALLED" ]; then
584 KTZ="$(getbootparam 'tz' 2>>$DEBUG)"
585 if [ -n "$KTZ" ] ; then
586 if [ ! -f "/usr/share/zoneinfo/$KTZ" ]
588 ewarn "Warning: unknown timezone $KTZ"; eend 0
590 einfo "Setting timezone."
592 area=$(echo $KTZ | cut -d '/' -f1)
593 zone=$(echo $KTZ | cut -d '/' -f2)
594 echo "tzdata tzdata/Areas select $area" | debconf-set-selections
595 echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections
597 echo $KTZ > /etc/timezone
599 cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $?
606 # activate serial console {{{
608 if checkbootparam 'console'; then
609 # this hack is no longer necessary with systemd
618 einfo "Bootoption for serial console detected:"
622 line="${line#*[$ws]}"
624 while [ -n "$line" ]; do
628 local device="${this%%,*}"
629 local device="${device##*=}"
630 if echo $serial | grep -q ttyS ; then
631 local option="${serial##*,}"
632 # default (works for kvm & CO):
633 local speed="115200,57600,38400,19200,9600,4800,2400,1200";
634 # ... unless overriden by command line:
636 115200*) speed=115200 ;;
637 57600*) speed=57600 ;;
638 38400*) speed=38400 ;;
639 19200*) speed=19200 ;;
646 einfo "Activating console login on device ${device} with speed ${speed}."
647 local number="${device#ttyS}"
648 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
655 this="${line%%[$ws]*}"
656 line="${line#*[$ws]}"
659 if [ -n "$telinitq" ]; then
669 if checkbootparam 'testcd' ; then
670 einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option."
674 local FOUND_FILE=false
675 local logfile='/tmp/md5sum.log'
679 for md5 in $(find "${LIVECD_PATH}" -name md5sums) ; do
680 einfo "Checking files against $md5, this may take a while..."
685 md5sum -c $(basename "$md5") |& tee -a "${logfile}"
686 if [ $pipestatus[1] -eq 0 ] ; then
692 if ! $FOUND_FILE ; then
693 eerror 'Error: Could not find md5sum file' ; eend 1
698 einfo "Everything looks OK" ; eend 0
700 eerror 'Checksum failed for theses files:' ; eend 1
701 egrep -v '(^md5sum:|OK$)' "${logfile}"
702 eerror 'Data on the medium is possibly incomplete/damaged or RAM of your system is broken.' ; eend 1
703 einfon "Hit return to continue, or press the power button to shut down system."
712 # {{{ blacklist specific module [ used in /etc/init.d/udev ]
714 if checkbootparam 'blacklist' ; then
715 if [ -z "$INSTALLED" ]; then
716 einfo "Bootoption blacklist found."
717 BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)"
718 BLACKLIST_FILE='/etc/modprobe.d/grml.conf'
719 if [ -n "$BLACK" ] ; then
720 for module in $(echo ${BLACK//,/ }) ; do
721 einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}."
722 echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE"
723 echo "blacklist $module" >> "$BLACKLIST_FILE"
724 echo "alias $module off" >> "$BLACKLIST_FILE"
725 echo "# end entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $?
728 eerror "No given module for blacklist found. Blacklisting will not work therefore."
731 ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1
733 einfo "Please blacklist the module(s) manually using the 'blacklist' script."
743 echo "systemd detected, no acpi(d) stuff needed." >>"$DEBUG"
747 if checkbootparam 'noacpi'; then
748 ewarn "ACPI: Not loading modules as requested by boot option \"noacpi\"." ; eend 0
749 elif checkbootparam 'nogrmlacpi' ; then
750 ewarn "ACPI: Not loading modules as requested by boot option \"nogrmlacpi\"." ; eend 0
751 elif [ ! -d /proc/acpi ] ; then
752 ewarn "ACPI: Kernel support not present." ; eend 0
754 einfo "ACPI: Loading modules (disable with boot option noacpi / nogrmlacpi): "
757 for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do
759 basename="${basename%%.*}"
760 case "$basename" in *_acpi)
761 egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;;
763 modprobe $basename >>$DEBUG 2>&1 && found="yes"
764 local BASE="$BASE $basename"
766 if [ -n "$found" ] ; then
767 einfo "$BASE" ; eend 0
769 ewarn "(none)" ; eend 1
771 if ! pgrep acpid >/dev/null ; then
772 einfo "Starting acpi daemon."
773 service_wrapper acpid.socket start >>$DEBUG 2>&1 ; eend $?
774 service_wrapper acpid start >>$DEBUG 2>&1 ; eend $?
776 ewarn "acpi daemon already running."
786 if checkbootparam 'brltty' ; then
787 einfo "Starting brltty service as requested on boot commandline."
788 service_wrapper brltty start ; eend $?
793 # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now
796 NOSWAP="yes" # we do not use swap by default!
797 if checkbootparam 'swap' || checkbootparam 'anyswap' ; then
799 checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP=""
802 # Scan for swap, config, homedir - but only in live-mode
803 if [ -z "$INSTALLED" ] ; then
804 [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested."
807 HOMEDIR="$(getbootparam 'home')"
808 if [ -n "$partitions" ]; then
809 while read p m f relax; do
810 case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac
811 partoptions="users,exec"
813 # it's a swap partition?
816 if [ -n "$NOSWAP" ]; then
817 ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)"
820 case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in
821 S1SUSP|S2SUSP|pmdisk|[zZ]*)
822 if [ -n "$ANYSWAP" ] ; then
823 einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]."
824 swapon $p 2>>$DEBUG ; eend $?
826 ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)"
830 if [[ "$p" == LABEL* ]] ; then
831 p=$(blkid -t $p | awk -F: '{print $1}')
833 if grep -q $p /proc/swaps ; then
834 ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0
836 if [ -b "$p" ] ; then
837 einfo "Using swap partition ${WHITE}${p}${NORMAL}."
838 swapon $p 2>>$DEBUG ; eend $?
840 ewarn "$p is not a valid block device - not using it therefore." ; eend 0
849 esac # it's a swap partition?
854 vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;;
855 ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;;
857 # *) NONEFOUND='1'; continue ;;
861 if [ -z "$NOSWAP" ] ; then
862 mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue
863 # Activate swapfile, if exists
864 SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)"
866 if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then
867 mount -o remount,rw $m && MOUNTED=1
868 if swapon "$SWAPFILE" 2>>$DEBUG ; then
870 einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}."
872 fnew="$SWAPFILE swap swap defaults 0 0"
873 grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab
874 GRML_SWP="$GRML_SWP $SWAPFILE"
877 mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
880 # use a image as home
881 IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)"
882 if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then
883 if [ -n "$HOMEDIR" ]; then
884 if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then
888 if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" </dev/console >/dev/console 2>&1; then
890 mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1
895 # Umount, if not in use
896 [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null
908 if checkbootparam 'nocpu'; then
909 ewarn "Skipping CPU detection as requested on boot commandline." ; eend 0
913 if ! [ -x "$(which lscpu)" ] ; then
914 ewarn "Skipping CPU detection due to lack of lscpu."; eend 0
918 local cpu_info num_cpus
920 cpu_info="$(lscpu | sed -n '/^Model name:/s/[^:]*:\s*//p')"
921 num_cpus=$(grep -c processor /proc/cpuinfo)
923 einfo "Found ${num_cpus} CPU(s): ${cpu_info}"
928 # {{{ autostart of ssh
930 if checkbootparam 'ssh' ; then
932 PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)"
935 einfo "Bootoption ssh found, trying to set password for root and user $localuser"
936 [ -z "$localuser" ] && eend 1
939 if [ -z "$PASSWD" ] ; then
940 set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0
944 if [ -n "$PASSWD" ] ; then
946 if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
950 echo "$localuser:$PASSWD" | chpasswd $chpass_options
951 echo "root:$PASSWD" | chpasswd $chpass_options
954 ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
958 einfo "Starting secure shell server in background for root and user $localuser"
959 service_wrapper haveged start >>$DEBUG 2>>$DEBUG
960 service_wrapper rmnologin start >>$DEBUG 2>>$DEBUG
961 service_wrapper ssh start background >>$DEBUG 2>>$DEBUG
969 # {{{ display hostkeys of SSH server
970 config_display_ssh_fingerprints() {
971 if ! ls /etc/ssh/ssh_host_\*_key >/dev/null 2>&1 ; then
972 return 0 # no SSH host keys present
975 einfo "SSH key fingerprints:"
976 for file in /etc/ssh/ssh_host_*_key ; do
978 ssh-keygen -l -f $file
984 # {{{ autostart of x11vnc
986 if checkbootparam 'vnc' ; then
989 VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)"
990 einfo "Bootoption vnc found, trying to set password for user $localuser."
992 if [ -z "$VNC_PASSWD" ] ; then
993 if [ -x /usr/bin/apg ] ; then
994 VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)"
995 elif [ -x /usr/bin/gpw ] ; then
996 VNC_PASSWD="$(gpw 1)"
997 elif [ -x /usr/bin/pwgen ] ; then
998 VNC_PASSWD="$(pwgen -1 8)"
999 elif [ -x /usr/bin/hexdump ] ; then
1000 VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')"
1001 elif [ -n "$RANDOM" ] ; then
1002 VNC_PASSWD="${localuser}${RANDOM}"
1005 eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping."
1009 if [ -n "$VNC_PASSWD" ] ; then
1010 ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0
1015 # finally check if we have a password we can use:
1016 if [ -n "$VNC_PASSWD" ] ; then
1018 VNCDIR="/home/${localuser}/.vnc"
1019 [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1021 if [ ! -x /usr/bin/x11vnc ] ; then
1022 eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package."
1025 /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $?
1026 /bin/chown -R "$localuser": "$VNCDIR"
1029 if checkbootparam 'vnc_connect' ; then
1031 VNC_CONNECT="$(getbootparam 'vnc_connect' 2>>$DEBUG)"
1032 einfo "Bootoption vnc_connect found, will start vnc with connect to $VNC_CONNECT."
1033 #store the options in a file
1034 VNCDIR="/home/${localuser}/.vnc"
1035 [ -d "$VNCDIR" ] || mkdir "$VNCDIR"
1036 echo " --connect $VNC_CONNECT " >> $VNCDIR/options
1042 # {{{ set password for root and default user
1044 if checkbootparam 'passwd' >>$DEBUG 2>&1; then
1046 PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)"
1049 einfo "Bootoption passwd found, trying to set password for root and user $localuser"
1050 [ -z "$localuser" ] && eend 1
1053 if [ -z "$PASSWD" ] ; then
1054 set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0
1058 if [ -n "$PASSWD" ] ; then
1060 if chpasswd --help 2>&1 | grep -q -- '-m,' ; then
1064 echo "$localuser:$PASSWD" | chpasswd $chpass_options
1065 echo "root:$PASSWD" | chpasswd $chpass_options
1068 ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
1074 if checkbootparam 'encpasswd' >>$DEBUG 2>&1; then
1076 PASSWD="$(getbootparam 'encpasswd' 2>>$DEBUG)"
1078 if [ -z "$PASSWD" ] ; then
1079 eerror "No hashed password found, can not set password."
1085 einfo "Bootoption encpasswd found, trying to set hashed password for root and user $localuser"
1086 [ -z "$localuser" ] && eend 1
1088 if [ -n "$PASSWD" ] ; then
1091 echo "$localuser:$PASSWD" | chpasswd $chpass_options
1092 echo "root:$PASSWD" | chpasswd $chpass_options
1095 ewarn "Warning: please change the password for root and user $localuser as soon as possible!"
1105 if ! [ -x /usr/bin/amixer ] ; then
1106 logger -t grml-autoconfig "amixer binary not available"
1110 if ! [ -r /proc/asound/cards ] ; then
1111 ewarn "No soundcard present, skipping mixer settings therefore."
1116 for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do
1117 einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\""
1120 if checkbootparam 'vol' ; then
1121 VOL="$(getbootparam 'vol' 2>>$DEBUG)"
1122 if [ -z "$VOL" ] ; then
1123 eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)."
1131 if checkbootparam 'nosound' ; then
1132 einfo "Muting sound devices on request."
1133 ERROR=$(amixer -q set Master mute)
1135 if [ -n "$ERROR" ] ; then
1137 eerror "Problem muting sound devices: $ERROR"
1141 elif [ -z "$INSTALLED" ] ; then
1142 einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}."
1144 if checkbootparam 'micvol' ; then
1145 MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)"
1146 einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}."
1151 CONTROLS=$(amixer -c $card scontrols | awk -F"Simple mixer control " '{print $2}')
1154 for CONTROL in ${=CONTROLS} ; do
1155 # such devices can not be controlled with amixer ... unmute
1156 [[ "$CONTROL" == *Console* ]] && continue
1158 if ! echo "${CONTROL}" | grep -q -i "mic" ; then
1159 if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*pswitch' ; then
1160 amixer -c $card -q set "${CONTROL}" unmute
1162 if amixer -c $card sget "${CONTROL}" | grep -q -P 'Capabilities:.*(pvolume| volume)' ; then
1163 amixer -c $card -q set "${CONTROL}" "${VOL}"%
1167 if [ ${MICVOL} -ne 0 ] ; then
1168 if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cswitch' ; then
1169 amixer -c $card -q set "${CONTROL}" unmute
1171 if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cvolume' ; then
1172 amixer -c $card -q set "${CONTROL}" $MICVOL%
1178 fi # checkbootparam 'nosound'
1184 # {{{ syslog service
1186 if checkbootparam 'nosyslog'; then
1187 ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0
1189 einfo "Starting rsyslog in background."
1190 service_wrapper rsyslog start >>$DEBUG
1198 if checkbootparam 'nogpm'; then
1199 ewarn "Not starting GPM as requested on boot commandline." ; eend 0
1201 if ! [ -r /dev/input/mice ] ; then
1202 eerror "No mouse found - not starting GPM." ; eend 1
1204 einfo "Starting gpm in background."
1205 service_wrapper gpm start background >>$DEBUG
1214 if checkbootparam 'services' ; then
1215 SERVICE="$(getbootparam 'services' 2>>$DEBUG)"
1216 SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g')
1217 SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g')
1218 for service in $(echo -e $SERVICELIST) ; do
1219 # support running (custom) init scripts in non-blocking mode
1220 # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND".
1221 if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then
1222 einfo "Starting service ${service}."
1223 service_wrapper "${service}" start >>$DEBUG
1225 einfo "Starting service ${service} in background."
1226 service_wrapper "${service}" start background >>$DEBUG
1236 [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 )
1237 SOURCE=$(eval echo "$1")
1240 wget --timeout=10 --dns-timeout=10 --connect-timeout=10 --tries=1 \
1241 --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1
1243 einfo "Trying to get ${WHITE}${TARGET}${NORMAL}"
1245 if checkbootparam 'getfile.retries' ; then
1246 local counter="$(getbootparam 'getfile.retries' 2>>$DEBUG)"
1251 while ! getconfig && [[ "$counter" != 0 ]] ; do
1252 echo -n "Sleeping for 1 second and trying to get config again... "
1253 counter=$(( counter-1 ))
1254 echo "$counter tries left" ; sleep 1
1256 if [ -s "$TARGET" ] ; then
1257 einfo "Downloading was successfull." ; eend 0
1258 einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: "
1259 md5sum ${TARGET} ; eend 0
1262 einfo "Sorry, could not fetch ${SOURCE}" ; eend 1
1270 if checkbootparam 'netconfig' ; then
1271 CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)"
1272 CONFIGFILE='/tmp/netconfig.grml'
1274 if get_remote_file ${CONFIG} ${CONFIGFILE} ; then
1275 cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $?
1282 # {{{ remote scripts
1283 config_netscript() {
1284 if checkbootparam 'netscript' ; then
1285 CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)"
1286 SCRIPTFILE='/tmp/netscript.grml'
1288 if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then
1289 chmod +x ${SCRIPTFILE}
1290 einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $?
1297 # {{{ start X window system via grml-x
1301 # make sure we start X only if startx is used *before* a nostartx option
1302 # so it's possible to disable automatic X startup using nostart
1303 if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then
1304 if [ -x "$(which X)" ] ; then
1305 if [ -z "$INSTALLED" ] ; then
1306 WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)"
1307 if [ -z "$WINDOWMANAGER" ] ; then
1308 einfo "No window manager specified. Using default one." && eend 0
1310 einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0
1312 einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles."
1315 if [ -n "$WINDOWMANAGER" ] ; then
1316 mkdir -p /var/run/grml-x/
1317 echo "$WINDOWMANAGER" > /var/run/grml-x/window-manager
1322 cat>|/etc/init.d/startx<<EOF
1324 su "${localuser}" -c "/usr/bin/grml-x ${WINDOWMANAGER}"
1326 chmod 755 /etc/init.d/startx
1328 # adjust inittab for startx
1329 if grep -q '^6:' /etc/inittab ; then
1330 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
1331 else # just append tty6 to inittab if no definition is present:
1332 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
1335 /sbin/telinit q ; eend $?
1337 if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then
1338 sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config
1340 echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config
1344 eerror "We are not running in live mode - startx will not work, skipping it."
1345 eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1
1348 eerror "/usr/bin/X is not present on this grml flavour."
1349 eerror " -> Boot parameter startx does not work therefore." ; eend 1
1355 # {{{ configuration framework
1357 if checkbootparam 'extract' ; then
1358 EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)"
1359 EXTRACTOPTIONS="-- -x $EXTRACT"
1363 config_finddcsdir() {
1364 # - If no GRMLCFG partition is found and noautoconfig is _not_ given
1365 # on the command line, nothing is changed and the dcs files are
1366 # searched within the .iso, $dcs-dir is set to the root directory
1368 # - If a GRMLCFG partition is found, $dcs-dir is set to the root of
1369 # the GRMLCFG partition unless noautoconfig is set. If noautoconfig is
1370 # set, $dcs-dir is set to the root directory within the .iso.
1371 # - If myconfig=foo is set on the command line, $dcs-dir is set to
1372 # foo, even if a GRMLCFG partition is present.
1375 # autoconfig, see issue673
1376 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)"
1377 [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG"
1378 if checkbootparam 'noautoconfig' ; then
1379 DCSDIR="${LIVECD_PATH}" # set default so it works for "scripts" boot option as expected
1380 ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0
1382 if [ -z "$INSTALLED" ] ; then
1383 if checkbootparam 'myconfig' ; then
1384 DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)"
1385 if [ -z "$DCSDEVICE" ]; then
1386 eerror "Error: No device for bootoption myconfig provided." ; eend 1
1387 fi # [ -z "$DCSDEVICE" ]
1388 elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig
1389 einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0
1391 DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}')
1393 modprobe 9p 2>/dev/null || true
1394 if [ -z "$DCSDEVICE" ] && grep -q 9p /proc/filesystems ; then
1395 if grep -q "$GRMLCFG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then
1396 einfo "Found 9p-virtio fs with mount_tag $GRMLCFG"
1397 DCSDEVICE="$GRMLCFG"
1398 MOUNTOPTIONS="ro,trans=virtio"
1403 if [ -n "$DCSDEVICE" ]; then
1404 DCSMP="/mnt/grmlcfg"
1409 # if not specified/present then assume default:
1410 if [ -z "$DCSDEVICE" ]; then
1411 DCSDIR="${LIVECD_PATH}"
1414 einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0
1415 DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')"
1416 if [ -n "$DCSDIR" ]; then
1417 ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0
1419 [ -d $DCSMP ] || mkdir $DCSMP
1420 umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted
1421 mount -o ${MOUNTOPTIONS:-ro} -t ${DCSFS:-auto} $DCSDEVICE $DCSMP ; RC="$?"
1422 if [[ $RC == 0 ]]; then
1423 einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0
1425 eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1
1434 if [ -n "$DCSDIR" -a "$DCSDIR" != "${LIVECD_PATH}" ] ; then
1435 einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0
1436 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then
1437 einfo "Debs, config, scripts will be read from the live image directly." ; eend 0
1443 if checkbootparam 'partconf' ; then
1444 MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)"
1445 if [ -n "$MOUNTDEVICE" ]; then
1446 [ -d /mnt/grml ] || mkdir /mnt/grml
1447 mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?"
1448 if [[ $RC == 0 ]]; then
1449 einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0
1450 einfo "Copying files from $MOUNTDEVICE over grml system."
1451 for file in `cat /etc/grml/partconf` ; do
1452 [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file"
1453 [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file} ${file} && echo "copied: $file"
1456 einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1
1457 fi # mount $MOUNTDEVICE
1458 grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml
1460 einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1
1461 fi # [ -n "$MOUNTDEVICE" ]
1466 # {{{ /cdrom/.*-options
1468 if checkbootparam 'debs' ; then
1469 iszsh && setopt localoptions shwordsplit
1470 DEBS="$(getbootparam 'debs' 2>>$DEBUG)"
1471 if [ -z "$DEBS" ] ; then
1474 if ! echo $DEBS | grep -q '/'; then
1475 # backwards compatibility: if no path is given get debs from debs/
1478 einfo "Trying to install Debian package(s) ${DEBS}"
1479 DEBS="$(eval echo ${DCSDIR}/$DEBS)"
1480 dpkg -i $DEBS ; eend $?
1485 if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1486 SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)"
1487 if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then
1488 SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)"
1490 if ! echo $SCRIPTS | grep -q '/'; then
1491 # backwards compatibility: if no path is given get scripts from scripts/
1492 SCRIPTS="scripts/$SCRIPTS"
1494 if [ -n "$SCRIPTS" ]; then
1495 SCRIPTS="${DCSDIR}/$SCRIPTS"
1496 if [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1497 einfo "Trying to execute ${SCRIPTS}"
1500 elif [ -d "$SCRIPTS" ]; then
1501 einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:"
1502 run-parts --regex '.*' $SCRIPTS
1505 einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:"
1514 if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then
1515 CONFIG="$(getbootparam 'config' 2>>$DEBUG)"
1516 if [ -z "$CONFIG" ]; then
1517 CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)"
1519 if [ -n "$CONFIG" ]; then
1520 if [ -d "${DCSDIR}/${CONFIG}" ] ; then
1521 einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}"
1523 cp -a ${DCSDIR}/${CONFIG}/* /
1524 elif [ -f "${DCSDIR}/${CONFIG}" ]; then
1525 einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}"
1528 unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $?
1530 ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1
1537 # {{{ confing_umount_dcsdir
1538 config_umount_dcsdir(){
1539 # umount $DCSMP if it was mounted by finddcsdir
1540 grep -q "$DCSMP" /proc/mounts && umount "$DCSMP"
1546 if checkbootparam 'mypath' ; then
1547 MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)"
1548 einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path"
1549 touch /etc/grml/my_path
1550 chmod 644 /etc/grml/my_path
1551 # make sure the directories exist:
1553 for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do
1554 if ! [ -d "$i" ] ; then
1555 einfo "Creating directory $i"
1556 mkdir -p "$i" ; eend $?
1559 grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $?
1567 [ -n "$INSTALLED" ] && return 0
1569 if checkbootparam 'noraid' || checkbootparam 'noswraid' || \
1570 checkbootparam 'raid=noautodetect' ; then
1571 ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0
1573 [ -e /proc/mdstat ] || modprobe md_mod
1574 if ! [ -x /sbin/mdadm ] ; then
1575 eerror "mdadm not available, can not execute it." ; eend 1
1578 # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1579 # find out whether we have a valid configuration file already
1580 if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then
1581 einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm."
1582 [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old
1583 MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $?
1585 ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0
1588 if ! checkbootparam 'swraid' ; then
1591 einfo "Just run 'mdadm --assemble --scan' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1593 einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart."
1597 einfo "Bootoption swraid found. Searching for software RAID arrays:"
1601 for line in $(mdadm --assemble --scan 2>&1) ; do
1603 *'No arrays found'*)
1604 ewarn "$line" ; eend 0
1607 einfo "$line" ; eend 0
1614 if [ -r /proc/mdstat ] ; then
1616 MDSTAT=$(grep '^md[0-9]' /proc/mdstat)
1617 if [ -z "$MDSTAT" ] ; then
1618 ewarn "No active arrays found" ; eend 0
1622 for line in $(grep '^md[0-9]' /proc/mdstat) ; do
1623 einfo "active arrays: $line" ; eend 0
1629 fi # bootoption swraid
1631 fi # is /sbin/mdadm executable?
1632 fi # check for bootoptions
1638 [ -n "$INSTALLED" ] && return 0
1640 if checkbootparam 'nodmraid' ; then
1641 ewarn "Skipping dmraid code as requested on boot commandline." ; eend 0
1645 if ! [ -x /sbin/dmraid ] ; then
1646 ewarn "dmraid not available, can not execute it." ; eend 1
1651 # usage: dmraid_wrapper <dmraid_option>
1652 [ -n "$1" ] || return 1
1658 for line in $(dmraid $1 ; echo errcode:$?); do
1660 *'no block devices found'*)
1661 einfo "No block devices found" ; eend 0
1665 einfo "No active dmraid devices found" ; eend 0
1684 if checkbootparam 'dmraid' ; then
1685 local ACTION="$(getbootparam 'dmraid' 2>>$DEBUG)"
1686 if [ "$ACTION" = "off" ] ; then
1687 # Deactivates all active software RAID sets:
1688 einfo "Deactivating present dmraid sets (as requested via dmraid=off):"
1691 # Activate all software RAID sets discovered:
1692 einfo "Activating present dmraid sets (as requested via dmraid):"
1699 # by default (no special bootoptions) discover all software RAID devices:
1700 einfo "Searching for any present dmraid sets:"
1705 # {{{ LVM (Logical Volumes)
1707 [ -n "$INSTALLED" ] && return 0
1709 if checkbootparam 'nolvm' ; then
1710 ewarn "Skipping LVM code as requested on boot commandline." ; eend 0
1712 if ! [ -x /sbin/lvm ] ; then
1713 eerror "LVM not available, can not execute it." ; eend 1
1715 if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then
1716 einfo "You seem to have logical volumes (LVM) on your system."
1719 einfo "Just run 'Start lvm2-pvscan@name' to activate LV or VG 'name' or boot using 'lvm' as bootoption for autostart."
1721 einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart."
1724 if checkbootparam 'lvm' ; then
1726 einfo "Bootoption LVM found, enabling related services."
1727 if [ -r /etc/init.d/lvm2-lvmetad ] ; then
1728 service_wrapper lvm2-lvmetad start ; eend $?
1730 if [ -r /etc/init.d/lvm2-lvmpolld ] ; then
1731 service_wrapper lvm2-lvmpolld start ; eend $?
1733 einfo "Searching for logical volumes and enabling them:"
1734 vgchange -ay ; eend $?
1736 einfo "Bootoption LVM found. Searching for logical volumes and enabling them:"
1737 service_wrapper lvm2 start ; eend $?
1742 fi # check for lvm binary
1743 fi # check for bootoption nolvm
1747 # {{{ debnet: setup network based on an existing one found on a partition
1749 if checkbootparam 'debnet' ; then
1750 einfo "Bootoption 'debnet' found. Searching for Debian network configuration: "
1756 # {{{ disable console blanking
1758 if checkbootparam 'noblank' ; then
1759 einfo "Bootoption noblank found. Disabling monitor blanking."
1760 setterm -blank 0 ; eend $?
1765 # {{{ debootstrap: automatic installation
1766 config_debootstrap(){
1768 if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then
1770 einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0
1772 if ! [ -x /usr/sbin/grml-debootstrap ] ; then
1774 eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1
1779 if checkbootparam 'target' ; then
1781 TARGET="$(getbootparam 'target' 2>>$DEBUG)"
1782 # notice: the following checks whether the given partition is available, if not the skip
1783 # execution of grml-debootstrap as it might result in data loss...
1784 if ! [ -r "$TARGET" ] ; then
1785 eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1
1789 eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1
1794 if checkbootparam 'grub' ; then
1796 GRUB="$(getbootparam 'grub' 2>>$DEBUG)"
1799 if checkbootparam 'groot' ; then
1801 GROOT="$(getbootparam 'groot' 2>>$DEBUG)"
1804 if checkbootparam 'release' ; then
1806 RELEASE="$(getbootparam 'release' 2>>$DEBUG)"
1809 if checkbootparam 'mirror' ; then
1811 MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)"
1814 if checkbootparam 'boot_append' ; then
1816 BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)"
1819 if checkbootparam 'password' ; then
1821 PASSWORD="$(getbootparam 'password' 2>>$DEBUG)"
1824 # now check which options are available
1825 if [ -n "TARGET" ] ; then
1826 TARGETCMD="--target $TARGET"
1830 eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1
1834 [ -n "$GRUB" ] && GRUBCMD="--grub $GRUB" || GRUBCMD=''
1835 [ -n "$GROOT" ] && GROOTCMD="--groot $GROOT" || GROOTCMD=''
1836 [ -n "$RELEASE" ] && RELEASECMD="--release $RELEASE" || RELEASECMD=''
1837 [ -n "$MIRROR" ] && MIRRORCMD="--mirror $MIRROR" || MIRRORCMD=''
1838 [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD" || PASSWORDCMD=''
1839 [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND=''
1841 # and finally write script and execute it
1842 cat>|/usr/bin/grml-debootstrap_noninteractive<<EOF
1844 AUTOINSTALL='yes' grml-debootstrap $TARGETCMD $GRUBCMD $GROOTCMD $RELEASECMD $MIRRORCMD $PASSWORDCMD $BOOT_APPEND
1847 chmod 750 /usr/bin/grml-debootstrap_noninteractive
1849 screen /usr/bin/grml-debootstrap_noninteractive
1850 einfo "Invoking a shell, just exit to continue booting..."
1853 fi # checkbootparam "BOOT_IMAGE=debian2hd
1857 # {{{ virtualbox shared folders
1858 config_virtualbox_shared_folders() {
1859 if ! $VIRTUALBOX ; then
1863 if checkbootparam 'novboxsf' ; then
1864 ewarn "Skipping VirtualBox Shared Folders setup as requested on boot commandline." ; eend 0
1866 einfo "VirtualBox detected, trying to set up Shared Folders."
1867 if ! modinfo vboxsf &>/dev/null ; then
1868 ewarn "vboxsf driver not present, not setting up VirtualBox Shared Folders."
1870 elif ! [ -x /usr/sbin/VBoxService ] ; then
1871 ewarn "virtualbox-guest-utils not installed, not setting up VirtualBox Shared Folders."
1876 einfo "Loading vboxsf driver."
1877 lsmod | grep -q vboxsf || modprobe vboxsf
1880 einfo "Adjusting /dev/vboxguest."
1881 chown root:vboxsf /dev/vboxguest
1882 chmod 660 /dev/vboxguest
1887 einfo "Adding user ${fstabuser:-grml} to group vboxsf."
1888 adduser "${fstabuser:-grml}" vboxsf >>"${DEBUG}" 2>&1
1891 einfo "Starting VBoxService."
1892 VBoxService >/dev/null
1895 local vbautomation='automation'
1896 if checkbootparam 'vbautomation'; then
1897 vbautomation="$(getbootparam 'vbautomation' 2>>$DEBUG)"
1900 if ! VBoxControl sharedfolder list | egrep -q "^[0-9]+ - ${vbautomation}(\s+|$)" ; then
1901 ewarn "No automount shared folder '$vbautomation' available"
1904 einfo "Found automount shared folder '$vbautomation'"
1907 local distri="$(getbootparam 'distri' 2>>$DEBUG)"
1908 [ -n "$distri" ] || distri='grml'
1910 local vbox_auto_sf="/media/sf_${vbautomation}"
1912 sleep 1 # ugly but necessary
1916 while ! [ -d "${vbox_auto_sf}" ] && [[ "$counter" != 0 ]]; do
1917 einfo "Waiting another second to retry access to ${vbox_auto_sf}"
1919 counter=$(( counter-1 ))
1924 if ! [ -d "${vbox_auto_sf}" ] ; then
1925 eerror "Giving up trying to access folder ${vbox_auto_sf} which doesn't seem to exist"
1928 einfo "Found shared folders automation directory $vbox_auto_sf"
1932 if checkbootparam 'novbautomation' ; then
1933 einfo "Bootoption novbautomation found. Disabling automation script execution."
1936 if ! [ -x "${vbox_auto_sf}/${distri}" ] ; then
1937 ewarn "Couldn't find an automation script named ${vbox_auto_sf}/${distri}"
1940 einfo "Executing '${vbox_auto_sf}/${distri}' now:"
1941 "${vbox_auto_sf}/${distri}"
1955 # {{{ VirtualBox application
1956 config_virtualbox_setup() {
1957 if checkbootparam 'novbox' ; then
1958 ewarn "Skipping VirtualBox setup as requested on boot commandline." ; eend 0
1962 if ! [ -x /usr/bin/VBox ] ; then
1966 if running_under_secureboot ; then
1967 ewarn "VirtualBox service can not be started as running under enabled Secure Boot." ; eend 0
1971 einfo "VirtualBox service detected, trying to set up."
1972 service_wrapper vboxdrv restart >>"${DEBUG}" 2>&1 ; eend $?
1976 einfo "Adding user ${fstabuser:-grml} to group vboxusers."
1977 adduser "${fstabuser:-grml}" vboxusers >>"${DEBUG}" 2>&1
1982 # {{{ Support customization
1984 if checkbootparam 'distri'; then
1985 DISTRI="$(getbootparam 'distri' 2>>$DEBUG)"
1986 if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then
1987 # make sure the desktop.jpg file is not a symlink, so copying does not file then
1988 [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg
1989 cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg
1995 # {{{ Easteregg (for 20 years grml.org)
1996 config_easteregg() {
1997 current_date=$(date +%Y-%m-%d)
1998 birthday="2023-09-16"
1999 one_month_later=$(date -d "${current_date} + 1 month" +%Y-%m-%d)
2001 einfo "You found the birthday easter egg!" ; eend 0
2003 # nothing to be done if it's more than one month since $birthday
2004 if ! [[ "${current_date}" == "${birthday}" || "${current_date}" == "${one_month_later}" ]]; then
2008 if [[ -x /bin/toilet && -x /usr/games/lolcat ]] ; then
2009 visualize() { printf "%s\n" "$*" | toilet | /usr/games/lolcat ; }
2010 elif [[ -x /bin/toilet ]] ; then
2011 visualize() { printf "%s\n" "$*" | toilet ; }
2013 visualize() { printf "%s\n" "$*" ; }
2017 visualize "20 years"
2018 visualize "grml.org"
2022 ## END OF FILE #################################################################
2023 # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=2