max / alloy
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+26 insertions,
-1 deletion
| @@ -591,9 +591,20 @@ | |||
| 591 | 591 | const LUKS_FSTYPE: &str = "crypto_LUKS"; | |
| 592 | 592 | ||
| 593 | 593 | /// Ask lsblk what filesystem is on `partition`, and what it holds open. | |
| 594 | + | /// | |
| 595 | + | /// **`NAME` is in the column list and nothing reads it.** lsblk builds its tree | |
| 596 | + | /// around that column, and asking for `PATH,FSTYPE` alone returns a flat array | |
| 597 | + | /// with the container and the mapper device inside it as siblings, no | |
| 598 | + | /// `children` anywhere. [`filesystem_device`] looks for a child, so without | |
| 599 | + | /// this every encrypted install read as a LUKS container nobody had opened — | |
| 600 | + | /// including the ones where it was open, which is every one of them. | |
| 601 | + | /// | |
| 602 | + | /// Measured in a VM 2026-08-09 against the failing install: the same command | |
| 603 | + | /// with `NAME` added nests `/dev/mapper/root` under `/dev/vda4`, and without it | |
| 604 | + | /// lists them side by side. | |
| 594 | 605 | fn partition_contents(partition: &str) -> Invocation { | |
| 595 | 606 | Invocation::new("lsblk") | |
| 596 | - | .args(["-J", "-o", "PATH,FSTYPE"]) | |
| 607 | + | .args(["-J", "-o", "NAME,PATH,FSTYPE"]) | |
| 597 | 608 | .arg(partition) | |
| 598 | 609 | } | |
| 599 | 610 | ||
| @@ -5725,6 +5736,20 @@ | |||
| 5725 | 5736 | ); | |
| 5726 | 5737 | } | |
| 5727 | 5738 | ||
| 5739 | + | // The two tests above hand-write the nesting, so they passed for as long as | |
| 5740 | + | // the command never produced it. lsblk builds its tree around the NAME | |
| 5741 | + | // column and emits a flat array without it, which made every encrypted | |
| 5742 | + | // install read as a container nobody had opened. Pin the column list, since | |
| 5743 | + | // that is the part that was wrong. | |
| 5744 | + | #[test] | |
| 5745 | + | fn the_partition_listing_asks_for_the_column_lsblk_nests_around() { | |
| 5746 | + | let shown = Stage::Run(partition_contents("/dev/sda3")).display(); | |
| 5747 | + | assert!( | |
| 5748 | + | shown.contains("NAME"), | |
| 5749 | + | "without NAME lsblk returns a flat list and no child is ever found: {shown}", | |
| 5750 | + | ); | |
| 5751 | + | } | |
| 5752 | + | ||
| 5728 | 5753 | // The branch this code cannot verify against a real disk from here. If bootc | |
| 5729 | 5754 | // ever leaves the container shut, the install has to say so rather than | |
| 5730 | 5755 | // mount the container and fail three stages later about a superblock. |