@@ -9,7 +9,9 @@ use std::sync::Arc;
9
9
use anyhow:: { Context , Result } ;
10
10
use camino:: Utf8Path ;
11
11
use camino:: Utf8PathBuf ;
12
+ use cap_std:: fs:: Dir ;
12
13
use cap_std_ext:: cap_std;
14
+ use cap_std_ext:: prelude:: CapStdExtDirExt ;
13
15
use clap:: ArgEnum ;
14
16
use fn_error_context:: context;
15
17
use ostree:: gio;
@@ -454,6 +456,7 @@ fn skopeo_supports_containers_storage() -> Result<bool> {
454
456
struct RootSetup {
455
457
device : Utf8PathBuf ,
456
458
rootfs : Utf8PathBuf ,
459
+ rootfs_fd : Dir ,
457
460
bootfs_type : Filesystem ,
458
461
boot_uuid : uuid:: Uuid ,
459
462
kargs : Vec < String > ,
@@ -601,6 +604,7 @@ fn install_create_rootfs(state: &State) -> Result<RootSetup> {
601
604
602
605
mount ( rootdev, & rootfs) ?;
603
606
lsm_label ( & rootfs, "/" . into ( ) , false ) ?;
607
+ let rootfs_fd = Dir :: open_ambient_dir ( & rootfs, cap_std:: ambient_authority ( ) ) ?;
604
608
let bootfs = rootfs. join ( "boot" ) ;
605
609
std:: fs:: create_dir ( & bootfs) . context ( "Creating /boot" ) ?;
606
610
// The underlying directory on the root should be labeled
@@ -623,6 +627,7 @@ fn install_create_rootfs(state: &State) -> Result<RootSetup> {
623
627
Ok ( RootSetup {
624
628
device,
625
629
rootfs,
630
+ rootfs_fd,
626
631
bootfs_type,
627
632
boot_uuid,
628
633
kargs,
@@ -751,12 +756,19 @@ pub(crate) async fn install(opts: InstallOpts) -> Result<()> {
751
756
kargs. push ( crate :: bootloader:: IGNITION_VARIABLE ) ;
752
757
}
753
758
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
+ }
760
772
761
773
crate :: bootloader:: install_via_bootupd ( & rootfs. device , & rootfs. rootfs , & rootfs. boot_uuid ) ?;
762
774
@@ -792,10 +804,14 @@ pub(crate) async fn install(opts: InstallOpts) -> Result<()> {
792
804
}
793
805
}
794
806
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
+
795
811
Task :: new_and_run (
796
812
"Unmounting filesystems" ,
797
813
"umount" ,
798
- [ "-R" , rootfs . rootfs . as_str ( ) ] ,
814
+ [ "-R" , rootfs_path . as_str ( ) ] ,
799
815
) ?;
800
816
801
817
println ! ( "Installation complete!" ) ;
0 commit comments