Skip to content

Instantly share code, notes, and snippets.

@DennisLfromGA
Last active January 24, 2026 16:45
Show Gist options
  • Select an option

  • Save DennisLfromGA/0e4d4c558ebee0857232c65ae8510cb3 to your computer and use it in GitHub Desktop.

Select an option

Save DennisLfromGA/0e4d4c558ebee0857232c65ae8510cb3 to your computer and use it in GitHub Desktop.
Re-prioritize CrOS boot pair to toggle the active image pair (KERNEL & ROOT) or set the active image pair as specified.
#!/bin/sh -e
REVISION=16
APPL_PATH="$(readlink -f $0)"
APPLICATION="${0##*/}"
BOOT_KERNEL=""
BOOT_ROOT=""
CURRENT_BOOTPAIR=""
CURRENT_CHROME=""
CURRENT_DRIVE=""
CURRENT_KERNEL=""
CURRENT_KERNVER=""
CURRENT_MILESTONE=""
CURRENT_ROOT=""
CURRENT_TRACK=""
DRIVE_PREFIX=""
ALTERNATE_BOOTPAIR=""
ALTERNATE_CHROME=""
ALTERNATE_KERNEL=""
ALTERNATE_KERNELVER=""
ALTERNATE_MILESTONE=""
ALTERNATE_ROOT=""
ALTERNATE_TRACK=""
ALT_ROOT_NODEV=""
NO_OP="y"
ROOTDEV=""
ROOTDEVPFX=""
RPLY=""
TRIES="3"
USAGE="$APPLICATION: REVISION $REVISION
Description:
### A script to toggle the active image pair: A or B $CH_MSG1 (KERNEL & ROOT)
##+ or set the active image (KERNEL & ROOT) as specified on the commandline.
Usage:
$ $APPLICATION [ -s,--showpartition (default) | -r,--rollback | partition_number | -h,--help | -v,--version ]
"
## Exits the script with exit code $1, spitting out message $@ to stderr
error() {
local ecode="$1"
shift
echo "$*" 1>&2
exit "$ecode"
}
if [ "$1" = "-h" -o "$1" = "--help" ]; then
error 0 "$USAGE"
elif [ "$1" = "-v" -o "$1" = "--version" ]; then
error 0 "$APPLICATION: REVISION $REVISION"
fi
## If we're not running as root, restart as root.
if [ $(id -u) -ne 0 ]; then
echo "...elevating $USER to superuser..."
echo
exec sudo /bin/bash "$APPL_PATH" "$@"
fi
## Following routine borrowed from @drinkcat ;)
ROOTDEV="$(rootdev -d -s)"
if [ -z "$ROOTDEV" ]; then
error 1 "Cannot find root device."
fi
if [ ! -b "$ROOTDEV" ]; then
error 1 "$ROOTDEV is not a block device."
fi
## If $ROOTDEV ends with a number (e.g. mmcblk0), partitions are named
## ${ROOTDEV}pX (e.g. mmcblk0p1). If not (e.g. sda), they are named
## ${ROOTDEV}X (e.g. sda1).
ROOTDEVPFX="$ROOTDEV"
if [ "${ROOTDEV%[0-9]}" != "$ROOTDEV" ]; then
ROOTDEVPFX="${ROOTDEV}p"
fi
DRIVE_PREFIX="${ROOTDEVPFX#/dev/}"
CURRENT_ROOT="$(rootdev -s)"
CURRENT_DRIVE="$ROOTDEV"
CURRENT_KERNVER="$(/bin/ls /lib/modules/ | cut -d- -f1,2)"
CURRENT_MILESTONE="$(grep -i chrome_milestone /etc/lsb-release 2>/dev/null | cut -d= -f2)"
CURRENT_CHROME="$(/opt/google/chrome/chrome --version --no-display 2>/dev/null | cut -d ' ' -f3)"
CURRENT_RELEASE="$(grep -i google_release /etc/lsb-release 2>/dev/null | cut -d= -f2)"
CURRENT_TRACK="$(grep -i release_track /etc/lsb-release 2>/dev/null | cut -d= -f2)"
### Neverware CloudReady OS partitions
##/dev/sda
## start size part contents
## 14929936 235139696 16 Label: "STATE"
## 20496 32768 17 Label: "KERN-A"
## Attr: priority=1 tries=0 successful=1
## 8687632 6242304 18 Label: "ROOT-A"
## 53264 32768 19 Label: "KERN-B"
## Attr: priority=2 tries=0 successful=1
## 2445328 6242304 20 Label: "ROOT-B"
## 16464 1 21 Label: "KERN-C"
## Attr: priority=0 tries=15 successful=0
## 16465 1 22 Label: "ROOT-C"
## 86032 2097152 23 Label: "OEM"
## 16466 1 24 Label: "reserved"
## 16467 1 25 Label: "reserved"
## 80 16384 26 Label: "RWFW"
## 2183184 131072 27 Label: "EFI-SYSTEM"
## Attr: legacy_boot=1
if [ "$CURRENT_ROOT" = "${ROOTDEVPFX}3" ]
then CURRENT_KERNEL="2"
CURRENT_BOOTPAIR="A"
ALTERNATE_ROOT="${ROOTDEVPFX}5"
ALTERNATE_KERNEL="4"
ALTERNATE_BOOTPAIR="B"
elif [ "$CURRENT_ROOT" = "${ROOTDEVPFX}5" ]
then CURRENT_KERNEL="4"
CURRENT_BOOTPAIR="B"
ALTERNATE_ROOT="${ROOTDEVPFX}3"
ALTERNATE_KERNEL="2"
ALTERNATE_BOOTPAIR="A"
elif [ "$CURRENT_ROOT" = "${ROOTDEVPFX}18" ]
then CURRENT_KERNEL="17"
CURRENT_BOOTPAIR="A"
ALTERNATE_KERNEL="19"
ALTERNATE_ROOT="${ROOTDEVPFX}20"
ALTERNATE_BOOTPAIR="B"
else CURRENT_KERNEL="19"
CURRENT_BOOTPAIR="B"
ALTERNATE_ROOT="${ROOTDEVPFX}18"
ALTERNATE_KERNEL="17"
ALTERNATE_BOOTPAIR="A"
fi
ALT_ROOT_NODEV="${ALTERNATE_ROOT#/dev/}"
mkdir -p /var/$ALT_ROOT_NODEV
if mount $ALTERNATE_ROOT /var/$ALT_ROOT_NODEV 2>/dev/null
then
ALTERNATE_KERNVER="$(/bin/ls /var/$ALT_ROOT_NODEV/lib/modules/ | cut -d- -f1,2)"
ALTERNATE_MILESTONE="$(grep -i chrome_milestone /var/$ALT_ROOT_NODEV/etc/lsb-release 2>/dev/null | cut -d= -f2)"
ALTERNATE_CHROME="$(/var/$ALT_ROOT_NODEV/opt/google/chrome/chrome --version --no-display 2>/dev/null | cut -d ' ' -f3)"
ALTERNATE_RELEASE="$(grep -i google_release /var/$ALT_ROOT_NODEV/etc/lsb-release 2>/dev/null | cut -d= -f2)"
ALTERNATE_TRACK="$(grep -i release_track /var/$ALT_ROOT_NODEV/etc/lsb-release 2>/dev/null | cut -d= -f2)"
umount /var/$ALT_ROOT_NODEV && rmdir /var/$ALT_ROOT_NODEV
else
echo "Cannot mount '/var/$ALT_ROOT_NODEV', perhaps a new update is waiting."
echo "No alternate releases, milestones, or track info. is available at the moment."
echo
# exit 1
fi
CH_SIZE="$(cgpt show -qnsi 7 $CURRENT_DRIVE)"
if [ "$CH_SIZE" -gt 1 ]; then CH_MSG1="or C"; CH_MSG2=", & 6"; CH_NBR=",6"; fi
if [ "$#" -eq 0 ];
then BOOT_KERNEL="$ALTERNATE_KERNEL"
BOOT_ROOT="$ALTERNATE_ROOT"
echo "$USAGE"
else BOOT_ROOT="${CURRENT_DRIVE}$(($1+1))"
case $1 in
[2,4${CH_NBR}]) BOOT_KERNEL="$1"
echo -n "Re-prioritizing to use KERNEL $BOOT_KERNEL ..."
sleep 3 && echo; echo
;;
-r*|--r*) NO_OP=''
BOOT_KERNEL="$ALTERNATE_KERNEL"
BOOT_ROOT="$ALTERNATE_ROOT"
;;
-s*|--s*) NO_OP="y"
;;
*) echo "KERNEL=$1 is invalid, only 2,4${CH_MSG2} accepted"; exit 2
;;
esac
fi
echo -n "CURRENT_BOOTPAIR=$CURRENT_BOOTPAIR"
echo " ALTERNATE_BOOTPAIR=$ALTERNATE_BOOTPAIR"
echo -n "-------------------------------"
echo " -------------------------------"
echo -n "CURRENT_KERNEL=$CURRENT_KERNEL"
echo " ALTERNATE_KERNEL=$ALTERNATE_KERNEL"
echo -n "CURRENT_ROOT=$CURRENT_ROOT"
echo " ALTERNATE_ROOT=$ALTERNATE_ROOT"
echo -n "CURRENT_MILESTONE=$CURRENT_MILESTONE"
[ -n "$ALTERNATE_MILESTONE" ] && echo " ALTERNATE_MILESTONE=$ALTERNATE_MILESTONE" ||echo
echo -n "CURRENT_CHROME=$CURRENT_CHROME"
[ -n "$ALTERNATE_CHROME" ] && echo " ALTERNATE_CHROME=$ALTERNATE_CHROME" || echo
echo -n "CURRENT_RELEASE=$CURRENT_RELEASE"
[ -n "$ALTERNATE_RELEASE" ] && echo " ALTERNATE_RELEASE=$ALTERNATE_RELEASE" || echo
echo -n "CURRENT_KERNVER=$CURRENT_KERNVER"
[ -n "$ALTERNATE_KERNVER" ] && echo " ALTERNATE_KERNVER=$ALTERNATE_KERNVER"
echo -n "CURRENT_TRACK=$CURRENT_TRACK"
[ -n "$ALTERNATE_TRACK" ] && echo " ALTERNATE_TRACK=$ALTERNATE_TRACK" || echo
echo
[ ! "$NO_OP" = "y" ] && echo "BOOT_KERNEL=$BOOT_KERNEL (prioritized)"
[ ! "$NO_OP" = "y" ] && echo "BOOT_ROOT=$BOOT_ROOT" && echo
cgpt show -i 2 "$CURRENT_DRIVE" | grep --color=always -e start -e size -e part -e KERN -e priority -e ROOT -e contents
for i in 3 4 5 17 18 19 20
do
cgpt show -i "$i" "$CURRENT_DRIVE" | grep --color=always -e KERN -e priority -e ROOT
done
if [ "$CH_SIZE" -gt 1 ]; then
cgpt show -i 6 "$CURRENT_DRIVE" | grep --color=always -e KERN -e priority -e ROOT -e CHRUBUNTU
cgpt show -i 7 "$CURRENT_DRIVE" | grep --color=always -e KERN -e priority -e ROOT -e CHRUBUNTU
fi
if [ "$NO_OP" = "y" ]; then echo; exit 0; fi
echo
echo "cgpt add $CURRENT_DRIVE -i $BOOT_KERNEL -S0 -T"$TRIES""
echo "cgpt prioritize $CURRENT_DRIVE -i $BOOT_KERNEL"
echo
echo -n "Press ENTER to perform the above ROLLBACK - Ctrl+C to abort "; read RPLY
if [ -n "${RPLY}" ]; then error 0 "Key entered, ABORTING ..."; fi
## Mark the kernel as successfully booted (success=0, tries="$TRIES").
cgpt add "$CURRENT_DRIVE" -i "$BOOT_KERNEL" -S0 -T"$TRIES"
## Mark the kernel as highest priority
cgpt prioritize "$CURRENT_DRIVE" -i "$BOOT_KERNEL"
echo
cgpt show -i 2 "$CURRENT_DRIVE" | grep --color=always -e start -e size -e part -e KERN -e priority -e ROOT -e contents
for i in 3 4 5 17 18 19 20
do
cgpt show -i "$i" "$CURRENT_DRIVE" | grep --color=always -e KERN -e priority -e ROOT
done
if [ "$CH_SIZE" -gt 1 ]; then
cgpt show -i 6 "$CURRENT_DRIVE" | grep --color=always -e KERN -e priority -e ROOT -e CHRUBUNTU
cgpt show -i 7 "$CURRENT_DRIVE" | grep --color=always -e KERN -e priority -e ROOT -e CHRUBUNTU
fi
echo
exit 0
@DennisLfromGA
Copy link
Copy Markdown
Author

Fixed a few root drive glitches and updated current & alternate info. displayed.

@DennisLfromGA
Copy link
Copy Markdown
Author

Revision #8 - fairly major update.

@DennisLfromGA
Copy link
Copy Markdown
Author

Revision #9 - updated for CloudReady OS partition scheme.

@DennisLfromGA
Copy link
Copy Markdown
Author

Revision #10 - Changed field for chrome version from 3 to 2, added another abort option.

@DennisLfromGA
Copy link
Copy Markdown
Author

Revision #11 - Added Boot pair and kernel version.

@DennisLfromGA
Copy link
Copy Markdown
Author

Revision #13 - Rearranged some logic, added revision/version output, fixed revision number.

@DennisLfromGA
Copy link
Copy Markdown
Author

DennisLfromGA commented May 25, 2021

Revision #14 - Reinstated '-s' option blunder - my bad & added the word ROLLBACK to the prompt.

@DennisLfromGA
Copy link
Copy Markdown
Author

Revision #15 - Changed default to no-op / display only action and added -r / -rollback option.
This reverses the logic so that only a -r / -rollback will force a rollback.

@DennisLfromGA
Copy link
Copy Markdown
Author

Revision 16: Added (default) for '-s ,--showpartition' options and removed display of $USAGE when no options present.

@DennisLfromGA
Copy link
Copy Markdown
Author

Tweaked line 153 to remove comment, no revision change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment