@@ -1095,6 +1095,8 @@ pub(crate) struct RootSetup {
10951095 pub ( crate ) physical_root_path : Utf8PathBuf ,
10961096 /// Directory file descriptor for the above physical root.
10971097 pub ( crate ) physical_root : Dir ,
1098+ /// Target root path /target.
1099+ pub ( crate ) target_root_path : Option < Utf8PathBuf > ,
10981100 pub ( crate ) rootfs_uuid : Option < String > ,
10991101 /// True if we should skip finalizing
11001102 skip_finalize : bool ,
@@ -1549,7 +1551,10 @@ async fn install_with_sysroot(
15491551 Bootloader :: Grub => {
15501552 crate :: bootloader:: install_via_bootupd (
15511553 & rootfs. device_info ,
1552- & rootfs. physical_root_path ,
1554+ & rootfs
1555+ . target_root_path
1556+ . clone ( )
1557+ . unwrap_or ( rootfs. physical_root_path . clone ( ) ) ,
15531558 & state. config_opts ,
15541559 Some ( & deployment_path. as_str ( ) ) ,
15551560 ) ?;
@@ -2050,6 +2055,18 @@ pub(crate) async fn install_to_filesystem(
20502055 . context ( "Mounting host / to {ALONGSIDE_ROOT_MOUNT}" ) ?;
20512056 }
20522057
2058+ let target_root_path = fsopts. root_path . clone ( ) ;
2059+ // Get a file descriptor for the root path /target
2060+ let target_rootfs_fd =
2061+ Dir :: open_ambient_dir ( & target_root_path, cap_std:: ambient_authority ( ) )
2062+ . with_context ( || format ! ( "Opening target root directory {target_root_path}" ) ) ?;
2063+
2064+ tracing:: debug!( "Target root filesystem: {target_root_path}" ) ;
2065+
2066+ if let Some ( false ) = target_rootfs_fd. is_mountpoint ( "." ) ? {
2067+ anyhow:: bail!( "Not a mountpoint: {target_root_path}" ) ;
2068+ }
2069+
20532070 // Check that the target is a directory
20542071 {
20552072 let root_path = & fsopts. root_path ;
@@ -2063,10 +2080,7 @@ pub(crate) async fn install_to_filesystem(
20632080
20642081 // Check to see if this happens to be the real host root
20652082 if !fsopts. acknowledge_destructive {
2066- let root_path = & fsopts. root_path ;
2067- let rootfs_fd = Dir :: open_ambient_dir ( root_path, cap_std:: ambient_authority ( ) )
2068- . with_context ( || format ! ( "Opening target root directory {root_path}" ) ) ?;
2069- warn_on_host_root ( & rootfs_fd) ?;
2083+ warn_on_host_root ( & target_rootfs_fd) ?;
20702084 }
20712085
20722086 // If we're installing to an ostree root, then find the physical root from
@@ -2082,7 +2096,8 @@ pub(crate) async fn install_to_filesystem(
20822096 } ;
20832097
20842098 // Get a file descriptor for the root path
2085- let rootfs_fd = {
2099+ // It will be /target/sysroot on ostree OS, or will be /target
2100+ let rootfs_fd = if is_already_ostree {
20862101 let root_path = & fsopts. root_path ;
20872102 let rootfs_fd = Dir :: open_ambient_dir ( & fsopts. root_path , cap_std:: ambient_authority ( ) )
20882103 . with_context ( || format ! ( "Opening target root directory {root_path}" ) ) ?;
@@ -2093,6 +2108,8 @@ pub(crate) async fn install_to_filesystem(
20932108 anyhow:: bail!( "Not a mountpoint: {root_path}" ) ;
20942109 }
20952110 rootfs_fd
2111+ } else {
2112+ target_rootfs_fd. clone ( )
20962113 } ;
20972114
20982115 match fsopts. replace {
@@ -2102,7 +2119,9 @@ pub(crate) async fn install_to_filesystem(
21022119 tokio:: task:: spawn_blocking ( move || remove_all_in_dir_no_xdev ( & rootfs_fd, true ) )
21032120 . await ??;
21042121 }
2105- Some ( ReplaceMode :: Alongside ) => clean_boot_directories ( & rootfs_fd, is_already_ostree) ?,
2122+ Some ( ReplaceMode :: Alongside ) => {
2123+ clean_boot_directories ( & target_rootfs_fd, is_already_ostree) ?
2124+ }
21062125 None => require_empty_rootdir ( & rootfs_fd) ?,
21072126 }
21082127
@@ -2147,7 +2166,7 @@ pub(crate) async fn install_to_filesystem(
21472166
21482167 let boot_is_mount = {
21492168 let root_dev = rootfs_fd. dir_metadata ( ) ?. dev ( ) ;
2150- let boot_dev = rootfs_fd
2169+ let boot_dev = target_rootfs_fd
21512170 . symlink_metadata_optional ( BOOT ) ?
21522171 . ok_or_else ( || {
21532172 anyhow ! ( "No /{BOOT} directory found in root; this is is currently required" )
@@ -2158,9 +2177,10 @@ pub(crate) async fn install_to_filesystem(
21582177 } ;
21592178 // Find the UUID of /boot because we need it for GRUB.
21602179 let boot_uuid = if boot_is_mount {
2161- let boot_path = fsopts. root_path . join ( BOOT ) ;
2180+ let boot_path = target_root_path. join ( BOOT ) ;
2181+ tracing:: debug!( "boot_path={boot_path}" ) ;
21622182 let u = bootc_mount:: inspect_filesystem ( & boot_path)
2163- . context ( "Inspecting /{BOOT}" ) ?
2183+ . with_context ( || format ! ( "Inspecting /{BOOT}" ) ) ?
21642184 . uuid
21652185 . ok_or_else ( || anyhow ! ( "No UUID found for /{BOOT}" ) ) ?;
21662186 Some ( u)
@@ -2241,6 +2261,7 @@ pub(crate) async fn install_to_filesystem(
22412261 device_info,
22422262 physical_root_path : fsopts. root_path ,
22432263 physical_root : rootfs_fd,
2264+ target_root_path : Some ( target_root_path. clone ( ) ) ,
22442265 rootfs_uuid : inspect. uuid . clone ( ) ,
22452266 boot,
22462267 kargs,
0 commit comments