#!/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:/usr/X11R6/bin" DEBUG="/dev/null" KERNEL="$(uname -r)" ARCH="$(uname -m)" umask 022 # old linuxrc version: [ -d /cdrom ] && export LIVECD_PATH=/cdrom # new initramfs layout: [ -d /live/image ] && export LIVECD_PATH=/live/image # Ignore these signals in non-interactive mode: INT, TERM, SEGV [ -z "$PS1" ] && trap "" 2 3 11 # 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 /cdrom/bootparams/ ] && CMDLINE="$CMDLINE $(cat /cdrom/bootparams/* | tr '\n' ' ')" [ -d /live/image/bootparams/ ] && CMDLINE="$CMDLINE $(cat /live/image/bootparams/* | tr '\n' ' ')" 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 } ### }}} # {{{ 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" # testcd TESTCD="" checkbootparam 'testcd' >>$DEBUG 2>&1 && TESTCD="yes" # }}} # {{{ source lsb-functions , color handling if checkbootparam 'nocolor'; then RC_NOCOLOR=yes . /etc/grml/lsb-functions einfo "Disabling colors in bootsequence as requested on commandline." ; eend 0 else . /etc/grml/lsb-functions . /etc/grml_colors 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 } # }}} # {{{ set firmware timeout via bootparam config_fwtimeout(){ if checkbootparam 'fwtimeout' ; then TIMEOUT="$(getbootparam 'fwtimeout' 2>>$DEBUG)" einfo "Bootoption fwtimeout found. (Re)Loading firmware_class module." rmmod firmware_class >>$DEBUG 2>&1 modprobe firmware_class ; eend $? fi if [ -z "$TIMEOUT" ] ; then TIMEOUT="100" # linux kernel default: 10 fi if [ -f /sys/class/firmware/timeout ] ; then einfo "Setting timeout for firmware loading to ${TIMEOUT}." echo 100 > /sys/class/firmware/timeout ; eend $? 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 checkgrmlsmall && /usr/sbin/grml-setlang "POSIX" || /usr/sbin/grml-setlang "$LANGUAGE" # otherwise default to lang=en else checkgrmlsmall && /usr/sbin/grml-setlang "POSIX" || /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 if checkgrmlsmall ; then export LANG='C' # grml-small does not provide any further locales else [ -r /etc/default/locale ] && . /etc/default/locale export LANG LANGUAGE fi # 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 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 ; RC=$? [ "$RC" = "0" ] && hostname $HOSTNAME eend $RC else hostname --file /etc/hostname fi } # }}} # fstabuser (needed when running from harddisk with username != grml {{{ config_userfstab(){ [ -r /etc/grml/autoconfig ] && . /etc/grml/autoconfig if [ -n "$CONFIG_FSTAB_USER" ] ; then fstabuser="$CONFIG_FSTAB_USER" else fstabuser=$(getent passwd 1000 | cut -d: -f1) fi # if not yet set fall back to default 'grml' user [ -n "$fstabuser" ] || fstabuser='grml' } # }}} # {{{ 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" 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" # 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="Europe/Vienna" 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(){ vmware-detect &>/dev/null && VMWARE="inside ${WHITE}VMware/Qemu${NORMAL}" [ -d /proc/xen ] && VMWARE='' # vmware-detect returns '0' when running with a Xen-enabled kernel einfo "Running Linux Kernel $KERNEL $VMWARE" ; eend 0 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 } # }}} # {{{ ld.so.cache + depmod config_ld_mod(){ if [ -n "$INSTALLED" ]; then if ! [ -r /etc/grml.first.boot ] ; then einfo "Running from HD for the first time, regenerate ld.so.cache and modules.dep:" eindent # Regenerate ld.so.cache and module dependencies on HD einfo "Running ldconfig" ; ldconfig ; eend $? einfo "Running depmod" ; depmod -a ; eend $? touch /etc/grml.first.boot eend 0 eoutdent 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 } # }}} # small computer / nearly no ram {{{ config_small(){ RAM=$(/usr/bin/gawk '/MemTotal/{print $2}' /proc/meminfo) # MEM=$(/usr/bin/gawk 'BEGIN{m=0};/MemFree|Cached|SwapFree/{m+=$2};END{print m}' /proc/meminfo) eindent if checkbootparam 'small'; then einfo "Information: ${RAM} kB of RAM available." ; eend 0 einfo "Bootoption small detected. Activating small system." if [ -r /etc/inittab.small ] ; then mv /etc/inittab /etc/inittab.normal mv /etc/inittab.small /etc/inittab else sed -i 's/^9/#&/' /etc/inittab sed -i 's/^10/#&/' /etc/inittab sed -i 's/^11/#&/' /etc/inittab sed -i 's/^12/#&/' /etc/inittab fi /sbin/telinit q ; eend $? else if checkgrmlsmall ; then if [[ $RAM -lt 25000 ]] ; then ewarn "Information: ${RAM} kB of RAM available." ; eend 1 ewarn "At least 32MB of RAM should be available for grml-small." ; eend 1 ewarn "Use the bootoption small to save some more MB of memory usage." ; eend 0 ewarn "Dropping you into a rescue shell. To continue booting exit the shell." ; eend 0 /bin/zsh --login else einfo "Information: ${RAM} kB of RAM available." ; eend 0 fi else if [[ $RAM -lt 58000 ]] ; then ewarn "Information: ${RAM} kB of RAM available." ; eend 1 ewarn "At least 64MB of RAM should be available for grml." ; eend 1 ewarn "Use the bootoption small to save some more MB of memory usage." ; eend 0 ewarn "Dropping you into a rescue shell. To continue booting exit the shell." ; eend 0 /bin/zsh --login else einfo "Information: ${RAM} kB of RAM available." ; eend 0 fi fi fi eoutdent } # }}} # skip startup of w3m {{{ config_fast(){ if checkbootparam 'fast'; then ewarn "Bootoption fast detected. Skipping startup of grml-quickconfig." sed -i 's#^1:.*#1:12345:respawn:/usr/bin/openvt -f -c 1 -w -- /bin/zsh#' /etc/inittab /sbin/telinit q ; eend $? fi } # }}} # activate serial console {{{ config_console(){ if checkbootparam 'console'; then 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 } # }}} # {{{ Bring up loopback interface now config_local_net(){ if [ -z "$INSTALLED" ] ; then if grep -q 'iface lo inet loopback' /etc/network/interfaces 2>/dev/null ; then grep -q lo=lo /etc/network/run/ifstate 2>/dev/null || ifup lo else ifconfig lo up fi fi } # }}} # {{{ copy passwd-lockfile to ramdisk (fix unionfs-behaviour) # otherwise we will get: passwd: Authentication token lock busy config_fix_passwd(){ if [ -z "$INSTALLED" ] ; then touch /etc/.pwd.lock fi } # }}} # {{{ CD Checker config_testcd(){ if [ -n "$TESTCD" ]; then einfo "Checking CD data integrity as requested by '${WHITE}testcd${NORMAL}' boot option." einfo "Reading files and checking against GRML/md5sums, this may take a while..." echo -n "${RED}" if [ -n "${LIVECD_PATH}"/GRML ] ; then ( cd "${LIVECD_PATH}"/GRML ; rm -f /tmp/md5sum.log ; md5sum -c md5sums 2>&1 | tee /tmp/md5sum.log ; RC=$? ) else echo "${RED} *** Error: Could not find md5sum file. ***" fi if [ "$RC" = "0" ]; then einfo "Everything looks OK" ; eend 0 else eerror 'Checksum failed for theses files:' ; eend 1 egrep -v '(^md5sum:|OK$)' /tmp/md5sum.log eerror 'Data on the grml medium is possibly incomplete/damaged or...' eerror '... RAM of your computer is broken.' ; eend 1 einfon "Hit return to continue, or press the reset button to quit." read a fi eend 0 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_apm(){ if [ -d /proc/acpi ]; then 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 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 ! ps x 2>>$DEBUG | grep -q /usr/sbin/acpid ; then einfo "Starting acpi daemon." /etc/init.d/acpid start >>$DEBUG 2>&1 ; eend $? else ewarn "acpi daemon already running." eend 0 fi eoutdent fi else # APM if checkbootparam 'noapm'; then ewarn "Skipping APM Bios detection as requested on boot commandline." ; eend 0 else modprobe apm power_off=1 >>$DEBUG 2>&1 if [ "$?" = "0" ] ; then if [ -x /etc/init.d/apmd ] ;then einfo "APM Bios found, enabling power management functions." /etc/init.d/apmd start ; eend $? fi else eerror "Loading apm module failed." ; eend 1 fi fi fi } # }}} # {{{ AGP config_agp(){ if checkbootparam 'forceagp' ; then # Probe for AGP. Hope this can fail safely grep -q "AGP" "/proc/pci" 2>>$DEBUG && { modprobe agpgart || modprobe agpgart agp_try_unsupported=1; } >>$DEBUG 2>&1 && einfo "AGP bridge detected." ; eend 0 fi } # }}} # {{{ Collect partitions from /proc/partitions first for enabling DMA check_partitions(){ partitions="" IDEDISKS="" while read major minor blocks partition relax; do partition="${partition##*/}" [ -z "$partition" -o ! -e "/dev/$partition" ] && continue case "$partition" in hd?) IDEDISKS="$IDEDISKS $partition";; # IDE Harddisk, entire disk sd?) ;; # SCSI Harddisk, entire disk # [hs]d*) partitions="$partitions /dev/$partition";; # IDE or SCSI disk partition [hs]d*|ub*) partitions="$partitions /dev/$partition";; # IDE, USB or SCSI disk partition esac done </dev/null 2>&1 # avoid output "check_partitions:3: read-only file system" # }}} # {{{ Enable DMA for all IDE drives now if not disabled # Notice: Already done by linuxrc, but make sure it's done also on harddisk-installed systems config_dma(){ if checkbootparam 'nodma'; then ewarn "Skipping DMA accelleration as requested on boot commandline." ; eend 0 else for d in $(cd /proc/ide 2>>$DEBUG && echo hd[a-z]); do if test -d /proc/ide/$d; then if egrep -q 'using_dma[ \t]+0' /proc/ide/$d/settings 2>>$DEBUG; then MODEL="$(cat /proc/ide/$d/model 2>>$DEBUG)" test -z "$MODEL" && MODEL="[GENERIC IDE DEVICE]" einfo "Enabling DMA acceleration for: ${WHITE}$d ${YELLOW}[${MODEL}]${NORMAL}" echo "using_dma:1" >/proc/ide/$d/settings eend 0 fi fi done 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 "Detecting 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 [ -r /proc/acpi/battery/BAT0/info ] && grep -q 'OEM info:.*innotek' /proc/acpi/battery/BAT0/info ; then einfo 'Virtual Box detected, skipping cpufreq setup.' ; eend 0 return 0 fi if [ -x /etc/init.d/loadcpufreq ] ; then 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 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 einfo "Loading cpufreq_ondemand, setting ondemand governor" RC=0 if modprobe cpufreq_ondemand ; RC=$? ; then for file in $(find /sys/devices/system/cpu/ -name scaling_governor 2>/dev/null) ; do echo ondemand > $file done fi eend $RC fi # cpu-governor eoutdent fi } # }}} # {{{ autostart of ssh config_ssh(){ if checkbootparam 'ssh' ; then SSH_PASSWD='' SSH_PASSWD="$(getbootparam 'ssh' 2>>$DEBUG)" einfo "Bootoption ssh found, trying to set password for user grml." eindent if [ -z "$SSH_PASSWD" ] ; then if [ -x /usr/bin/apg ] ; then SSH_PASSWD="$(apg -M NL -a 0 -m 8 -x 12 -n 1)" elif [ -x /usr/bin/gpw ] ; then SSH_PASSWD="$(gpw 1)" elif [ -x /usr/bin/pwgen ] ; then SSH_PASSWD="$(pwgen -1 8)" elif [ -x /usr/bin/hexdump ] ; then SSH_PASSWD="$(dd if=/dev/urandom bs=14 count=1 2>/dev/null | hexdump | awk '{print $3 $4}')" elif [ -n "$RANDOM" ] ; then SSH_PASSWD="grml${RANDOM}" else SSH_PASSWD='' eerror "Empty passphrase and neither pwgen nor hexdump nor \$RANDOM found. Skipping." eend 1 fi if [ -n "$SSH_PASSWD" ] ; then ewarn "No given password for ssh found. Using random password: $SSH_PASSWD" ; eend 0 fi fi eoutdent # finally check if we have a password we can use: if [ -n "$SSH_PASSWD" ] ; then # chpasswd sucks, seriously. if chpasswd --help 2>&1 | grep -q -- '-m,' ; then echo "grml:$SSH_PASSWD" | chpasswd -m else echo "grml:$SSH_PASSWD" | chpasswd fi fi einfo 'Starting secure shell server in background.' /etc/init.d/rmnologin start >>$DEBUG 2>>$DEBUG /etc/init.d/ssh start >>$DEBUG 2>>$DEBUG & eend $? eindent ewarn 'Warning: please change the password for user grml as soon as possible!' eoutdent fi } # }}} # {{{ autostart of x11vnc config_vnc(){ USER=grml # TODO: make it dynamically configurable if checkbootparam 'vnc' ; then VNC_PASSWD='' VNC_PASSWD="$(getbootparam 'vnc' 2>>$DEBUG)" einfo "Bootoption vnc found, trying to set password for user $USER." 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="${USER}${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/${USER}/.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 "$USER": "$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/${USER}/.vnc" [ -d "$VNCDIR" ] || mkdir "$VNCDIR" echo " --connect $VNC_CONNECT " >> $VNCDIR/options fi fi } # }}} # {{{ set password for user grml config_passwd(){ if checkbootparam 'passwd' >>$DEBUG 2>&1; then einfo "Bootoption passwd found." PASSWD="$(getbootparam 'passwd' 2>>$DEBUG)" if [ -n "$PASSWD" ] ; then echo "grml:$PASSWD" | chpasswd -m ; eend $? else eerror "No given password for ssh found. Autostart of SSH will not work." ; eend 1 fi eindent ewarn "Warning: please change the password for user grml set via bootparameter as soon as possible!" eoutdent 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)" else MICVOL=0 fi for CONTROL in Master PCM ; do if amixer -q | grep -q "Simple mixer control '$CONTROL'" ; then amixer -q set "${CONTROL}" "${VOL}"% eend $? fi done if [ ${MICVOL} -ne 0 ] ; then einfo "Setting microphone to ${WHITE}${MICVOL}${NORMAL}." amixer -q set "Mic" $MICVOL &> /dev/null eend $? fi fi # checkbootparam 'nosound' eoutdent done fi } # }}} # {{{ modem detection config_modem(){ if checkbootparam 'nomodem'; then ewarn "Skipping check for AC97 modem controller as requested on boot commandline." ; eend 0 else if [ -x /etc/init.d/sl-modem-daemon ] ; then if lspci | grep Intel | grep -q "AC'97 Modem Controller" ; then einfo "AC97 modem controller detected. Start it running 'Start sl-modem-daemon'." eend 0 fi fi fi } # }}} # {{{ wondershaper config_wondershaper(){ if checkbootparam 'wondershaper' ; then WONDER="$(getbootparam 'wondershaper' 2>>$DEBUG)" CMD=wondershaper DEVICE="" DOWNSTREAM="" UPSTREAM="" if [ -n "$WONDER" ]; then # Extra options DEVICE="${WONDER%%,*}" R="${WONDER#*,}" if [ -n "$R" -a "$R" != "$WONDER" ]; then WONDER="$R" DOWNSTREAM="${WONDER%%,*}" R="${WONDER#*,}" if [ -n "$R" -a "$R" != "$WONDER" ]; then WONDER="$R" UPSTREAM="${WONDER%%,*}" R="${WONDER#*,}" fi fi fi [ -n "$DEVICE" ] && CMD="$CMD $DEVICE" [ -n "$DOWNSTREAM" ] && CMD="$CMD $DOWNSTREAM" [ -n "$UPSTREAM" ] && CMD="$CMD $UPSTREAM" einfo "Starting wondershaper (${CMD}) in background." ( sh -c $CMD & ) && eend 0 fi } # }}} # {{{ syslog-ng config_syslog(){ if checkbootparam 'nosyslog'; then ewarn "Not starting syslog daemon as requested on boot commandline." ; eend 0 else SYSLOGD='' [ -x /etc/init.d/syslog-ng ] && SYSLOGD='syslog-ng' [ -x /etc/init.d/rsyslog ] && SYSLOGD='rsyslog' [ -x /etc/init.d/dsyslog ] && SYSLOGD='dsyslog' [ -x /etc/init.d/sysklogd ] && SYSLOGD='sysklogd' [ -x /etc/init.d/inetutils-syslogd ] && SYSLOGD='inetutils-syslogd' if [ -z "$SYSLOGD" ] ; then eerror "No syslog daemon found." ; eend 1 else einfo "Starting $SYSLOGD in background." /etc/init.d/$SYSLOGD start >>$DEBUG & eend 0 fi 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." /etc/init.d/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}." /etc/init.d/${service} start >>$DEBUG else einfo "Starting service ${service} in background." /etc/init.d/${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}" counter=10 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 } # }}} # {{{ fix/workaround for unionfs fix_unionfs(){ if [ -z "$INSTALLED" ]; then touch /var/cache/apt/*cache.bin 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. Taking ${WHITE}wm-ng${NORMAL} as default." && eend 0 WINDOWMANAGER="wm-ng" 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_userfstab || fstabuser='grml' cat>|/etc/init.d/xstartup</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/X11R6/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' || checkbootparam 'forensic' ; then 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 # We do need the following fix so floppy disk is available to blkid in any case :-/ if [ -r /dev/fd0 ] ; then einfo "Floppy device detected. Trying to access floppy disk." if timeout 4 dd if=/dev/fd0 of=/dev/null bs=512 count=1 >>$DEBUG 2>&1 ; then blkid /dev/fd0 >>$DEBUG 2>&1 fi fi DCSDEVICE=$(blkid -t LABEL=$GRMLCFG | head -1 | awk -F: '{print $1}') if [ -n "$DCSDEVICE" ]; then DCSMP="/mnt/grmlcfg" fi eoutdent fi # if not specified/present then assume default: if [ -z "$DCSDEVICE" ]; then DCSDIR="/live/image" 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 ro -t 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" != "/live/image" ] ; 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 "Tring 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 [ "$DCSMP" = "/mnt/grmlcfg" ]; then # we are executing from a GRMLCFG labeled fs # kick everything we have done before and start over SCRIPTS="$(cd ${DCSDIR}; /bin/ls -1d [Gg][Rr][Mm][Ll].[Ss][Hh] 2>>$DEBUG)" fi if [ -n "$SCRIPTS" ]; then SCRIPTS="${DCSDIR}/$SCRIPTS" if [ "$DCSMP" = "/mnt/grmlcfg" ]; then einfo "Trying to execute ${SCRIPTS}" sh -c $SCRIPTS elif [ -d "$SCRIPTS" ]; then einfo "Bootparameter scripts found. Trying to execute from directory ${SCRIPTS}:" run-parts $SCRIPTS else einfo "Bootparameter scripts found. Trying to execute ${SCRIPTS}:" sh -c $SCRIPTS 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 } # }}} # {{{ distcc config_distcc(){ if checkbootparam 'distcc' ; then OPTIONS="$(getbootparam 'distcc' 2>>$DEBUG)" if [ -n "$OPTIONS" ]; then NET="" INTERFACE="" if [ -n "$OPTIONS" ]; then NET="${OPTIONS%%,*}" R="${OPTIONS#*,}" if [ -n "$R" -a "$R" != "$OPTIONS" ]; then OPTIONS="$R" INTERFACE="${OPTIONS%%,*}" R="${OPTIONS#*,}" fi fi fi CONFIG=/etc/default/distcc sed -i "s#^STARTDISTCC=.*#STARTDISTCC=YES#" $CONFIG sed -i "s#^ALLOWEDNETS=.*#ALLOWEDNETS=$NET#" $CONFIG if [ -n "$INTERFACE" ] ; then IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}') counter=10 while [ -z "$IP" ] && [[ "$counter" != 0 ]] ; do counter=$(( counter-1 )) ewarn "No ip address for $INTERFACE found. Sleeping for 3 seconds. $counter tries left." sleep 3 IP=$(LANG=C ifconfig $INTERFACE | gawk -F: /"inet addr"/'{print $2}' | gawk '{print $1}') done fi if [ -n "$IP" ] ; then sed -i "s#^LISTENER=.*#LISTENER=$IP#" $CONFIG einfo "Bootoption distcc found. Preparing setup for distcc daemon." eindent id distccd >/dev/null 2>&1 || \ ( einfo "Creating distcc user" ; \ adduser --quiet --system --ingroup nogroup --home / --no-create-home distccd ; eend $? ) einfo "Starting distcc for network ${NET}, listening on ${IP}." /etc/init.d/distcc start >/dev/null ; eend $? eoutdent else eerror "No ip address for $INTERFACE found. distcc can not be used without it." ; eend 1 fi fi if checkbootparam 'gcc'; then GCC="$(getbootparam 'gcc' 2>>$DEBUG)" eindent einfo "Pointing /usr/bin/gcc to /usr/bin/gcc-${GCC}." eoutdent rm -f /usr/bin/gcc ln -s /usr/bin/gcc-${GCC} /usr/bin/gcc ; eend $? fi if checkbootparam 'gpp'; then GPP="$(getbootparam 'gpp' 2>>$DEBUG)" eindent einfo "Pointing /usr/bin/g++ to /usr/bin/g++-${GPP}." if [ -x /usr/bin/g++-${GPP} ] ; then rm -f /usr/bin/g++ ln -s /usr/bin/g++-${GPP} /usr/bin/g++ ; eend $? fi einfo "Pointing /usr/bin/cpp to /usr/bin/cpp-${GPP}." if [ -x /usr/bin/cpp-${GPP} ] ; then rm -f /usr/bin/cpp ln -s /usr/bin/cpp-${GPP} /usr/bin/cpp ; eend $? fi eoutdent fi } # }}} # {{{ load modules # Notice: use it only on live-cd system, if running from harddisk please # add modules to /etc/modules and activate /etc/init.d/module-init-tools # in /etc/runlevel.conf config_modules(){ MODULES_FILE=/etc/grml/modules if checkbootparam 'nomodules' ; then ewarn "Skipping loading of modules defined in ${MODULES_FILE} as requested." ; eend 0 elif [ -z "$INSTALLED" ]; then if [ -r $MODULES_FILE ] ; then einfo "Loading modules specified in ${MODULES_FILE}:" eindent grep '^[^#]' $MODULES_FILE | \ while read module args; do [ "$module" ] || continue einfo "${module}" modprobe $module $args ; eend $? done eoutdent else ewarn "File $MODULES_FILE does not exist. Skipping loading of specific modules." ; eend 1 fi fi } # }}} # {{{ 915resolution config_915resolution(){ if checkbootparam '915resolution' ; then OPTIONS="$(getbootparam '915resolution' 2>>$DEBUG)" if [ -x /usr/sbin/915resolution ]; then CMD=915resolution MODE="" XRESO="" YRESO="" if [ -n "$OPTIONS" ]; then # Extra options MODE="${OPTIONS%%,*}" R="${OPTIONS#*,}" if [ -n "$R" -a "$R" != "$OPTIONS" ]; then OPTIONS="$R" XRESO="${OPTIONS%%,*}" R="${OPTIONS#*,}" if [ -n "$R" -a "$R" != "$OPTIONS" ]; then OPTIONS="$R" YRESO="${OPTIONS%%,*}" R="${OPTIONS#*,}" fi fi fi einfo "Running 915resolution with options ${MODE} ${XRESO} ${YRESO}." [ -n "$MODE" ] && [ -n "$XRESO" ] && [ -n "$YRESO" ] && ( sh -c "$CMD $MODE $XRESO $YRESO" & ) eend 0 fi fi } # }}} # {{{ SW-RAID config_swraid(){ [ -n "$INSTALLED" ] && return 0 # notice: checkbootparam "forensic" is just for users who don't know how to really use the bootoption if checkbootparam 'noraid' || checkbootparam 'noswraid' || \ checkbootparam 'forensic' || checkbootparam 'raid=noautodetect' ; then ewarn "Skipping SW-RAID code as requested on boot commandline." ; eend 0 else 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 einfo "Just run 'Start mdadm-raid' to assemble md arrays or boot using 'swraid' as bootoption for autostart." 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 # Debian etch provides /etc/init.d/lvm only, newer suites provide /etc/init.d/lvm2 if ! [ -x /sbin/lvm -a -x /sbin/lvdisplay ] || ! [ -x /etc/init.d/lvm2 -o -x /etc/init.d/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 einfo "Just run 'Start lvm2' to activate them or boot using 'lvm' as bootoption for autostart." eend 0 if checkbootparam 'lvm' ; then einfo "Bootoption LVM found. Searching for logical volumes:" /etc/init.d/lvm2 start ; eend $? 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 } # }}} # {{{ tohd= bootoption config_tohd() { if checkbootparam 'tohd' ; then local TARGET="$(getbootparam 'tohd' 2>>$DEBUG)" if [ -z "$TARGET" ] ; then eerror "Error: tohd specified without any partition, can not continue." ; eend 1 eerror "Please use something like tohd=/dev/sda9." ; eend 1 return 1 fi if ! [ -b "$TARGET" ] ; then eerror "Error: $TARGET is not a valid block device, sorry." ; eend 1 return 1 fi if grep -q $TARGET /proc/mounts ; then eerror "$TARGET already mounted, skipping execution of tohd therefore." eend 1 return 1 fi local MOUNTDIR=$(mktemp -d) if mount -o rw "$TARGET" "$MOUNTDIR" ; then einfo "Copyring live system to $TARGET - this might take a while" rsync -a --progress /live/image/live $MOUNTDIR sync umount "$MOUNTDIR" eend $? einfo "Booting with \"grml bootfrom=$TARGET\" should work now." ; eend 0 else eerror "Error when trying to mount $TARGET, sorry."; eend 1 return 1 fi rmdir "$MOUNTDIR" fi } # }}} # {{{ grml2hd: automatic installation config_grml2hd(){ if checkbootparam "grml2hd" || checkbootparam "BOOT_IMAGE=grml2hd" ; then if checkbootparam 'user' ; then NEWUSER='' NEWUSER="$(getbootparam 'user' 2>>$DEBUG)" sed -i "s/^NEWUSER=.*/NEWUSER=$NEWUSER/" /etc/grml2hd/config || export GRML2HD_FAIL=1 fi if checkbootparam 'filesystem' ; then FILESYSTEM='' FILESYSTEM="$(getbootparam 'filesystem' 2>>$DEBUG)" sed -i "s/^FILESYSTEM=.*/FILESYSTEM=$FILESYSTEM/" /etc/grml2hd/config || export GRML2HD_FAIL=1 fi if checkbootparam 'partition' ; then PARTITION='' PARTITION="$(getbootparam 'partition' 2>>$DEBUG)" # notice: the following checks whether the given partition is available, if not the skip # execution of grml2hd as it might result in data loss... if [ -r $PARTITION ] ; then sed -i "s#^PARTITION=.*#PARTITION=$PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1 else ewarn "Partition $PARTITION does not exist. Skipping execution of grml2hd therefore." ; eend 1 fi fi if checkbootparam 'mbr' ; then BOOT_PARTITION='' BOOT_PARTITION="$(getbootparam 'mbr' 2>>$DEBUG)" sed -i "s#^BOOT_PARTITION=.*#BOOT_PARTITION=$BOOT_PARTITION#" /etc/grml2hd/config || export GRML2HD_FAIL=1 fi cat>|/usr/bin/grml2hd_noninteractive<|/usr/bin/grml-debootstrap_noninteractive</dev/null eend $? einfo "Starting VBoxService." VBoxService >/dev/null & eend $? 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=3