@@ -163,8 +163,10 @@ impl RuncFactory {
163
163
( Some ( s) , None )
164
164
} else {
165
165
let pio = create_io ( & id, opts. io_uid , opts. io_gid , stdio) ?;
166
- create_opts. io = pio. io . as_ref ( ) . cloned ( ) ;
167
- ( None , Some ( pio) )
166
+ let ref_pio = Arc :: new ( pio) ;
167
+ create_opts. io = ref_pio. io . clone ( ) ;
168
+ init. io = Some ( ref_pio. clone ( ) ) ;
169
+ ( None , Some ( ref_pio) )
168
170
} ;
169
171
170
172
let resp = init
@@ -178,6 +180,22 @@ impl RuncFactory {
178
180
}
179
181
return Err ( runtime_error ( bundle, e, "OCI runtime create failed" ) . await ) ;
180
182
}
183
+ if !init. stdio . stdin . is_empty ( ) {
184
+ let stdin_clone = init. stdio . stdin . clone ( ) ;
185
+ let stdin_w = init. stdin . clone ( ) ;
186
+ // Open the write side in advance to make sure read side will not block,
187
+ // open it in another thread otherwise it will block too.
188
+ tokio:: spawn ( async move {
189
+ if let Ok ( stdin_w_file) = OpenOptions :: new ( )
190
+ . write ( true )
191
+ . open ( stdin_clone. as_str ( ) )
192
+ . await
193
+ {
194
+ let mut lock_guard = stdin_w. lock ( ) . unwrap ( ) ;
195
+ * lock_guard = Some ( stdin_w_file) ;
196
+ }
197
+ } ) ;
198
+ }
181
199
copy_io_or_console ( init, socket, pio, init. lifecycle . exit_signal . clone ( ) ) . await ?;
182
200
let pid = read_file_to_str ( pid_path) . await ?. parse :: < i32 > ( ) ?;
183
201
init. pid = pid;
@@ -232,6 +250,7 @@ impl ProcessFactory<ExecProcess> for RuncExecFactory {
232
250
stderr : req. stderr . to_string ( ) ,
233
251
terminal : req. terminal ,
234
252
} ,
253
+ io : None ,
235
254
pid : 0 ,
236
255
exit_code : 0 ,
237
256
exited_at : None ,
@@ -299,6 +318,8 @@ impl ProcessLifecycle<InitProcess> for RuncInitLifecycle {
299
318
) ;
300
319
}
301
320
}
321
+
322
+ debug ! ( "Do close io complete" ) ;
302
323
self . exit_signal . signal ( ) ;
303
324
Ok ( ( ) )
304
325
}
@@ -394,8 +415,10 @@ impl ProcessLifecycle<ExecProcess> for RuncExecLifecycle {
394
415
( Some ( s) , None )
395
416
} else {
396
417
let pio = create_io ( & p. id , self . io_uid , self . io_gid , & p. stdio ) ?;
397
- exec_opts. io = pio. io . as_ref ( ) . cloned ( ) ;
398
- ( None , Some ( pio) )
418
+ let ref_pio = Arc :: new ( pio) ;
419
+ exec_opts. io = ref_pio. io . clone ( ) ;
420
+ p. io = Some ( ref_pio. clone ( ) ) ;
421
+ ( None , Some ( ref_pio) )
399
422
} ;
400
423
//TODO checkpoint support
401
424
let exec_result = self
@@ -457,6 +480,8 @@ impl ProcessLifecycle<ExecProcess> for RuncExecLifecycle {
457
480
458
481
async fn delete ( & self , p : & mut ExecProcess ) -> Result < ( ) > {
459
482
self . exit_signal . signal ( ) ;
483
+
484
+ debug ! ( "Do close io complete" ) ;
460
485
let exec_pid_path = Path :: new ( self . bundle . as_str ( ) ) . join ( format ! ( "{}.pid" , p. id) ) ;
461
486
remove_file ( exec_pid_path) . await . unwrap_or_default ( ) ;
462
487
Ok ( ( ) )
@@ -632,7 +657,7 @@ where
632
657
async fn copy_io_or_console < P > (
633
658
p : & mut ProcessTemplate < P > ,
634
659
socket : Option < ConsoleSocket > ,
635
- pio : Option < ProcessIO > ,
660
+ pio : Option < Arc < ProcessIO > > ,
636
661
exit_signal : Arc < ExitSignal > ,
637
662
) -> Result < ( ) > {
638
663
if p. stdio . terminal {
@@ -670,6 +695,7 @@ impl Spawner for ShimExecutor {
670
695
}
671
696
} ;
672
697
let pid = child. id ( ) . unwrap ( ) ;
698
+
673
699
let ( stdout, stderr, exit_code) = tokio:: join!(
674
700
read_std( child. stdout) ,
675
701
read_std( child. stderr) ,
0 commit comments