diff options
author | Sebastian | 2016-04-25 12:01:08 +0200 |
---|---|---|
committer | Sebastian | 2016-04-25 12:01:08 +0200 |
commit | 5acda3eaeabae9045609539303a8c12c4ce401f1 (patch) | |
tree | 7e71975f8570b05aafe2ea6ec0e242a8912387bb /core/rootfs/rootfs-stage31/data/inc | |
parent | initial commit (diff) | |
download | mltk-5acda3eaeabae9045609539303a8c12c4ce401f1.tar.gz mltk-5acda3eaeabae9045609539303a8c12c4ce401f1.tar.xz mltk-5acda3eaeabae9045609539303a8c12c4ce401f1.zip |
merge with latest dev version
Diffstat (limited to 'core/rootfs/rootfs-stage31/data/inc')
-rw-r--r-- | core/rootfs/rootfs-stage31/data/inc/activate_sysconfig | 98 | ||||
-rw-r--r-- | core/rootfs/rootfs-stage31/data/inc/drm.functions | 80 | ||||
-rw-r--r-- | core/rootfs/rootfs-stage31/data/inc/functions | 84 | ||||
-rw-r--r-- | core/rootfs/rootfs-stage31/data/inc/network.functions | 23 | ||||
-rwxr-xr-x | core/rootfs/rootfs-stage31/data/inc/ntp_sync | 26 | ||||
-rw-r--r-- | core/rootfs/rootfs-stage31/data/inc/parse_kcl | 58 | ||||
-rw-r--r-- | core/rootfs/rootfs-stage31/data/inc/setup_network | 84 | ||||
-rw-r--r-- | core/rootfs/rootfs-stage31/data/inc/setup_network_retry | 33 | ||||
-rw-r--r-- | core/rootfs/rootfs-stage31/data/inc/setup_stage32 | 68 | ||||
-rw-r--r-- | core/rootfs/rootfs-stage31/data/inc/setup_stage4 | 69 | ||||
-rwxr-xr-x | core/rootfs/rootfs-stage31/data/inc/udhcpc-trigger | 93 |
11 files changed, 716 insertions, 0 deletions
diff --git a/core/rootfs/rootfs-stage31/data/inc/activate_sysconfig b/core/rootfs/rootfs-stage31/data/inc/activate_sysconfig new file mode 100644 index 00000000..c9b74791 --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/activate_sysconfig @@ -0,0 +1,98 @@ +#!/bin/ash + +echo "Configuring stage 3.2 ..." + +# first a few variables +CONFIG="${FUTURE_ROOT}/opt/openslx/config" + +######################################################################### +# +# This function downloads the config containing environment variables +# +fetch_sysconfig() { + [ -e "$CONFIG" ] && grep -E '^#_RCONFIG_TAG$' "$CONFIG" > /dev/null \ + && echo "Config already fetched." && return 0 + + download "${SLX_BASE_PATH}/config" "${CONFIG}-remote" || return 1 + + echo "# Config fetched from $URL" >> "$CONFIG" + echo "#_RCONFIG_TAG" >> "$CONFIG" + cat "${CONFIG}-remote" >> "$CONFIG" +} +######################################################################### +# +# This function downloads the config.tgz and unpacks it to $TARGET_PATH <-- no it doesn't! +# +fetch_config_files() { + [ -e "${CONFIG}.tgz" ] && echo "config.tgz already downloaded." && return 0 + + download "${SLX_BASE_PATH}/config.tgz" "${CONFIG}.tgz" +} + + +######################################################################### +# +# This function updates the downloaded config with the IP information +# received from /inc/setup_network <-- plus 500 other things +update_sysconfig() { + # sanity checks + [ ! -e "${CONFIG}" ] && { echo "Cannot update. '$CONFIG' does not exist."; return 1; } + + # write IP and SLX_SERVER configuration to $CONFIG +cat >> "$CONFIG" <<HEREEND +# IP Config written in stage31 +SLX_PXE_CLIENT_IP='$CLIENTIP' +SLX_PXE_SERVER_IP='$SERVERIP' +SLX_PXE_GATEWAY='$GATEWAY' +SLX_PXE_DNS='$DNS_SERVER' +SLX_PXE_MAC='$BRIDGEMAC' +HEREEND + + [ ! -e "${CONFIG}.tgz" ] && { echo "Cannot update. '$CONFIG' does not exist."; return 1; } + + # setup hardware clock + . "${CONFIG}" + if [ "x$SLX_BIOS_CLOCK" == "xlocal" ]; then + hwclock -s -l + elif [ "x$SLX_BIOS_CLOCK" == "xutc" ]; then + hwclock -s -u + fi + + local TEMP_EXTRACT_DIR="/tmp/config.tgz.tmp" + # TODO perserve existing directories permissions (but overwrite the permissions of files!) + mkdir -p "${TEMP_EXTRACT_DIR}" + tar xf "${CONFIG}.tgz" -C "${TEMP_EXTRACT_DIR}" || { echo "Could not untar ${CONFIG}.tgz to ${TEMP_EXTRACT_DIR}"; return 1; } + chown -R 0:0 "${TEMP_EXTRACT_DIR}" 2>/dev/null + cd "${TEMP_EXTRACT_DIR}" + # first we look for local config.tgz files, which we merge with the common + # config.tgz files + local LOCAL_CONFIG_DIR="openslx-configs/${SLX_LOCAL_CONFIG}" + if [ -n "${SLX_LOCAL_CONFIG}" -a -d "${LOCAL_CONFIG_DIR}" ]; then + tarcopy "${LOCAL_CONFIG_DIR}" "${TEMP_EXTRACT_DIR}" + echo "Merged local configuration files for '${SLX_LOCAL_CONFIG}'" + fi + # purge openslx-configs/* + rm -rf -- "openslx-configs/" + # now just tarcopy them to future root + tarcopy "${TEMP_EXTRACT_DIR}" "${FUTURE_ROOT}" + # cleanup the downloaded stuff + cd / + rm -rf -- "${TEMP_EXTRACT_DIR}" + [ $DEBUG -eq 0 ] && rm -f -- "${CONFIG}.tgz" + # Display branding logo if splash screen is shown + [ "x${MUTED_OUTPUT}" = "x1" ] && [ -e "${FUTURE_ROOT}/etc/branding.ppm" ] && fbsplash -s "${FUTURE_ROOT}/etc/branding.ppm" & + return 0 +} + + +######################################################################### +# +# MAIN PART +# + +fetch_sysconfig || drop_shell "Could not download remote config" +. "${CONFIG}-remote" || drop_shell "Could not source remote config" +fetch_config_files || drop_shell "Could not download config.tgz" +update_sysconfig || drop_shell "Could not update sysconfig" +true + diff --git a/core/rootfs/rootfs-stage31/data/inc/drm.functions b/core/rootfs/rootfs-stage31/data/inc/drm.functions new file mode 100644 index 00000000..c62c562b --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/drm.functions @@ -0,0 +1,80 @@ + +# pass module name(s) relative path in /lib/modules with .ko extension, or special like @nvidia or @amd +load_gfx () { + local MOD FILES OFFSET RETVAL + RETVAL=1 # default: failure + while [ $# -gt 0 ]; do + MOD=$(echo $1) # trim :) + shift + [ -z "$MOD" ] && continue + if [ "x${MOD}" != "x${MOD#@}" ]; then + # starts with '@' - special + OFFSET=$(( ${#MOD} + 2 )) + FILES=$( grep "^$MOD\s" "/drm.cfg" | cut -c ${OFFSET}- ) + [ -z "$FILES" ] && drop_shell "Could not find entry for special $MOD" + if load_gfx $FILES; then + RETVAL=0 + else + # loading special case failed, try fallback if found + MOD="${MOD}_fallback" + OFFSET=$(( ${#MOD} + 2 )) + FILES=$( grep "^$MOD\s" "/drm.cfg" | cut -c ${OFFSET}- ) + [ -n "$FILES" ] && load_gfx $FILES && RETVAL=0 + fi + else # regular module name or filename + if [ "x${MOD%.ko}" == "x${MOD}" ]; then + # regular module name + modprobe "$MOD" && RETVAL=0 + else + # a .ko file + insmod "/lib/modules/$MOD" && RETVAL=0 + fi + fi + done + return $RETVAL +} + +setup_gfx () { + local KERN RETVAL CARD CARDS SUCCESS FILES DRM + # check if forced by KCL + if [ "x$GFX" == "xnvidia" ]; then + load_gfx @nvidia + return + fi + if [ "x$GFX" == "xamd" ]; then + load_gfx @amd + return + fi + # not forced - check which driver to load + CARDS=$(lspci | grep 'Class 0300' | awk '{print $4}') + if [ -e "/drm.cfg" ] && [ -n "$CARDS" ]; then + SUCCESS="yes" + for CARD in $CARDS; do + # look up exact pci id of this card + [ $DEBUG -ge 1 ] && echo Trying exact matching for drm drivers for $CARD + FILES=$(grep "^$CARD\s" "/drm.cfg" | cut -c 11-) + load_gfx $FILES && continue + # failed... try vendor id only + CARD=$(echo $CARD | cut -c 1-4) + [ $DEBUG -ge 1 ] && echo Trying vendor matching for drm drivers for $CARD + FILES=$(grep "^$CARD\s" "/drm.cfg" | cut -c 6-) + load_gfx $FILES && continue + # everything failed for this card + echo Unknown PCI vendor id: $CARD + SUCCESS="no" + done + [ "x$SUCCESS" == "xyes" ] && return 0 + fi + # braindead fallback + echo "At least one gfx card has no known drm drivers.... will load them all :/" + KERN=$(uname -r) + RETVAL=1 + [ -z "$KERN" ] && KERN=$(ls '/lib/modules' | grep '\.' | tail -n 1) + for DRM in $(find "/lib/modules/$KERN/kernel/drivers/gpu/drm" -name "*.ko"); do + DRM="$(basename "$DRM")" + DRM="${DRM%.ko}" + modprobe "$DRM" && RETVAL=0 + done + return $RETVAL +} + diff --git a/core/rootfs/rootfs-stage31/data/inc/functions b/core/rootfs/rootfs-stage31/data/inc/functions new file mode 100644 index 00000000..248d0149 --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/functions @@ -0,0 +1,84 @@ +######################################################################### +# +# COMMON HELPER FUNCTIONS +# + +######################################################################### +# +# Function to drop a debug shell with an error message. +# +# Usage: +# drop_shell "This is your error message." +# +drop_shell() { + if [ -n "$MUTED_OUTPUT" ]; then + exec 1>&4 2>&5 + reset + fi + [ $# -gt 0 ] && echo $@ + echo "CTRL + D will continue booting." + setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1' +} + +######################################################################### +# +# Helper function to download given FILE_URL from servers in 'slxsrv' +# as given through the kernel command line. File will be saved under TARGET_PATH +# +# Usage: +# download FILE_URL TARGET_PATH +# +# Example: +# download "config" "/opt/openslx/config" +# +# Note: +# FILE_URL can have subpath, e.g. "ubuntu-13.04-x64/config" +# +download() { + [ $# -ne 2 ] && echo "Error - 'download' requires 2 arguments, $# given." && return 1 + + if [ -z "$SLX_KCL_SERVERS" ]; then + . "/opt/openslx/config" || echo "Error - could not source '/opt/openslx/config'" + fi + + local FILE_URL="$1" + local TARGET_PATH="$2" + + # Shuffle server list + local SERVERS=$(for SERVER in $SLX_CONFIG_SERVERS $SLX_KCL_SERVERS; do echo "$RANDOM $SERVER"; done | sort -u | sed -r 's/^[0-9]+ //') + + for TIMEOUT in 1 1 2 END; do + for SERVER in $SERVERS; do + rm -f -- "${TARGET_PATH}" + wget -T 5 -q -O "$TARGET_PATH" "http://${SERVER}/${FILE_URL}" + RET=$? + if [ "x$RET" != "x0" -o ! -e "$TARGET_PATH" ]; then + echo "Error - downloading 'http://$SERVER/$FILE_URL' via wget failed. Exit Code: $RET" + usleep 50000 # 50ms + else + echo "Successfully downloaded 'http://${SERVER}/$FILE_URL'." + return 0 + fi + done + [ "$TIMEOUT" = "END" ] && break + echo "Trying again in $(($TIMEOUT * 250)) ms..." + usleep $(($TIMEOUT * 250000)) + done + # Max retries reached, no success :-( + return 1 +} + +# Add benchmark event to var, including uptime as prefix +bench_event() { + bench_result="${bench_result}$(cut -f 1 -d ' ' "/proc/uptime") $@ +" +} + +# mini tarcopy <3 +# tarcopy <source_dir> <target_dir> +tarcopy() { + [ -d "$1" -a -d "$2" ] || return 1 + cd "$1" + tar -cp * | tar -xp -C "$2" + cd - &>/dev/null +} diff --git a/core/rootfs/rootfs-stage31/data/inc/network.functions b/core/rootfs/rootfs-stage31/data/inc/network.functions new file mode 100644 index 00000000..641f4f55 --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/network.functions @@ -0,0 +1,23 @@ +wait_for_iface() { + local DEVICE=$1 + local TIMEOUT=10 + echo -n "Waiting for interface $DEVICE: " + # Some systems don't have operstate. Seems to be hardware dependent + [ ! -e "/sys/class/net/${DEVICE}/operstate" ] && usleep 10000 + if [ -e "/sys/class/net/${DEVICE}/operstate" ]; then + while true; do + # check linkstate + [ "x$(cat "/sys/class/net/${DEVICE}/operstate")" == "xup" ] && break + TIMEOUT=$(( $TIMEOUT - 1 )) # don't wait forever, the pcnet iface of vmware will never be "up" although it's working + [ "$TIMEOUT" -le 0 ] && break + # else + echo -n "." + usleep 500000 + done + else + # we really don't have a operstate .. then just wait a sec and hope for the best. + sleep 1 + fi + echo ".$(cat "/sys/class/net/${DEVICE}/operstate" 2>/dev/null)" +} +true diff --git a/core/rootfs/rootfs-stage31/data/inc/ntp_sync b/core/rootfs/rootfs-stage31/data/inc/ntp_sync new file mode 100755 index 00000000..940af366 --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/ntp_sync @@ -0,0 +1,26 @@ +# Sync time via network + +func_sync_net_time() { + local SERVER + if [ -n "$SLX_NTP_SERVER" ]; then + for SERVER in $SLX_NTP_SERVER; do + if ntpdate -u -p 2 "$SERVER"; then + echo "Successfully queried $SERVER for time." + if [ "x$SLX_BIOS_CLOCK" = "xlocal" ]; then + usleep 100000 + hwclock -l -w || echo "... but could not set BIOS clock to localtime" + elif [ "x$SLX_BIOS_CLOCK" = "xutc" ]; then + usleep 100000 + hwclock -u -w || echo "... but could not set BIOS clock to UTC" + fi + break + fi + echo "Error querying $SERVER for current time." + done + fi +} + +func_sync_net_time & + +true + diff --git a/core/rootfs/rootfs-stage31/data/inc/parse_kcl b/core/rootfs/rootfs-stage31/data/inc/parse_kcl new file mode 100644 index 00000000..4a69ac25 --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/parse_kcl @@ -0,0 +1,58 @@ +#!/bin/ash + +getip () { + echo "${IPINFO}" | awk -F ':' "{print \$$1}" +} +parse_ip () { + local IPINFO=$1 + CLIENTIP="$(getip 1)" + SERVERIP="$(getip 2)" + GATEWAY="$(getip 3)" + SUBNET_MASK="$(getip 4)" + BROADCAST_ADDRESS="$(ipcalc -s -b "$CLIENTIP" "$SUBNET_MASK" | sed s/.*=//)" + [ -z "$BROADCAST_ADDRESS" ] && BROADCAST_ADDRESS="255.255.255.255" + # we might have an idea of the dns server via preboot + DNS_SERVER="$(getip 5)" +} + +# read kernel command line +DEBUG=0 +SPLASH=0 +read KCL < "/proc/cmdline" +for opts in ${KCL}; do + case "${opts}" in + debug=*) + DEBUG=${opts#debug=} + DEBUG_SHELL=set + ;; + ip=*) + # process IP info + parse_ip ${opts#ip=} ;; + nfs=*) # TODO: Still working? Still needed? Also see related code in setup_stage32 + NFS=${opts#nfs=} + NFSPATH=${NFS#*:} + NFSSERVER=${NFS%:/*} + ;; + BOOTIF=*) + MAC="$( echo "$opts" | cut -b 11- | tr '-' ':' | tr '[A-Z]' '[a-z]' )" ;; # make mac lowercase for udev (see setup_network) + slxsrv=*) + SLX_KCL_SERVERS=$( echo "${opts#slxsrv=}" | tr ',' " " ) ;; + slxbase=*) + SLX_BASE_PATH=${opts#slxbase=} ;; + splash) + SPLASH=1 ;; + nvidia) + GFX=nvidia ;; + ati|amd) + GFX=amd ;; + esac +done + +# If slxsrv was not given on command line, just use the PXE server's address +[ -z "$SLX_KCL_SERVERS" ] && [ -n "$SERVERIP" ] && SLX_KCL_SERVERS="$SERVERIP" +# Now save to config file +echo "SLX_KCL_SERVERS='$SLX_KCL_SERVERS'" >> "${FUTURE_ROOT}/opt/openslx/config" +echo "SLX_BASE_PATH='$SLX_BASE_PATH'" >> "${FUTURE_ROOT}/opt/openslx/config" + +true + diff --git a/core/rootfs/rootfs-stage31/data/inc/setup_network b/core/rootfs/rootfs-stage31/data/inc/setup_network new file mode 100644 index 00000000..13c52289 --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/setup_network @@ -0,0 +1,84 @@ +#!/bin/ash + +echo "Setting up network..." + +echo "Main MAC address is '$MAC'" + +# setup network +source /inc/network.functions + +# set up loopback networking +echo "Setting up loopback" +ip link set dev lo up 2>/dev/null +ip addr add 127.0.0.1/8 dev lo 2>/dev/null + +echo "Setting up bridge" +BRIDGE="br0" + +# Following was supposed to prevent scripts from getting confused by multiple interfaces with same MAC - does not work though +## Flip mac address of original interface - this var is not local so init sees the changes too +#MAC="$(echo "$MAC" | awk -F ':' '{printf $1 ":" $2 ":" $5 ":" $3 ":" $6 ":" $4}')" +#ip link set addr "$MAC" "$SLAVE" + +mkdir -p "${FUTURE_ROOT}/etc/udev/rules.d" + +#IP_OUT=$(ip a | sed -r ':a;N;$!ba;s/: ([a-z0-9]+): /####\1####/g;s/ether ([a-f0-9:]+) /####\1####/g'| grep -E -o '####[^ ]+####' | sed 's/#//g' | grep -B 1 ':') +IP_OUT=$(ip a | grep -B 1 "/ether" | sed -r '/^--$/d;$!N;s#^[0-9]+: ([a-z0-9\.:]+): .*?/ether ([0-9a-fA-Z:]+) .*$#\1==\2#') + +if ! echo "$IP_OUT" | grep -q -- "$MAC"; then + drop_shell "Boot interface not found in interface list. NIC driver missing?" +fi + +for LINE in $IP_OUT; do + IFACE=$(echo "$LINE" | awk -F '==' '{printf $1}') + IFMAC=$(echo "$LINE" | awk -F '==' '{printf $2}' | tr '[A-Z]' '[a-z]') # udev requires mac addesses to be lowercase (a-f), see http://www.debianhelp.co.uk/udev.htm + echo "${IFACE} = ${IFMAC}" + + if [ "x$IFMAC" == "x$MAC" ]; then + brctl addbr "$BRIDGE" || drop_shell "Could not create bridge $BRIDGE" + brctl stp "$BRIDGE" 0 + brctl setfd "$BRIDGE" 0.000000000001 + ip link set addr "$IFMAC" "$BRIDGE" || drop_shell "Could not set mac of $BRIDGE" + ip link set dev "$IFACE" up + wait_for_iface "$IFACE" + brctl addif "$BRIDGE" "$IFACE" || drop_shell "Could not add $IFACE to $BRIDGE" + + # save our variables for retry on fail + echo "IFACE=$IFACE" > /run/network.conf + + # analyze ip information from the kernel command line and put parts + # of it into several variables + if [ -n "$CLIENTIP" ] ; then + # set static ip address + ip addr add "$CLIENTIP/$(ipcalc -s -p "$CLIENTIP" "$SUBNET_MASK" | sed "s/.*=//")" broadcast "$BROADCAST_ADDRESS" dev "$BRIDGE" + ip link set dev "$BRIDGE" up + [ -n "$GATEWAY" ] && ip route add default via "$GATEWAY" dev "$BRIDGE" + else + NOIPYET="yes" + fi + # Ignore this device later on when systemd handles network interfaces (see hacked 99-systemd.rules in systemd data dir) + echo "SUBSYSTEM==\"net\", ACTION==\"add\", KERNEL==\"eth*\", ATTR{address}==\"$IFMAC\", TAG+=\"openslxignore\"" >> "${FUTURE_ROOT}/etc/udev/rules.d/01-ignore-boot-interface.rules" + fi + # youdev + echo "SUBSYSTEM==\"net\", ACTION==\"add\", DRIVERS==\"?*\", ATTR{address}==\"$IFMAC\", ATTR{dev_id}==\"0x0\", ATTR{type}==\"1\", KERNEL==\"eth*\", NAME=\"$IFACE\"" >> "${FUTURE_ROOT}/etc/udev/rules.d/70-net-boot-nic-name.rules" + # continue... + IFACE="" +done + +wait_for_iface "$BRIDGE" + +# udhcpc +PARAM= +if [ -n "$CLIENTIP" ]; then + PARAM="-r $CLIENTIP" +fi +echo -n "$CLIENTIP" > "/run/firstip" +echo -n "$GATEWAY" > "/run/firstgw" + +# save our variables for retry on fail ff. +echo "CLIENTIP=$CLIENTIP" >> /run/network.conf +echo "GATEWAY=$GATEWAY" >> /run/network.conf +echo "BRIDGE=$BRIDGE" >> /run/network.conf + +udhcpc $PARAM -O domain -O nissrv -O nisdomain -O wpad -O search -t 5 -T 2 -s "/inc/udhcpc-trigger" -f -n -q -i "$BRIDGE" +# udhcpc return value will be return value of this script diff --git a/core/rootfs/rootfs-stage31/data/inc/setup_network_retry b/core/rootfs/rootfs-stage31/data/inc/setup_network_retry new file mode 100644 index 00000000..0578d9b2 --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/setup_network_retry @@ -0,0 +1,33 @@ +#!/bin/ash + +source /inc/network.functions +source /run/network.conf + +for i in 1 2 3 4 5 6 7 8; do + echo "<$i> Try to fix broken network" + echo -n "Take interface $IFACE down .. " + + ip link set dev $IFACE down + usleep 1000 + + echo "and up again.." + ip link set dev $IFACE up + usleep 1000 + + wait_for_iface "$IFACE" + + udhcpc $PARAM -O domain -O nissrv -O nisdomain -O wpad -O search -t 5 -T 2 -s "/inc/udhcpc-trigger" -f -n -q -i "$BRIDGE" + + if [ $? -eq 0 ]; then + echo "Finally fixed IP config. Continue boot." + RET=0 + break + else + RET=1 + fi +done + +[ $RET -gt 0 ] && drop_shell "Something is really broken.. Please check your network cable and reset your computer." + +# create correct return value +[ $RET -eq 0 ] diff --git a/core/rootfs/rootfs-stage31/data/inc/setup_stage32 b/core/rootfs/rootfs-stage31/data/inc/setup_stage32 new file mode 100644 index 00000000..5ec5a69d --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/setup_stage32 @@ -0,0 +1,68 @@ +#!/bin/ash +# +# This script sets up the stage 3.2. +# - downloads/mounts stage32.sqfs +# - merge it with current rootfs through aufs +# - will not download, if the "nfs=" is used in the +# kernel command line +# +######################################################################### +# +# first check if an NFS-share was given per command line +# +if [ -n "$NFS" ]; then + echo "Mounting stage 3.2 as NFS..." + busybox mount -n -t nfs -o ro,async,nolock ${NFSSERVER}:${NFSPATH} /rorootfs \ + || drop_shell "Problem mounting NFS-Directory from ${NFSSERVER}:${NFSPATH}." \ + || return 1 + return 0 +fi + +######################################################################### +# +# MAIN PART +# + +echo "Setting up stage 3.2 ..." + +STAGE32_TARGET_PATH="/stage32.sqfs" +STAGE32_MOUNT_POINT="/rorootfs" + +# try to download it +download "${SLX_BASE_PATH}/stage32.sqfs" "$STAGE32_TARGET_PATH" || drop_shell "Could not download stage32!" + +# "Delete" addon hook-script in aufs view +touch "${FUTURE_ROOT}/.wh.addon-init" + +# try to mount it at STAGE32_MOUNT_POINT +echo "Mounting stage 3.2 as SquashFS..." +busybox mount -n -t squashfs "$STAGE32_TARGET_PATH" "$STAGE32_MOUNT_POINT" || drop_shell "Problem mounting Squashfs." + +echo "Building aufs ..." +busybox mount -n -t aufs -o "br:${FUTURE_ROOT}:${STAGE32_MOUNT_POINT}=ro" none /mnt || drop_shell "Problem building aufs." +mkdir -p /mnt/opt/openslx/uniontmp /mnt/tmp +#busybox mount -n --move "$FUTURE_ROOT" /mnt/opt/openslx/uniontmp || drop_shell "Problem moving uniontmp." # Move needed? +FUTURE_ROOT="/mnt" + +# Move network stuff +cp /etc/hostname /etc/hosts "${FUTURE_ROOT}/etc/" +cp /etc/resolv.conf "${FUTURE_ROOT}/opt/openslx/" +[ -s "/run/config" ] && cat "/run/config" >> "${FUTURE_ROOT}/opt/openslx/config" + +# if booting with splash, suppress kernel output in stage32 +if [ $SPLASH -eq 1 ]; then + if grep -q -E "^ *kernel.printk" "${FUTURE_ROOT}/usr/lib/sysctl.d/50-default.conf"; then + sed -i 's/^ *kernel\.printk.*/kernel\.printk = 1 1 0 1/g' "${FUTURE_ROOT}/usr/lib/sysctl.d/50-default.conf" + else + echo "kernel.printk = 1 1 0 1" >> "${FUTURE_ROOT}/usr/lib/sysctl.d/50-default.conf" + fi +fi + +# Kinda specific for virtualization environment: Autologin and run VM for benchmarks +if [ -n "$SLX_BENCHMARK_VM" ]; then + # Enable KDM autologin for demo user + sed -i 's/^AutoLoginUser=.*//;s/^AutoLoginEnable=.*/AutoLoginEnable=true\nAutoLoginUser=demo/' "${FUTURE_ROOT}/etc/kde4/kdm/kdmrc" + # Running the VM automatically has to be taken care of by run-virt and vmchooser. SLX_BENCHMARK_VM should contain + # a numeric value for the index in vmchooser +fi + diff --git a/core/rootfs/rootfs-stage31/data/inc/setup_stage4 b/core/rootfs/rootfs-stage31/data/inc/setup_stage4 new file mode 100644 index 00000000..585627c2 --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/setup_stage4 @@ -0,0 +1,69 @@ +#!/bin/ash + +[ -z "${SLX_STAGE4}" ] && { echo "SLX_STAGE4 is not set in /opt/openslx/config." && exit 1; } + +MOUNTPOINT="/rorootfs/" +mkdir -p "$MOUNTPOINT" + + +# first load module +insmod /lib/modules/dnbd3/dnbd3.ko + +# dnbd3 it is +if [ -z "${SLX_DNBD3_SERVERS}${SLX_DNBD3_PRIO_SERVERS}" ]; then + slxlog --echo "mount-stage4" "dnbd3 stage4 configured, but SLX_DNBD3(_PRIO)_SERVERS empty or not set in /opt/openslx/config." + exit 1 +fi +# Determine revision +if [ -z "$SLX_STAGE4_RID" ] || echo "$SLX_STAGE4_RID" | grep -v -q -E "^[0-9]+$"; then + SLX_STAGE4_RID="0" +fi +# Randomize list +SERVERS=$(for SERVER in $SLX_DNBD3_SERVERS; do echo "$RANDOM $SERVER"; done | sort -u | sed -r 's/^[0-9]+ //') +IMAGE=$(echo $SLX_STAGE4 | awk '{printf $2}') +[ -e /var/run/dnbd3.socket ] || sleep 2 # Ugly, service should only start when dnbd3 daemon is up and running +RET=1337 +for SRV in $SLX_DNBD3_PRIO_SERVERS $SERVERS; do + echo "Requesting $IMAGE from $SRV" + dnbd3=$(/opt/openslx/bin/dnbd3-client -h "$SRV" -i "$IMAGE" -r "$SLX_STAGE4_RID" -d /dev/dnbd0) + RET=$? + [ "$RET" -eq "0" ] && break + echo "... didn't work ($RET)" + sleep 1 +done +if [ "$RET" -ne "0" ]; then + drop_shell "Omg" + slxlog --echo "mount-stage4" "Could not get stage4 via dnbd3 ($IMAGE : $SLX_STAGE4_RID) ($SLX_DNBD3_PRIO_SERVERS / $SERVERS)" + exit $RET +fi +echo "Mounting /dev/dnbd0 to $MOUNTPOINT" +if ! busybox mount -t squashfs -o ro /dev/dnbd0 "$MOUNTPOINT"; then + slxlog --echo "mount-stage4" "Could not mount stage4 from '$dnbd3' to '$MOUNTPOINT' ($SRV, $IMAGE)" + exit 1 +fi + +busybox mount -n -t aufs -o "br:${FUTURE_ROOT}:${MOUNTPOINT}=ro" none /mnt || drop_shell "Problem building aufs." +mkdir -p /mnt/opt/openslx/uniontmp /mnt/tmp +FUTURE_ROOT="/mnt" + +cp /etc/hostname /etc/hosts "${FUTURE_ROOT}/etc/" +cp /etc/resolv.conf "${FUTURE_ROOT}/opt/openslx/" +[ -s "/run/config" ] && cat "/run/config" >> "${FUTURE_ROOT}/opt/openslx/config" + +# if booting with splash, suppress kernel output in stage32 +if [ $SPLASH -eq 1 ]; then + if grep -q -E "^ *kernel.printk" "${FUTURE_ROOT}/usr/lib/sysctl.d/50-default.conf"; then + sed -i 's/^ *kernel\.printk.*/kernel\.printk = 1 1 0 1/g' "${FUTURE_ROOT}/usr/lib/sysctl.d/50-default.conf" + else + echo "kernel.printk = 1 1 0 1" >> "${FUTURE_ROOT}/usr/lib/sysctl.d/50-default.conf" + fi +fi + +# Kinda specific for virtualization environment: Autologin and run VM for benchmarks +if [ -n "$SLX_BENCHMARK_VM" ]; then + # Enable KDM autologin for demo user + sed -i 's/^AutoLoginUser=.*//;s/^AutoLoginEnable=.*/AutoLoginEnable=true\nAutoLoginUser=demo/' "${FUTURE_ROOT}/etc/kde4/kdm/kdmrc" + # Running the VM automatically has to be taken care of by run-virt and vmchooser. SLX_BENCHMARK_VM should contain + # a numeric value for the index in vmchooser +fi + diff --git a/core/rootfs/rootfs-stage31/data/inc/udhcpc-trigger b/core/rootfs/rootfs-stage31/data/inc/udhcpc-trigger new file mode 100755 index 00000000..02987f21 --- /dev/null +++ b/core/rootfs/rootfs-stage31/data/inc/udhcpc-trigger @@ -0,0 +1,93 @@ +#!/bin/ash + +exec >> /run/stdout +exec 2>> /run/stderr +set -x + +if [ "x$1" != "xbound" -a "x$1" != "xrenew" ] || [ "x$interface" != "xbr0" ] || [ -z "$ip" ]; then + exit 0 +fi + +# If we already got an IP from KCL, see if it differs, and remove first if so +# We just try to prevent everything from breaking if the DHCP server doesn't +# objey the renew request by the client and hands out a new address +if [ -s "/run/firstip" ]; then + #...some address is already configured... + OLD=$(cat "/run/firstip") + if [ "x${OLD}" != "x${ip}" ]; then + #...it's a different one, reconfigure... + echo "..reconfiguring ${OLD} to ${ip}.." + # remove default route and let it be added again below, as it might get lost when changing the primary address on the interface + ip route del default 2>/dev/null + rm -f -- "/run/firstgw" + ip addr del "${OLD}" dev "${interface}" 2>/dev/null + ip addr add "${ip}/$(ipcalc -s -p "${ip}" "${subnet}" | sed s/.*=//)" dev "${interface}" + fi +else + #...no address configured yet, just add... + echo "..adding ${ip}.." + ip addr add "${ip}/$(ipcalc -s -p "${ip}" "${subnet}" | sed s/.*=//)" dev "${interface}" +fi +echo -n "$ip" > "/run/firstip" + +# Same procedure for default gateway +if [ -n "${router}" ]; then + if [ -s "/run/firstgw" ]; then + OLD=$(cat "/run/firstgw") + if [ "x${OLD}" != "x${router}" ]; then + echo "..reconfiguring default gw from ${OLD} to ${router}.." + ip route del default 2>/dev/null + ip route add default via "$router" + fi + else + ip route add default via "$router" + fi + echo -n "$router" > "/run/firstgw" +fi + +rm -f -- "/etc/resolv.conf" + +# DNS/domain? +if [ -n "$dns" ]; then + echo "..got DNS.." + echo "# From DHCP in stage 3.1" >> "/run/config" + echo "SLX_DNS='$dns'" >> "/run/config" +fi +for serv in $dns; do + echo "nameserver $serv" >> "/etc/resolv.conf" +done +if [ -z "$domain" ]; then + # try to get domain via reverse lookup if empty + echo "..trying to get domain via DNS, as DHCP didn't supply one.." + fqdn=$(timeout -t 3 nslookup "$ip" | grep -E "^Address +[0-9]+: +$ip " | head -n 1 | awk '{print $4}') + domain="${fqdn#*.}" +fi +if [ -n "$domain" ]; then + echo "domain $domain" >> "/etc/resolv.conf" +fi +if [ -n "$search" ]; then + echo "search $search" >> "/etc/resolv.conf" +elif [ -n "$domain" ]; then + echo "search $domain" >> "/etc/resolv.conf" +fi + + +# Hostname +if [ -z "$hostname" ]; then + # as with domain, if there's no hostname, try to get via DNS + echo "..trying to get hostname via DNS, as DHCP didn't supply one.." + [ -z "$fqdn" ] && fqdn=$(timeout -t 3 nslookup "$ip" | grep -E "^Address +[0-9]+: +$ip " | head -n 1 | awk '{print $4}') + hostname="${fqdn%%.*}" +elif [ -n "$domain" ]; then + fqdn="${hostname}.${domain%% *}" # in case domain is a list +fi +if [ -n "$hostname" ]; then + [ -z "$fqdn" ] && fqdn="$hostname" + echo "..setting hostname $hostname (fqdn: $fqdn).." + echo "$hostname" > "/proc/sys/kernel/hostname" + echo "$hostname" > "/etc/hostname" + echo "127.0.0.1 localhost" > "/etc/hosts" + echo "127.0.1.1 $fqdn $hostname" >> "/etc/hosts" + echo "SLX_HOSTNAME='$hostname'" >> "/run/config" +fi + |