@@ -659,6 +659,27 @@ fn gather_source_data() -> Result<SourceData> {
659
659
Ok ( SourceData { commit, selinux } )
660
660
}
661
661
662
+ /// Trim, flush outstanding writes, and freeze/thaw the target mounted filesystem;
663
+ /// these steps prepare the filesystem for its first booted use.
664
+ pub ( crate ) fn finalize_filesystem ( fs : & Utf8Path ) -> Result < ( ) > {
665
+ let fsname = fs. file_name ( ) . unwrap ( ) ;
666
+ // fstrim ensures the underlying block device knows about unused space
667
+ Task :: new_and_run ( format ! ( "Trimming {fsname}" ) , "fstrim" , [ "-v" , fs. as_str ( ) ] ) ?;
668
+ // Remounting readonly will flush outstanding writes and ensure we error out if there were background
669
+ // writeback problems.
670
+ Task :: new ( & format ! ( "Finalizing filesystem {fsname}" ) , "mount" )
671
+ . args ( [ "-o" , "remount,ro" , fs. as_str ( ) ] )
672
+ . run ( ) ?;
673
+ // Finally, freezing (and thawing) the filesystem will flush the journal, which means the next boot is clean.
674
+ for a in [ "-f" , "-u" ] {
675
+ Task :: new ( "Flushing filesystem journal" , "xfs_freeze" )
676
+ . quiet ( )
677
+ . args ( [ a, fs. as_str ( ) ] )
678
+ . run ( ) ?;
679
+ }
680
+ Ok ( ( ) )
681
+ }
682
+
662
683
/// Implementation of the `bootc install` CLI command.
663
684
pub ( crate ) async fn install ( opts : InstallOpts ) -> Result < ( ) > {
664
685
// This command currently *must* be run inside a privileged container.
@@ -780,25 +801,17 @@ pub(crate) async fn install(opts: InstallOpts) -> Result<()> {
780
801
println ! ( "Installed Ignition config from {ignition_file}" ) ;
781
802
}
782
803
804
+ // ostree likes to have the immutable bit on the physical sysroot to ensure
805
+ // that it doesn't accumulate junk; all system state should be in deployments.
783
806
Task :: new ( "Setting root immutable bit" , "chattr" )
784
807
. root ( & rootfs. rootfs_fd ) ?
785
808
. args ( [ "+i" , "." ] )
786
809
. run ( ) ?;
787
810
788
- Task :: new_and_run ( "Trimming filesystems" , "fstrim" , [ "-a" , "-v" ] ) ?;
789
-
811
+ // Finalize mounted filesystems
790
812
let bootfs = rootfs. rootfs . join ( "boot" ) ;
791
813
for fs in [ bootfs. as_path ( ) , rootfs. rootfs . as_path ( ) ] {
792
- let fsname = fs. file_name ( ) . unwrap ( ) ;
793
- Task :: new ( & format ! ( "Finalizing filesystem {fsname}" ) , "mount" )
794
- . args ( [ "-o" , "remount,ro" , fs. as_str ( ) ] )
795
- . run ( ) ?;
796
- for a in [ "-f" , "-u" ] {
797
- Task :: new ( "Flushing filesystem journal" , "xfs_freeze" )
798
- . quiet ( )
799
- . args ( [ a, fs. as_str ( ) ] )
800
- . run ( ) ?;
801
- }
814
+ finalize_filesystem ( fs) ?;
802
815
}
803
816
804
817
// Drop all data about the root except the path to ensure any file descriptors etc. are closed.
0 commit comments