@@ -1080,6 +1080,7 @@ pub(crate) struct RootSetup {
10801080 pub ( crate ) physical_root_path : Utf8PathBuf ,
10811081 /// Directory file descriptor for the above physical root.
10821082 pub ( crate ) physical_root : Dir ,
1083+ pub ( crate ) target_root_path : Option < Utf8PathBuf > ,
10831084 pub ( crate ) rootfs_uuid : Option < String > ,
10841085 /// True if we should skip finalizing
10851086 skip_finalize : bool ,
@@ -1521,7 +1522,10 @@ async fn install_with_sysroot(
15211522 Bootloader :: Grub => {
15221523 crate :: bootloader:: install_via_bootupd (
15231524 & rootfs. device_info ,
1524- & rootfs. physical_root_path ,
1525+ & rootfs
1526+ . target_root_path
1527+ . clone ( )
1528+ . unwrap_or ( rootfs. physical_root_path . clone ( ) ) ,
15251529 & state. config_opts ,
15261530 Some ( & deployment_path. as_str ( ) ) ,
15271531 ) ?;
@@ -1993,6 +1997,7 @@ pub(crate) async fn install_to_filesystem(
19931997 . context ( "Mounting host / to {ALONGSIDE_ROOT_MOUNT}" ) ?;
19941998 }
19951999
2000+ let target_root_path = & fsopts. root_path . clone ( ) ;
19962001 // Check that the target is a directory
19972002 {
19982003 let root_path = & fsopts. root_path ;
@@ -2012,6 +2017,20 @@ pub(crate) async fn install_to_filesystem(
20122017 warn_on_host_root ( & rootfs_fd) ?;
20132018 }
20142019
2020+ // Get a file descriptor for the root path /target
2021+ // This is needed to find boot dev
2022+ let target_rootfs_fd = {
2023+ let rootfs_fd = Dir :: open_ambient_dir ( & target_root_path, cap_std:: ambient_authority ( ) )
2024+ . with_context ( || format ! ( "Opening target root directory {target_root_path}" ) ) ?;
2025+
2026+ tracing:: debug!( "Root filesystem: {target_root_path}" ) ;
2027+
2028+ if let Some ( false ) = rootfs_fd. is_mountpoint ( "." ) ? {
2029+ anyhow:: bail!( "Not a mountpoint: {target_root_path}" ) ;
2030+ }
2031+ rootfs_fd
2032+ } ;
2033+
20152034 // If we're installing to an ostree root, then find the physical root from
20162035 // the deployment root.
20172036 let possible_physical_root = fsopts. root_path . join ( "sysroot" ) ;
@@ -2025,9 +2044,9 @@ pub(crate) async fn install_to_filesystem(
20252044 } ;
20262045
20272046 // Get a file descriptor for the root path
2028- let rootfs_fd = {
2047+ let rootfs_fd = if fsopts . root_path . ends_with ( "sysroot" ) {
20292048 let root_path = & fsopts. root_path ;
2030- let rootfs_fd = Dir :: open_ambient_dir ( & fsopts . root_path , cap_std:: ambient_authority ( ) )
2049+ let rootfs_fd = Dir :: open_ambient_dir ( root_path, cap_std:: ambient_authority ( ) )
20312050 . with_context ( || format ! ( "Opening target root directory {root_path}" ) ) ?;
20322051
20332052 tracing:: debug!( "Root filesystem: {root_path}" ) ;
@@ -2036,6 +2055,8 @@ pub(crate) async fn install_to_filesystem(
20362055 anyhow:: bail!( "Not a mountpoint: {root_path}" ) ;
20372056 }
20382057 rootfs_fd
2058+ } else {
2059+ target_rootfs_fd. try_clone ( ) ?
20392060 } ;
20402061
20412062 match fsopts. replace {
@@ -2045,8 +2066,11 @@ pub(crate) async fn install_to_filesystem(
20452066 tokio:: task:: spawn_blocking ( move || remove_all_in_dir_no_xdev ( & rootfs_fd, true ) )
20462067 . await ??;
20472068 }
2048- Some ( ReplaceMode :: Alongside ) => clean_boot_directories ( & rootfs_fd, is_already_ostree) ?,
2049- None => require_empty_rootdir ( & rootfs_fd) ?,
2069+ // Find boot under /
2070+ Some ( ReplaceMode :: Alongside ) => {
2071+ clean_boot_directories ( & target_rootfs_fd, is_already_ostree) ?
2072+ }
2073+ None => require_empty_rootdir ( & target_rootfs_fd) ?,
20502074 }
20512075
20522076 // Gather data about the root filesystem
@@ -2090,7 +2114,7 @@ pub(crate) async fn install_to_filesystem(
20902114
20912115 let boot_is_mount = {
20922116 let root_dev = rootfs_fd. dir_metadata ( ) ?. dev ( ) ;
2093- let boot_dev = rootfs_fd
2117+ let boot_dev = target_rootfs_fd
20942118 . symlink_metadata_optional ( BOOT ) ?
20952119 . ok_or_else ( || {
20962120 anyhow ! ( "No /{BOOT} directory found in root; this is is currently required" )
@@ -2101,9 +2125,10 @@ pub(crate) async fn install_to_filesystem(
21012125 } ;
21022126 // Find the UUID of /boot because we need it for GRUB.
21032127 let boot_uuid = if boot_is_mount {
2104- let boot_path = fsopts. root_path . join ( BOOT ) ;
2128+ let boot_path = target_root_path. join ( BOOT ) ;
2129+ tracing:: debug!( "boot_path={boot_path}" ) ;
21052130 let u = bootc_mount:: inspect_filesystem ( & boot_path)
2106- . context ( "Inspecting /{BOOT}" ) ?
2131+ . with_context ( || format ! ( "Inspecting /{BOOT}" ) ) ?
21072132 . uuid
21082133 . ok_or_else ( || anyhow ! ( "No UUID found for /{BOOT}" ) ) ?;
21092134 Some ( u)
@@ -2184,6 +2209,7 @@ pub(crate) async fn install_to_filesystem(
21842209 device_info,
21852210 physical_root_path : fsopts. root_path ,
21862211 physical_root : rootfs_fd,
2212+ target_root_path : Some ( target_root_path. clone ( ) ) ,
21872213 rootfs_uuid : inspect. uuid . clone ( ) ,
21882214 boot,
21892215 kargs,
0 commit comments