From 2a577b837b5f3b9d59109954359dc14741def98e Mon Sep 17 00:00:00 2001 From: padman Date: Thu, 22 Feb 2018 21:40:16 -0500 Subject: [PATCH 1/4] Support OS9 -> SONiC fast-reboot migration --- build_debian.sh | 2 +- dockers/docker-orchagent/swssconfig.sh | 15 +++++ files/image_config/platform/rc.local | 82 +++++++++++++++++++++++--- 3 files changed, 90 insertions(+), 9 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 033ac6ff270f..66e3ba6add48 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -315,7 +315,7 @@ sudo tee -a $FILESYSTEM_ROOT/etc/network/interfaces > /dev/null <> /etc/migration.log +} + +# Import files from another NOS's partition onto SONiC +nos_migration_import() { + [ -f $1 ] && cp $1 $2 || log_migration "ERROR: $1 not found!" +} + # If the machine.conf is absent, it indicates that the unit booted # into SONiC from another NOS. Extract the machine.conf from ONIE. if [ ! -e /host/machine.conf ]; then @@ -20,7 +30,7 @@ if [ ! -e /host/machine.conf ]; then onie_grub_cfg=/mnt/onie-boot/onie/grub/grub-machine.cfg if [ ! -e $onie_grub_cfg ]; then - echo "$onie_grub_cfg not found" >> /etc/migration.log + log_migration "$onie_grub_cfg not found" else . ./$onie_grub_cfg grep = $onie_grub_cfg | sed -e 's/onie_//' -e 's/=.*$//' | while read var ; do @@ -29,8 +39,60 @@ if [ ! -e /host/machine.conf ]; then done fi + # Extract the previous NOS's partition that contains the migration artifacts + set -- $(cat /proc/cmdline) + for x in "$@"; do + case "$x" in + nos-config-part=*) + nos_val="${x#nos-config-part=}" + ;; + esac + done + + if [ -n "$nos_val" ]; then + nos_dev=$(findfs $nos_val) + if [ $? != 0 ]; then + log_migration "ERROR: nos_dev not found. Check grub parameters" + fi + else + log_migration "ERROR: nos_val not found. Check grub parameters" + fi + + if [ -n "$nos_dev" ]; then + # Mount the previous NOS's partition + mkdir -p /mnt/nos_migration + mount $nos_dev /mnt/nos_migration + mkdir -p /etc/sonic/migration + + # Copy relevant files + nos_migration_import /mnt/nos_migration/minigraph.xml /etc/sonic/migration + nos_migration_import /mnt/nos_migration/arp.json /etc/sonic/migration + nos_migration_import /mnt/nos_migration/fdb.json /etc/sonic/migration + nos_migration_import /mnt/nos_migration/mgmt_interface.mac /etc/sonic/migration + + umount /mnt/nos_migration + rmdir /mnt/nos_migration + fi + + # Extract, validate and set the eth0's mac address + if [ -f /etc/sonic/migration/mgmt_interface.mac ]; then + eth0_mac=$(grep "macaddr" /etc/sonic/migration/mgmt_interface.mac | awk -F'=' '{print $2}') + log_migration "Setting eth0 mac as $eth0_mac." + if [ `echo $eth0_mac | egrep "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$"` ]; then + ifconfig eth0 down + ip link set eth0 address $eth0_mac + ifconfig eth0 up + rm /etc/sonic/migration/mgmt_interface.mac + else + log_migration "ERROR: $eth0_mac: invalid MAC!" + fi + fi + migration="TRUE" umount /mnt/onie-boot +else + # this is a reboot post NOS migration : remove stale imported files that were used during migration. + rm -fr /etc/sonic/migration fi . /host/machine.conf @@ -96,6 +158,10 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then # Combine information in minigraph and init_cfg.json to form initiate config DB dump file. # TODO: After moving all information from minigraph to DB, sample config DB dump should be provide sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json + elif [ -n "$migration" ] && [ -f /etc/sonic/migration/minigraph.xml ]; then + # Use the minigraph that was imported from the NOS + mv /etc/sonic/migration/minigraph.xml /etc/sonic/ + sonic-cfggen -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json else # Use default minigraph.xml cp /usr/share/sonic/device/$platform/minigraph.xml /etc/sonic/ @@ -127,26 +193,26 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then grub_bin=$(ls /host/image-$sonic_version/platform/x86_64-grub/grub-pc-bin*.deb 2> /dev/null) if [ -z "$grub_bin" ]; then - echo "Unable to locate grub package !" >> /etc/migration.log + log_migration "Unable to locate grub package !" firsttime_exit fi dpkg -i $grub_bin > /dev/null 2>&1 if [ $? != 0 ]; then - echo "Unable to install grub package !" >> /etc/migration.log + log_migration "Unable to install grub package !" firsttime_exit fi # Determine the block device to install grub sonic_dev=$(blkid | grep SONiC-OS | head -n 1 | awk '{print $1}' | sed -e 's/[0-9]:.*$//') if [ -z "$sonic_dev" ]; then - echo "Unable to determine sonic partition !" >> /etc/migration.log + log_migration "Unable to determine sonic partition !" firsttime_exit fi grub-install --boot-directory=/host --recheck $sonic_dev 2>/dev/null if [ $? != 0 ]; then - echo "grub install failed !" >> /etc/migration.log + log_migration "grub install failed !" firsttime_exit fi @@ -163,7 +229,7 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then if [ ! -z "$console_port" ] && [ "$console_port" != "$CONSOLE_PORT" ]; then sed -i -e "s/\-\-port=$console_port/\-\-port=$CONSOLE_PORT/g" /host/grub.cfg fi - echo "grub.cfg console port=$console_port & installer.conf CONSOLE_PORT=$CONSOLE_PORT" >> /etc/migration.log + log_migration "grub.cfg console port=$console_port & installer.conf CONSOLE_PORT=$CONSOLE_PORT" fi if [ ! -z "$CONSOLE_DEV" ]; then @@ -175,7 +241,7 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then if [ "$console_dev" != "$CONSOLE_DEV" ]; then sed -i -e "s/console=ttyS$console_dev/console=ttyS$CONSOLE_DEV/g" /host/grub.cfg fi - echo "grub.cfg console dev=$console_dev & installer.conf CONSOLE_DEV=$CONSOLE_DEV" >> /etc/migration.log + log_migration "grub.cfg console dev=$console_dev & installer.conf CONSOLE_DEV=$CONSOLE_DEV" fi if [ ! -z "$VAR_LOG_SIZE" ]; then @@ -186,7 +252,7 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then if [ ! -z "$var_log_size" ] && [ "$var_log_size" != "$VAR_LOG_SIZE" ]; then sed -i -e "s/var_log_size=$var_log_size/var_log_size=$VAR_LOG_SIZE/g" /host/grub.cfg fi - echo "grub.cfg var_log_size=$var_log_size & installer.conf VAR_LOG_SIZE=$VAR_LOG_SIZE" >> /etc/migration.log + log_migration "grub.cfg var_log_size=$var_log_size & installer.conf VAR_LOG_SIZE=$VAR_LOG_SIZE" fi # Set the root based on the label From 5a806b87cbd1b448d33caa893a643c90ad19adaf Mon Sep 17 00:00:00 2001 From: padman Date: Mon, 26 Feb 2018 11:20:11 -0500 Subject: [PATCH 2/4] Address review comments. Update NOS mac in EEPROM and net.rules for eth0 --- build_debian.sh | 3 +- dockers/docker-orchagent/swssconfig.sh | 15 ---- files/image_config/platform/rc.local | 99 +++++++++++++++++++------- 3 files changed, 77 insertions(+), 40 deletions(-) diff --git a/build_debian.sh b/build_debian.sh index 66e3ba6add48..ac0bb20b869d 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -221,7 +221,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in unzip \ gdisk \ sysfsutils \ - grub2-common + grub2-common \ + ethtool sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \ grub-pc-bin diff --git a/dockers/docker-orchagent/swssconfig.sh b/dockers/docker-orchagent/swssconfig.sh index fd80bad5d841..826dc6e33f87 100755 --- a/dockers/docker-orchagent/swssconfig.sh +++ b/dockers/docker-orchagent/swssconfig.sh @@ -2,18 +2,6 @@ set -e -function fast_migration { - if [[ -f /etc/sonic/migration/fdb.json ]]; - then - cp /etc/sonic/migration/fdb.json /fdb.json - fi - - if [[ -f /etc/sonic/migration/arp.json ]]; - then - cp /etc/sonic/migration/arp.json /arp.json - fi -} - function fast_reboot { case "$(cat /proc/cmdline)" in *fast-reboot*) @@ -41,9 +29,6 @@ function fast_reboot { esac } -# If we are migrating, import the dumps from the previous NOS -fast_migration - # Restore FDB and ARP table ASAP fast_reboot diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/rc.local index 59c9592b28d2..070fde59e235 100755 --- a/files/image_config/platform/rc.local +++ b/files/image_config/platform/rc.local @@ -13,7 +13,7 @@ # In case the unit is migrating from another NOS, save the logs log_migration() { - echo $1 >> /etc/migration.log + echo $1 >> /host/migration/migration.log } # Import files from another NOS's partition onto SONiC @@ -21,9 +21,74 @@ nos_migration_import() { [ -f $1 ] && cp $1 $2 || log_migration "ERROR: $1 not found!" } +# While migrating form another NOS, we need to preserve the MAC addresses +# of eth0 (and eventually switchports). +# Update the eth0 mac and also the EEPROM using ethtool so that subsequent +# reboots use the NOS's mac. +# Input : mgmt_interface.cfg file imported from the previous NOS. +update_mgmt_interface_macaddr() { + mgmt_config=$1 + if [ ! -f "$mgmt_config" ]; then + log_migration "ERROR : unable update eth0 MAC : $mgmt_config not found!" + return + fi + + # Save the previous NOS's mac + old_mac=`ip link show eth0 | grep ether | awk '{print $2}'` + [ -z "$old_mac" ] && log_migration "Unable to retrieve old mac address !" && return + + # Extract, validate and set the eth0's mac address for the current session + new_mac=$(grep "macaddr" $mgmt_config | awk -F'=' '{print $2}') + log_migration "Setting eth0 mac as $new_mac." + if [ `echo $new_mac | egrep "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$"` ]; then + ip link set eth0 down + ip link set eth0 address $new_mac + ip link set eth0 up + else + log_migration "ERROR: mac imported from NOS is invalid : $new_mac !" + return + fi + + # Get the ethtool magic and offset for changing the mac address in the EEPROM + ethtool_magic=$(grep "ethtool_magic" $mgmt_config | awk -F'=' '{print $2}') + ethtool_offset=$(grep "ethtool_offset" $mgmt_config | awk -F'=' '{print $2}') + if [ -z "$ethtool_magic" ] || [ -z "$ethtool_offset" ]; then + log_migration "Unable to retrieve ethtool params ($ethtool_magic,ethtool_offset)" + return + fi + + log_migration "eth0 mac in EEPROM before update:" + ethtool -e eth0 offset $ethtool_offset length 6 >> /host/migration/migration.log + + # Update the mac address in the EEPROM for subsequent reboots + # Write only changed octets + for i in 1 2 3 4 5 6; do + offset=$(($ethtool_offset+$i-1)) + old_mac_octet="$(echo $old_mac | cut -d":" -f$i)" + new_mac_octet="$(echo $new_mac | cut -d":" -f$i)" + + if [ "$old_mac_octet" != "$new_mac_octet" ]; then + ethtool -E eth0 magic $ethtool_magic offset $offset value 0x$new_mac_octet + if [ $? != 0 ]; then + log_migration "ERROR: unable to update eth0 EEPROM!" + log_migration "index $i, magic $ethtool_magic offset $offset, value $new_mac_octet" + return + fi + done + + log_migration "eth0 mac in EEPROM after update:" + ethtool -e eth0 offset $ethtool_offset length 6 >> /host/migration/migration.log + + # Update the 70-persistent-net.rules with the new mac for eth0 + log_migration "/etc/udev/rules.d/70-persistent-net.rules : replacing $old_mac with $new_mac for eth0" + sed -i "/eth0/ s/ATTR{address}==\"$old_mac\"/ATTR{address}==\"$new_mac\"/g" /etc/udev/rules.d/70-persistent-net.rules +} + # If the machine.conf is absent, it indicates that the unit booted # into SONiC from another NOS. Extract the machine.conf from ONIE. if [ ! -e /host/machine.conf ]; then + mkdir -p /host/migration + onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//') mkdir -p /mnt/onie-boot mount $onie_dev /mnt/onie-boot @@ -62,37 +127,23 @@ if [ ! -e /host/machine.conf ]; then # Mount the previous NOS's partition mkdir -p /mnt/nos_migration mount $nos_dev /mnt/nos_migration - mkdir -p /etc/sonic/migration + mkdir -p /host/fast-reboot # Copy relevant files - nos_migration_import /mnt/nos_migration/minigraph.xml /etc/sonic/migration - nos_migration_import /mnt/nos_migration/arp.json /etc/sonic/migration - nos_migration_import /mnt/nos_migration/fdb.json /etc/sonic/migration - nos_migration_import /mnt/nos_migration/mgmt_interface.mac /etc/sonic/migration + nos_migration_import /mnt/nos_migration/mgmt_interface.cfg /host/migration + nos_migration_import /mnt/nos_migration/minigraph.xml /host/migration + nos_migration_import /mnt/nos_migration/arp.json /host/fast-reboot + nos_migration_import /mnt/nos_migration/fdb.json /host/fast-reboot + nos_migration_import /mnt/nos_migration/default_routes.json /host/fast-reboot umount /mnt/nos_migration rmdir /mnt/nos_migration fi - # Extract, validate and set the eth0's mac address - if [ -f /etc/sonic/migration/mgmt_interface.mac ]; then - eth0_mac=$(grep "macaddr" /etc/sonic/migration/mgmt_interface.mac | awk -F'=' '{print $2}') - log_migration "Setting eth0 mac as $eth0_mac." - if [ `echo $eth0_mac | egrep "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$"` ]; then - ifconfig eth0 down - ip link set eth0 address $eth0_mac - ifconfig eth0 up - rm /etc/sonic/migration/mgmt_interface.mac - else - log_migration "ERROR: $eth0_mac: invalid MAC!" - fi - fi + update_mgmt_interface_macaddr /host/migration/mgmt_interface.cfg migration="TRUE" umount /mnt/onie-boot -else - # this is a reboot post NOS migration : remove stale imported files that were used during migration. - rm -fr /etc/sonic/migration fi . /host/machine.conf @@ -158,9 +209,9 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then # Combine information in minigraph and init_cfg.json to form initiate config DB dump file. # TODO: After moving all information from minigraph to DB, sample config DB dump should be provide sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json - elif [ -n "$migration" ] && [ -f /etc/sonic/migration/minigraph.xml ]; then + elif [ -n "$migration" ] && [ -f /host/migration/minigraph.xml ]; then # Use the minigraph that was imported from the NOS - mv /etc/sonic/migration/minigraph.xml /etc/sonic/ + mv /host/migration/minigraph.xml /etc/sonic/ sonic-cfggen -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json else # Use default minigraph.xml From 71572c5b9c25fa99d1e9f46c4f17b5bc7b0321c9 Mon Sep 17 00:00:00 2001 From: padman Date: Wed, 28 Feb 2018 08:36:41 -0500 Subject: [PATCH 3/4] Address review comments. Update sonic-platform-modules-dell to fac81d... --- build_debian.sh | 5 ++- files/image_config/platform/rc.local | 3 +- files/initramfs-tools/mgmt-intf-dhcp | 36 +++++++++++++++++++ platform/broadcom/sonic-platform-modules-dell | 2 +- 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 files/initramfs-tools/mgmt-intf-dhcp diff --git a/build_debian.sh b/build_debian.sh index ac0bb20b869d..bc04a71800ce 100755 --- a/build_debian.sh +++ b/build_debian.sh @@ -144,6 +144,9 @@ sudo cp files/initramfs-tools/union-mount $FILESYSTEM_ROOT/etc/initramfs-tools/s sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/union-mount sudo cp files/initramfs-tools/varlog $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/varlog sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/varlog +# Management interface (eth0) dhcp can be optionally turned off (during a migration from another NOS to SONiC) +sudo cp files/initramfs-tools/mgmt-intf-dhcp $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/mgmt-intf-dhcp +sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/scripts/init-bottom/mgmt-intf-dhcp sudo cp files/initramfs-tools/union-fsck $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/union-fsck sudo chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/union-fsck sudo chroot $FILESYSTEM_ROOT update-initramfs -u @@ -316,7 +319,7 @@ sudo tee -a $FILESYSTEM_ROOT/etc/network/interfaces > /dev/null < Date: Thu, 1 Mar 2018 05:22:55 -0500 Subject: [PATCH 4/4] Fix script for POSIX compliance --- files/initramfs-tools/mgmt-intf-dhcp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/initramfs-tools/mgmt-intf-dhcp b/files/initramfs-tools/mgmt-intf-dhcp index 89c67e7f8d1b..52f7ff5f495c 100644 --- a/files/initramfs-tools/mgmt-intf-dhcp +++ b/files/initramfs-tools/mgmt-intf-dhcp @@ -24,9 +24,9 @@ for x in "$@"; do fi if [ -e "${rootmnt}/etc/network/interfaces" ]; then - if [ "$val" == "off" ]; then + if [ "$val" = "off" ]; then sed -i 's/iface eth0 inet dhcp/iface eth0 inet static/g' ${rootmnt}/etc/network/interfaces - elif [ "$val" == "on" ]; then + elif [ "$val" = "on" ]; then sed -i 's/iface eth0 inet static/iface eth0 inet dhcp/g' ${rootmnt}/etc/network/interfaces fi fi