From 5c7527aa84590ea6b852d4cb1e3be0899351387c Mon Sep 17 00:00:00 2001 From: Thierry Parmentelat Date: Thu, 7 Jul 2016 18:14:50 +0200 Subject: [PATCH] reviewed to ensure maximal coverage of forensics traces --- initscripts/pl_boot | 58 +++++++------- initscripts/pl_functions | 81 ++++++++++++++------ initscripts/pl_hwinit | 119 +++++++++++++++-------------- initscripts/pl_netinit | 158 ++++++++++++--------------------------- initscripts/pl_sysinit | 153 ++++++++++++++++++------------------- 5 files changed, 274 insertions(+), 295 deletions(-) diff --git a/initscripts/pl_boot b/initscripts/pl_boot index 20f4491..b057701 100755 --- a/initscripts/pl_boot +++ b/initscripts/pl_boot @@ -77,10 +77,10 @@ CONNECT_BOOT_SERVER_PATH=$BOOT_SERVER_PATH CONNECT_BOOT_SERVER_GPG_KEYRING=$BOOT_SERVER_GPG_KEYRING CONNECT_BOOT_SERVER_CACERT=$BOOT_SERVER_CACERT -while : ; do +while true; do if [[ -f $CANCEL_BOOT_FLAG ]]; then - echo $(date "+%H:%M:%S") " pl_boot: got request to cancel boot, exiting" + verbose-message "pl_boot: got request to cancel boot, exiting" exit 0 fi @@ -89,7 +89,7 @@ while : ; do contact_count=0 if [[ $on_backup_server == 1 ]]; then - echo $(date "+%H:%M:%S") " pl_boot: failed to contact backup server, trying primary $BOOT_SERVER" + verbose-message "pl_boot: failed to contact backup server, trying primary $BOOT_SERVER" on_backup_server=0 @@ -99,7 +99,7 @@ while : ; do CONNECT_BOOT_SERVER_GPG_KEYRING=$BOOT_SERVER_GPG_KEYRING CONNECT_BOOT_SERVER_CACERT=$BOOT_SERVER_CACERT else - echo $(date "+%H:%M:%S") " pl_boot: failed to contact primary server, trying backup $BACKUP_BOOT_SERVER" + verbose-message "pl_boot: failed to contact primary server, trying backup $BACKUP_BOOT_SERVER" on_backup_server=1 @@ -113,7 +113,7 @@ while : ; do if [[ $contact_count != 0 ]]; then - echo $(date "+%H:%M:%S") " pl_boot: next attempt in 30s, to fetch script from server at $CONNECT_BOOT_SERVER" + verbose-message "pl_boot: next attempt in 30s, to fetch script from server at $CONNECT_BOOT_SERVER" /bin/sleep 30 fi @@ -146,18 +146,18 @@ while : ; do --always-trust \ --decrypt $UNVERIFIED_SCRIPT" - echo $(date "+%H:%M:%S") " pl_boot: generating new nonce" + verbose-message "pl_boot: generating new nonce" /usr/bin/head --bytes=32 /dev/urandom | \ /usr/bin/od -tx1 -An --width=32 | \ /bin/sed 's/ //g' > /tmp/nonce - echo $(date "+%H:%M:%S") " pl_boot: fetching script from boot server $CONNECT_BOOT_SERVER" + verbose-message "pl_boot: fetching script from boot server $CONNECT_BOOT_SERVER" ((contact_count++)) rm -f $UNVERIFIED_SCRIPT $CURL_CMD curl_err=$? if [ $curl_err -ne 0 ]; then - echo $(date "+%H:%M:%S") " pl_boot: curl request failed with error $curl_err:" + verbose-message "pl_boot: curl request failed with error $curl_err:" cat /tmp/curl_errors echo if [ -n "$DISCONNECTED_OPERATION" ]; then @@ -169,28 +169,28 @@ while : ; do else case $curl_err in 6) - echo $(date "+%H:%M:%S") " This error likely indicates a networking configuration error. " - echo $(date "+%H:%M:%S") " Please, check whether you can ping this machine. If you can, " - echo $(date "+%H:%M:%S") " we recommend checking your DNS settings. If you cannot, then " - echo $(date "+%H:%M:%S") " please double check your network settings registered at PLC and " - echo $(date "+%H:%M:%S") " stored on this Boot Image." + verbose-message "This error likely indicates a networking configuration error. " + verbose-message "Please, check whether you can ping this machine. If you can, " + verbose-message "we recommend checking your DNS settings. If you cannot, then " + verbose-message "please double check your network settings registered at PLC and " + verbose-message "stored on this Boot Image." ;; 60) - echo $(date "+%H:%M:%S") " This error likely indicates that the hardware clock is likely not set " - echo $(date "+%H:%M:%S") " to GMT. The result is that authentication between the local and " - echo $(date "+%H:%M:%S") " remote site fails. Please double check this machine's system " - echo $(date "+%H:%M:%S") " clock, and set it to GMT in the BIOS. If after rebooting the same " - echo $(date "+%H:%M:%S") " error occurs, please report the situation to support@planet-lab.org " - echo $(date "+%H:%M:%S") " with as much detail as possible." + verbose-message "This error likely indicates that the hardware clock is likely not set " + verbose-message "to GMT. The result is that authentication between the local and " + verbose-message "remote site fails. Please double check this machine's system " + verbose-message "clock, and set it to GMT in the BIOS. If after rebooting the same " + verbose-message "error occurs, please report the situation to support@planet-lab.org " + verbose-message "with as much detail as possible." ;; *) - echo $(date "+%H:%M:%S") " The best-practice approach for handling this error is not yet " - echo $(date "+%H:%M:%S") " documented. Please report this error to support@planet-lab.org " - echo $(date "+%H:%M:%S") " with as much detail as possible." + verbose-message "The best-practice approach for handling this error is not yet " + verbose-message "documented. Please report this error to support@planet-lab.org " + verbose-message "with as much detail as possible." ;; esac # in any case display as much info as we can (see pl_functions) - pl_network_sanity_checks + verbose-forensics "after curl" # retry continue fi @@ -202,23 +202,23 @@ while : ; do rmdir /tmp/boot-media fi - echo $(date "+%H:%M:%S") " pl_boot: verifying downloaded script" + verbose-message "pl_boot: verifying downloaded script" rm -f $VERIFIED_SCRIPT $GPG_CMD 2> /tmp/gpg_errors if [ $? -ne 0 ]; then - echo $(date "+%H:%M:%S") " pl_boot: failed to verify file:" + verbose-message "pl_boot: failed to verify file:" cat /tmp/gpg_errors echo continue fi - echo $(date "+%H:%M:%S") " pl_boot: decrypted and verified script succesfully" + verbose-message "pl_boot: decrypted and verified script succesfully" - echo $(date "+%H:%M:%S") " pl_boot: handing control to download script" + verbose-message "pl_boot: handing control to download script" rm -f $UNVERIFIED_SCRIPT chmod +x $VERIFIED_SCRIPT $VERIFIED_SCRIPT - echo $(date "+%H:%M:%S") " pl_boot: downloaded script has returned" + verbose-message "pl_boot: downloaded script has returned" done -echo $(date "+%H:%M:%S") " pl_boot: automatic boot process canceled by user" +verbose-message "pl_boot: automatic boot process canceled by user" diff --git a/initscripts/pl_functions b/initscripts/pl_functions index e2d24c1..72878d6 100644 --- a/initscripts/pl_functions +++ b/initscripts/pl_functions @@ -1,46 +1,81 @@ #-*-shell-script-*- -function verbose_show_message () { +function verbose-message () { + echo "" echo $(date "+%H:%M:%S") " ==================== " "$@" } -function verbose_run_command () { +function verbose-run () { echo $(date "+%H:%M:%S") " ========== running" "$@" "$@" echo $(date "+%H:%M:%S") " ==========" "$@" "returned with retcod=$?" } -function pl_network_sanity_checks () { - echo $(date "+%H:%M:%S") " ======================================== BEG SANITY CHECKS" - for file in $(ls /etc/resolv.conf /etc/sysconfig/network-scripts/ifcfg-eth* ) ; do - verbose_run_command cat $file +function verbose-file() { + file=$1; shift + echo "$file" + if ! [ -f "$file" ]; then + verbose-message "!!!!!!!!!! missing $file" + else + verbose-run cat $file + fi +} + +function verbose-file-uncommented-patterns () { + file=$1; shift + egrep_pattern=$2; shift + + if ! [ -f "$file" ]; then + verbose-message "!!!!!!!!!! missing $file" + else + echo '---------- egrep $egrep_pattern' $file + grep -v '^#' $file | egrep "$egrep_pattern" + fi +} + +function verbose-forensics () { + message="$1"; shift + verbose-message "BEG FORENSICS -- $message" + verbose-run dmesg + verbose-run lsmod + verbose-run lspci + + for file in /etc/resolv.conf /run/resolvconf/resolv.conf /etc/sysconfig/network-scripts/ifcfg-eth*; do + verbose-file $file done - verbose_show_message Loaded modules - verbose_run_command lsmod - verbose_show_message Configured interfaces - verbose_run_command ifconfig - verbose_show_message cat /proc/net/dev - verbose_run_command cat /proc/net/dev - verbose_show_message Routing table - verbose_run_command netstat -rn + verbose-message Configured interfaces + verbose-run ls -l /sys/class/net/ + verbose-run cat /proc/net/dev + verbose-run ip address show + verbose-message Routing table + verbose-run ip route show BOOT_FILE=/usr/boot/boot_server BOOT_SERVER=$(cat $BOOT_FILE) - verbose_show_message Pinging boot server "(" $BOOT_SERVER ")" from file $BOOT_FILE - verbose_run_command ping -c 4 -w 4 $BOOT_SERVER - verbose_show_message Pinging google public DNS - verbose_run_command ping -c 1 -w 5 8.8.8.8 + verbose-message Pinging boot server $BOOT_SERVER "(" from file $BOOT_FILE ")" + verbose-run ping -c 4 -w 4 $BOOT_SERVER + verbose-message Pinging google public DNS + verbose-run ping -c 1 -w 5 8.8.8.8 # try to resolve this hostname as that's the one used for ntp dnss=$(grep '^nameserver' /etc/resolv.conf 2>/dev/null | awk '{print $2;}') if [ -z "$dnss" ] ; then # not too helpful, but.. - verbose_show_message No server found in /etc/resolv.conf - Resolving hostname at the google public DNS - verbose_run_command host -W 4 pool.ntp.org 8.8.8.8 + verbose-message "!!!" No server found in /etc/resolv.conf - Resolving hostname at the google public DNS + verbose-run host -W 4 pool.ntp.org 8.8.8.8 else for dns in $dnss; do - verbose_show_message Resolving hostname at $dns - verbose_run_command host -W 4 pool.ntp.org $dns + verbose-message Resolving hostname at $dns + verbose-run host -W 4 pool.ntp.org $dns done fi - echo $(date "+%H:%M:%S") " ======================================== END SANITY CHECKS" + verbose-file /root/.ssh/authorized_keys + verbose-file-uncommented-patterns /etc/ssh/sshd_config 'Pass|Auth|PAM|Root' + verbose-message "END FORENSICS -- $message" } +function hang-and-shutdown() { + message=$1; shift + verbose-message "message - shutting down in 2h" + # todo: maybe we can put a staticly linked sshd here + /bin/sleep 2h + /sbin/shutdown -h now +} diff --git a/initscripts/pl_hwinit b/initscripts/pl_hwinit index 7985511..8224a9e 100755 --- a/initscripts/pl_hwinit +++ b/initscripts/pl_hwinit @@ -6,16 +6,17 @@ import pypcimap import os import time -loadedmodules = None - def now(): - format="%H:%M:%S(%Z)" - return time.strftime(format,time.localtime()) + format = "%H:%M:%S(%Z)" + return time.strftime(format, time.localtime()) + +def verbose_message(single): + print now(), single -def modprobe(module, args = ""): - ret = os.system("/sbin/modprobe %s %s" % (module, args)) +def modprobe(module, summary_file, args = ""): + ret = os.system("/sbin/modprobe {} {}".format(module, args)) if os.WEXITSTATUS(ret) == 0: - globals()['loadedmodules'].write("%s\n" % module) + summary_file.write("{}\n".format(module)) return True else: return False @@ -29,12 +30,12 @@ def main(argv): if os.path.exists(kernel): path = kernel else: - path = "/lib/modules/%s/modules.pcimap" % kernel + path = "/lib/modules/{}/modules.pcimap".format(kernel) blacklisted_modules = [] blacklists = os.listdir("/etc/modprobe.d") for blacklist in blacklists: - blf = "/etc/modprobe.d/%s" % blacklist + blf = "/etc/modprobe.d/{}".format(blacklist) if os.path.exists(blf): f = open(blf) for i in f.readlines(): @@ -44,54 +45,56 @@ def main(argv): blacklisted_modules = list(set(blacklisted_modules)) pcimap = pypcimap.PCIMap(path) - print now(),"pl_hwinit: loading applicable modules" + verbose_message("pl_hwinit: loading applicable modules") devices = pypci.get_devices() storage_devices = 0 network_devices = 0 missing = [] - globals()['loadedmodules'] = file('/tmp/loadedmodules', 'w') - for slot in sorted(devices.keys()): - dev = devices[slot] - modules = pcimap.get(dev) - base = (dev[4] & 0xff0000) >> 16 - if len(modules) == 0: - if base == 0x01 or base == 0x02: - # storage or network device, in that order - missing.append((slot, dev)) - else: - if base == 0x01: - storage_devices += 1 - elif base == 0x02: - network_devices += 1 - - # FIXME: This needs improved logic in the case of multiple matching modules - for module in modules: - if module not in blacklisted_modules: - print now(),"pl_hwinit: found and loading module %s (%s)" % (module, slot) - modprobe(module) - - if network_devices == 0: - print now(),"pl_hwinit: no supported network devices found!" - print now(),"pl_hwinit: the following devices were found, but have no driver:" - print now(),"pl_hwinit: ", "\npl_hwinit: ".join(missing) - - # XXX: could check for storage devices too, but older kernels have a lot of that built-in - - # sd_mod won't get loaded automatically - print now(),"pl_hwinit: loading sd_mod" - modprobe("sd_mod") - - # load usb_storage to support node conf files on flash disks - print now(),"pl_hwinit: loading usb_storage" - modprobe("usb_storage") - - print now(),"pl_hwinit: loading floppy device driver" - modprobe("floppy","floppy=0,allowed_drive_mask") + with open('/tmp/loadedmodules', 'w') as loadedmodules: + for slot in sorted(devices.keys()): + dev = devices[slot] + modules = pcimap.get(dev) + base = (dev[4] & 0xff0000) >> 16 + if len(modules) == 0: + if base == 0x01 or base == 0x02: + # storage or network device, in that order + missing.append((slot, dev)) + else: + if base == 0x01: + storage_devices += 1 + elif base == 0x02: + network_devices += 1 + + # FIXME: This needs improved logic in the case of multiple matching modules + for module in modules: + if module not in blacklisted_modules: + verbose_message("pl_hwinit: found and loading module {} (%s)" % (module, slot)) + modprobe(module, loadedmodules) + + if network_devices == 0: + verbose_message("pl_hwinit: no supported network devices found!") + verbose_message("pl_hwinit: the following devices were found, but have no driver:") + lines = [ "{} x {}".format(slot, dev) for slot, dev in missing ] + for line in lines: + verbose_message("pl_hwinit: missing " + line) + + # XXX: could check for storage devices too, but older kernels have a lot of that built-in + + # sd_mod won't get loaded automatically + verbose_message("pl_hwinit: loading sd_mod") + modprobe("sd_mod", loadedmodules) + + # load usb_storage to support node conf files on flash disks + verbose_message("pl_hwinit: loading usb_storage") + modprobe("usb_storage", loadedmodules) + + verbose_message("pl_hwinit: loading floppy device driver") + modprobe("floppy", loadedmodules, "floppy=0,allowed_drive_mask") # always wait a bit between loading the usb drivers, and checking /sys/ # for usb devices (this isn't necessarily for waiting for mass storage files, # that is done below) - print now(),"pl_hwinit: waiting for usb system to initialize." + verbose_message("pl_hwinit: waiting for usb system to initialize.") time.sleep(10) # sometimes, flash devices take a while to initialize. in fact, the kernel @@ -132,15 +135,15 @@ def main(argv): os.path.walk("/sys/devices", filter_and_add, wait_dev_list) if len(wait_dev_list) > 0: - print now(),"pl_hwinit: found USB mass storage device(s). Attempting to wait" - print now(),"pl_hwinit: up to %d seconds for them to come online." % MAX_USB_WAIT_TIME + verbose_message("pl_hwinit: found USB mass storage device(s). Attempting to wait") + verbose_message("pl_hwinit: up to %d seconds for them to come online." % MAX_USB_WAIT_TIME) total_wait_time = 0 success = False while total_wait_time < MAX_USB_WAIT_TIME: total_wait_time += PER_CHECK_USB_WAIT_TIME - print now(),"pl_hwinit: waiting %d seconds." % PER_CHECK_USB_WAIT_TIME + verbose_message("pl_hwinit: waiting {} seconds.".format(PER_CHECK_USB_WAIT_TIME)) time.sleep(PER_CHECK_USB_WAIT_TIME) all_devices_online = True @@ -150,17 +153,17 @@ def main(argv): if all_devices_online: success = True - print now(),"pl_hwinit: looks like the devices are now online." + verbose_message("pl_hwinit: looks like the devices are now online.") break else: - print now(),"pl_hwinit: not all devices online yet, waiting..." + verbose_message("pl_hwinit: not all devices online yet, waiting...") if success: - print now(),"pl_hwinit: Succesfully waited for USB mass storage devices" - print now(),"pl_hwinit: to come online." + verbose_message("pl_hwinit: Succesfully waited for USB mass storage devices") + verbose_message("pl_hwinit: to come online.") else: - print now(),"pl_hwinit: One or more USB mass storage devices did not" - print now(),"pl_hwinit: initialize in time. Continuing anyway." + verbose_message("pl_hwinit: One or more USB mass storage devices did not") + verbose_message("pl_hwinit: initialize in time. Continuing anyway.") if __name__ == "__main__": main(sys.argv[1:]) diff --git a/initscripts/pl_netinit b/initscripts/pl_netinit index 9102d91..2363cea 100755 --- a/initscripts/pl_netinit +++ b/initscripts/pl_netinit @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash #-*-shell-script-*- set -x @@ -58,50 +58,21 @@ IFCONFIG_OUTPUT=/tmp/ifconfig DEFAULT_NET_CONF=0 -function net_init_failed() { - echo - echo $(date "+%H:%M:%S") " pl_netinit: network initialization failed with interface $ETH_DEVICE" - echo - echo For forensics - echo - echo ========== lspci beg - /sbin/lspci -n | /bin/grep "Class 0200" - echo ========== lspci end - echo - echo ========== ifconfig beg - /sbin/ifconfig - echo ========== ifconfig end - echo ========== ip address show beg - ip address show - echo ========== ip address show end - echo - echo $(date "+%H:%M:%S") " pl_netinit: network initialization failed with interface $ETH_DEVICE" - echo $(date "+%H:%M:%S") " pl_netinit: shutting down machine in two hours" - /bin/sleep 2h - /sbin/shutdown -h now +function net-init-failed() { + verbose-message "pl_netinit: network initialization failed with interface $ETH_DEVICE" + verbose-forensics "failed to configure $ETH_DEVICE" + hang-and-shutdown "net-init-failed" exit 1 } -# Function for checking the IP address to see if its sensible. -function check_ip() { - case "$*" in - "" | *[!0-9.]* | *[!0-9]) return 1 ;; - esac - local IFS=. - set -- $* - [ $# -eq 4 ] && - [ ${1:-666} -le 255 ] && [ ${2:-666} -le 255 ] && - [ ${3:-666} -le 255 ] && [ ${4:-666} -le 255 ] -} - # find and parse a node network configuration file. return 0 if not found, # return 1 if found and parsed. if this is the case, DEFAULT_NET_CONF will # be set to 1. For any found configuration file, $USED_NET_CONF will # contain the validated contents -function find_node_config() { +function find-node-config() { /bin/rm -f $TMP_OLD_FLOPPY_CONF_FILE 2>&1 > /dev/null - echo $(date "+%H:%M:%S") " pl_netinit: looking for node configuration file on floppy" + verbose-message "pl_netinit: looking for node configuration file on floppy" /bin/mount -o ro -t $NODE_CONF_DEVICE_FS_TYPES /dev/fd0 \ $CONF_DEVICE_MOUNT_POINT 2>&1 > /dev/null @@ -110,7 +81,7 @@ function find_node_config() { # 1. check for new named file first on the floppy disk if [ -r "$CONF_DEVICE_MOUNT_POINT/$NEW_NODE_CONF_NAME" ]; then conf_file="$CONF_DEVICE_MOUNT_POINT/$NEW_NODE_CONF_NAME" - echo $(date "+%H:%M:%S") " pl_netinit: found node configuration file $conf_file" + verbose-message "pl_netinit: found node configuration file $conf_file" /etc/init.d/pl_validateconf < $conf_file > $USED_NET_CONF /bin/umount $CONF_DEVICE_MOUNT_POINT return 1 @@ -122,14 +93,14 @@ function find_node_config() { elif [ -r "$CONF_DEVICE_MOUNT_POINT/$OLD_NODE_CONF_NAME" ]; then conf_file="$CONF_DEVICE_MOUNT_POINT/$OLD_NODE_CONF_NAME" /bin/cp -f $conf_file $TMP_OLD_FLOPPY_CONF_FILE - echo $(date "+%H:%M:%S") " pl_netinit: found old named configuration file, checking later." + verbose-message "pl_netinit: found old named configuration file, checking later." else - echo $(date "+%H:%M:%S") " pl_netinit: floppy mounted, but no configuration file." + verbose-message "pl_netinit: floppy mounted, but no configuration file." fi /bin/umount $CONF_DEVICE_MOUNT_POINT else - echo $(date "+%H:%M:%S") " pl_netinit: no floppy could be mounted, continuing search." + verbose-message "pl_netinit: no floppy could be mounted, continuing search." fi # 2. check for a new named file on removable flash devices (those @@ -137,7 +108,7 @@ function find_node_config() { # to prevent checking normal scsi disks, also make sure # /sys/block//removable is set to 1 - echo $(date "+%H:%M:%S") " pl_netinit: looking for node configuration file on flash based devices" + verbose-message "pl_netinit: looking for node configuration file on flash based devices" # make the sd* hd* expansion fail to an empty string if there are no sd # devices @@ -153,20 +124,20 @@ function find_node_config() { for partition in $partitions ; do check_dev=/dev/$partition - echo $(date "+%H:%M:%S") " pl_netinit: looking for node configuration file on device $check_dev" + verbose-message "pl_netinit: looking for node configuration file on device $check_dev" /bin/mount -o ro -t $NODE_CONF_DEVICE_FS_TYPES $check_dev \ $CONF_DEVICE_MOUNT_POINT 2>&1 > /dev/null if [[ $? -eq 0 ]]; then if [ -r "$CONF_DEVICE_MOUNT_POINT/$NEW_NODE_CONF_NAME" ]; then conf_file="$CONF_DEVICE_MOUNT_POINT/$NEW_NODE_CONF_NAME" - echo $(date "+%H:%M:%S") " pl_netinit: found node configuration file $conf_file" + verbose-message "pl_netinit: found node configuration file $conf_file" /etc/init.d/pl_validateconf < $conf_file > $USED_NET_CONF - echo $(date "+%H:%M:%S") " pl_netinit: found configuration" + verbose-message "pl_netinit: found configuration" /bin/umount $CONF_DEVICE_MOUNT_POINT return 1 fi - echo $(date "+%H:%M:%S") " pl_netinit: not found" + verbose-message "pl_netinit: ERROR - not found" /bin/umount $CONF_DEVICE_MOUNT_POINT fi @@ -180,27 +151,27 @@ function find_node_config() { # the file $TMP_OLD_FLOPPY_CONF_FILE will be readable. if [ -r "$TMP_OLD_FLOPPY_CONF_FILE" ]; then conf_file=$TMP_OLD_FLOPPY_CONF_FILE - echo $(date "+%H:%M:%S") " pl_netinit: found node configuration file $conf_file" + verbose-message "pl_netinit: found node configuration file $conf_file" /etc/init.d/pl_validateconf < $conf_file > $USED_NET_CONF return 1 fi # 4. check for plnode.txt on the cd at /usr/boot - echo $(date "+%H:%M:%S") " pl_netinit: looking for network configuration on cd in /usr/boot" + verbose-message "pl_netinit: looking for network configuration on cd in /usr/boot" if [ -r "$CD_NET_CONF_BOOT" ]; then - echo $(date "+%H:%M:%S") " pl_netinit: found cd configuration file $CD_NET_BOOT_CONF" + verbose-message "pl_netinit: found cd configuration file $CD_NET_BOOT_CONF" /etc/init.d/pl_validateconf < $CD_NET_CONF_BOOT > $USED_NET_CONF return 1 fi # 5. check for plnode.txt on the cd at /usr - echo $(date "+%H:%M:%S") " pl_netinit: looking for network configuration on cd in /usr" + verbose-message "pl_netinit: looking for network configuration on cd in /usr" if [ -r "$CD_NET_CONF_ROOT" ]; then - echo $(date "+%H:%M:%S") " pl_netinit: found cd configuration file $CD_NET_CONF_ROOT" + verbose-message "pl_netinit: found cd configuration file $CD_NET_CONF_ROOT" /etc/init.d/pl_validateconf < $CD_NET_CONF_ROOT > $USED_NET_CONF return 1 fi @@ -210,9 +181,9 @@ function find_node_config() { # builtin default. this can't be used to install a machine, but # will at least let it download and run the boot manager, which # can inform the users appropriately. - echo $(date "+%H:%M:%S") " pl_netinit: using default network configuration" + verbose-message "pl_netinit: using default network configuration" if [ -r "$FALLBACK_NET_CONF" ]; then - echo $(date "+%H:%M:%S") " pl_netinit: found cd default configuration file $FALLBACK_NET_CONF" + verbose-message "pl_netinit: found cd default configuration file $FALLBACK_NET_CONF" /etc/init.d/pl_validateconf < $FALLBACK_NET_CONF > $USED_NET_CONF DEFAULT_NET_CONF=1 return 1 @@ -222,16 +193,16 @@ function find_node_config() { } -echo $(date "+%H:%M:%S") " pl_netinit: bringing loopback network device up" +verbose-message "pl_netinit: bringing loopback network device up" /sbin/ifconfig lo 127.0.0.1 up -find_node_config +find-node-config if [ $? -eq 0 ]; then # no network configuration file found. this should not happen as the # default cd image has a backup one. halt. - echo $(date "+%H:%M:%S") " pl_netinit: unable to find even a default network configuration" - echo $(date "+%H:%M:%S") " pl_netinit: file, this cd may be corrupt." - net_init_failed + verbose-message "pl_netinit: ERROR - unable to find even a default network configuration" + verbose-message "pl_netinit: file, this cd may be corrupt." + net-init-failed fi # load the configuration file. if it was a default one (not user specified), @@ -240,7 +211,7 @@ fi # they will fail (as they should) - but the network will be up if dhcp is # available -echo $(date "+%H:%M:%S") " pl_netinit: loading network configuration" +verbose-message "pl_netinit: loading network configuration" . $USED_NET_CONF if [[ $DEFAULT_NET_CONF -eq 1 ]]; then @@ -274,7 +245,7 @@ if [[ -n "$NET_DEVICE" ]]; then dev_address=$(cat $device/address | tr A-Z a-z) if [ "$device" == "$NET_DEVICE" -o "$dev_address" == "$NET_DEVICE" ]; then ETH_DEVICE=$device - echo $(date "+%H:%M:%S") " pl_netinit: found device $ETH_DEVICE with mac address $dev_address" + verbose-message "pl_netinit: found device $ETH_DEVICE with mac address $dev_address" break fi done @@ -294,10 +265,10 @@ fi # still nothing? fail the boot. if [[ -z "$ETH_DEVICE" ]]; then - echo $(date "+%H:%M:%S") " pl_netinit: unable to find a usable device, check to make sure" - echo $(date "+%H:%M:%S") " pl_netinit: the NET_DEVICE field in the configuration file" - echo $(date "+%H:%M:%S") " pl_netinit: corresponds with a network adapter on this system" - net_init_failed + verbose-message "pl_netinit: unable to find a usable device, check to make sure" + verbose-message "pl_netinit: the NET_DEVICE field in the configuration file" + verbose-message "pl_netinit: corresponds with a network adapter on this system" + net-init-failed fi # within a systemd-driven startup, we often see this stage @@ -317,17 +288,17 @@ ALLOW=60 COUNTER=0 while true; do if /sbin/ifconfig $ETH_DEVICE >& /dev/null; then - echo $(date "+%H:%M:%S") " pl_netinit: device present $ETH_DEVICE, proceeding (${COUNTER}s/${ALLOW}s)" + verbose-message "pl_netinit: device present $ETH_DEVICE, proceeding (${COUNTER}s/${ALLOW}s)" break fi - echo $(date "+%H:%M:%S") " pl_netinit: waiting for device $ETH_DEVICE - ${COUNTER}s/${ALLOW}s" + verbose-message "pl_netinit: waiting for device $ETH_DEVICE - ${COUNTER}s/${ALLOW}s" set -x /sbin/ifconfig journalctl -b | egrep 'eth|bnx|udev' systemctl list-unit-files | grep -i network set +x COUNTER=$(($COUNTER+1)) - [ $COUNTER -ge $ALLOW ] && net_init_failed + [ $COUNTER -ge $ALLOW ] && net-init-failed sleep 1 done @@ -335,23 +306,23 @@ done # actually check to make sure ifconfig succeeds /sbin/ifconfig $ETH_DEVICE up 2>&1 > /dev/null || { - echo $(date "+%H:%M:%S") " pl_netinit: device $ETH_DEVICE does not exist, most likely" - echo $(date "+%H:%M:%S") " pl_netinit: this CD does not have hardware support for your" - echo $(date "+%H:%M:%S") " pl_netinit: network adapter. please send the following lines" - echo $(date "+%H:%M:%S") " pl_netinit: to your PlanetLab support for further assistance" - net_init_failed + verbose-message "pl_netinit: device $ETH_DEVICE does not exist, most likely" + verbose-message "pl_netinit: this CD does not have hardware support for your" + verbose-message "pl_netinit: network adapter. please send the following lines" + verbose-message "pl_netinit: to your PlanetLab support for further assistance" + net-init-failed } -echo $(date "+%H:%M:%S") " pl_netinit: attempting to start networking" +verbose-message "pl_netinit: attempting to start networking" /sbin/service network start # for backwards compatibility /sbin/ifconfig $ETH_DEVICE > $IFCONFIG_OUTPUT -echo $(date "+%H:%M:%S") " pl_netinit: network online" +verbose-message "pl_netinit: network online" # patch for f22 - if /etc/resolv.conf is empty in static mode -function pl_netinit_patch_resolv_conf () { +function pl-netinit-patch-resolv-conf () { file=/etc/resolv.conf needed="" # missing file : patch needed @@ -362,7 +333,7 @@ function pl_netinit_patch_resolv_conf () { needed=true fi if [ -n "$needed" ]; then - echo pl_netinit patching $file + verbose-message "pl_netinit: patching $file" source /etc/sysconfig/network-scripts/ifcfg-${ETH_DEVICE} # delete because it's a symlink to /run/systemd/resolve/resolv.conf # which looks really weird (ls -lL /etc/resolv.conf does not show anything) @@ -372,41 +343,8 @@ function pl_netinit_patch_resolv_conf () { else echo pl_netinit has no need to patch $file fi - } - -function pl_netinit_forensics () { - - echo "-------------------- BEG post pl_netinit forensics" - - file=/root/.ssh/authorized_keys - echo "$file" - if ! [ -f "$file" ]; then - echo "!!!!!!!!!! missing $file" - else - echo "---------- $file" - cat $file - fi - - file="/etc/ssh/sshd_config" - if ! [ -f "$file" ]; then - echo "!!!!!!!!!! missing $file" - else - echo '---------- egrep Pass|Auth|PAM|Root' $file - grep -v '^#' $file | egrep 'Pass|Auth|PAM|Root' - fi - - # on f22 we see an emty resolv.conf... - file=/etc/resolv.conf - if ! [ -f "$file" ]; then - echo "!!!!!!!!!! missing $file" - else - echo "---------- $file" - cat $file - fi - - echo "-------------------- END post pl_netinit forensics" } -pl_netinit_patch_resolv_conf +pl-netinit-patch-resolv-conf -pl_netinit_forensics +verbose-forensics "pl_netinit epilogue" diff --git a/initscripts/pl_sysinit b/initscripts/pl_sysinit index 85282b5..630b9f0 100755 --- a/initscripts/pl_sysinit +++ b/initscripts/pl_sysinit @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash ### make sure this output shows up in the console @@ -8,42 +8,41 @@ exec > /dev/console ### . /etc/init.d/pl_functions -echo "" -echo "PlanetLab BootCD - distro @PLDISTRO@ based on @FCDISTRO@" +verbose-message "PlanetLab BootCD - distro @PLDISTRO@ based on @FCDISTRO@" -echo "" -echo $(date "+%H:%M:%S") "pl_sysinit: bringing system online" +verbose-message "pl_sysinit: bringing system online" -echo "" -echo $(date "+%H:%M:%S") "pl_sysinit: mounting file systems" -/bin/mount -v -a +verbose-message "pl_sysinit: mounting file systems" +verbose-run /bin/mount -v -a -echo "" -echo $(date "+%H:%M:%S") "pl_sysinit: starting udevd" -[ -x /sbin/start_udev ] && /sbin/start_udev +if [ -x /sbin/start_udev ]; then + verbose-message "pl_sysinit: starting udev daemon" + verbose-run /sbin/start_udev +else + verbose-message "pl_sysinit: WARNING cannot start udev daemon - /sbin/start_udev NOT FOUND" +fi -echo "" -echo $(date "+%H:%M:%S") "pl_sysinit: invoking hardware initialization script" -/etc/init.d/pl_hwinit +verbose-message "pl_sysinit: invoking hardware initialization script" +verbose-run /etc/init.d/pl_hwinit -check_initrd() -{ +function check-initrd() { _mounted=0 if [ -f /usr/isolinux/pl_version ] ; then - # it mounted, but we should probably make sure its our boot cd + # it is mounted, but we should probably make sure its our boot cd # this can be done by making sure the /pl_version file (on initrd) # matches /usr/isolinux/pl_version initrd_version=$(/bin/cat /pl_version) cd_version=$(/bin/cat /usr/isolinux/pl_version) if [ "$initrd_version" == "$cd_version" ]; then - _mounted=1 + _mounted=1 + else + verbose-message "pl_sysinit: WARNING pl_version mismatch" fi fi return $_mounted } -check_block_devices() -{ +function check-block-devices() { _mounted=0 # so that * expands to empty string if there are no block devices shopt -s nullglob @@ -83,7 +82,7 @@ check_block_devices() done fi - echo $(date "+%H:%M:%S") "pl_sysinit: checking $device for /usr contents" + verbose-message "pl_sysinit: checking $device for /usr contents" /bin/mount -o ro -t iso9660 /dev/$device /usr 2>&1 > /dev/null if [ $? -eq 0 ]; then # it mounted, but we should probably make sure its our boot cd @@ -96,7 +95,7 @@ check_block_devices() # eh, wrong cd, keep trying /bin/umount /usr 2>&1 /dev/null else - echo $(date "+%H:%M:%S") "pl_sysinit: found cd and mounted on /usr" + verbose-message "pl_sysinit: found CD and mounted on /usr" _mounted=1 break fi @@ -105,79 +104,83 @@ check_block_devices() return $_mounted } -echo $(date "+%H:%M:%S") "pl_sysinit: finding cd to mount on /usr" +verbose-message "pl_sysinit: finding CD to mount on /usr" mounted=0 -check_initrd +check-initrd if [ $? -eq 1 ]; then mounted=1 else [ ! -d /usr ] && mkdir /usr - check_block_devices + check-block-devices [ $? -eq 1 ] && mounted=1 fi if [ $mounted -eq 0 ]; then - echo $(date "+%H:%M:%S") "pl_sysinit: unable to find boot cdrom, cannot continue." - # todo: maybe we can put a staticly linked sshd here - /sbin/shutdown -h now + hang-and-shutdown "pl_sysinit: ERROR - unable to find boot CD" + exit 1 fi - # parts of this were copied from devmap_mknod.sh from the device-mapper # source. Since fedora decided not to include it in the rpm, it is # being copied here -echo $(date "+%H:%M:%S") "pl_sysinit: creating device mapper control node" +function create-device-mapper-node() { + + DM_DIR="mapper" + DM_NAME="device-mapper" + DIR="/dev/$DM_DIR" + CONTROL="$DIR/control" + + MAJOR=$(sed -n 's/^ *\([0-9]\+\) \+misc$/\1/p' /proc/devices) + MINOR=$(sed -n "s/^ *\([0-9]\+\) \+$DM_NAME\$/\1/p" /proc/misc) + + if [ -n "$MAJOR" ] && [ -n "$MINOR" ]; then + /bin/mkdir -p --mode=755 $DIR + /bin/rm -f $CONTROL + /bin/mknod --mode=600 $CONTROL c $MAJOR $MINOR + else + verbose-message "pl_sysinit: unable to create device mapper control node, continuing" + fi +} -DM_DIR="mapper" -DM_NAME="device-mapper" -DIR="/dev/$DM_DIR" -CONTROL="$DIR/control" +verbose-message "pl_sysinit: creating device mapper control node" +create-device-mapper-node -MAJOR=$(sed -n 's/^ *\([0-9]\+\) \+misc$/\1/p' /proc/devices) -MINOR=$(sed -n "s/^ *\([0-9]\+\) \+$DM_NAME\$/\1/p" /proc/misc) +verbose-message "pl_sysinit: configuring kernel parameters" +verbose-run /sbin/sysctl -e -p /etc/sysctl.conf -if [ -n "$MAJOR" ] && [ -n "$MINOR" ]; then - /bin/mkdir -p --mode=755 $DIR - /bin/rm -f $CONTROL - /bin/mknod --mode=600 $CONTROL c $MAJOR $MINOR +# startup rsyslog if available (we're *NOT* running the standard rc) +syslog=/etc/rc.d/init.d/rsyslog +if [ -x $syslog ]; then + verbose-message "pl_sysinit: starting rsyslog" + verbose-run $syslog start else - echo $(date "+%H:%M:%S") "pl_sysinit: unable to create device mapper control node, continuing" + verbose-message "pl_sysinit: WARNING cannot start rsyslog" fi -echo "" -echo $(date "+%H:%M:%S") "pl_sysinit: configuring kernel parameters" -/sbin/sysctl -e -p /etc/sysctl.conf - -# startup rsyslog if available (we're *NOT* running the standard rc) -syslog=/etc/rc.d/init.d/rsyslog -[ -x $syslog ] && $syslog start - -echo "" -echo $(date "+%H:%M:%S") "pl_sysinit: bringing network online" -/etc/init.d/pl_netinit - -# just in case, sometimes we're seeing weird stuff already at this point -pl_network_sanity_checks - -echo "" -echo $(date "+%H:%M:%S") "pl_sysinit: attempting to sync clock" -/usr/sbin/ntpdate -b -t 10 -u pool.ntp.org - -# Handle /dev/rtc name change for newer kernels -# otherwise hwclock fails -baseMaj=`uname -r | cut -d "." -f1` -baseMin=`uname -r | cut -d "." -f2` -vers=`uname -r | cut -d "." -f3 | cut -d "-" -f1` -if [ $baseMaj -eq 2 ];then - if [ $baseMin -eq 6 ]; then - if [ $vers -ge 32 ];then - if [ "$(readlink /dev/rtc)" != "/dev/rtc0" ]; then - rm -f /dev/rtc - ln -s /dev/rtc0 /dev/rtc +verbose-message "pl_sysinit: bringing network online" +verbose-run /etc/init.d/pl_netinit + +function sync-clock() { + /usr/sbin/ntpdate -b -t 10 -u pool.ntp.org + + # Handle /dev/rtc name change for newer kernels + # otherwise hwclock fails + baseMaj=`uname -r | cut -d "." -f1` + baseMin=`uname -r | cut -d "." -f2` + vers=`uname -r | cut -d "." -f3 | cut -d "-" -f1` + if [ $baseMaj -eq 2 ];then + if [ $baseMin -eq 6 ]; then + if [ $vers -ge 32 ];then + if [ "$(readlink /dev/rtc)" != "/dev/rtc0" ]; then + rm -f /dev/rtc + ln -s /dev/rtc0 /dev/rtc + fi fi - fi + fi fi -fi + # save ntp clock to hardware + /sbin/hwclock --systohc --utc +} -# save ntp clock to hardware -/sbin/hwclock --systohc --utc +verbose-message "pl_sysinit: attempting to sync clock" +sync-clock -- 2.43.0