@@ -1122,6 +1122,8 @@ pub(crate) struct RootSetup {
11221122 pub ( crate ) physical_root_path : Utf8PathBuf ,
11231123 /// Directory file descriptor for the above physical root.
11241124 pub ( crate ) physical_root : Dir ,
1125+ /// Target root path /target.
1126+ pub ( crate ) target_root_path : Option < Utf8PathBuf > ,
11251127 pub ( crate ) rootfs_uuid : Option < String > ,
11261128 /// True if we should skip finalizing
11271129 skip_finalize : bool ,
@@ -1577,7 +1579,10 @@ async fn install_with_sysroot(
15771579 Bootloader :: Grub => {
15781580 crate :: bootloader:: install_via_bootupd (
15791581 & rootfs. device_info ,
1580- & rootfs. physical_root_path ,
1582+ & rootfs
1583+ . target_root_path
1584+ . clone ( )
1585+ . unwrap_or ( rootfs. physical_root_path . clone ( ) ) ,
15811586 & state. config_opts ,
15821587 Some ( & deployment_path. as_str ( ) ) ,
15831588 ) ?;
@@ -2112,6 +2117,18 @@ pub(crate) async fn install_to_filesystem(
21122117 . context ( "Mounting host / to {ALONGSIDE_ROOT_MOUNT}" ) ?;
21132118 }
21142119
2120+ let target_root_path = fsopts. root_path . clone ( ) ;
2121+ // Get a file descriptor for the root path /target
2122+ let target_rootfs_fd =
2123+ Dir :: open_ambient_dir ( & target_root_path, cap_std:: ambient_authority ( ) )
2124+ . with_context ( || format ! ( "Opening target root directory {target_root_path}" ) ) ?;
2125+
2126+ tracing:: debug!( "Target root filesystem: {target_root_path}" ) ;
2127+
2128+ if let Some ( false ) = target_rootfs_fd. is_mountpoint ( "." ) ? {
2129+ anyhow:: bail!( "Not a mountpoint: {target_root_path}" ) ;
2130+ }
2131+
21152132 // Check that the target is a directory
21162133 {
21172134 let root_path = & fsopts. root_path ;
@@ -2125,10 +2142,7 @@ pub(crate) async fn install_to_filesystem(
21252142
21262143 // Check to see if this happens to be the real host root
21272144 if !fsopts. acknowledge_destructive {
2128- let root_path = & fsopts. root_path ;
2129- let rootfs_fd = Dir :: open_ambient_dir ( root_path, cap_std:: ambient_authority ( ) )
2130- . with_context ( || format ! ( "Opening target root directory {root_path}" ) ) ?;
2131- warn_on_host_root ( & rootfs_fd) ?;
2145+ warn_on_host_root ( & target_rootfs_fd) ?;
21322146 }
21332147
21342148 // If we're installing to an ostree root, then find the physical root from
@@ -2144,7 +2158,8 @@ pub(crate) async fn install_to_filesystem(
21442158 } ;
21452159
21462160 // Get a file descriptor for the root path
2147- let rootfs_fd = {
2161+ // It will be /target/sysroot on ostree OS, or will be /target
2162+ let rootfs_fd = if is_already_ostree {
21482163 let root_path = & fsopts. root_path ;
21492164 let rootfs_fd = Dir :: open_ambient_dir ( & fsopts. root_path , cap_std:: ambient_authority ( ) )
21502165 . with_context ( || format ! ( "Opening target root directory {root_path}" ) ) ?;
@@ -2155,6 +2170,8 @@ pub(crate) async fn install_to_filesystem(
21552170 anyhow:: bail!( "Not a mountpoint: {root_path}" ) ;
21562171 }
21572172 rootfs_fd
2173+ } else {
2174+ target_rootfs_fd. try_clone ( ) ?
21582175 } ;
21592176
21602177 match fsopts. replace {
@@ -2164,7 +2181,9 @@ pub(crate) async fn install_to_filesystem(
21642181 tokio:: task:: spawn_blocking ( move || remove_all_in_dir_no_xdev ( & rootfs_fd, true ) )
21652182 . await ??;
21662183 }
2167- Some ( ReplaceMode :: Alongside ) => clean_boot_directories ( & rootfs_fd, is_already_ostree) ?,
2184+ Some ( ReplaceMode :: Alongside ) => {
2185+ clean_boot_directories ( & target_rootfs_fd, is_already_ostree) ?
2186+ }
21682187 None => require_empty_rootdir ( & rootfs_fd) ?,
21692188 }
21702189
@@ -2209,7 +2228,7 @@ pub(crate) async fn install_to_filesystem(
22092228
22102229 let boot_is_mount = {
22112230 let root_dev = rootfs_fd. dir_metadata ( ) ?. dev ( ) ;
2212- let boot_dev = rootfs_fd
2231+ let boot_dev = target_rootfs_fd
22132232 . symlink_metadata_optional ( BOOT ) ?
22142233 . ok_or_else ( || {
22152234 anyhow ! ( "No /{BOOT} directory found in root; this is is currently required" )
@@ -2220,9 +2239,10 @@ pub(crate) async fn install_to_filesystem(
22202239 } ;
22212240 // Find the UUID of /boot because we need it for GRUB.
22222241 let boot_uuid = if boot_is_mount {
2223- let boot_path = fsopts. root_path . join ( BOOT ) ;
2242+ let boot_path = target_root_path. join ( BOOT ) ;
2243+ tracing:: debug!( "boot_path={boot_path}" ) ;
22242244 let u = bootc_mount:: inspect_filesystem ( & boot_path)
2225- . context ( "Inspecting /{BOOT}" ) ?
2245+ . with_context ( || format ! ( "Inspecting /{BOOT}" ) ) ?
22262246 . uuid
22272247 . ok_or_else ( || anyhow ! ( "No UUID found for /{BOOT}" ) ) ?;
22282248 Some ( u)
@@ -2309,6 +2329,7 @@ pub(crate) async fn install_to_filesystem(
23092329 device_info,
23102330 physical_root_path : fsopts. root_path ,
23112331 physical_root : rootfs_fd,
2332+ target_root_path : Some ( target_root_path. clone ( ) ) ,
23122333 rootfs_uuid : inspect. uuid . clone ( ) ,
23132334 boot,
23142335 kargs,
0 commit comments