cos-kernel: Use root disk p12 as EFI partition If a second boot disk has been mounted, the /dev/disk/bypartlabel/EFI-SYSTEM link can be overwritten. On COS, it's more reliable to use partition 12 of the root disk instead, which should always be the actual EFI partition. BUG=b/567952125 TEST=presubmit, unlock and deploy kernel on x86 and arm64 Change-Id: If44102e4f85ca14ef1b1a5667024568b43fe0afe Reviewed-on: https://cos-review.googlesource.com/c/cos/tools/+/219608 Reviewed-by: Derek Taylor <ddtaylor@google.com> Cloud-Build: 228075978874@cloudbuild.gserviceaccount.com <228075978874@cloudbuild.gserviceaccount.com> Tested-by: Kevin Berry <kpberry@google.com>
diff --git a/src/pkg/kernel/scripts/cos-kernel-deploy b/src/pkg/kernel/scripts/cos-kernel-deploy index b919e98..30c9553 100755 --- a/src/pkg/kernel/scripts/cos-kernel-deploy +++ b/src/pkg/kernel/scripts/cos-kernel-deploy
@@ -48,7 +48,31 @@ # We have to do this before removing the existing modules since we might need # to load a file system driver (such as vfat) to mount the EFI partition. ESPMOUNT=$(mktemp -d) -mount /dev/disk/by-label/EFI-SYSTEM "${ESPMOUNT}" + +# Get the EFI partition of the root device. The steps are: +# 1. Get the block devices. +# 2. Filter to the block dev that has a descendant with "/" as a mount point. +# 3. Filter to the objects that have a device maj:min number. +# 4. Filter to the leaf partitions (no children). +# 5. Take the partition name from the 12th partition. +# +# This avoids several edge cases: +# 1. The /dev/disk/by-partlabel/EFI-SYSTEM symlink can be overwritten if a second disk is +# mounted. +# 2. There may be virtual mounts for the root partition, so it might not be at the top level. +# 3. The device minor number for the 12th partition on the root device might not be 12 on +# NVME since NVME devices share a device major number and increment the minor number for +# each partition. +readonly ESPNAME=$( + lsblk --json | + jq '.blockdevices.[]' | + jq 'select(.. | (.mountpoints? // []).[] == "/")' | + jq '.. | select(."maj:min"? // "" != "")' | + jq 'select(.children == null)' | + jq -sr '.[11].name' +) +readonly ESPDEV="/dev/${ESPNAME}" +mount "${ESPDEV}" "${ESPMOUNT}" if [ -d "/lib/modules/${VERSION}" ]; then rm -rf "/lib/modules/${VERSION}"
diff --git a/src/pkg/kernel/scripts/cos-set-dev-mode b/src/pkg/kernel/scripts/cos-set-dev-mode index cdde8cf..2c7cb99 100755 --- a/src/pkg/kernel/scripts/cos-set-dev-mode +++ b/src/pkg/kernel/scripts/cos-set-dev-mode
@@ -29,7 +29,31 @@ exit 1 fi -readonly ESPDEV="/dev/disk/by-partlabel/EFI-SYSTEM" + +# Get the EFI partition of the root device. The steps are: +# 1. Get the block devices. +# 2. Filter to the block dev that has a descendant with "/" as a mount point. +# 3. Filter to the objects that have a device maj:min number. +# 4. Filter to the leaf partitions (no children). +# 5. Take the partition name from the 12th partition. +# +# This avoids several edge cases: +# 1. The /dev/disk/by-partlabel/EFI-SYSTEM symlink can be overwritten if a second disk is +# mounted. +# 2. There may be virtual mounts for the root partition, so it might not be at the top level. +# 3. The device minor number for the 12th partition on the root device might not be 12 on +# NVME since NVME devices share a device major number and increment the minor number for +# each partition. +readonly ESPNAME=$( + lsblk --json | + jq '.blockdevices.[]' | + jq 'select(.. | (.mountpoints? // []).[] == "/")' | + jq '.. | select(."maj:min"? // "" != "")' | + jq 'select(.children == null)' | + jq -sr '.[11].name' +) +ESPDEV="/dev/${ESPNAME}" + readonly GRUBCFG="/efi/boot/grub.cfg" CONFIRMED="no"