[fast-reboot]: Support OS9 -> SONiC fast-reboot migration (#1414)

* Support OS9 -> SONiC fast-reboot migration

* Address review comments. Update NOS mac in EEPROM and net.rules for eth0

* Address review comments. Update sonic-platform-modules-dell to fac81d...

* Fix script for POSIX compliance
This commit is contained in:
padmanarayana 2018-03-09 06:12:41 +05:30 committed by lguohan
parent 2d4c8a2ae6
commit 02b62ac9bb
4 changed files with 168 additions and 10 deletions

View File

@ -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 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 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 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 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 chmod +x $FILESYSTEM_ROOT/etc/initramfs-tools/hooks/union-fsck
sudo chroot $FILESYSTEM_ROOT update-initramfs -u sudo chroot $FILESYSTEM_ROOT update-initramfs -u
@ -221,7 +224,8 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
unzip \ unzip \
gdisk \ gdisk \
sysfsutils \ sysfsutils \
grub2-common grub2-common \
ethtool
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y download \
grub-pc-bin grub-pc-bin

View File

@ -11,16 +11,92 @@
# #
# By default this script does nothing. # By default this script does nothing.
# In case the unit is migrating from another NOS, save the logs
log_migration() {
echo $1 >> /host/migration/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!"
}
# 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
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 # If the machine.conf is absent, it indicates that the unit booted
# into SONiC from another NOS. Extract the machine.conf from ONIE. # into SONiC from another NOS. Extract the machine.conf from ONIE.
if [ ! -e /host/machine.conf ]; then 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/:.*$//') onie_dev=$(blkid | grep ONIE-BOOT | head -n 1 | awk '{print $1}' | sed -e 's/:.*$//')
mkdir -p /mnt/onie-boot mkdir -p /mnt/onie-boot
mount $onie_dev /mnt/onie-boot mount $onie_dev /mnt/onie-boot
onie_grub_cfg=/mnt/onie-boot/onie/grub/grub-machine.cfg onie_grub_cfg=/mnt/onie-boot/onie/grub/grub-machine.cfg
if [ ! -e $onie_grub_cfg ]; then if [ ! -e $onie_grub_cfg ]; then
echo "$onie_grub_cfg not found" >> /etc/migration.log log_migration "$onie_grub_cfg not found"
else else
. ./$onie_grub_cfg . ./$onie_grub_cfg
grep = $onie_grub_cfg | sed -e 's/onie_//' -e 's/=.*$//' | while read var ; do grep = $onie_grub_cfg | sed -e 's/onie_//' -e 's/=.*$//' | while read var ; do
@ -29,6 +105,44 @@ if [ ! -e /host/machine.conf ]; then
done done
fi 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 /host/fast-reboot
# Copy relevant files
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
update_mgmt_interface_macaddr /host/migration/mgmt_interface.cfg
migration="TRUE" migration="TRUE"
umount /mnt/onie-boot umount /mnt/onie-boot
fi fi
@ -96,6 +210,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. # 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 # 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 sonic-cfggen -H -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json
elif [ -n "$migration" ] && [ -f /host/migration/minigraph.xml ]; then
# Use the minigraph that was imported from the NOS
mv /host/migration/minigraph.xml /etc/sonic/
sonic-cfggen -m -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json
else else
# Use default minigraph.xml # Use default minigraph.xml
cp /usr/share/sonic/device/$platform/minigraph.xml /etc/sonic/ cp /usr/share/sonic/device/$platform/minigraph.xml /etc/sonic/
@ -127,26 +245,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) grub_bin=$(ls /host/image-$sonic_version/platform/x86_64-grub/grub-pc-bin*.deb 2> /dev/null)
if [ -z "$grub_bin" ]; then if [ -z "$grub_bin" ]; then
echo "Unable to locate grub package !" >> /etc/migration.log log_migration "Unable to locate grub package !"
firsttime_exit firsttime_exit
fi fi
dpkg -i $grub_bin > /dev/null 2>&1 dpkg -i $grub_bin > /dev/null 2>&1
if [ $? != 0 ]; then if [ $? != 0 ]; then
echo "Unable to install grub package !" >> /etc/migration.log log_migration "Unable to install grub package !"
firsttime_exit firsttime_exit
fi fi
# Determine the block device to install grub # Determine the block device to install grub
sonic_dev=$(blkid | grep SONiC-OS | head -n 1 | awk '{print $1}' | sed -e 's/[0-9]:.*$//') sonic_dev=$(blkid | grep SONiC-OS | head -n 1 | awk '{print $1}' | sed -e 's/[0-9]:.*$//')
if [ -z "$sonic_dev" ]; then if [ -z "$sonic_dev" ]; then
echo "Unable to determine sonic partition !" >> /etc/migration.log log_migration "Unable to determine sonic partition !"
firsttime_exit firsttime_exit
fi fi
grub-install --boot-directory=/host --recheck $sonic_dev 2>/dev/null grub-install --boot-directory=/host --recheck $sonic_dev 2>/dev/null
if [ $? != 0 ]; then if [ $? != 0 ]; then
echo "grub install failed !" >> /etc/migration.log log_migration "grub install failed !"
firsttime_exit firsttime_exit
fi fi
@ -163,7 +281,7 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then
if [ ! -z "$console_port" ] && [ "$console_port" != "$CONSOLE_PORT" ]; then if [ ! -z "$console_port" ] && [ "$console_port" != "$CONSOLE_PORT" ]; then
sed -i -e "s/\-\-port=$console_port/\-\-port=$CONSOLE_PORT/g" /host/grub.cfg sed -i -e "s/\-\-port=$console_port/\-\-port=$CONSOLE_PORT/g" /host/grub.cfg
fi 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 fi
if [ ! -z "$CONSOLE_DEV" ]; then if [ ! -z "$CONSOLE_DEV" ]; then
@ -175,7 +293,7 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then
if [ "$console_dev" != "$CONSOLE_DEV" ]; then if [ "$console_dev" != "$CONSOLE_DEV" ]; then
sed -i -e "s/console=ttyS$console_dev/console=ttyS$CONSOLE_DEV/g" /host/grub.cfg sed -i -e "s/console=ttyS$console_dev/console=ttyS$CONSOLE_DEV/g" /host/grub.cfg
fi 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 fi
if [ ! -z "$VAR_LOG_SIZE" ]; then if [ ! -z "$VAR_LOG_SIZE" ]; then
@ -186,7 +304,7 @@ if [ -f /host/image-$sonic_version/platform/firsttime ]; then
if [ ! -z "$var_log_size" ] && [ "$var_log_size" != "$VAR_LOG_SIZE" ]; 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 sed -i -e "s/var_log_size=$var_log_size/var_log_size=$VAR_LOG_SIZE/g" /host/grub.cfg
fi 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 fi
# Set the root based on the label # Set the root based on the label

View File

@ -0,0 +1,36 @@
#!/bin/sh
PREREQS="union-mount"
prereqs() { echo "$PREREQS"; }
case $1 in
prereqs)
prereqs
exit 0
;;
esac
# Extract kernel parameters
set -- $(cat /proc/cmdline)
for x in "$@"; do
case "$x" in
mgmt-intf-dhcp=*)
val="${x#mgmt-intf-dhcp=}"
if [ -z "$val" ]; then
echo "ERROR: mgmt-intf-dhcp value (on/off) not specified !"
exit 0
fi
if [ -e "${rootmnt}/etc/network/interfaces" ]; 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
sed -i 's/iface eth0 inet static/iface eth0 inet dhcp/g' ${rootmnt}/etc/network/interfaces
fi
fi
;;
esac
done

@ -1 +1 @@
Subproject commit d2f58195831e6e7016992ef449778f3474e60e95 Subproject commit fac81d02276d7245233c0401ac699029b0b41cdd