os_update: address GPT partitions by PARTLABEL, use layout offsets only without one - #24
os_update: address GPT partitions by PARTLABEL, use layout offsets only without one#24mobileoverlord wants to merge 4 commits into
Conversation
4a3c410 to
8983878
Compare
…ly without one A bundle's layout (devpath + computed offsets) was preferred over the partition's PARTLABEL whenever the bundle carried one, so a GPT artifact was written by raw offset to the manifest's devpath. On i.MX that device name is kernel-dependent (/dev/mmcblk1 in the manifest, /dev/mmcblk2 under 6.18), and the computed offsets need not match where the flasher placed the partitions: Writing rootfs_hash -> /dev/mmcblk1@618659840 (partition: rootfs-b-hash) Failed to open device /dev/mmcblk1 for rootfs_hash: No such file or directory Resolve /dev/disk/by-partlabel/<name> first and fall back to the layout only when udev has no label for the partition (MBR layouts). Both the staged and the streaming write paths go through the same locate_target.
8983878 to
6e15f73
Compare
|
Follow-up (stone has issues disabled, noting here): |
There was a problem hiding this comment.
Pull request overview
This PR fixes os_update device targeting by preferring kernel-resolved GPT PARTLABEL paths (/dev/disk/by-partlabel/...) over bundle layout device paths/offsets, and only using layout offsets as a fallback when PARTLABELs aren’t available.
Changes:
- Introduces
locate_target/WriteTargetto route writes to either a resolved partition path (preferred) or a raw device + byte offset (fallback). - Applies the same targeting logic to both staged (
apply_os_update) and streaming (apply_os_update_streaming) write paths. - Adds unit tests covering the “no PARTLABEL + layout -> offset” and “no PARTLABEL + no layout -> error” behaviors.
Suppressed comments (1)
src/os_update.rs:1576
- Same flakiness concern as the test above: use a deliberately-unique PARTLABEL so the test result doesn’t depend on the host’s attached disks.
#[test]
fn an_unlabeled_partition_without_a_layout_is_an_error() {
assert!(locate_target("avocadoctl-test-no-such-label", None).is_err());
}
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…ue test label A label that exists but fails to resolve (dangling symlink, EACCES, I/O error) is surfaced as the error it is rather than treated as absent, so a transient failure can never turn into a computed-offset write. The tests derive their nonexistent label from the pid so attached media cannot collide with it.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
src/os_update.rs:594
Path::exists()follows symlinks and returnsfalseon metadata errors, so a dangling PARTLABEL or anEACCES/I/O failure still reaches the raw-offset fallback. This contradicts the fail-safe behavior described above and can write to the wrong location. Inspect the directory entry without following it, and only treat a definiteNotFoundas absence.
if label.exists() {
Path::exists() answers false for a dangling symlink or a metadata error, so both the label check in locate_target and the neighbour scan in disk_has_any_label could misclassify a labeled disk as unlabeled and enable raw offset writes. One helper, label_absent, now decides via symlink_metadata and only a clean NotFound counts; every other outcome is surfaced by resolve_partition or treated as evidence the disk is labeled.
test_mode_redirects_os_releases_to_tmpdir set TMPDIR=/scratch under ENV_VAR_MUTEX, but tests in other modules call TempDir::new() without that lock and read TMPDIR while it is set; whichever one raced into the window failed on NotFound (seen as config::tests::test_load_invalid_toml in CI). Use a real, kept directory so a racing TempDir still has somewhere to go.
avocado deployto an imx8mp-evk failed inos_update:What
When the bundle carries a
layout(stone always emits one), artifacts were written by raw offset to the layout's device path even though/dev/disk/by-partlabel/<name>existed. The manifest's devpath is kernel-dependent (the eMMC ismmcblk1in the manifest,mmcblk2under 6.18), and computed offsets need not match where fwup placed the partitions.How
locate_targetresolves the PARTLABEL first. The layout offset is used only when the disk carries no labels at all (MBR layouts). A labeled disk that lacks this one label is a layout mismatch — a device provisioned before the partition existed — and is refused with a message saying to reprovision, rather than written at a computed offset onto whatever is there now. Both the staged and the streaming write paths use it.Tests: unlabeled + layout → offset; unlabeled without layout → error.
https://claude.ai/code/session_01S75qGgqVA2cQUsZdW46qUz