mirror of
				https://github.com/Telecominfraproject/ols-nos.git
				synced 2025-11-03 19:47:56 +00:00 
			
		
		
		
	[Aboot] refactor boot0.j2 for Aboot bootloader (#1445)
Now properly differenciate the image installation and the kexec operations. This is useful for fast-reboot operations. Minor updates include - better command line management - using partition UUID in the command line
This commit is contained in:
		
				
					committed by
					
						
						Prince Sunny
					
				
			
			
				
	
			
			
			
						parent
						
							667ca3254e
						
					
				
				
					commit
					e18e15f31b
				
			@@ -14,23 +14,55 @@
 | 
				
			|||||||
# You should have received a copy of the GNU General Public License
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Aboot stage 0 boot
 | 
					# Aboot stage 0 boot script
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This boot0 script can be used in different scenario
 | 
				
			||||||
 | 
					#  - Installation and boot from Aboot (manual or reboot on a new image)
 | 
				
			||||||
 | 
					#  - EOS to SONiC fast-reboot (installation and kexec in EOS)
 | 
				
			||||||
 | 
					#  - SONiC to SONiC fast-reboot (installation and kexec in SONiC)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Use it this way:
 | 
				
			||||||
 | 
					#   - swipath=path/to/swi install=true boot0
 | 
				
			||||||
 | 
					#   - swipath=path/to/swi install=true force=true boot0
 | 
				
			||||||
 | 
					#   - swipath=path/to/swi kexec=true boot0
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# The logic defaults to the first scenario but providing extra environment variable
 | 
				
			||||||
 | 
					# will affect the behavior of the script.
 | 
				
			||||||
 | 
					# The list of variables is maintained here
 | 
				
			||||||
 | 
					#   - KERNEL : relative path to the kernel to execute
 | 
				
			||||||
 | 
					#   - INITRD : relative path to the initrd to load
 | 
				
			||||||
 | 
					#   - CMDLINE : place to find the default kernel cmdline to use for the platform
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# By default the boot0 script will behave for an Aboot based behavior.
 | 
				
			||||||
 | 
					# Options can be provided to only run some features of this script.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Extra kernel parameters can be provided at runtime by the user by adding them
 | 
				
			||||||
 | 
					# into a kernel-params file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set -x
 | 
					set -x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
kernel=boot/vmlinuz-3.16.0-5-amd64
 | 
					image_name="image-%%IMAGE_VERSION%%"
 | 
				
			||||||
initrd=boot/initrd.img-3.16.0-5-amd64
 | 
					
 | 
				
			||||||
kernel_params=kernel-params
 | 
					do_not_clean="do-not-clean"
 | 
				
			||||||
 | 
					kernel_params="kernel-params"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
aboot_machine="arista_unknown"
 | 
					aboot_machine="arista_unknown"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ -z "$target_path" ] && target_path=/mnt/flash
 | 
					 | 
				
			||||||
image_path="$target_path/image-%%IMAGE_VERSION%%"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# expect the swi to be a non empty file
 | 
					# extract mount point from the swi path, e.g., /mnt/flash/sonic.swi --> /mnt/flash
 | 
				
			||||||
[ -s "$swipath" ] || exit 1
 | 
					if [ -z "$target_path" ]; then
 | 
				
			||||||
 | 
					    if [ -z "$swipath" ]; then
 | 
				
			||||||
 | 
					       echo "target_path= is required when swipath= is not provided"
 | 
				
			||||||
 | 
					       exit 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    target_path=$(df "$swipath" | tail -1 | tr -s " " | cut -d ' ' -f6)
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					image_path="$target_path/$image_name"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bootconfigvars="SWI SWI_COPY POST_LEVEL CONSOLESPEED PASSWORD NETDEV NETAUTO NETIP NETMASK NETGW NETDOMAIN NETDNS NETHW memtest"
 | 
					cmdline_base="$target_path/kernel-params-base"
 | 
				
			||||||
 | 
					cmdline_image="$image_path/kernel-cmdline"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bootconfigvars="KERNEL INITRD CONSOLESPEED PASSWORD NETDEV NETAUTO NETIP NETMASK NETGW NETDOMAIN NETDNS NETHW memtest"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
parse_environment_config() {
 | 
					parse_environment_config() {
 | 
				
			||||||
    for n in ${bootconfigvars}; do
 | 
					    for n in ${bootconfigvars}; do
 | 
				
			||||||
@@ -46,6 +78,8 @@ clean_flash() {
 | 
				
			|||||||
    for f in $(ls -A $target_path); do
 | 
					    for f in $(ls -A $target_path); do
 | 
				
			||||||
        if [ $f != "${swipath##*/}" ] &&
 | 
					        if [ $f != "${swipath##*/}" ] &&
 | 
				
			||||||
           [ $f != "boot-config" ] &&
 | 
					           [ $f != "boot-config" ] &&
 | 
				
			||||||
 | 
					           [ $f != "$kernel_params" ] &&
 | 
				
			||||||
 | 
					           [ $f != "$cmdline_base" ] &&
 | 
				
			||||||
           [ $f != "minigraph.xml" ]
 | 
					           [ $f != "minigraph.xml" ]
 | 
				
			||||||
        then
 | 
					        then
 | 
				
			||||||
            rm -rf "$target_path/$f"
 | 
					            rm -rf "$target_path/$f"
 | 
				
			||||||
@@ -54,7 +88,6 @@ clean_flash() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extract_image() {
 | 
					extract_image() {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    mkdir -p "$image_path"
 | 
					    mkdir -p "$image_path"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ## Unzip the image except boot0 and dockerfs archive
 | 
					    ## Unzip the image except boot0 and dockerfs archive
 | 
				
			||||||
@@ -80,7 +113,7 @@ extract_image() {
 | 
				
			|||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ## use new reduced-size boot swi
 | 
					    ## use new reduced-size boot swi
 | 
				
			||||||
    echo "SWI=flash:image-%%IMAGE_VERSION%%/{{ ABOOT_BOOT_IMAGE }}" > "$target_path/boot-config"
 | 
					    echo "SWI=flash:$image_name/{{ ABOOT_BOOT_IMAGE }}" > "$target_path/boot-config"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ## Remove installer swi as it has lots of redundunt contents
 | 
					    ## Remove installer swi as it has lots of redundunt contents
 | 
				
			||||||
    rm -f "$swipath"
 | 
					    rm -f "$swipath"
 | 
				
			||||||
@@ -91,8 +124,12 @@ extract_image() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
write_machine_config() {
 | 
					write_machine_config() {
 | 
				
			||||||
    ## Detect SKU and create a hardware description file
 | 
					    ## Detect SKU and create a hardware description file
 | 
				
			||||||
    aboot_version=$(grep ^Aboot /etc/cmdline | sed 's/^.*norcal.-//')
 | 
					    aboot_version=$(grep ^Aboot "$cmdline_base" | sed 's/^.*norcal.-//' | tail -n 1)
 | 
				
			||||||
 | 
					    if [ -x /bin/sysinit ]; then
 | 
				
			||||||
       aboot_build_date=$(stat -c %y /bin/sysinit | sed 's/ /T/')
 | 
					       aboot_build_date=$(stat -c %y /bin/sysinit | sed 's/ /T/')
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					       aboot_build_date="unknown"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
    cat <<EOF > ${target_path}/machine.conf
 | 
					    cat <<EOF > ${target_path}/machine.conf
 | 
				
			||||||
aboot_version=$aboot_version
 | 
					aboot_version=$aboot_version
 | 
				
			||||||
aboot_vendor=arista
 | 
					aboot_vendor=arista
 | 
				
			||||||
@@ -101,16 +138,17 @@ aboot_machine=$aboot_machine
 | 
				
			|||||||
aboot_arch=x86_64
 | 
					aboot_arch=x86_64
 | 
				
			||||||
aboot_build_date=$aboot_build_date
 | 
					aboot_build_date=$aboot_build_date
 | 
				
			||||||
EOF
 | 
					EOF
 | 
				
			||||||
 | 
					    chmod a+r "${target_path}/machine.conf"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
platform_specific() {
 | 
					platform_specific() {
 | 
				
			||||||
    local platform="$(grep -Eo 'platform=[^ ]+' /etc/cmdline | cut -f2 -d=)"
 | 
					    local platform="$(grep -Eo 'platform=[^ ]+' "$cmdline_base" | cut -f2 -d=)"
 | 
				
			||||||
    local sid="$(grep -Eo 'sid=[^ ]+' /etc/cmdline | cut -f2 -d=)"
 | 
					    local sid="$(grep -Eo 'sid=[^ ]+' "$cmdline_base" | cut -f2 -d=)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # set varlog size to 100MB
 | 
					    # set varlog size to 100MB
 | 
				
			||||||
    local varlog_size=100
 | 
					    local varlog_size=100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    local flash_size=$(($(df | grep flash | tr -s ' ' | cut -f2 -d' ') / 1000))
 | 
					    local flash_size=$(($(df | grep -E '/mnt/flash|/host' | tr -s ' ' | cut -f2 -d' ') / 1000))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if [ "$platform" = "raven" ]; then
 | 
					    if [ "$platform" = "raven" ]; then
 | 
				
			||||||
        aboot_machine=arista_7050_qx32
 | 
					        aboot_machine=arista_7050_qx32
 | 
				
			||||||
@@ -132,7 +170,12 @@ platform_specific() {
 | 
				
			|||||||
        flash_size=28000
 | 
					        flash_size=28000
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
    if [ "$platform" = "rook" ]; then
 | 
					    if [ "$platform" = "rook" ]; then
 | 
				
			||||||
 | 
					        if [ -x /bin/readprefdl ]; then
 | 
				
			||||||
           readprefdl -f /tmp/.system-prefdl -d > /mnt/flash/.system-prefdl
 | 
					           readprefdl -f /tmp/.system-prefdl -d > /mnt/flash/.system-prefdl
 | 
				
			||||||
 | 
					        elif [ -f /etc/prefdl ]; then
 | 
				
			||||||
 | 
					           cp /etc/prefdl /mnt/flash/.system-prefdl
 | 
				
			||||||
 | 
					           chmod a+r /mnt/flash/.system-prefdl
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if [ $flash_size -ge 28000 ]; then
 | 
					    if [ $flash_size -ge 28000 ]; then
 | 
				
			||||||
@@ -144,45 +187,119 @@ platform_specific() {
 | 
				
			|||||||
    echo "varlog_size=$varlog_size" >>/tmp/append
 | 
					    echo "varlog_size=$varlog_size" >>/tmp/append
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# check the hash file in the image, and determine to install or just skip
 | 
					get_uuid_for() {
 | 
				
			||||||
GIT_REVISION=$(unzip -p "$swipath" .imagehash)
 | 
					    local dev="$1"
 | 
				
			||||||
LOCAL_IMAGEHASH=$(cat $image_path/.imagehash 2>/dev/null || true)
 | 
					
 | 
				
			||||||
if [ "$GIT_REVISION" != "$LOCAL_IMAGEHASH" ]; then
 | 
					    if type lsblk 2>&1 > /dev/null; then
 | 
				
			||||||
    [ -z "$sonic_upgrade" ] && clean_flash
 | 
					       lsblk "$dev" -n --output UUID
 | 
				
			||||||
    extract_image
 | 
					    elif type blkid 2>&1 > /dev/null; then
 | 
				
			||||||
 | 
					       blkid | grep "^$dev" | sed -n "s/^.* UUID=\"//p" | grep -Eo '[^"]+'
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					write_boot_configs() {
 | 
				
			||||||
 | 
					    if $in_aboot; then
 | 
				
			||||||
 | 
					        # generate the default kernel parameters for the platform
 | 
				
			||||||
 | 
					        echo "$append" > $cmdline_base
 | 
				
			||||||
 | 
					        cat /etc/cmdline | sed "/^\(${bootconfigvars// /\|}\|crashkernel\|loglevel\|ignore_loglevel\)\(\$\|=\)/d;/^\$/d" >> $cmdline_base
 | 
				
			||||||
 | 
					        parse_environment_config >> $cmdline_base
 | 
				
			||||||
 | 
					    elif [ ! -f "$cmdline_base" ]; then
 | 
				
			||||||
 | 
					        # some systems were started with other versions of this script and therefore
 | 
				
			||||||
 | 
					        # do not have the $cmdline_base file. we assume that we are on Sonic or EOS.
 | 
				
			||||||
 | 
					        cat /proc/cmdline > $cmdline_base
 | 
				
			||||||
 | 
					        sed -Ei 's/^(.*) rw .*$/\1/' $cmdline_base
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ -z "$sonic_upgrade" ] || exit 0
 | 
					    cp $cmdline_base /tmp/append
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# build the new cmdline
 | 
					 | 
				
			||||||
echo "$append" >/tmp/append
 | 
					 | 
				
			||||||
parse_environment_config >>/tmp/append
 | 
					 | 
				
			||||||
cat /etc/cmdline | sed "/^\(${bootconfigvars// /\|}\|crashkernel\|loglevel\|ignore_loglevel\)\(\$\|=\)/d;/^\$/d" >>/tmp/append
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
echo "rw loop=image-%%IMAGE_VERSION%%/fs.squashfs loopfstype=squashfs apparmor=1 security=apparmor quiet" >>/tmp/append
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# process platform specific operations
 | 
					 | 
				
			||||||
    platform_specific
 | 
					    platform_specific
 | 
				
			||||||
 | 
					    echo "rw loop=$image_name/fs.squashfs loopfstype=squashfs apparmor=1 security=apparmor quiet" >> /tmp/append
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[ -e ${taget_path}/machine.conf ] || write_machine_config
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # use extra parameters from kernel-params hook if the file exists
 | 
					    # use extra parameters from kernel-params hook if the file exists
 | 
				
			||||||
if [ -f "$image_path/$kernel_params" ]; then
 | 
					    if [ -f "$target_path/$kernel_params" ]; then
 | 
				
			||||||
    cat "$image_path/$kernel_params" >>/tmp/append
 | 
					        cat "$target_path/$kernel_params" >> /tmp/append
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # setting root partition if not overridden by kernel-params
 | 
					    # setting root partition if not overridden by kernel-params
 | 
				
			||||||
    if ! grep -q "root=" /tmp/append; then
 | 
					    if ! grep -q "root=" /tmp/append; then
 | 
				
			||||||
   rootdev=$(mount | grep '/mnt/flash' | cut -f1 -d' ')
 | 
					        rootdev="$(mount | grep -E '/mnt/flash|/host' | cut -f1 -d' ')"
 | 
				
			||||||
   rootfstype=$(mount | grep '/mnt/flash' | cut -f5 -d' ')
 | 
					        rootfstype="$(mount | grep -E '/mnt/flash|/host' | cut -f5 -d' ')"
 | 
				
			||||||
 | 
					        rootuuid="$(get_uuid_for $rootdev)"
 | 
				
			||||||
 | 
					        if [ -z "$rootuuid" ] || [ "$rootfstype" = "vfat" ] ; then
 | 
				
			||||||
            echo "root=$rootdev" >> /tmp/append
 | 
					            echo "root=$rootdev" >> /tmp/append
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            echo "root=UUID=$rootuuid" >> /tmp/append
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mv /tmp/append $cmdline_image
 | 
				
			||||||
 | 
					    [ -e ${target_path}/machine.conf ] || write_machine_config
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run_kexec() {
 | 
				
			||||||
 | 
					    local cmdline="$(cat $cmdline_image | tr '\n' ' ')"
 | 
				
			||||||
 | 
					    local kernel="${KERNEL:-$(find $image_path/boot -name 'vmlinuz-*' -type f | head -n 1)}"
 | 
				
			||||||
 | 
					    local initrd="${INITRD:-$(find $image_path/boot -name 'initrd.img-*' -type f | head -n 1)}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    kexec --load --initrd="$initrd" --append="$cmdline" "$kernel"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [ -z "$testonly" ] || exit 0
 | 
				
			||||||
 | 
					    echo "kexecing..."
 | 
				
			||||||
 | 
					    kexec --exec
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# In Aboot no option will be provided therefore these are the default values to use
 | 
				
			||||||
 | 
					in_aboot=true
 | 
				
			||||||
 | 
					do_clean=true
 | 
				
			||||||
 | 
					do_install=true
 | 
				
			||||||
 | 
					do_kexec=true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# prevent the flash from being cleaned if the do-not-clean file exists
 | 
				
			||||||
 | 
					if [ -f "$target_path/$do_not_clean" ]; then
 | 
				
			||||||
 | 
					    do_clean=false
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Parse the cmdline options (used from EOS or from SONiC)
 | 
				
			||||||
 | 
					if [ ! -z "$install" ] || [ ! -z "$sonic_upgrade" ]; then
 | 
				
			||||||
 | 
					    # install from SONiC or EOS
 | 
				
			||||||
 | 
					    in_aboot=false
 | 
				
			||||||
 | 
					    do_clean=false
 | 
				
			||||||
 | 
					    do_kexec=false
 | 
				
			||||||
 | 
					elif [ ! -z "$kexec" ]; then
 | 
				
			||||||
 | 
					    # kexec from SONiC or EOS
 | 
				
			||||||
 | 
					    in_aboot=false
 | 
				
			||||||
 | 
					    do_install=false
 | 
				
			||||||
 | 
					    do_clean=false
 | 
				
			||||||
 | 
					elif [ $# -ne 0 ]; then
 | 
				
			||||||
 | 
					    echo "usage: $0 (see code)"
 | 
				
			||||||
 | 
					    exit 1
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# install the image if newer
 | 
				
			||||||
 | 
					if $do_install; then
 | 
				
			||||||
 | 
					    # we expect the swi to install to be a non empty file
 | 
				
			||||||
 | 
					    if [ ! -s "$swipath" ]; then
 | 
				
			||||||
 | 
					        echo "The swipath= environment variable does not point to a valid SWI"
 | 
				
			||||||
 | 
					        exit 1
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # check the hash file in the image, and determine to install or just skip
 | 
				
			||||||
 | 
					    GIT_REVISION=$(unzip -p "$swipath" .imagehash)
 | 
				
			||||||
 | 
					    LOCAL_IMAGEHASH=$(cat $image_path/.imagehash 2>/dev/null || true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if [ "$GIT_REVISION" != "$LOCAL_IMAGEHASH" ] || [ ! -z "$force" ]; then
 | 
				
			||||||
 | 
					        if $do_clean; then
 | 
				
			||||||
 | 
					            clean_flash
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        extract_image
 | 
				
			||||||
 | 
					        write_boot_configs
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# chainloading using kexec
 | 
					# chainloading using kexec
 | 
				
			||||||
initrd_path="$image_path/$initrd"
 | 
					if $do_kexec; then
 | 
				
			||||||
kernel_path="$image_path/$kernel"
 | 
					    run_kexec
 | 
				
			||||||
cmdline="$(tr '\n' ' ' </tmp/append)"
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
kexec --load --initrd="$initrd_path" --append="$cmdline" "$kernel_path"
 | 
					 | 
				
			||||||
[ -z "$testonly" ] || exit 0
 | 
					 | 
				
			||||||
kexec --exec
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user