1- use crate :: checkpoint:: { Checkpoint , FdInfo , MemoryMap , MemorySegment } ;
1+ use crate :: checkpoint:: { Checkpoint , FdInfo , MemoryMap , MemorySegment , SkippedFd } ;
22
33/// One planned memory-restore action for a saved region.
44#[ derive( Debug ) ]
@@ -53,17 +53,17 @@ fn is_restorable_file_path(path: &str) -> bool {
5353
5454/// Split the saved fd table into transparently restorable regular files and a
5555/// list of skipped non-regular fds (sockets, pipes, eventfd, ...). The skipped
56- /// list is logged by the caller; those resources fall to the app_state hatch.
56+ /// list is surfaced to the caller; those resources fall to the app_state hatch.
5757/// memfd, "(deleted)", and pseudo-filesystem (/proc/, /sys/, /dev/) paths start
5858/// with '/' but are not transparently reopenable, so they are skipped.
59- pub ( crate ) fn build_fd_plan ( fds : & [ FdInfo ] ) -> ( Vec < FdInfo > , Vec < String > ) {
59+ pub ( crate ) fn build_fd_plan ( fds : & [ FdInfo ] ) -> ( Vec < FdInfo > , Vec < SkippedFd > ) {
6060 let mut restorable = Vec :: new ( ) ;
6161 let mut skipped = Vec :: new ( ) ;
6262 for f in fds {
6363 if is_restorable_file_path ( & f. path ) {
6464 restorable. push ( f. clone ( ) ) ;
6565 } else {
66- skipped. push ( f . path . clone ( ) ) ;
66+ skipped. push ( SkippedFd { fd : f . fd , path : f . path . clone ( ) } ) ;
6767 }
6868 }
6969 ( restorable, skipped)
@@ -83,8 +83,8 @@ fn prot_from_perms(perms: &str) -> libc::c_int {
8383/// a valid executable rip). Drives the rebuild entirely via ptrace syscall
8484/// injection through a trampoline placed in a hole of the CHECKPOINT's layout.
8585/// Leaves the child stopped with the saved registers loaded; the caller resumes
86- /// it (PTRACE_CONT / detach). Returns the list of non-transparently-restored
87- /// resource names (skipped fds ) for the caller to log .
86+ /// it (PTRACE_CONT / detach). Returns the non-transparently-restored fds
87+ /// (as [`SkippedFd`] fd + path entries ) for the caller to surface .
8888/// On `Err`, the child is left half-built and still ptrace-stopped; the caller
8989/// MUST kill and reap it.
9090/// Limitation: file-backed regions are restored `MAP_PRIVATE` from the on-disk
@@ -98,7 +98,7 @@ fn prot_from_perms(perms: &str) -> libc::c_int {
9898pub ( crate ) fn restore_into (
9999 pid : i32 ,
100100 cp : & Checkpoint ,
101- ) -> Result < Vec < String > , crate :: error:: SandlockError > {
101+ ) -> Result < Vec < SkippedFd > , crate :: error:: SandlockError > {
102102 use crate :: checkpoint:: inject;
103103 use crate :: error:: { SandboxRuntimeError , SandlockError } ;
104104
@@ -316,7 +316,7 @@ pub(crate) fn restore_into(
316316pub ( crate ) fn restore_into (
317317 _pid : i32 ,
318318 _cp : & Checkpoint ,
319- ) -> Result < Vec < String > , crate :: error:: SandlockError > {
319+ ) -> Result < Vec < SkippedFd > , crate :: error:: SandlockError > {
320320 Err ( crate :: error:: SandlockError :: Runtime (
321321 crate :: error:: SandboxRuntimeError :: Child (
322322 "injection-based restore is only implemented on x86_64" . into ( ) ,
@@ -327,7 +327,7 @@ pub(crate) fn restore_into(
327327#[ cfg( test) ]
328328mod tests {
329329 use super :: * ;
330- use crate :: checkpoint:: { FdInfo , MemoryMap , MemorySegment } ;
330+ use crate :: checkpoint:: { FdInfo , MemoryMap , MemorySegment , SkippedFd } ;
331331
332332 #[ test]
333333 fn fd_plan_keeps_regular_files_only ( ) {
@@ -339,7 +339,10 @@ mod tests {
339339 let ( restorable, skipped) = build_fd_plan ( & fds) ;
340340 assert_eq ! ( restorable. len( ) , 1 ) ;
341341 assert_eq ! ( restorable[ 0 ] . fd, 3 ) ;
342- assert_eq ! ( skipped, vec![ "socket:[12345]" . to_string( ) , "pipe:[6789]" . to_string( ) ] ) ;
342+ assert_eq ! ( skipped, vec![
343+ SkippedFd { fd: 4 , path: "socket:[12345]" . into( ) } ,
344+ SkippedFd { fd: 5 , path: "pipe:[6789]" . into( ) } ,
345+ ] ) ;
343346 }
344347
345348 #[ test]
@@ -357,13 +360,13 @@ mod tests {
357360 assert_eq ! ( restorable[ 0 ] . fd, 3 ) ;
358361 assert ! ( restorable. iter( ) . all( |f| f. fd != 6 && f. fd != 7 && f. fd != 8 && f. fd != 9 && f. fd != 10 ) ,
359362 "deleted, memfd, and pseudo-filesystem fds must not appear in restorable" ) ;
360- assert ! ( skipped. contains( & "/tmp/gone (deleted)" . to_string ( ) ) ) ;
361- assert ! ( skipped. contains( & "/memfd:scratch (deleted)" . to_string ( ) ) ) ;
362- assert ! ( skipped. contains( & "/proc/1234/maps" . to_string ( ) ) ,
363+ assert ! ( skipped. contains( & SkippedFd { fd : 6 , path : "/tmp/gone (deleted)" . into ( ) } ) ) ;
364+ assert ! ( skipped. contains( & SkippedFd { fd : 7 , path : "/memfd:scratch (deleted)" . into ( ) } ) ) ;
365+ assert ! ( skipped. contains( & SkippedFd { fd : 8 , path : "/proc/1234/maps" . into ( ) } ) ,
363366 "/proc/ paths must be skipped" ) ;
364- assert ! ( skipped. contains( & "/dev/pts/3" . to_string ( ) ) ,
367+ assert ! ( skipped. contains( & SkippedFd { fd : 9 , path : "/dev/pts/3" . into ( ) } ) ,
365368 "/dev/ paths must be skipped" ) ;
366- assert ! ( skipped. contains( & "/sys/kernel/x" . to_string ( ) ) ,
369+ assert ! ( skipped. contains( & SkippedFd { fd : 10 , path : "/sys/kernel/x" . into ( ) } ) ,
367370 "/sys/ paths must be skipped" ) ;
368371 }
369372
0 commit comments