[vm-repair] Fix ADE OS disk unlock: select root and boot partitions by role instead of size - #10198
Conversation
…y role instead of size
|
Hi Mauricio (@msaenzbosupport), |
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
Thank you for your contribution Mauricio (@msaenzbosupport)! We will review the pull request and get back to you soon. |
There was a problem hiding this comment.
Pull request overview
This PR fixes az vm repair create --unlock-encrypted-vm for ADE-encrypted Linux VMs by changing the unlock/mount script to identify /boot and the encrypted root partition by partition role/signature (and verifying by actually opening LUKS), instead of guessing the root partition by “largest size”.
Changes:
- Update
linux-mount-encrypted-disk.shto classify boot/root candidates by GPT type GUID + filesystem signature, probe/bootread-only for the detached LUKS header, and verify the root by attemptingcryptsetup luksOpenand checking decrypted content. - Fix failure-path exit codes (use
exit 1) to avoid reporting success after failures. - Bump extension version to
2.2.4and document the fix in release notes.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/vm-repair/azext_vm_repair/scripts/linux-mount-encrypted-disk.sh | Reworks boot/root detection and unlock verification; improves error-path exit codes. |
| src/vm-repair/setup.py | Bumps extension version to 2.2.4. |
| src/vm-repair/HISTORY.rst | Adds 2.2.4 release note describing the ADE unlock fix. |
Suppressed comments (1)
src/vm-repair/azext_vm_repair/scripts/linux-mount-encrypted-disk.sh:57
- The
-zcheck is unquoted ([ -z ${data_disk} ]). Ifdata_diskis empty/unset, this expands to[ -z ]and can error out instead of entering the intended failure branch. Quote the variable in the test.
if [ -z ${data_disk} ]
then
echo "`date` OS disk attached as data disk was not found, cannot continue" >> ${logpath}/${logfile}
exit 1
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| @@ -31,7 +31,7 @@ locatebekvol () { | |||
| if [ -z ${bekdisk} ] | |||
| echo "`date` unlocking root with command: cryptsetup luksOpen --key-file /mnt/azure_bek_disk/LinuxPassPhraseFileName --header /investigateboot/luks/osluksheader ${part} osencrypt" >> ${logpath}/${logfile} | ||
| cryptsetup luksOpen --key-file /mnt/azure_bek_disk/LinuxPassPhraseFileName --header /investigateboot/luks/osluksheader ${part} osencrypt >> ${logpath}/${logfile} 2>&1 || continue |
|
/azp run |
|
Azure Pipelines: Successfully started running 2 pipeline(s). |
🤖 PR Validation — ️✔️ All clear
Description
az vm repair create --unlock-encrypted-vmfails on ADE single-pass Linux VMs whose OS disk contains a partition larger than the root partition.Repro layout (Ubuntu 22.04, ADE single pass, detached LUKS header):
sda1root 126.6G (encrypted),sda2/boot 256M ext2,sda3129G ext4 mounted at/512G,sda14BIOS boot,sda15EFI.Root cause
linux-mount-encrypted-disk.shpicks the root partition by size:root_part=$(lsblk "${data_disk}" -l -n -p -b | grep -w -v "${data_disk}" | sort -k4 -rn | awk 'NR==1{print $1}')"root is always the largest partition" does not hold.
sda3(129G) wins oversda1(126.6G), andcryptsetup luksOpenis then run against a partition thatlocate_mount_data_boothas already mounted under/tmp, hence the "already mapped or mounted" error.Two related issues in the same code path:
fdisk -l | grep -i lvm, which reads the partition table type code. Under ADE the LVM lives inside the LUKS container, so the partition type never reports LVM./bootpartition is located by mounting every partition read-write under/tmpand runningfind /tmp -name osluksheader. That replays the journal of a filesystem belonging to a VM that already failed to boot, andfind /tmpalso scans the repair VM's own/tmp.Note on the repro layout
We are aware that an extra data partition on the OS disk is not part of any Azure Marketplace image, and that this is a customer-customized layout. The point of the fix is not that specific layout, though: the assumption "root is the largest partition" has no ground truth behind it, so the script is guessing where it could be checking. Any of these produce a wrong pick with the current code, and none of them require an exotic disk:
/boot— a plain marketplace-derived Ubuntu 22.04 with/bootgrown to 36G and root at 31G already selects/bootas the root;Selecting by role and confirming the choice by actually opening the device costs a handful of
lsblk/blkidcalls and removes the guess entirely, so it is the safer behaviour even on stock images where the current heuristic happens to work.Fix
Classify partitions by role, then verify instead of guessing:
21686148-6449-6e6f-744e-656564454649) and EFI (c12a7328-f81f-11d2-ba4b-00a0c93ec93b) by GPT type GUID, with ablkidfallback for olderlsblkthat lacksPARTTYPE./bootcandidate. A partition with emptyFSTYPEorcrypto_LUKSis a root candidate./bootis the candidate that actually containsluks/osluksheader, probed read-only (ro,noloadthenro,norecoverythenro) one at a time. No more mass read-write mounts and nofind /tmp.mount_lvmpath is reached exactly as before.exit 1instead of bareexit, which returned status 0 and let the caller report success after mounting nothing.No parameter, API or dependency changes.
mount_lvm,check_local_lvm,mount_cmdandinstall_required_packagesare untouched.Testing
Verified end to end with the patched script installed in the local extension, running
az vm repair create --unlock-encrypted-vmon its own:sda3129G >sda1126.6G)Cannot use device /dev/sda3 which is in usesda1unlocked,/investigaterootonosencrypt,/investigateroot/bootonsda2FSTYPEsdb4decrypts toLVM2_member,rootvgactivated, all 5 LVs mountedLog from the fixed run on the failing layout:
Resulting state in the repair VM, matching the guest's own
/etc/fstab(UUID=4e109fbd... /,UUID=da920a35... /boot,UUID=6e0aaa26... /512G):sda3is left untouched, and no partition remains mounted under/tmp.LVM run:
Known issues not addressed here
Kept out of scope to limit the blast radius of this change:
mount_lvmhardcodesrootvgand the LV setrootlv/varlv/homelv/usrlv/tmplv; layouts with other names or an extra LV are not fully mounted.mount_cmd's probe (mount -o nouuidwith no device or mountpoint) validates nothing and always logsTrapped error code 1.check_local_lvmrenames the repair VM's own VG instead of importing the source VG withvgimportclone, and only when exactly one VG is present.