@@ -11,23 +11,30 @@ pub async fn clone_disk(src_ext4: &str, sandbox_id: &str, data_dir: &str) -> Res
1111 let sandbox_dir = format ! ( "{}/sandboxes/{}" , data_dir, sandbox_id) ;
1212 let dest = format ! ( "{}/rootfs.ext4" , sandbox_dir) ;
1313
14+ // Resolve relative source paths against data_dir
15+ let resolved_src = if Path :: new ( src_ext4) . is_relative ( ) {
16+ format ! ( "{}/{}" , data_dir, src_ext4)
17+ } else {
18+ src_ext4. to_string ( )
19+ } ;
20+
1421 // Create sandbox directory
1522 tokio:: fs:: create_dir_all ( & sandbox_dir) . await . map_err ( |e| {
1623 DiskError :: Io ( format ! ( "failed to create sandbox directory {}: {}" , sandbox_dir, e) )
1724 } ) ?;
1825
19- if !Path :: new ( src_ext4 ) . exists ( ) {
20- return Err ( DiskError :: SourceNotFound ( src_ext4 . to_string ( ) ) ) ;
26+ if !Path :: new ( & resolved_src ) . exists ( ) {
27+ return Err ( DiskError :: SourceNotFound ( resolved_src ) ) ;
2128 }
2229
2330 info ! (
24- src = %src_ext4 ,
31+ src = %resolved_src ,
2532 dest = %dest,
2633 sandbox_id = %sandbox_id,
2734 "cloning disk with reflink"
2835 ) ;
2936
30- let src = src_ext4 . to_string ( ) ;
37+ let src = resolved_src ;
3138 let dst = dest. clone ( ) ;
3239
3340 // Use --reflink=auto on Linux for instant CoW clones on XFS/btrfs.
@@ -62,20 +69,27 @@ pub async fn clone_disk(src_ext4: &str, sandbox_id: &str, data_dir: &str) -> Res
6269///
6370/// Like `clone_disk` but allows specifying the target directory directly.
6471/// The destination directory must already exist.
65- pub async fn clone_disk_to ( src_ext4 : & str , dest_dir : & str ) -> Result < String , DiskError > {
72+ pub async fn clone_disk_to ( src_ext4 : & str , dest_dir : & str , data_dir : & str ) -> Result < String , DiskError > {
6673 let dest = format ! ( "{}/rootfs.ext4" , dest_dir) ;
6774
68- if !Path :: new ( src_ext4) . exists ( ) {
69- return Err ( DiskError :: SourceNotFound ( src_ext4. to_string ( ) ) ) ;
75+ // Resolve relative source paths against data_dir
76+ let resolved_src = if Path :: new ( src_ext4) . is_relative ( ) {
77+ format ! ( "{}/{}" , data_dir, src_ext4)
78+ } else {
79+ src_ext4. to_string ( )
80+ } ;
81+
82+ if !Path :: new ( & resolved_src) . exists ( ) {
83+ return Err ( DiskError :: SourceNotFound ( resolved_src) ) ;
7084 }
7185
7286 info ! (
73- src = %src_ext4 ,
87+ src = %resolved_src ,
7488 dest = %dest,
7589 "cloning disk with reflink to target directory"
7690 ) ;
7791
78- let src = src_ext4 . to_string ( ) ;
92+ let src = resolved_src ;
7993 let dst = dest. clone ( ) ;
8094
8195 let output = if cfg ! ( target_os = "linux" ) {
@@ -258,7 +272,7 @@ mod tests {
258272 let dest_dir = tmp. join ( "target" ) ;
259273 std:: fs:: create_dir_all ( & dest_dir) . unwrap ( ) ;
260274
261- let result = clone_disk_to ( src_file. to_str ( ) . unwrap ( ) , dest_dir. to_str ( ) . unwrap ( ) ) . await ;
275+ let result = clone_disk_to ( src_file. to_str ( ) . unwrap ( ) , dest_dir. to_str ( ) . unwrap ( ) , tmp . to_str ( ) . unwrap ( ) ) . await ;
262276 assert ! ( result. is_ok( ) ) ;
263277
264278 let dest = result. unwrap ( ) ;
@@ -274,7 +288,7 @@ mod tests {
274288 let tmp = std:: env:: temp_dir ( ) . join ( "sandchest-disk-to-missing" ) ;
275289 std:: fs:: create_dir_all ( & tmp) . unwrap ( ) ;
276290
277- let result = clone_disk_to ( "/nonexistent/rootfs.ext4" , tmp. to_str ( ) . unwrap ( ) ) . await ;
291+ let result = clone_disk_to ( "/nonexistent/rootfs.ext4" , tmp. to_str ( ) . unwrap ( ) , "/tmp" ) . await ;
278292 assert ! ( matches!( result. unwrap_err( ) , DiskError :: SourceNotFound ( _) ) ) ;
279293
280294 let _ = std:: fs:: remove_dir_all ( & tmp) ;
0 commit comments