Skip to content

Commit 13f3c22

Browse files
committed
install: preserve loader and ostree when cleaning /boot
Signed-off-by: Huijing Hei <[email protected]> Co-worked by: Jean-Baptiste Trystram <[email protected]>
1 parent 4c8db70 commit 13f3c22

File tree

1 file changed

+50
-21
lines changed

1 file changed

+50
-21
lines changed

crates/lib/src/install.rs

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,6 +1815,42 @@ fn require_empty_rootdir(rootfs_fd: &Dir) -> Result<()> {
18151815
Ok(())
18161816
}
18171817

1818+
#[context("Removing boot directory content except loader and ostree dirs")]
1819+
fn remove_all_except_loader_dirs(bootdir: &Dir) -> Result<()> {
1820+
let entries = bootdir.entries().context("Reading boot directory entries")?;
1821+
let protected_dirs = ["loader", "ostree"];
1822+
1823+
for entry in entries {
1824+
let entry = entry.context("Reading directory entry")?;
1825+
let file_name = entry.file_name();
1826+
let file_name = if let Some(n) = file_name.to_str() {
1827+
n
1828+
} else {
1829+
anyhow::bail!("Invalid non-UTF8 filename: {file_name:?} in /boot");
1830+
};
1831+
1832+
// Skip any entry that starts with a protected prefix,
1833+
// as we also need to protect loader.0 or loader.1
1834+
if protected_dirs.iter().any(|p| file_name.starts_with(p)) {
1835+
continue;
1836+
}
1837+
1838+
let etype = entry.file_type()?;
1839+
if etype == FileType::dir() {
1840+
// Open the directory and remove its contents
1841+
if let Some(subdir) = bootdir.open_dir_noxdev(&file_name)? {
1842+
remove_all_in_dir_no_xdev(&subdir, false)
1843+
.with_context(|| format!("Removing directory contents: {}", file_name))?;
1844+
}
1845+
} else {
1846+
bootdir
1847+
.remove_file_optional(&file_name)
1848+
.with_context(|| format!("Removing file: {}", file_name))?;
1849+
}
1850+
}
1851+
Ok(())
1852+
}
1853+
18181854
/// Remove all entries in a directory, but do not traverse across distinct devices.
18191855
/// If mount_err is true, then an error is returned if a mount point is found;
18201856
/// otherwise it is silently ignored.
@@ -1838,29 +1874,22 @@ fn remove_all_in_dir_no_xdev(d: &Dir, mount_err: bool) -> Result<()> {
18381874
}
18391875

18401876
#[context("Removing boot directory content")]
1841-
fn clean_boot_directories(rootfs: &Dir, is_ostree: bool) -> Result<()> {
1877+
fn clean_boot_directories(rootfs: &Dir) -> Result<()> {
18421878
let bootdir =
18431879
crate::utils::open_dir_remount_rw(rootfs, BOOT.into()).context("Opening /boot")?;
18441880

1845-
if is_ostree {
1846-
// On ostree systems, the boot directory already has our desired format, we should only
1847-
// remove the bootupd-state.json file to avoid bootupctl complaining it already exists.
1848-
bootdir
1849-
.remove_file_optional("bootupd-state.json")
1850-
.context("removing bootupd-state.json")?;
1851-
} else {
1852-
// This should not remove /boot/efi note.
1853-
remove_all_in_dir_no_xdev(&bootdir, false).context("Emptying /boot")?;
1854-
// TODO: Discover the ESP the same way bootupd does it; we should also
1855-
// support not wiping the ESP.
1856-
if ARCH_USES_EFI {
1857-
if let Some(efidir) = bootdir
1858-
.open_dir_optional(crate::bootloader::EFI_DIR)
1859-
.context("Opening /boot/efi")?
1860-
{
1861-
remove_all_in_dir_no_xdev(&efidir, false)
1862-
.context("Emptying EFI system partition")?;
1863-
}
1881+
// This should not remove /boot/efi note.
1882+
remove_all_except_loader_dirs(&bootdir).context("Emptying /boot except protected dirs")?;
1883+
1884+
// TODO: Discover the ESP the same way bootupd does it; we should also
1885+
// support not wiping the ESP.
1886+
if ARCH_USES_EFI {
1887+
if let Some(efidir) = bootdir
1888+
.open_dir_optional(crate::bootloader::EFI_DIR)
1889+
.context("Opening /boot/efi")?
1890+
{
1891+
remove_all_in_dir_no_xdev(&efidir, false)
1892+
.context("Emptying EFI system partition")?;
18641893
}
18651894
}
18661895

@@ -2068,7 +2097,7 @@ pub(crate) async fn install_to_filesystem(
20682097
}
20692098
// Find boot under /
20702099
Some(ReplaceMode::Alongside) => {
2071-
clean_boot_directories(&target_rootfs_fd, is_already_ostree)?
2100+
clean_boot_directories(&target_rootfs_fd)?
20722101
}
20732102
None => require_empty_rootdir(&target_rootfs_fd)?,
20742103
}

0 commit comments

Comments
 (0)