@@ -1691,7 +1691,7 @@ pub(crate) fn setup_composefs_bls_boot(
1691
1691
) -> Result < String > {
1692
1692
let id_hex = id. to_hex ( ) ;
1693
1693
1694
- let ( root_path, cmdline_refs) = match setup_type {
1694
+ let ( root_path, esp_device , cmdline_refs) = match setup_type {
1695
1695
BootSetupType :: Setup ( ( root_setup, state) ) => {
1696
1696
// root_setup.kargs has [root=UUID=<UUID>, "rw"]
1697
1697
let mut cmdline_options = String :: from ( root_setup. kargs . join ( " " ) ) ;
@@ -1705,23 +1705,60 @@ pub(crate) fn setup_composefs_bls_boot(
1705
1705
}
1706
1706
} ;
1707
1707
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
+ )
1709
1721
}
1710
1722
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
+ }
1720
1744
} ;
1721
1745
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
+
1723
1759
let is_upgrade = matches ! ( setup_type, BootSetupType :: Upgrade ) ;
1724
1760
1761
+ let efi_dir = mounted_esp. join ( format ! ( "EFI/Linux" ) ) ;
1725
1762
let ( bls_config, boot_digest) = match & entry {
1726
1763
ComposefsBootEntry :: Type1 ( ..) => unimplemented ! ( ) ,
1727
1764
ComposefsBootEntry :: Type2 ( ..) => unimplemented ! ( ) ,
@@ -1735,16 +1772,18 @@ pub(crate) fn setup_composefs_bls_boot(
1735
1772
bls_config. title = Some ( id_hex. clone ( ) ) ;
1736
1773
bls_config. sort_key = Some ( "1" . into ( ) ) ;
1737
1774
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" ) ] ;
1740
1777
bls_config. options = Some ( cmdline_refs) ;
1741
1778
bls_config. extra = HashMap :: new ( ) ;
1742
1779
1743
1780
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" ) ] ;
1746
1783
} 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) ?;
1748
1787
}
1749
1788
1750
1789
( bls_config, boot_digest)
@@ -1757,43 +1796,57 @@ pub(crate) fn setup_composefs_bls_boot(
1757
1796
1758
1797
// This will be atomically renamed to 'loader/entries' on shutdown/reboot
1759
1798
(
1760
- boot_dir . join ( format ! ( "loader/{STAGED_BOOT_LOADER_ENTRIES}" ) ) ,
1799
+ efi_dir . join ( format ! ( "loader/{STAGED_BOOT_LOADER_ENTRIES}" ) ) ,
1761
1800
Some ( booted_bls) ,
1762
1801
)
1763
1802
} else {
1764
- ( boot_dir . join ( format ! ( "loader/{BOOT_LOADER_ENTRIES}" ) ) , None )
1803
+ ( efi_dir . join ( format ! ( "loader/{BOOT_LOADER_ENTRIES}" ) ) , None )
1765
1804
} ;
1766
1805
1767
1806
create_dir_all ( & entries_path) . with_context ( || format ! ( "Creating {:?}" , entries_path) ) ?;
1768
1807
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:?}" ) ) ?;
1781
1813
1782
- if let Some ( booted_bls) = booted_bls {
1783
1814
loader_entries_dir. atomic_write (
1784
1815
// SAFETY: We set sort_key above
1785
1816
format ! (
1786
1817
"bootc-composefs-{}.conf" ,
1787
- booted_bls . sort_key. as_ref( ) . unwrap( )
1818
+ bls_config . sort_key. as_ref( ) . unwrap( )
1788
1819
) ,
1789
- booted_bls . to_string ( ) . as_bytes ( ) ,
1820
+ bls_config . to_string ( ) . as_bytes ( ) ,
1790
1821
) ?;
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" ) ?;
1791
1838
}
1792
1839
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
+ }
1797
1850
1798
1851
Ok ( boot_digest)
1799
1852
}
0 commit comments