@@ -1073,6 +1073,7 @@ pub(crate) struct RootSetup {
10731073 pub ( crate ) physical_root_path : Utf8PathBuf ,
10741074 /// Directory file descriptor for the above physical root.
10751075 pub ( crate ) physical_root : Dir ,
1076+ pub ( crate ) target_root_path : Option < Utf8PathBuf > ,
10761077 pub ( crate ) rootfs_uuid : Option < String > ,
10771078 /// True if we should skip finalizing
10781079 skip_finalize : bool ,
@@ -1514,7 +1515,10 @@ async fn install_with_sysroot(
15141515 Bootloader :: Grub => {
15151516 crate :: bootloader:: install_via_bootupd (
15161517 & rootfs. device_info ,
1517- & rootfs. physical_root_path ,
1518+ & rootfs
1519+ . target_root_path
1520+ . clone ( )
1521+ . unwrap_or ( rootfs. physical_root_path . clone ( ) ) ,
15181522 & state. config_opts ,
15191523 Some ( & deployment_path. as_str ( ) ) ,
15201524 ) ?;
@@ -1986,6 +1990,7 @@ pub(crate) async fn install_to_filesystem(
19861990 . context ( "Mounting host / to {ALONGSIDE_ROOT_MOUNT}" ) ?;
19871991 }
19881992
1993+ let target_root_path = & fsopts. root_path . clone ( ) ;
19891994 // Check that the target is a directory
19901995 {
19911996 let root_path = & fsopts. root_path ;
@@ -2005,6 +2010,20 @@ pub(crate) async fn install_to_filesystem(
20052010 warn_on_host_root ( & rootfs_fd) ?;
20062011 }
20072012
2013+ // Get a file descriptor for the root path /target
2014+ // This is needed to find boot dev
2015+ let target_rootfs_fd = {
2016+ let rootfs_fd = Dir :: open_ambient_dir ( & target_root_path, cap_std:: ambient_authority ( ) )
2017+ . with_context ( || format ! ( "Opening target root directory {target_root_path}" ) ) ?;
2018+
2019+ tracing:: debug!( "Root filesystem: {target_root_path}" ) ;
2020+
2021+ if let Some ( false ) = rootfs_fd. is_mountpoint ( "." ) ? {
2022+ anyhow:: bail!( "Not a mountpoint: {target_root_path}" ) ;
2023+ }
2024+ rootfs_fd
2025+ } ;
2026+
20082027 // If we're installing to an ostree root, then find the physical root from
20092028 // the deployment root.
20102029 let possible_physical_root = fsopts. root_path . join ( "sysroot" ) ;
@@ -2018,9 +2037,9 @@ pub(crate) async fn install_to_filesystem(
20182037 } ;
20192038
20202039 // Get a file descriptor for the root path
2021- let rootfs_fd = {
2040+ let rootfs_fd = if fsopts . root_path . ends_with ( "sysroot" ) {
20222041 let root_path = & fsopts. root_path ;
2023- let rootfs_fd = Dir :: open_ambient_dir ( & fsopts . root_path , cap_std:: ambient_authority ( ) )
2042+ let rootfs_fd = Dir :: open_ambient_dir ( root_path, cap_std:: ambient_authority ( ) )
20242043 . with_context ( || format ! ( "Opening target root directory {root_path}" ) ) ?;
20252044
20262045 tracing:: debug!( "Root filesystem: {root_path}" ) ;
@@ -2029,6 +2048,8 @@ pub(crate) async fn install_to_filesystem(
20292048 anyhow:: bail!( "Not a mountpoint: {root_path}" ) ;
20302049 }
20312050 rootfs_fd
2051+ } else {
2052+ target_rootfs_fd. try_clone ( ) ?
20322053 } ;
20332054
20342055 match fsopts. replace {
@@ -2038,8 +2059,11 @@ pub(crate) async fn install_to_filesystem(
20382059 tokio:: task:: spawn_blocking ( move || remove_all_in_dir_no_xdev ( & rootfs_fd, true ) )
20392060 . await ??;
20402061 }
2041- Some ( ReplaceMode :: Alongside ) => clean_boot_directories ( & rootfs_fd, is_already_ostree) ?,
2042- None => require_empty_rootdir ( & rootfs_fd) ?,
2062+ // Find boot under /
2063+ Some ( ReplaceMode :: Alongside ) => {
2064+ clean_boot_directories ( & target_rootfs_fd, is_already_ostree) ?
2065+ }
2066+ None => require_empty_rootdir ( & target_rootfs_fd) ?,
20432067 }
20442068
20452069 // Gather data about the root filesystem
@@ -2083,7 +2107,7 @@ pub(crate) async fn install_to_filesystem(
20832107
20842108 let boot_is_mount = {
20852109 let root_dev = rootfs_fd. dir_metadata ( ) ?. dev ( ) ;
2086- let boot_dev = rootfs_fd
2110+ let boot_dev = target_rootfs_fd
20872111 . symlink_metadata_optional ( BOOT ) ?
20882112 . ok_or_else ( || {
20892113 anyhow ! ( "No /{BOOT} directory found in root; this is is currently required" )
@@ -2094,9 +2118,10 @@ pub(crate) async fn install_to_filesystem(
20942118 } ;
20952119 // Find the UUID of /boot because we need it for GRUB.
20962120 let boot_uuid = if boot_is_mount {
2097- let boot_path = fsopts. root_path . join ( BOOT ) ;
2121+ let boot_path = target_root_path. join ( BOOT ) ;
2122+ tracing:: debug!( "boot_path={boot_path}" ) ;
20982123 let u = bootc_mount:: inspect_filesystem ( & boot_path)
2099- . context ( "Inspecting /{BOOT}" ) ?
2124+ . with_context ( || format ! ( "Inspecting /{BOOT}" ) ) ?
21002125 . uuid
21012126 . ok_or_else ( || anyhow ! ( "No UUID found for /{BOOT}" ) ) ?;
21022127 Some ( u)
@@ -2175,6 +2200,7 @@ pub(crate) async fn install_to_filesystem(
21752200 device_info,
21762201 physical_root_path : fsopts. root_path ,
21772202 physical_root : rootfs_fd,
2203+ target_root_path : Some ( target_root_path. clone ( ) ) ,
21782204 rootfs_uuid : inspect. uuid . clone ( ) ,
21792205 boot,
21802206 kargs,
0 commit comments