@@ -10,6 +10,7 @@ use fn_error_context::context;
1010use bootc_blockdev:: { Partition , PartitionTable } ;
1111use bootc_mount as mount;
1212use rustix:: mount:: UnmountFlags ;
13+ use rustix:: path:: Arg ;
1314
1415use crate :: bootc_composefs:: boot:: { mount_esp, SecurebootKeys } ;
1516use crate :: { discoverable_partition_specification, utils} ;
@@ -59,13 +60,18 @@ pub(crate) fn install_via_bootupd(
5960 // When not running inside the target container (through `--src-imgref`) we chroot
6061 // into the deployment before running bootupd. This makes sure we use binaries
6162 // from the target image rather than the buildroot
62- // But then `/target` (or wherever the user mounted the target FS) is not available,
63- // but since bootupd use that just to find the underlying device,
64- // we can use the deployement path just fine.
65- // Another way of doing this would be to enforce having the target
66- // rootfs mounted under `/run` so we'd get access to it as part of
67- // the standard bind-mounts below.
68- let chroot_root: Option < & str > ;
63+ // In some cases (e.g. --write-uuid), bootupd needs to find the underlying device
64+ // for /boot. But since we don't control where the destination rootfs is mounted
65+ // let's bind mount it to a temp mountpoint under /run
66+ // so it gets carried over in the chroot.
67+
68+ let rootfs_mount = if rootfs. starts_with ( "/run" ) {
69+ rootfs. to_path_buf ( ) . into_std_path_buf ( )
70+ } else {
71+ let rootfs_mount = tempfile:: tempdir_in ( "/run" ) ?. keep ( ) ;
72+ rustix:: mount:: mount_bind_recursive ( rootfs. as_std_path ( ) , & rootfs_mount) ?;
73+ rootfs_mount
74+ } ;
6975 let bind_mount_dirs = [ "/dev" , "/run" , "/proc" , "/sys" ] ;
7076 let chroot_args = if let Some ( target_root) = abs_deployment_path. as_deref ( ) {
7177 tracing:: debug!( "Setting up bind-mounts before chrooting to the target deployment" ) ;
@@ -77,12 +83,10 @@ pub(crate) fn install_via_bootupd(
7783 tracing:: debug!( "bind mounting {}" , dest. display( ) ) ;
7884 rustix:: mount:: mount_bind_recursive ( src, dest) ?;
7985 }
80- chroot_root = Some ( "/" ) ;
8186 // Append the `bootupctl` command, it will be passed as
8287 // an argument to chroot
8388 vec ! [ target_root. as_str( ) , "bootupctl" ]
8489 } else {
85- chroot_root = None ;
8690 vec ! [ ]
8791 } ;
8892
@@ -98,8 +102,7 @@ pub(crate) fn install_via_bootupd(
98102 . args ( [ "backend" , "install" , "--write-uuid" ] )
99103 . args ( verbose)
100104 . args ( bootupd_opts. iter ( ) . copied ( ) . flatten ( ) )
101- . args ( [ "--device" , devpath. as_str ( ) ] )
102- . args ( chroot_root. or ( Some ( rootfs. as_str ( ) ) ) )
105+ . args ( [ "--device" , devpath. as_str ( ) , rootfs_mount. as_str ( ) ?] )
103106 . log_debug ( )
104107 . run_inherited_with_cmd_context ( ) ;
105108
0 commit comments