Skip to content

Commit ad0647b

Browse files
cgwaltersjeckersb
authored andcommitted
install/baseline: use sfdisk, not lsblk
I think this may also help with the install flake we've been seeing where we somehow get the partitions mixed up. - Use `sfdisk` in the baseline install because it's what we're switching to using anyways later on - Add some verification at least for the root and EFI partitions that we read back the expected type Signed-off-by: Colin Walters <[email protected]>
1 parent 14cf04b commit ad0647b

File tree

2 files changed

+41
-27
lines changed

2 files changed

+41
-27
lines changed

lib/src/blockdev.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,21 @@ impl PartitionTable {
165165
pub(crate) fn path(&self) -> &Utf8Path {
166166
self.device.as_str().into()
167167
}
168+
169+
// Find the partition with the given offset (starting at 1)
170+
pub(crate) fn find_partno(&self, partno: u32) -> Result<&Partition> {
171+
let r = self
172+
.partitions
173+
.get(partno.checked_sub(1).expect("1 based partition offset") as usize)
174+
.ok_or_else(|| anyhow::anyhow!("Missing partition for index {partno}"))?;
175+
Ok(r)
176+
}
177+
}
178+
179+
impl Partition {
180+
pub(crate) fn path(&self) -> &Utf8Path {
181+
self.node.as_str().into()
182+
}
168183
}
169184

170185
#[context("Listing partitions of {dev}")]

lib/src/install/baseline.rs

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -328,24 +328,18 @@ pub(crate) fn install_create_rootfs(
328328
// we're targeting, but this is a simple coarse hammer.
329329
crate::blockdev::udev_settle()?;
330330

331-
// Now inspect the partitioned device again so we can find the names of the child devices.
332-
let device_partitions = crate::blockdev::list_dev(&devpath)?
333-
.children
334-
.ok_or_else(|| anyhow::anyhow!("Failed to find children after partitioning"))?;
335-
// Given a partition number, return the path to its device.
336-
let findpart = |idx: u32| -> Result<String> {
337-
// checked_sub is here because our partition numbers start at 1, but the vec starts at 0
338-
let devpath = device_partitions
339-
.get(idx.checked_sub(1).unwrap() as usize)
340-
.ok_or_else(|| anyhow::anyhow!("Missing partition for index {idx}"))?
341-
.path();
342-
Ok(devpath)
343-
};
344-
345-
let base_rootdev = findpart(rootpn)?;
331+
// Re-read what we wrote into structured information
332+
let base_partitions = &crate::blockdev::partitions_of(&devpath)?;
346333

334+
let root_partition = base_partitions.find_partno(rootpn)?;
335+
if root_partition.parttype.as_str() != LINUX_PARTTYPE {
336+
anyhow::bail!(
337+
"root partition {partno} has type {}; expected {LINUX_PARTTYPE}",
338+
root_partition.parttype.as_str()
339+
);
340+
}
347341
let (rootdev, root_blockdev_kargs) = match block_setup {
348-
BlockSetup::Direct => (base_rootdev, None),
342+
BlockSetup::Direct => (root_partition.node.to_owned(), None),
349343
BlockSetup::Tpm2Luks => {
350344
let uuid = uuid::Uuid::new_v4().to_string();
351345
// This will be replaced via --wipe-slot=all when binding to tpm below
@@ -356,21 +350,23 @@ pub(crate) fn install_create_rootfs(
356350
let tmp_keyfile = tmp_keyfile.path();
357351
let dummy_passphrase_input = Some(dummy_passphrase.as_bytes());
358352

353+
let root_devpath = root_partition.path();
354+
359355
Task::new("Initializing LUKS for root", "cryptsetup")
360356
.args(["luksFormat", "--uuid", uuid.as_str(), "--key-file"])
361357
.args([tmp_keyfile])
362-
.args([base_rootdev.as_str()])
358+
.args([root_devpath])
363359
.run()?;
364360
// The --wipe-slot=all removes our temporary passphrase, and binds to the local TPM device.
365361
// We also use .verbose() here as the details are important/notable.
366362
Task::new("Enrolling root device with TPM", "systemd-cryptenroll")
367363
.args(["--wipe-slot=all", "--tpm2-device=auto", "--unlock-key-file"])
368364
.args([tmp_keyfile])
369-
.args([base_rootdev.as_str()])
365+
.args([root_devpath])
370366
.verbose()
371367
.run_with_stdin_buf(dummy_passphrase_input)?;
372368
Task::new("Opening root LUKS device", "cryptsetup")
373-
.args(["luksOpen", base_rootdev.as_str(), luks_name])
369+
.args(["luksOpen", root_devpath.as_str(), luks_name])
374370
.run()?;
375371
let rootdev = format!("/dev/mapper/{luks_name}");
376372
let kargs = vec![
@@ -383,12 +379,15 @@ pub(crate) fn install_create_rootfs(
383379

384380
// Initialize the /boot filesystem
385381
let bootdev = if let Some(bootpn) = boot_partno {
386-
Some(findpart(bootpn)?)
382+
Some(base_partitions.find_partno(bootpn)?)
387383
} else {
388384
None
389385
};
390-
let boot_uuid = if let Some(bootdev) = bootdev.as_deref() {
391-
Some(mkfs(bootdev, root_filesystem, "boot", []).context("Initializing /boot")?)
386+
let boot_uuid = if let Some(bootdev) = bootdev {
387+
Some(
388+
mkfs(bootdev.node.as_str(), root_filesystem, "boot", [])
389+
.context("Initializing /boot")?,
390+
)
392391
} else {
393392
None
394393
};
@@ -418,23 +417,23 @@ pub(crate) fn install_create_rootfs(
418417
let bootfs = rootfs.join("boot");
419418
// Create the underlying mount point directory, which should be labeled
420419
crate::lsm::ensure_dir_labeled(&target_rootfs, "boot", None, 0o755.into(), sepolicy)?;
421-
if let Some(bootdev) = bootdev.as_deref() {
422-
mount::mount(bootdev, &bootfs)?;
420+
if let Some(bootdev) = bootdev {
421+
mount::mount(bootdev.node.as_str(), &bootfs)?;
423422
}
424423
// And we want to label the root mount of /boot
425424
crate::lsm::ensure_dir_labeled(&target_rootfs, "boot", None, 0o755.into(), sepolicy)?;
426425

427426
// Create the EFI system partition, if applicable
428427
if let Some(esp_partno) = esp_partno {
429-
let espdev = &findpart(esp_partno)?;
428+
let espdev = base_partitions.find_partno(esp_partno)?;
430429
Task::new("Creating ESP filesystem", "mkfs.fat")
431-
.args([espdev.as_str(), "-n", "EFI-SYSTEM"])
430+
.args([espdev.node.as_str(), "-n", "EFI-SYSTEM"])
432431
.verbose()
433432
.quiet_output()
434433
.run()?;
435434
let efifs_path = bootfs.join(crate::bootloader::EFI_DIR);
436435
std::fs::create_dir(&efifs_path).context("Creating efi dir")?;
437-
mount::mount(espdev, &efifs_path)?;
436+
mount::mount(espdev.node.as_str(), &efifs_path)?;
438437
}
439438

440439
let luks_device = match block_setup {

0 commit comments

Comments
 (0)