Skip to content

Commit f0cf4b0

Browse files
authored
Merge pull request #46 from cgwalters/root-fd
install: Also hold a fd open on target root
2 parents 76939a7 + 18f7147 commit f0cf4b0

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

lib/src/install.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ use std::sync::Arc;
99
use anyhow::{Context, Result};
1010
use camino::Utf8Path;
1111
use camino::Utf8PathBuf;
12+
use cap_std::fs::Dir;
1213
use cap_std_ext::cap_std;
14+
use cap_std_ext::prelude::CapStdExtDirExt;
1315
use clap::ArgEnum;
1416
use fn_error_context::context;
1517
use ostree::gio;
@@ -454,6 +456,7 @@ fn skopeo_supports_containers_storage() -> Result<bool> {
454456
struct RootSetup {
455457
device: Utf8PathBuf,
456458
rootfs: Utf8PathBuf,
459+
rootfs_fd: Dir,
457460
bootfs_type: Filesystem,
458461
boot_uuid: uuid::Uuid,
459462
kargs: Vec<String>,
@@ -601,6 +604,7 @@ fn install_create_rootfs(state: &State) -> Result<RootSetup> {
601604

602605
mount(rootdev, &rootfs)?;
603606
lsm_label(&rootfs, "/".into(), false)?;
607+
let rootfs_fd = Dir::open_ambient_dir(&rootfs, cap_std::ambient_authority())?;
604608
let bootfs = rootfs.join("boot");
605609
std::fs::create_dir(&bootfs).context("Creating /boot")?;
606610
// The underlying directory on the root should be labeled
@@ -623,6 +627,7 @@ fn install_create_rootfs(state: &State) -> Result<RootSetup> {
623627
Ok(RootSetup {
624628
device,
625629
rootfs,
630+
rootfs_fd,
626631
bootfs_type,
627632
boot_uuid,
628633
kargs,
@@ -751,12 +756,19 @@ pub(crate) async fn install(opts: InstallOpts) -> Result<()> {
751756
kargs.push(crate::bootloader::IGNITION_VARIABLE);
752757
}
753758

754-
let aleph =
755-
initialize_ostree_root_from_self(&state, &container_state, &rootfs, kargs.as_slice())
756-
.await?;
757-
758-
let aleph = serde_json::to_string(&aleph)?;
759-
std::fs::write(rootfs.rootfs.join(BOOTC_ALEPH_PATH), aleph).context("Writing aleph version")?;
759+
// Write the aleph data that captures the system state at the time of provisioning for aid in future debugging.
760+
{
761+
let aleph =
762+
initialize_ostree_root_from_self(&state, &container_state, &rootfs, kargs.as_slice())
763+
.await?;
764+
rootfs
765+
.rootfs_fd
766+
.atomic_replace_with(BOOTC_ALEPH_PATH, |f| {
767+
serde_json::to_writer(f, &aleph)?;
768+
anyhow::Ok(())
769+
})
770+
.context("Writing aleph version")?;
771+
}
760772

761773
crate::bootloader::install_via_bootupd(&rootfs.device, &rootfs.rootfs, &rootfs.boot_uuid)?;
762774

@@ -792,10 +804,14 @@ pub(crate) async fn install(opts: InstallOpts) -> Result<()> {
792804
}
793805
}
794806

807+
// Drop all data about the root except the path to ensure any file descriptors etc. are closed.
808+
let rootfs_path = rootfs.rootfs.clone();
809+
drop(rootfs);
810+
795811
Task::new_and_run(
796812
"Unmounting filesystems",
797813
"umount",
798-
["-R", rootfs.rootfs.as_str()],
814+
["-R", rootfs_path.as_str()],
799815
)?;
800816

801817
println!("Installation complete!");

0 commit comments

Comments
 (0)