Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support OS9 -> SONiC fast-reboot migration #1414

Merged
merged 4 commits into from
Mar 9, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions build_debian.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -315,7 +316,7 @@ sudo tee -a $FILESYSTEM_ROOT/etc/network/interfaces > /dev/null <<EOF

auto eth0
allow-hotplug eth0
iface eth0 inet dhcp
iface eth0 inet static
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we are not going to disable dhcp globally? the dhcp is disabled only from ftos to sonic fast-boot migration?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the earlier thought. But I could not disable this during migration since squashfs is readonly... So, changed the approach. Note that with this change, though we disable dhcp globally during the build, if there is no IP configured in the minigraph, the interfaces-config.sh would override the startup /etc/network/interfaces with a config that is set to dhcp.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you do not need to change squash fs, you can change the entry after you have mounted the union fs.

EOF

sudo cp files/dhcp/rfc3442-classless-routes $FILESYSTEM_ROOT/etc/dhcp/dhclient-exit-hooks.d
Expand Down
133 changes: 125 additions & 8 deletions files/image_config/platform/rc.local
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,91 @@
#
# 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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

form -> from

# 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)"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missed $ in the error message?

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
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for sonic, we are using the same mac for management interface and vlan interface. are you using the same mac for you management interface and vlan interface? The goal here is to make sure your vlan interface has the same mac as our vlan interface.


# 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
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
Expand All @@ -29,6 +104,44 @@ 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 /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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please put your files into /host/fast-reboot directory?
See following changes in fast-reboot script: sonic-net/sonic-utilities@461470b

In this case you don't need any changes in swssconfig.sh

umount /mnt/nos_migration
rmdir /mnt/nos_migration
fi

update_mgmt_interface_macaddr /host/migration/mgmt_interface.cfg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure this will work for any platform?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an assumption that the platform supports ethtool to modify the eth (GbE in S6100/Z9100) case using igb. If the platform does not support ethtool to change the EEPROM, the alternative (workaround) is to note that the unit has migrated and apply the previous NOS' mac to eth0 (using ip link set) everytime the unit reboots...


migration="TRUE"
umount /mnt/onie-boot
fi
Expand Down Expand Up @@ -96,6 +209,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 /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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-H -m -j

else
# Use default minigraph.xml
cp /usr/share/sonic/device/$platform/minigraph.xml /etc/sonic/
Expand Down Expand Up @@ -127,26 +244,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

Expand All @@ -163,7 +280,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
Expand All @@ -175,7 +292,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
Expand All @@ -186,7 +303,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
Expand Down