@@ -1084,6 +1084,8 @@ pub(crate) struct RootSetup {
10841084 pub ( crate ) physical_root_path : Utf8PathBuf ,
10851085 /// Directory file descriptor for the above physical root.
10861086 pub ( crate ) physical_root : Dir ,
1087+ /// Target root path /target.
1088+ pub ( crate ) target_root_path : Option < Utf8PathBuf > ,
10871089 pub ( crate ) rootfs_uuid : Option < String > ,
10881090 /// True if we should skip finalizing
10891091 skip_finalize : bool ,
@@ -1538,7 +1540,10 @@ async fn install_with_sysroot(
15381540 Bootloader :: Grub => {
15391541 crate :: bootloader:: install_via_bootupd (
15401542 & rootfs. device_info ,
1541- & rootfs. physical_root_path ,
1543+ & rootfs
1544+ . target_root_path
1545+ . clone ( )
1546+ . unwrap_or ( rootfs. physical_root_path . clone ( ) ) ,
15421547 & state. config_opts ,
15431548 Some ( & deployment_path. as_str ( ) ) ,
15441549 ) ?;
@@ -2039,6 +2044,18 @@ pub(crate) async fn install_to_filesystem(
20392044 . context ( "Mounting host / to {ALONGSIDE_ROOT_MOUNT}" ) ?;
20402045 }
20412046
2047+ let target_root_path = fsopts. root_path . clone ( ) ;
2048+ // Get a file descriptor for the root path /target
2049+ let target_rootfs_fd =
2050+ Dir :: open_ambient_dir ( & target_root_path, cap_std:: ambient_authority ( ) )
2051+ . with_context ( || format ! ( "Opening target root directory {target_root_path}" ) ) ?;
2052+
2053+ tracing:: debug!( "Target root filesystem: {target_root_path}" ) ;
2054+
2055+ if let Some ( false ) = target_rootfs_fd. is_mountpoint ( "." ) ? {
2056+ anyhow:: bail!( "Not a mountpoint: {target_root_path}" ) ;
2057+ }
2058+
20422059 // Check that the target is a directory
20432060 {
20442061 let root_path = & fsopts. root_path ;
@@ -2052,10 +2069,7 @@ pub(crate) async fn install_to_filesystem(
20522069
20532070 // Check to see if this happens to be the real host root
20542071 if !fsopts. acknowledge_destructive {
2055- let root_path = & fsopts. root_path ;
2056- let rootfs_fd = Dir :: open_ambient_dir ( root_path, cap_std:: ambient_authority ( ) )
2057- . with_context ( || format ! ( "Opening target root directory {root_path}" ) ) ?;
2058- warn_on_host_root ( & rootfs_fd) ?;
2072+ warn_on_host_root ( & target_rootfs_fd) ?;
20592073 }
20602074
20612075 // If we're installing to an ostree root, then find the physical root from
@@ -2071,7 +2085,8 @@ pub(crate) async fn install_to_filesystem(
20712085 } ;
20722086
20732087 // Get a file descriptor for the root path
2074- let rootfs_fd = {
2088+ // It will be /target/sysroot on ostree OS, or will be /target
2089+ let rootfs_fd = if is_already_ostree {
20752090 let root_path = & fsopts. root_path ;
20762091 let rootfs_fd = Dir :: open_ambient_dir ( & fsopts. root_path , cap_std:: ambient_authority ( ) )
20772092 . with_context ( || format ! ( "Opening target root directory {root_path}" ) ) ?;
@@ -2082,6 +2097,8 @@ pub(crate) async fn install_to_filesystem(
20822097 anyhow:: bail!( "Not a mountpoint: {root_path}" ) ;
20832098 }
20842099 rootfs_fd
2100+ } else {
2101+ target_rootfs_fd. clone ( )
20852102 } ;
20862103
20872104 match fsopts. replace {
@@ -2091,7 +2108,9 @@ pub(crate) async fn install_to_filesystem(
20912108 tokio:: task:: spawn_blocking ( move || remove_all_in_dir_no_xdev ( & rootfs_fd, true ) )
20922109 . await ??;
20932110 }
2094- Some ( ReplaceMode :: Alongside ) => clean_boot_directories ( & rootfs_fd, is_already_ostree) ?,
2111+ Some ( ReplaceMode :: Alongside ) => {
2112+ clean_boot_directories ( & target_rootfs_fd, is_already_ostree) ?
2113+ }
20952114 None => require_empty_rootdir ( & rootfs_fd) ?,
20962115 }
20972116
@@ -2136,7 +2155,7 @@ pub(crate) async fn install_to_filesystem(
21362155
21372156 let boot_is_mount = {
21382157 let root_dev = rootfs_fd. dir_metadata ( ) ?. dev ( ) ;
2139- let boot_dev = rootfs_fd
2158+ let boot_dev = target_rootfs_fd
21402159 . symlink_metadata_optional ( BOOT ) ?
21412160 . ok_or_else ( || {
21422161 anyhow ! ( "No /{BOOT} directory found in root; this is is currently required" )
@@ -2147,9 +2166,10 @@ pub(crate) async fn install_to_filesystem(
21472166 } ;
21482167 // Find the UUID of /boot because we need it for GRUB.
21492168 let boot_uuid = if boot_is_mount {
2150- let boot_path = fsopts. root_path . join ( BOOT ) ;
2169+ let boot_path = target_root_path. join ( BOOT ) ;
2170+ tracing:: debug!( "boot_path={boot_path}" ) ;
21512171 let u = bootc_mount:: inspect_filesystem ( & boot_path)
2152- . context ( "Inspecting /{BOOT}" ) ?
2172+ . with_context ( || format ! ( "Inspecting /{BOOT}" ) ) ?
21532173 . uuid
21542174 . ok_or_else ( || anyhow ! ( "No UUID found for /{BOOT}" ) ) ?;
21552175 Some ( u)
@@ -2230,6 +2250,7 @@ pub(crate) async fn install_to_filesystem(
22302250 device_info,
22312251 physical_root_path : fsopts. root_path ,
22322252 physical_root : rootfs_fd,
2253+ target_root_path : Some ( target_root_path. clone ( ) ) ,
22332254 rootfs_uuid : inspect. uuid . clone ( ) ,
22342255 boot,
22352256 kargs,
0 commit comments