Skip to content

Commit 22a1106

Browse files
committed
composefs-backend: store boot assets in ESP during install
Signed-off-by: Robert Sturla <[email protected]>
1 parent 017206d commit 22a1106

File tree

1 file changed

+91
-38
lines changed

1 file changed

+91
-38
lines changed

crates/lib/src/install.rs

Lines changed: 91 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,7 @@ pub(crate) fn setup_composefs_bls_boot(
16911691
) -> Result<String> {
16921692
let id_hex = id.to_hex();
16931693

1694-
let (root_path, cmdline_refs) = match setup_type {
1694+
let (root_path, esp_device, cmdline_refs) = match setup_type {
16951695
BootSetupType::Setup((root_setup, state)) => {
16961696
// root_setup.kargs has [root=UUID=<UUID>, "rw"]
16971697
let mut cmdline_options = String::from(root_setup.kargs.join(" "));
@@ -1705,23 +1705,60 @@ pub(crate) fn setup_composefs_bls_boot(
17051705
}
17061706
};
17071707

1708-
(root_setup.physical_root_path.clone(), cmdline_options)
1708+
// Locate ESP partition device
1709+
let esp_part = root_setup
1710+
.device_info
1711+
.partitions
1712+
.iter()
1713+
.find(|p| p.parttype.as_str() == ESP_GUID)
1714+
.ok_or_else(|| anyhow::anyhow!("ESP partition not found"))?;
1715+
1716+
(
1717+
root_setup.physical_root_path.clone(),
1718+
esp_part.node.clone(),
1719+
cmdline_options,
1720+
)
17091721
}
17101722

1711-
BootSetupType::Upgrade => (
1712-
Utf8PathBuf::from("/sysroot"),
1713-
vec![
1714-
format!("root=UUID={DPS_UUID}"),
1715-
RW_KARG.to_string(),
1716-
format!("{COMPOSEFS_CMDLINE}={id_hex}"),
1717-
]
1718-
.join(" "),
1719-
),
1723+
BootSetupType::Upgrade => {
1724+
let sysroot = Utf8PathBuf::from("/sysroot");
1725+
1726+
let fsinfo = inspect_filesystem(&sysroot)?;
1727+
let parent_devices = find_parent_devices(&fsinfo.source)?;
1728+
1729+
let Some(parent) = parent_devices.into_iter().next() else {
1730+
anyhow::bail!("Could not find parent device for mountpoint /sysroot");
1731+
};
1732+
1733+
(
1734+
sysroot,
1735+
get_esp_partition(&parent)?.0,
1736+
vec![
1737+
format!("root=UUID={DPS_UUID}"),
1738+
RW_KARG.to_string(),
1739+
format!("{COMPOSEFS_CMDLINE}={id_hex}"),
1740+
]
1741+
.join(" "),
1742+
)
1743+
}
17201744
};
17211745

1722-
let boot_dir = root_path.join("boot");
1746+
let mounted_esp: PathBuf = root_path.join("esp").into();
1747+
let esp_mount_point_existed = mounted_esp.exists();
1748+
1749+
Task::new("Mounting ESP", "mount")
1750+
.args([&PathBuf::from(&esp_device), &mounted_esp.clone()])
1751+
.run()?;
1752+
1753+
create_dir_all(&mounted_esp).context("Failed to create dir {mounted_esp:?}")?;
1754+
1755+
Task::new("Mounting ESP", "mount")
1756+
.args([&PathBuf::from(&esp_device), &mounted_esp.clone()])
1757+
.run()?;
1758+
17231759
let is_upgrade = matches!(setup_type, BootSetupType::Upgrade);
17241760

1761+
let efi_dir = mounted_esp.join(format!("EFI/Linux"));
17251762
let (bls_config, boot_digest) = match &entry {
17261763
ComposefsBootEntry::Type1(..) => unimplemented!(),
17271764
ComposefsBootEntry::Type2(..) => unimplemented!(),
@@ -1735,16 +1772,18 @@ pub(crate) fn setup_composefs_bls_boot(
17351772
bls_config.title = Some(id_hex.clone());
17361773
bls_config.sort_key = Some("1".into());
17371774
bls_config.machine_id = None;
1738-
bls_config.linux = format!("/boot/{id_hex}/vmlinuz");
1739-
bls_config.initrd = vec![format!("/boot/{id_hex}/initrd")];
1775+
bls_config.linux = format!("/EFI/Linux/{id_hex}/vmlinuz");
1776+
bls_config.initrd = vec![format!("/EFI/Linux/{id_hex}/initrd")];
17401777
bls_config.options = Some(cmdline_refs);
17411778
bls_config.extra = HashMap::new();
17421779

17431780
if let Some(symlink_to) = find_vmlinuz_initrd_duplicates(&boot_digest)? {
1744-
bls_config.linux = format!("/boot/{symlink_to}/vmlinuz");
1745-
bls_config.initrd = vec![format!("/boot/{symlink_to}/initrd")];
1781+
bls_config.linux = format!("/EFI/Linux/{symlink_to}/vmlinuz");
1782+
bls_config.initrd = vec![format!("/EFI/Linux/{symlink_to}/initrd")];
17461783
} else {
1747-
write_bls_boot_entries_to_disk(&boot_dir, id, usr_lib_modules_vmlinuz, &repo)?;
1784+
let efi_dir_utf8 = Utf8PathBuf::from_path_buf(efi_dir.clone())
1785+
.map_err(|_| anyhow::anyhow!("EFI dir is not valid UTF-8"))?;
1786+
write_bls_boot_entries_to_disk(&efi_dir_utf8, id, usr_lib_modules_vmlinuz, &repo)?;
17481787
}
17491788

17501789
(bls_config, boot_digest)
@@ -1757,43 +1796,57 @@ pub(crate) fn setup_composefs_bls_boot(
17571796

17581797
// This will be atomically renamed to 'loader/entries' on shutdown/reboot
17591798
(
1760-
boot_dir.join(format!("loader/{STAGED_BOOT_LOADER_ENTRIES}")),
1799+
efi_dir.join(format!("loader/{STAGED_BOOT_LOADER_ENTRIES}")),
17611800
Some(booted_bls),
17621801
)
17631802
} else {
1764-
(boot_dir.join(format!("loader/{BOOT_LOADER_ENTRIES}")), None)
1803+
(efi_dir.join(format!("loader/{BOOT_LOADER_ENTRIES}")), None)
17651804
};
17661805

17671806
create_dir_all(&entries_path).with_context(|| format!("Creating {:?}", entries_path))?;
17681807

1769-
let loader_entries_dir =
1770-
cap_std::fs::Dir::open_ambient_dir(&entries_path, cap_std::ambient_authority())
1771-
.with_context(|| format!("Opening {entries_path}"))?;
1772-
1773-
loader_entries_dir.atomic_write(
1774-
// SAFETY: We set sort_key above
1775-
format!(
1776-
"bootc-composefs-{}.conf",
1777-
bls_config.sort_key.as_ref().unwrap()
1778-
),
1779-
bls_config.to_string().as_bytes(),
1780-
)?;
1808+
// Scope to allow for proper unmounting
1809+
{
1810+
let loader_entries_dir =
1811+
cap_std::fs::Dir::open_ambient_dir(&entries_path, cap_std::ambient_authority())
1812+
.with_context(|| format!("Opening {entries_path:?}"))?;
17811813

1782-
if let Some(booted_bls) = booted_bls {
17831814
loader_entries_dir.atomic_write(
17841815
// SAFETY: We set sort_key above
17851816
format!(
17861817
"bootc-composefs-{}.conf",
1787-
booted_bls.sort_key.as_ref().unwrap()
1818+
bls_config.sort_key.as_ref().unwrap()
17881819
),
1789-
booted_bls.to_string().as_bytes(),
1820+
bls_config.to_string().as_bytes(),
17901821
)?;
1822+
1823+
if let Some(booted_bls) = booted_bls {
1824+
loader_entries_dir.atomic_write(
1825+
// SAFETY: We set sort_key above
1826+
format!(
1827+
"bootc-composefs-{}.conf",
1828+
booted_bls.sort_key.as_ref().unwrap()
1829+
),
1830+
booted_bls.to_string().as_bytes(),
1831+
)?;
1832+
}
1833+
1834+
let owned_loader_entries_fd = loader_entries_dir
1835+
.reopen_as_ownedfd()
1836+
.context("Reopening as owned fd")?;
1837+
rustix::fs::fsync(owned_loader_entries_fd).context("fsync")?;
17911838
}
17921839

1793-
let owned_loader_entries_fd = loader_entries_dir
1794-
.reopen_as_ownedfd()
1795-
.context("Reopening as owned fd")?;
1796-
rustix::fs::fsync(owned_loader_entries_fd).context("fsync")?;
1840+
Task::new("Unmounting ESP", "umount")
1841+
.arg(&mounted_esp)
1842+
.run()?;
1843+
1844+
if !esp_mount_point_existed {
1845+
// This shouldn't be a fatal error
1846+
if let Err(e) = std::fs::remove_dir(&mounted_esp) {
1847+
tracing::error!("Failed to remove mount point '{mounted_esp:?}': {e}");
1848+
}
1849+
}
17971850

17981851
Ok(boot_digest)
17991852
}

0 commit comments

Comments
 (0)