#!/bin/zsh # Filename: autoconfig.functions # Purpose: basic system configuration and hardware setup for grml system # Authors: grml-team (grml.org), (c) Michael Prokop # Bug-Reports: see http://grml.org/bugs/ # License: This file is licensed under the GPL v2. ################################################################################ # {{{ path, variables, signals, umask, zsh export PATH="/bin:/sbin:/usr/bin:/usr/sbin" DEBUG="/dev/null" 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 # Ignore these signals in non-interactive mode: INT, TERM, SEGV [ -z "$PS1" ] && trap "" 2 3 11 if [ "$(cat /proc/1/comm 2>/dev/null)" = "systemd" ] ; then SYSTEMD=true else SYSTEMD=false fi service_wrapper() { if [ "$#" -lt 2 ] ; then echo "Usage: service_wrapper " >&2 return 1 fi local service="$1" local action="$2" if $SYSTEMD ; then systemctl "$action" "$service" else /etc/init.d/"$service" "$action" fi } # zsh stuff iszsh(){ if [ -n "$ZSH_VERSION" ] ; then return 0 else return 1 fi } # avoid 'no matches found: ...' iszsh && setopt no_nomatch # || echo "Warning: not running under zsh!" # }}} # {{{ Read in boot parameters if [ -z "$CMDLINE" ]; then # if CMDLINE was set from the outside, we're debugging. # otherwise, take CMDLINE from Kernel and config files. CMDLINE="$(cat /proc/cmdline)" [ -d ${LIVECD_PATH}/bootparams/ ] && CMDLINE="$CMDLINE $(cat ${LIVECD_PATH}/bootparams/* | tr '\n' ' ')" modprobe 9p 2>/dev/null || true if grep -q 9p /proc/filesystems ; then TAG="grml-parameters" if grep -q "$TAG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then MOUNTDIR="$(mktemp -d)" mount -t 9p -o trans=virtio,ro "$TAG" "$MOUNTDIR" CMDLINE="$CMDLINE $(cat "$MOUNTDIR"/* 2>/dev/null | tr '\n' ' ')" umount "$MOUNTDIR" rmdir "$MOUNTDIR" fi fi fi # }}} ### {{{ Utility Functions # Get a bootoption's parameter: read boot command line and either # echo last parameter's argument or return false. getbootparam(){ local line local ws ws=' ' line=" $CMDLINE " case "$line" in *[${ws}]"$1="*) result="${line##*[$ws]$1=}" result="${result%%[$ws]*}" echo "$result" return 0 ;; *) # no match? return 1 ;; esac } # Check boot commandline for specified option checkbootparam(){ [ -n "$1" ] || ( echo "Error: missing argument to checkbootparam()" ; return 1 ) local line local ws ws=' ' line=" $CMDLINE " case "$line" in *[${ws}]"$1"=*|*[${ws}]"$1"[${ws}]*) return 0 ;; *) return 1 ;; esac } # Check if currently using a framebuffer hasfb() { [ -e /dev/fb0 ] && return 0 || return 1 } # Check wheter a configuration variable (like $CONFIG_TOHD) is # enabled or not checkvalue(){ case "$1" in [yY][eE][sS]) return 0 ;; # it's set to 'yes' [tT][rR][uU][eE]) return 0 ;; # it's set to 'true' *) return 1 ;; # default esac } # Are we using grml-small? checkgrmlsmall(){ grep -q small /etc/grml_version 2>>$DEBUG && return 0 || return 1 } # if no password is set return a random password set_passwd() { [ -n "$PASSWD" ] && return 0 if [ -x /usr/bin/apg ] ; then PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)" elif [ -x /usr/bin/gpw ] ; then PASSWD="$(gpw 1)" elif [ -x /usr/bin/pwgen ] ; then PASSWD="$(pwgen -1 8)" elif [ -x /usr/bin/hexdump ] ; then PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')" elif [ -n "$RANDOM" ] ; then PASSWD="grml${RANDOM}" else PASSWD='' eerror "Empty passphrase and neither apg, gpw, pwgen, hexdump nor \$RANDOM available. Skipping." eend 1 return 1 fi } ### }}} # {{{ filesystems (proc, pts, sys) and fixes mount_proc(){ [ -f /proc/version ] || mount -t proc /proc /proc 2>/dev/null } mount_pts(){ grep -q "/dev/pts" /proc/mounts || mount -t devpts /dev/pts /dev/pts 2>/dev/null } mount_sys(){ [ -d /sys/devices ] || mount -t sysfs /sys /sys 2>/dev/null } # }}} # {{{ Check if we are running in live mode or from HD INSTALLED="" [ -e /etc/grml_cd ] || INSTALLED="yes" # }}} # {{{ provide information about virtual environments VIRTUAL=false # assume physical system by default KVM=false VIRTUALBOX=false VMWARE=false if vmware-detect &>/dev/null; then VIRTUAL=true; VMWARE=true; VIRTUAL_ENV='VMware' elif [ "$(virt-what 2>/dev/null)" = "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 VIRTUAL=true; VIRTUALBOX=true; VIRTUAL_ENV='VirtualBox' fi # }}} # {{{ source lsb-functions , color handling if checkbootparam 'nocolor'; then . /etc/grml/lsb-functions einfo "Disabling colors in bootsequence as requested on commandline." ; eend 0 else . /etc/grml/lsb-functions fi # }}} # {{{ debug config_debug(){ checkbootparam 'debug' && BOOTDEBUG="yes" checkbootparam "BOOT_IMAGE=debug" && BOOTDEBUG="yes" rundebugshell(){ if [ -n "$BOOTDEBUG" ]; then einfo "Starting intermediate shell stage $stage as requested by \"debug\" option." if [ grep -q "debug=noscreen" "$CMDLINE" ] ; then einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!" einfo "Just exit the shell to continue boot process..." /bin/zsh else eindent if [ -r /etc/grml/screenrc ] ; then einfo "Starting GNU screen to be able to use a full featured shell environment." einfo "Just exit the shells (and therefore screen) to continue boot process..." /bin/zsh -c "screen -c /etc/grml/screenrc" else einfo "Notice that the shell does not provide job handling: ctrl-z, bg and fg won't work!" einfo "Just exit the shell to continue boot process..." /bin/zsh fi eoutdent fi fi } } # }}} # {{{ log 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 else DEBUG="/dev/null" fi } # }}} ### {{{ language configuration / localization config_language(){ einfo "Activating language settings:" eindent # 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" # set default to 'en' in live-cd mode iff $LANGUAGE is not set yet if [ -z "$INSTALLED" ] ; then [ -n "$LANGUAGE" ] || LANGUAGE='en' 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 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 CONSOLEFONT='Lat15-Terminus16' fi fi fi # 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 # 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 [ -r /etc/sysconfig/keyboard ] && . /etc/sysconfig/keyboard # 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 $? 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 # 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 $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 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 [ "$CUR_CONSOLE" != "serial" ] && chvt $CUR_CONSOLE fi eend $RC fi fi eoutdent } # }}} # {{{ Set hostname config_hostname(){ if ! checkbootparam 'hostname' ; then return 0 fi HOSTNAME="$(getbootparam 'hostname' 2>>$DEBUG)" if [ -z "$HOSTNAME" ] && [ -x /usr/bin/random-hostname ] ; then einfo "Generating random hostname as no hostname was specified." HOSTNAME="$(/usr/bin/random-hostname)" eend $? fi einfo "Setting hostname to $HOSTNAME as requested." grml-hostname $HOSTNAME >>$DEBUG eend $? } # }}} # fstabuser (needed when running from harddisk with username != grml {{{ config_userfstab(){ # force load of build-in and local config [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig.local # 1st. try configured fstab user if [ -n "$CONFIG_FSTAB_USER" ] ; then fstabuser=$(getent passwd $CONFIG_FSTAB_USER | cut -d: -f1) fi # 2nd. use standard user id [ -n "$fstabuser" ] || fstabuser=$(getent passwd 1000 | cut -d: -f1) # 3rd. use standard user name [ -n "$fstabuser" ] || fstabuser=$(getent passwd grml | cut -d: -f1) # if not yet set fall back to 'root' user, avoid bad /etc/fstab [ -n "$fstabuser" ] || fstabuser='root' } # }}} # local_user (needed when running with username != grml {{{ config_userlocal() { # force load of build-in and local config [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig.local # 1st. try id of primary user localuser=$(getent passwd 1000 | cut -d: -f1) # 2nd. use name standard user [ -n "$localuser" ] || localuser=$(getent passwd grml | cut -d: -f1) } # }}} # {{{ Set clock (Local time is more often used than GMT, so it is default) config_time(){ # don't touch the files if running from harddisk: if [ -z "$INSTALLED" ]; then # The default hardware clock timezone is stated as representing local time. UTC="--localtime" if [ -f /etc/default/rcS ] ; then grep -q "^UTC=" /etc/default/rcS || echo "UTC=no" >> /etc/default/rcS checkbootparam 'utc' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS checkbootparam 'gmt' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=yes|" /etc/default/rcS checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s|^UTC=.*$|UTC=no|" /etc/default/rcS grep -q -i "^UTC=yes" /etc/default/rcS && UTC="-u" # recent initscripts package versions don't ship /etc/default/rcS anymore, instead rely on /etc/adjtime elif [ -f /etc/adjtime ] ; then checkbootparam 'utc' >>$DEBUG 2>&1 && sed -i "s/^LOCAL/UTC/" /etc/adjtime checkbootparam 'gmt' >>$DEBUG 2>&1 && sed -i "s/^LOCAL/UTC/" /etc/adjtime checkbootparam 'localtime' >>$DEBUG 2>&1 && sed -i "s/^UTC$/LOCAL/" /etc/adjtime grep -q "^UTC$" /etc/adjtime && UTC="-u" fi # hwclock uses the TZ variable KTZ="$(getbootparam 'tz' 2>>$DEBUG)" [ -z "$KTZ" ] && [ -r /etc/timezone ] && KTZ=$(cat /etc/timezone) if [ ! -f "/usr/share/zoneinfo/$KTZ" ] ; then ewarn "Warning: unknown timezone $KTZ" ; eend 1 KTZ="UTC" ewarn "Falling back to timezone $KTZ" ; eend 0 fi if ! [ -r /dev/rtc ] ; then ewarn "Warning: realtime clock not available, trying to execute hwclock anyway." ; eend 0 fi ERROR=$(TZ="$KTZ" hwclock $UTC -s 2>&1 | head -1) ; RC=$? if [ -n "$ERROR" ] ; then eindent ERROR=$(TZ="$KTZ" hwclock $UTC -s --directisa 2>&1 | head -1) if [ -n "$ERROR" ] ; then eerror "Problem running hwclock: $ERROR" ; eend 1 fi eoutdent fi fi } # }}} # {{{ print kernel info config_kernel(){ if $VIRTUAL && [ -n "$VIRTUAL_ENV" ] ; then einfo "Running Linux Kernel $KERNEL inside $VIRTUAL_ENV" ; eend 0 else einfo "Running Linux Kernel $KERNEL" ; eend 0 fi if [ -r /proc/cpuinfo ] ; then if egrep -q '^flags.*(vmx|svm)' /proc/cpuinfo ; then eindent einfo 'CPU(s) featuring virtualization technology detected' ; eend 0 eoutdent fi fi if [ -d /proc/xen ] ; then eindent einfo 'Running kernel featuring support for Xen detected' ; eend 0 eoutdent fi } # }}} # {{{ 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 else ewarn "SecureBoot not detected" ; eend 0 fi else if modprobe efivars &>/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 else ewarn "SecureBoot not detected" ; eend 0 fi fi fi } # }}} # {{{ timezone config_timezone(){ # don't touch the files if running from harddisk: if [ -z "$INSTALLED" ]; then KTZ="$(getbootparam 'tz' 2>>$DEBUG)" if [ -n "$KTZ" ] ; then if [ ! -f "/usr/share/zoneinfo/$KTZ" ] then ewarn "Warning: unknown timezone $KTZ"; eend 0 else einfo "Setting timezone." # update debconf area=$(echo $KTZ | cut -d '/' -f1) zone=$(echo $KTZ | cut -d '/' -f2) echo "tzdata tzdata/Areas select $area" | debconf-set-selections echo "tzdata tzdata/Zones/$area select $zone" | debconf-set-selections # update files echo $KTZ > /etc/timezone rm -f /etc/localtime cp "/usr/share/zoneinfo/$KTZ" /etc/localtime ; eend $? fi fi fi } # }}} # activate serial console {{{ config_console(){ if checkbootparam 'console'; then # this hack is no longer necessary with systemd if $SYSTEMD ; then return fi local line local ws ws=' ' einfo "Bootoption for serial console detected:" line="$CMDLINE x " this="" line="${line#*[$ws]}" local telinitq="" while [ -n "$line" ]; do case "$this" in console=*) local serial="$this" local device="${this%%,*}" local device="${device##*=}" if echo $serial | grep -q ttyS ; then local option="${serial##*,}" # default (works for kvm & CO): local speed="115200,57600,38400,19200,9600,4800,2400,1200"; # ... unless overriden by command line: case "$option" in 115200*) speed=115200 ;; 57600*) speed=57600 ;; 38400*) speed=38400 ;; 19200*) speed=19200 ;; 9600*) speed=9600 ;; 4800*) speed=4800 ;; 2400*) speed=2400 ;; 1200*) speed=1200 ;; esac eindent einfo "Activating console login on device ${device} with speed ${speed}." local number="${device#ttyS}" 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 eend $? telinitq="1" eoutdent fi ;; esac this="${line%%[$ws]*}" line="${line#*[$ws]}" done if [ -n "$telinitq" ]; then /sbin/telinit q fi eend $? fi } # }}} # {{{ CD Checker config_testcd(){ if checkbootparam 'testcd' ; then einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option." eindent local ERROR=true local FOUND_FILE=false local logfile='/tmp/md5sum.log' rm -f "$logfile" for md5 in $(find "${LIVECD_PATH}" -name md5sums) ; do einfo "Checking files against $md5, this may take a while..." FOUND_FILE=true OLD_PWD=$(pwd) cd $(dirname "$md5") md5sum -c $(basename "$md5") |& tee -a "${logfile}" if [ $pipestatus[1] -eq 0 ] ; then ERROR=false fi cd "${OLD_PWD}" done if ! $FOUND_FILE ; then eerror 'Error: Could not find md5sum file' ; eend 1 return fi if ! $ERROR ; then einfo "Everything looks OK" ; eend 0 else eerror 'Checksum failed for theses files:' ; eend 1 egrep -v '(^md5sum:|OK$)' "${logfile}" eerror 'Data on the medium is possibly incomplete/damaged or RAM of your system is broken.' ; eend 1 einfon "Hit return to continue, or press the power button to shut down system." read a fi eoutdent fi } # }}} # {{{ blacklist specific module [ used in /etc/init.d/udev ] config_blacklist(){ if checkbootparam 'blacklist' ; then if [ -z "$INSTALLED" ]; then einfo "Bootoption blacklist found." BLACK="$(getbootparam 'blacklist' 2>>$DEBUG)" BLACKLIST_FILE='/etc/modprobe.d/grml.conf' if [ -n "$BLACK" ] ; then for module in $(echo ${BLACK//,/ }) ; do einfo "Blacklisting module ${module} via ${BLACKLIST_FILE}." echo "# begin entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" echo "blacklist $module" >> "$BLACKLIST_FILE" echo "alias $module off" >> "$BLACKLIST_FILE" echo "# end entry generated by config_blacklist of grml-autoconfig" >> "$BLACKLIST_FILE" ; eend $? done else eerror "No given module for blacklist found. Blacklisting will not work therefore." fi else ewarn "Backlisting via bootoption is not intended for use on harddisk installations." ; eend 1 eindent einfo "Please blacklist the module(s) manually using the 'blacklist' script." eoutdent fi fi } # }}} # {{{ ACPI config_acpi(){ if $SYSTEMD ; then echo "systemd detected, no acpi(d) stuff needed." >>"$DEBUG" return fi if checkbootparam 'noacpi'; then ewarn "ACPI: Not loading modules as requested by boot option \"noacpi\"." ; eend 0 elif checkbootparam 'nogrmlacpi' ; then ewarn "ACPI: Not loading modules as requested by boot option \"nogrmlacpi\"." ; eend 0 elif [ ! -d /proc/acpi ] ; then ewarn "ACPI: Kernel support not present." ; eend 0 else einfo "ACPI: Loading modules (disable with boot option noacpi / nogrmlacpi): " eindent found="" for a in /lib/modules/$KERNEL/kernel/drivers/acpi/*; do basename="${a##*/}" basename="${basename%%.*}" case "$basename" in *_acpi) egrep -qi "${basename%%_acpi}" /proc/acpi/dsdt 2>>$DEBUG || continue ;; esac modprobe $basename >>$DEBUG 2>&1 && found="yes" local BASE="$BASE $basename" done if [ -n "$found" ] ; then einfo "$BASE" ; eend 0 else ewarn "(none)" ; eend 1 fi if ! pgrep acpid >/dev/null ; then einfo "Starting acpi daemon." service_wrapper acpid.socket start >>$DEBUG 2>&1 ; eend $? service_wrapper acpid start >>$DEBUG 2>&1 ; eend $? else ewarn "acpi daemon already running." eend 0 fi eoutdent fi } # }}} # {{{ Start brltty config_brltty() { if checkbootparam 'brltty' ; then [ -x /lib/brltty/brltty.sh ] && /lib/brltty/brltty.sh fi } # }}} # {{{ Start creating /etc/fstab with HD partitions and USB SCSI devices now config_fstab(){ NOSWAP="yes" # we do not use swap by default! if checkbootparam 'swap' || checkbootparam 'anyswap' ; then NOSWAP='' checkbootparam 'anyswap' && export ANYSWAP='yes' || export ANYSWAP="" fi # Scan for swap, config, homedir - but only in live-mode if [ -z "$INSTALLED" ] ; then [ -z "$NOSWAP" ] && einfo "Searching for swap partition(s) as requested." GRML_IMG="" GRML_SWP="" HOMEDIR="$(getbootparam 'home')" if [ -n "$partitions" ]; then while read p m f relax; do case "$p" in *fd0*|*proc*|*sys*|*\#*) continue;; esac partoptions="users,exec" fnew="" # it's a swap partition? case "$f" in swap) eindent if [ -n "$NOSWAP" ]; then ewarn "Ignoring swap partition ${WHITE}$p${NORMAL}. (Force usage via boot option 'swap', or execute grml-swapon)" eend 0 else case "$(dd if=$p bs=1 count=6 skip=4086 2>/dev/null)" in S1SUSP|S2SUSP|pmdisk|[zZ]*) if [ -n "$ANYSWAP" ] ; then einfo "Using swap partition ${WHITE}${p}${NORMAL} [bootoption anyswap found]." swapon $p 2>>$DEBUG ; eend $? else ewarn "Suspend signature on ${WHITE}${p}${NORMAL} found, not using as swap. (Force usage via boot option: anyswap)" fi ;; *) if [[ "$p" == LABEL* ]] ; then p=$(blkid -t $p | awk -F: '{print $1}') fi if grep -q $p /proc/swaps ; then ewarn "Not using swap partition ${WHITE}${p}${NORMAL} as it is already in use." ; eend 0 else if [ -b "$p" ] ; then einfo "Using swap partition ${WHITE}${p}${NORMAL}." swapon $p 2>>$DEBUG ; eend $? else ewarn "$p is not a valid block device - not using it therefore." ; eend 0 fi fi ;; esac # dd-check fi # -n "$NOSWAP eoutdent continue ;; esac # it's a swap partition? # mount read-only MOUNTOPTS="ro" case "$f" in vfat|msdos|ntfs) MOUNTOPTS="$MOUNTOPTS,uid=${fstabuser},gid=${fstabuser}" ;; ext2|ext3|reiserfs|jfs|reiser4|xfs) MOUNTOPTS="$MOUNTOPTS,noatime" ;; *) continue ;; # *) NONEFOUND='1'; continue ;; esac # use a swapfile if [ -z "$NOSWAP" ] ; then mount -o "$MOUNTOPTS" -t $f $p $m 2>>$DEBUG && MOUNTED=1 || continue # Activate swapfile, if exists SWAPFILE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ss][Ww][Pp] 2>/dev/null)" fi if [ -z "$NOSWAP" -a -n "$SWAPFILE" -a -f "$SWAPFILE" ]; then mount -o remount,rw $m && MOUNTED=1 if swapon "$SWAPFILE" 2>>$DEBUG ; then eindent einfo "Using GRML swapfile ${WHITE}${SWAPFILE}${NORMAL}." eoutdent fnew="$SWAPFILE swap swap defaults 0 0" grep -q "$fnew" "/etc/fstab" || echo "$fnew" >> /etc/fstab GRML_SWP="$GRML_SWP $SWAPFILE" eend 0 fi mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1 fi # use a image as home IMAGE="$(/bin/ls -1d $m/[Gg][Rr][Mm][Ll].[Ii][Mm][Gg] 2>/dev/null)" if [ -z "$GRML_IMG" -a -n "$IMAGE" -a -f "$IMAGE" ]; then if [ -n "$HOMEDIR" ]; then if [ "$HOMEDIR" != "scan" -a "$HOMEDIR" != "$IMAGE" -a "$HOMEDIR" != "${IMAGE%/*.*}" ]; then continue fi fi if type -a grml-image >/dev/null 2>&1 && grml-image "$IMAGE" /dev/console 2>&1; then GRML_IMG="$IMAGE" mount -o remount,ro $m 2>>$DEBUG && MOUNTED=1 fi fi eend 0 # Umount, if not in use [ -n "$MOUNTED" ] && umount -r $m 2>/dev/null done <>$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 ! [ -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 rm -f "$LOADCPUFREQ" 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 eoutdent fi } # }}} # {{{ autostart of ssh config_ssh(){ if checkbootparam 'ssh' ; then local PASSWD PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)" config_userlocal einfo "Bootoption ssh found, trying to set password for root and user $localuser" [ -z "$localuser" ] && eend 1 eindent if [ -z "$PASSWD" ] ; then set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0 fi eoutdent if [ -n "$PASSWD" ] ; then chpass_options="" if chpasswd --help 2>&1 | grep -q -- '-m,' ; then chpass_options="-m" fi echo "$localuser:$PASSWD" | chpasswd $chpass_options echo "root:$PASSWD" | chpasswd $chpass_options eindent ewarn "Warning: please change the password for root and user $localuser as soon as possible!" eoutdent fi einfo "Starting secure shell server in background for root and user $localuser" service_wrapper rmnologin start >>$DEBUG 2>>$DEBUG service_wrapper ssh start >>$DEBUG 2>>$DEBUG & eend $? fi } # }}} # {{{ display hostkeys of SSH server config_display_ssh_fingerprints() { if ! ls /etc/ssh/ssh_host_\*_key >/dev/null 2>&1 ; then return 0 # no SSH host keys present fi einfo "SSH key fingerprints:" for file in /etc/ssh/ssh_host_*_key ; do einfon ssh-keygen -l -f $file done | column -t eend $? } # }}} # {{{ autostart of x11vnc config_vnc(){ if checkbootparam 'vnc' ; then config_userlocal VNC_PASSWD='' VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)" einfo "Bootoption vnc found, trying to set password for user $localuser." eindent if [ -z "$VNC_PASSWD" ] ; then if [ -x /usr/bin/apg ] ; then VNC_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)" elif [ -x /usr/bin/gpw ] ; then VNC_PASSWD="$(gpw 1)" elif [ -x /usr/bin/pwgen ] ; then VNC_PASSWD="$(pwgen -1 8)" elif [ -x /usr/bin/hexdump ] ; then VNC_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')" elif [ -n "$RANDOM" ] ; then VNC_PASSWD="${localuser}${RANDOM}" else VNC_PASSWD='' eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping." eend 1 fi if [ -n "$VNC_PASSWD" ] ; then ewarn "No given password for vnc found. Using random password: $VNC_PASSWD" ; eend 0 fi fi eoutdent # finally check if we have a password we can use: if [ -n "$VNC_PASSWD" ] ; then VNCDIR="/home/${localuser}/.vnc" [ -d "$VNCDIR" ] || mkdir "$VNCDIR" if [ ! -x /usr/bin/x11vnc ] ; then eerror "Error: x11vnc not found - can not set up vnc. Please make sure to install the x11vnc package." eend 1 else /usr/bin/x11vnc -storepasswd "$VNC_PASSWD" "$VNCDIR"/passwd ; eend $? /bin/chown -R "$localuser": "$VNCDIR" fi fi if checkbootparam 'vnc_connect' ; then VNC_CONNECT='' VNC_CONNECT="$(getbootparam 'vnc_connect' 2>>$DEBUG)" einfo "Bootoption vnc_connect found, will start vnc with connect to $VNC_CONNECT." #store the options in a file VNCDIR="/home/${localuser}/.vnc" [ -d "$VNCDIR" ] || mkdir "$VNCDIR" echo " --connect $VNC_CONNECT " >> $VNCDIR/options fi fi } # }}} # {{{ set password for root and default user config_passwd(){ if checkbootparam 'passwd' >>$DEBUG 2>&1; then local PASSWD PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)" config_userlocal einfo "Bootoption passwd found, trying to set password for root and user $localuser" [ -z "$localuser" ] && eend 1 eindent if [ -z "$PASSWD" ] ; then set_passwd && ewarn "No given password for found. Using random password: $PASSWD" && eend 0 fi eoutdent if [ -n "$PASSWD" ] ; then chpass_options="" if chpasswd --help 2>&1 | grep -q -- '-m,' ; then chpass_options="-m" fi echo "$localuser:$PASSWD" | chpasswd $chpass_options echo "root:$PASSWD" | chpasswd $chpass_options eindent ewarn "Warning: please change the password for root and user $localuser as soon as possible!" eoutdent fi fi if checkbootparam 'encpasswd' >>$DEBUG 2>&1; then local PASSWD PASSWD="$(getbootparam 'encpasswd' 2>>$DEBUG)" if [ -z "$PASSWD" ] ; then eerror "No hashed password found, can not set password." eend 1 return fi config_userlocal einfo "Bootoption encpasswd found, trying to set hashed password for root and user $localuser" [ -z "$localuser" ] && eend 1 if [ -n "$PASSWD" ] ; then chpass_options="-e" echo "$localuser:$PASSWD" | chpasswd $chpass_options echo "root:$PASSWD" | chpasswd $chpass_options eindent ewarn "Warning: please change the password for root and user $localuser as soon as possible!" eoutdent fi fi } # }}} # {{{ Sound config_mixer () { if ! [ -x /usr/bin/amixer ] ; then eerror "amixer binary not available. Can not set sound volumes therefore." eend 1 else if ! [ -r /proc/asound/cards ] ; then ewarn "No soundcard present, skipping mixer settings therefore." eend 0 return fi for card in $(cat /proc/asound/cards| grep -e '^\s*[0-9]' | awk '{print $1}') ; do einfo "Configuring soundcard \"$(awk -F\[ '/^ *'$card' \[/{ FS=" "; $0=$2; print $1}' < /proc/asound/cards)\"" eindent if checkbootparam 'vol' ; then VOL="$(getbootparam 'vol' 2>>$DEBUG)" if [ -z "$VOL" ] ; then eerror "Bootoption vol found but no volume level/parameter given. Using defaults (75%)." VOL='75' eend 1 fi else VOL='75' fi if checkbootparam 'nosound' ; then einfo "Muting sound devices on request." ERROR=$(amixer -q set Master mute) RC=$? if [ -n "$ERROR" ] ; then eindent eerror "Problem muting sound devices: $ERROR" eoutdent fi eend $RC elif [ -z "$INSTALLED" ] ; then einfo "Setting mixer volumes to level ${WHITE}${VOL}${NORMAL}." if checkbootparam 'micvol' ; then MICVOL="$(getbootparam 'micvol' 2>>$DEBUG)" einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}." else MICVOL=0 fi CONTROLS=$(amixer -c $card scontrols | awk -F"Simple mixer control " '{print $2}') IFSOLD=${IFS:-} IFS=' ' for CONTROL in ${=CONTROLS} ; do # such devices can not be controlled with amixer ... unmute [[ "$CONTROL" == *Console* ]] && continue if ! echo "${CONTROL}" | grep -q -i "mic" ; then if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*pswitch' ; then amixer -c $card -q set "${CONTROL}" unmute fi if amixer -c $card sget "${CONTROL}" | grep -q -P 'Capabilities:.*(pvolume| volume)' ; then amixer -c $card -q set "${CONTROL}" "${VOL}"% fi fi if [ ${MICVOL} -ne 0 ] ; then if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cswitch' ; then amixer -c $card -q set "${CONTROL}" unmute fi if amixer -c $card sget "${CONTROL}" | grep -q 'Capabilities:.*cvolume' ; then amixer -c $card -q set "${CONTROL}" $MICVOL% fi eend $? fi done IFS=$IFSOLD fi # checkbootparam 'nosound' eoutdent done fi } # }}} # {{{ syslog service config_syslog(){ if checkbootparam 'nosyslog'; then ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0 else einfo "Starting rsyslog in background." service_wrapper rsyslog start >>$DEBUG & eend 0 fi } # }}} # {{{ gpm config_gpm(){ if checkbootparam 'nogpm'; then ewarn "Not starting GPM as requested on boot commandline." ; eend 0 else if ! [ -r /dev/input/mice ] ; then 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 ) & eend 0 fi fi } # }}} # {{{ services config_services(){ if checkbootparam 'services' ; then SERVICE="$(getbootparam 'services' 2>>$DEBUG)" SERVICELIST=$(echo "$SERVICE" | sed 's/,/\\n/g') SERVICENL=$(echo "$SERVICE" | sed 's/,/ /g') for service in $(echo -e $SERVICELIST) ; do # support running (custom) init scripts in non-blocking mode # if they contain the keyword "DO_NO_RUN_IN_BACKGROUND". if grep -q 'DO_NO_RUN_IN_BACKGROUND' "/etc/init.d/${service}" 2>>$DEBUG ; then einfo "Starting service ${service}." service_wrapper "${service}" start >>$DEBUG else einfo "Starting service ${service} in background." service_wrapper "${service}" start >>$DEBUG & fi done eend $? fi } # }}} # {{{ remote files get_remote_file() { [ "$#" -eq 2 ] || ( echo "Error: wrong parameter for get_remote_file()" ; return 1 ) SOURCE=$(eval echo "$1") TARGET="$2" getconfig() { wget --timeout=10 --dns-timeout=10 --connect-timeout=10 --tries=1 \ --read-timeout=10 ${SOURCE} -O ${TARGET} && return 0 || return 1 } einfo "Trying to get ${WHITE}${TARGET}${NORMAL}" if checkbootparam 'getfile.retries' ; then local counter="$(getbootparam 'getfile.retries' 2>>$DEBUG)" else local counter=10 fi while ! getconfig && [[ "$counter" != 0 ]] ; do echo -n "Sleeping for 1 second and trying to get config again... " counter=$(( counter-1 )) echo "$counter tries left" ; sleep 1 done if [ -s "$TARGET" ] ; then einfo "Downloading was successfull." ; eend 0 einfo "md5sum of ${WHITE}${TARGET}${NORMAL}: " md5sum ${TARGET} ; eend 0 return 0; else einfo "Sorry, could not fetch ${SOURCE}" ; eend 1 return 1; fi } # }}} # {{{ config files config_netconfig(){ if checkbootparam 'netconfig' ; then CONFIG="$(getbootparam 'netconfig' 2>>$DEBUG)" CONFIGFILE='/tmp/netconfig.grml' if get_remote_file ${CONFIG} ${CONFIGFILE} ; then cd / && einfo "Unpacking ${WHITE}${CONFIGFILE}${NORMAL}:" && /usr/bin/unp $CONFIGFILE $EXTRACTOPTIONS ; eend $? fi fi } # }}} # {{{ remote scripts config_netscript() { if checkbootparam 'netscript' ; then CONFIG="$(getbootparam 'netscript' 2>>$DEBUG)" SCRIPTFILE='/tmp/netscript.grml' if get_remote_file ${CONFIG} ${SCRIPTFILE} ; then chmod +x ${SCRIPTFILE} einfo "Running ${WHITE}${SCRIPTFILE}${NORMAL}:" && NETSCRIPT=${CONFIG} ${SCRIPTFILE} ; eend $? fi fi } # }}} # {{{ stats config_stats() { if ! checkbootparam 'nostats' ; then BASE_URL="http://stats.grml.org/report/" ACTION_NAME=Boot HOST_ID=$(cat /proc/sys/kernel/random/boot_id) grep -q " lm " /proc/cpuinfo && HAS_64BIT="1" || HAS_64BIT="0" DATE_STRING=$(date +'h=%H&m=%M&s=%S') [ -e /etc/grml_version ] && VERSION=$(cat /etc/grml_version) || \ VERSION=$(lsb_release -d | awk -F: '{gsub(/^[ \t]+/, "", $2); print $2}') PARAMS="$( echo "$CMDLINE" | sed -e 's/=[^ ]*/=x/g' | tr " " "\n"|sort|tr "\n" " " )" echo "$CMDLINE" | grep -q -e "fetch" -e "nfsroot" && BOOT="remote" [ -z "$BOOT" ] && BOOT="local" ADDITIONAL_PARAMS="" ( [ -n "$COLUMNS" ] && [ -n "$LINES" ] ) && \ ADDITIONAL_PARAMS="$ADDITIONAL_PARAMS&res=$((COLUMNS * 8))x$((LINES * 16))" URI='$BASE_URL?action=${ACTION_NAME}\&$DATE_STRING\&unique_id=${HOST_ID}\&support_64bit=$HAS_64BIT\&version=$VERSION\&bootup=$BOOT\¶ms=$PARAMS$ADDITIONAL_PARAMS' get_remote_file "$URI" "/dev/null" >/dev/null 2>&1 &! fi } # }}} # {{{ start X window system via grml-x config_x_startup(){ # make sure we start X only if startx is used *before* a nostartx option # so it's possible to disable automatic X startup using nostart if checkbootparam 'startx' && ! echo "$CMDLINE" | grep -q 'startx.*nostartx' ; then if [ -x "$(which X)" ] ; then if [ -z "$INSTALLED" ] ; then WINDOWMANAGER="$(getbootparam 'startx' 2>>$DEBUG)" if [ -z "$WINDOWMANAGER" ] ; then einfo "No window manager specified. Using default one." && eend 0 else einfo "Window manager ${WHITE}${WINDOWMANAGER}${NORMAL} found as bootoption." && eend 0 fi einfo "Setting up and invoking grml-x ${WINDOWMANAGER}. Just exit X windows system to get full featured consoles." config_userlocal if $SYSTEMD ; then cat>|/etc/init.d/startx<|/etc/init.d/startx</dev/tty6 2>\&1 /dev/tty6 2>&1 < /dev/tty6' >> /etc/inittab fi /sbin/telinit q ; eend $? if grep -q '^allowed_users=' /etc/X11/Xwrapper.config ; then sed -i 's/^allowed_users=.*/allowed_users=anybody/' /etc/X11/Xwrapper.config else echo 'allowed_users=anybody' >> /etc/X11/Xwrapper.config fi else eerror "We are not running in live mode - startx will not work, skipping it." eerror " -> Please use something like xdm, gdm or kdm for starting X on a harddisk system!" ; eend 1 fi else eerror "/usr/bin/X is not present on this grml flavour." eerror " -> Boot parameter startx does not work therefore." ; eend 1 fi fi } # }}} # {{{ configuration framework config_extract(){ if checkbootparam 'extract' ; then EXTRACT="$(getbootparam 'extract' 2>>$DEBUG)" EXTRACTOPTIONS="-- -x $EXTRACT" fi } config_finddcsdir() { # - If no GRMLCFG partition is found and noautoconfig is _not_ given # on the command line, nothing is changed and the dcs files are # searched within the .iso, $dcs-dir is set to the root directory # within the .iso # - If a GRMLCFG partition is found, $dcs-dir is set to the root of # the GRMLCFG partition unless noautoconfig is set. If noautoconfig is # set, $dcs-dir is set to the root directory within the .iso. # - If myconfig=foo is set on the command line, $dcs-dir is set to # foo, even if a GRMLCFG partition is present. DCSDIR="" DCSMP="/mnt/grml" # autoconfig, see issue673 GRMLCFG="$(getbootparam 'autoconfig' 2>>$DEBUG)" [ -n "$GRMLCFG" ] || GRMLCFG="GRMLCFG" if checkbootparam 'noautoconfig' ; then DCSDIR="${LIVECD_PATH}" # set default so it works for "scripts" boot option as expected ewarn "Skipping running automount of device(s) labeled $GRMLCFG as requested." ; eend 0 else if [ -z "$INSTALLED" ] ; then if checkbootparam 'myconfig' ; then DCSDEVICE="$(getbootparam 'myconfig' 2>>$DEBUG)" if [ -z "$DCSDEVICE" ]; then eerror "Error: No device for bootoption myconfig provided." ; eend 1 fi # [ -z "$DCSDEVICE" ] elif checkvalue $CONFIG_MYCONFIG; then # checkbootparam myconfig einfo "Searching for device(s) labeled with $GRMLCFG. (Disable this via boot option: noautoconfig)" ; eend 0 eindent DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}') modprobe 9p 2>/dev/null || true if [ -z "$DCSDEVICE" ] && grep -q 9p /proc/filesystems ; then if grep -q "$GRMLCFG" /sys/bus/virtio/devices/*/mount_tag 2>/dev/null ; then einfo "Found 9p-virtio fs with mount_tag $GRMLCFG" DCSDEVICE="$GRMLCFG" MOUNTOPTIONS="ro,trans=virtio" DCSFS="9p" fi fi if [ -n "$DCSDEVICE" ]; then DCSMP="/mnt/grmlcfg" fi eoutdent fi # if not specified/present then assume default: if [ -z "$DCSDEVICE" ]; then DCSDIR="${LIVECD_PATH}" else eindent einfo "debs, config, scripts are read from $DCSDEVICE." ; eend 0 DCSDIR="$(< /proc/mounts awk -v DCSDEV=$DCSDEVICE '{if ($1 == DCSDEV) { print $2 }}')" if [ -n "$DCSDIR" ]; then ewarn "$DCSDEVICE already mounted on $DCSDIR"; eend 0 else [ -d $DCSMP ] || mkdir $DCSMP umount $DCSMP >>$DEBUG 2>&1 # make sure it is not mounted mount -o ${MOUNTOPTIONS:-ro} -t ${DCSFS:-auto} $DCSDEVICE $DCSMP ; RC="$?" if [[ $RC == 0 ]]; then einfo "Successfully mounted $DCSDEVICE to $DCSMP (readonly)." ; eend 0 else eerror "Error: mounting $DCSDEVICE to $DCSMP (readonly) failed." ; eend 1 fi DCSDIR="$DCSMP" fi eoutdent fi fi fi if [ -n "$DCSDIR" -a "$DCSDIR" != "${LIVECD_PATH}" ] ; then einfo "Debs, config, scripts (if present) will be read from $DCSDIR." ; eend 0 elif checkbootparam 'debs' || checkbootparam 'config' || checkbootparam 'scripts'; then einfo "Debs, config, scripts will be read from the live image directly." ; eend 0 fi } config_partconf() { if checkbootparam 'partconf' ; then MOUNTDEVICE="$(getbootparam 'partconf' 2>>$DEBUG)" if [ -n "$MOUNTDEVICE" ]; then [ -d /mnt/grml ] || mkdir /mnt/grml mount -o ro -t auto $MOUNTDEVICE /mnt/grml ; RC="$?" if [[ $RC == 0 ]]; then einfo "Successfully mounted $MOUNTDEVICE to /mnt/grml (readonly)." ; eend 0 einfo "Copying files from $MOUNTDEVICE over grml system." for file in `cat /etc/grml/partconf` ; do [ -d /mnt/grml/$file ] && cp -a /mnt/grml/${file}* ${file} && echo "copied: $file" [ -f /mnt/grml/$file ] && cp -a /mnt/grml/${file} ${file} && echo "copied: $file" done && eend 0 else einfo "Could not mount $MOUNTDEVICE to /mnt/grml - sorry." ; eend 1 fi # mount $MOUNTDEVICE grep -q '/mnt/grml' /proc/mounts && umount /mnt/grml else einfo "Sorry, no device for bootoption partconf provided. Skipping." ; eend 1 fi # [ -n "$MOUNTDEVICE" ] fi } # }}} # {{{ /cdrom/.*-options config_debs(){ if checkbootparam 'debs' ; then iszsh && setopt localoptions shwordsplit DEBS="$(getbootparam 'debs' 2>>$DEBUG)" if [ -z "$DEBS" ] ; then DEBS="*.deb" fi if ! echo $DEBS | grep -q '/'; then # backwards compatibility: if no path is given get debs from debs/ DEBS="debs/$DEBS" fi einfo "Trying to install Debian package(s) ${DEBS}" DEBS="$(eval echo ${DCSDIR}/$DEBS)" dpkg -i $DEBS ; eend $? fi } config_scripts(){ if checkbootparam 'scripts' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then SCRIPTS="$(getbootparam 'scripts' 2>>$DEBUG)" if [ -d ${DCSDIR}/scripts ] && [ -z "$SCRIPTS" ]; then SCRIPTS="$(cd ${DCSDIR}/scripts; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)" fi if ! echo $SCRIPTS | grep -q '/'; then # backwards compatibility: if no path is given get scripts from scripts/ SCRIPTS="scripts/$SCRIPTS" fi if [ -n "$SCRIPTS" ]; then SCRIPTS="${DCSDIR}/$SCRIPTS" if [ "$DCSMP" = "/mnt/grmlcfg" ]; then einfo "Trying to execute ${SCRIPTS}" sh -c $SCRIPTS eend $? elif [ -d "$SCRIPTS" ]; then einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:" run-parts --regex '.*' $SCRIPTS eend $? else einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:" sh -c $SCRIPTS eend $? fi fi fi } config_config(){ if checkbootparam 'config' || [ "$DCSMP" = "/mnt/grmlcfg" ]; then CONFIG="$(getbootparam 'config' 2>>$DEBUG)" if [ -z "$CONFIG" ]; then CONFIG="$(cd ${DCSDIR}; ls -1d [Cc][Oo][Nn][Ff][Ii][Gg].[Tt][Bb][Zz] 2>>$DEBUG)" fi if [ -n "$CONFIG" ]; then if [ -d "${DCSDIR}/${CONFIG}" ] ; then einfo "Taking configuration from directory ${DCSDIR}/${CONFIG}" cp -a ${DCSDIR}/${CONFIG}/* / elif [ -f "${DCSDIR}/${CONFIG}" ]; then einfo "Extracting configuration from file ${DCSDIR}/${CONFIG}" cd / unp ${DCSDIR}/${CONFIG} $EXTRACTOPTIONS ; eend $? else ewarn "Sorry, could not find configuration file or directory ${DCSDIR}/${FILENAME}." ; eend 1 fi fi fi } # }}} # {{{ confing_umount_dcsdir config_umount_dcsdir(){ # umount $DCSMP if it was mounted by finddcsdir grep -q "$DCSMP" /proc/mounts && umount "$DCSMP" } # }}} # {{{ mypath config_mypath(){ if checkbootparam 'mypath' ; then MY_PATH="$(getbootparam 'mypath' 2>>$DEBUG)" einfo "Bootparameter mypath found, adding ${MY_PATH} to /etc/grml/my_path" touch /etc/grml/my_path chmod 644 /etc/grml/my_path # make sure the directories exist: eindent for i in $(echo $MY_PATH | sed 's/:/\n/g') ; do if ! [ -d "$i" ] ; then einfo "Creating directory $i" mkdir -p "$i" ; eend $? fi done grep -q "${MY_PATH}" /etc/grml/my_path || echo "${MY_PATH}" >> /etc/grml/my_path ; eend $? eoutdent fi } # }}} # {{{ SW-RAID config_swraid(){ [ -n "$INSTALLED" ] && return 0 if checkbootparam 'noraid' || checkbootparam 'noswraid' || \ checkbootparam 'raid=noautodetect' ; then ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0 else [ -e /proc/mdstat ] || modprobe md_mod if ! [ -x /sbin/mdadm ] ; then eerror "mdadm not available, can not execute it." ; eend 1 else # if ! egrep -qv '^(MAILADDR.*|#.*|)$' /etc/mdadm/mdadm.conf 2>>$DEBUG ; then # find out whether we have a valid configuration file already if ! grep -q ARRAY /etc/mdadm/mdadm.conf 2>>$DEBUG ; then einfo "Creating /etc/mdadm/mdadm.conf for use with mdadm." [ -r /etc/mdadm/mdadm.conf ] && mv /etc/mdadm/mdadm.conf /etc/mdadm/mdadm.conf.old MDADM_MAILADDR__='root' /usr/share/mdadm/mkconf > /etc/mdadm/mdadm.conf ; eend $? else ewarn "/etc/mdadm/mdadm.conf looks like a configured mdadm setup, will not touch it." ; eend 0 fi 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." else einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart." fi eoutdent else 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 case $line in *'No arrays found'*) ewarn "$line" ; eend 0 ;; *) einfo "$line" ; eend 0 ;; esac done IFS=$IFSOLD eoutdent if [ -r /proc/mdstat ] ; then eindent MDSTAT=$(grep '^md[0-9]' /proc/mdstat) if [ -z "$MDSTAT" ] ; then ewarn "No active arrays found" ; eend 0 else IFSOLD=${IFS:-} IFS=' ' for line in $(grep '^md[0-9]' /proc/mdstat) ; do einfo "active arrays: $line" ; eend 0 done IFS=$IFSOLD fi eoutdent fi # /proc/mdstat fi # bootoption swraid fi # is /sbin/mdadm executable? fi # check for bootoptions } # }}} # {{{ 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 [ -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 if checkbootparam 'nolvm' ; then ewarn "Skipping LVM code as requested on boot commandline." ; eend 0 else if ! [ -x /sbin/lvm ] ; then eerror "LVM not available, can not execute it." ; eend 1 else if lvdisplay 2>&1 | grep -v 'No volume groups found' >/dev/null 2>&1 ; then 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." 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 $? else service_wrapper lvm2 start ; eend $? fi fi eoutdent fi fi # check for lvm binary fi # check for bootoption nolvm } # }}} # {{{ debnet: setup network based on an existing one found on a partition config_debnet(){ if checkbootparam 'debnet' ; then einfo "Bootoption 'debnet' found. Searching for Debian network configuration: " /usr/sbin/debnet fi } # }}} # {{{ disable console blanking config_blanking(){ if checkbootparam 'noblank' ; then einfo "Bootoption noblank found. Disabling monitor blanking." setterm -blank 0 ; eend $? fi } # }}} # {{{ debootstrap: automatic installation config_debootstrap(){ if checkbootparam "BOOT_IMAGE=debian2hd" || checkbootparam "debian2hd" ; then einfo "Bootoption debian2hd found. Setting up environment for automatic installation via grml-debootstrap." ; eend 0 if ! [ -x /usr/sbin/grml-debootstrap ] ; then eindent eerror "Bootoption debian2hd found, but grml-debootstrap is not available." ; eend 1 eoutdent exit 1 fi if checkbootparam 'target' ; then TARGET='' TARGET="$(getbootparam 'target' 2>>$DEBUG)" # notice: the following checks whether the given partition is available, if not the skip # execution of grml-debootstrap as it might result in data loss... if ! [ -r "$TARGET" ] ; then eerror "Target $TARGET does not exist. Skipping execution of grml-debootstrap therefore." ; eend 1 fi else eindent eerror "No bootoption named target found, can not continue execution of grml-debootstrap." ; eend 1 eoutdent exit 1 fi if checkbootparam 'grub' ; then GRUB='' GRUB="$(getbootparam 'grub' 2>>$DEBUG)" fi if checkbootparam 'groot' ; then GROOT='' GROOT="$(getbootparam 'groot' 2>>$DEBUG)" fi if checkbootparam 'release' ; then RELEASE='' RELEASE="$(getbootparam 'release' 2>>$DEBUG)" fi if checkbootparam 'mirror' ; then MIRROR='' MIRROR="$(getbootparam 'mirror' 2>>$DEBUG)" fi if checkbootparam 'boot_append' ; then BOOT_APPEND='' BOOT_APPEND="$(getbootparam 'boot_append' 2>>$DEBUG)" fi if checkbootparam 'password' ; then PASSWORD='' PASSWORD="$(getbootparam 'password' 2>>$DEBUG)" fi # now check which options are available if [ -n "TARGET" ] ; then TARGETCMD="--target $TARGET" else TARGETCMD='' eindent eerror "Target not set via bootoption. Skipping execution of grml-debootstrap therefore."; eend 1 eoutdent exit 1 fi [ -n "$GRUB" ] && GRUBCMD="--grub $GRUB" || GRUBCMD='' [ -n "$GROOT" ] && GROOTCMD="--groot $GROOT" || GROOTCMD='' [ -n "$RELEASE" ] && RELEASECMD="--release $RELEASE" || RELEASECMD='' [ -n "$MIRROR" ] && MIRRORCMD="--mirror $MIRROR" || MIRRORCMD='' [ -n "$PASSWORD" ] && PASSWORDCMD="--password $PASSWORD" || PASSWORDCMD='' [ -n "$BOOT_APPEND" ] && BOOT_APPEND="--boot_append $BOOT_APPEND" || BOOT_APPEND='' # and finally write script and execute it cat>|/usr/bin/grml-debootstrap_noninteractive</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 eend $? einfo "Adjusting /dev/vboxguest." chown root:vboxsf /dev/vboxguest chmod 660 /dev/vboxguest eend $? config_userfstab einfo "Adding $fstabuser to group vboxsf." adduser grml vboxsf &>/dev/null eend $? einfo "Starting VBoxService." VBoxService >/dev/null eend $? local vbautomation='automation' if checkbootparam 'vbautomation'; then vbautomation="$(getbootparam 'vbautomation' 2>>$DEBUG)" fi if ! VBoxControl sharedfolder list | egrep -q "^[0-9]+ - ${vbautomation}$" ; then ewarn "No automount shared folder '$vbautomation' available" eend 0 else einfo "Found automount shared folder '$vbautomation'" eend 0 local distri="$(getbootparam 'distri' 2>>$DEBUG)" [ -n "$distri" ] || distri='grml' local vbox_auto_sf="/media/sf_${vbautomation}" sleep 1 # ugly but necessary counter=10 eindent while ! [ -d "${vbox_auto_sf}" ] && [[ "$counter" != 0 ]]; do einfo "Waiting another second to retry access to ${vbox_auto_sf}" sleep 1 counter=$(( counter-1 )) eend 0 done eoutdent if ! [ -d "${vbox_auto_sf}" ] ; then eerror "Giving up trying to access folder ${vbox_auto_sf} which doesn't seem to exist" eend 1 else einfo "Found shared folders automation directory $vbox_auto_sf" eend 0 eindent if checkbootparam 'novbautomation' ; then einfo "Bootoption novbautomation found. Disabling automation script execution." eend 0 else if ! [ -x "${vbox_auto_sf}/${distri}" ] ; then ewarn "Couldn't find an automation script named ${vbox_auto_sf}/${distri}" eend 1 else einfo "Executing '${vbox_auto_sf}/${distri}' now:" "${vbox_auto_sf}/${distri}" eend $? fi fi eoutdent fi fi eoutdent fi fi } # }}} # {{{ Support customization config_distri(){ if checkbootparam 'distri'; then DISTRI="$(getbootparam 'distri' 2>>$DEBUG)" if [ -r "${LIVECD_PATH}"/desktop/"$DISTRI".jpg ] ; then [ -n "$BOOTDEBUG" ] && einfo "Debug: bootoption distri found and file ${LIVECD_PATH}/desktop/${DISTRI} present" && eend 0 # make sure the desktop.jpg file is not a symlink, so copying does not file then [ -L /usr/share/grml/desktop.jpg ] && rm /usr/share/grml/desktop.jpg cp "${LIVECD_PATH}"/desktop/"$DISTRI".jpg /usr/share/grml/desktop.jpg fi fi } # }}} ## END OF FILE ################################################################# # vim:foldmethod=marker expandtab ai ft=zsh shiftwidth=2