@@ -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 ,
@@ -394,8 +413,10 @@ impl ProcessLifecycle<ExecProcess> for RuncExecLifecycle {
394
413
( Some ( s) , None )
395
414
} else {
396
415
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) )
416
+ let ref_pio = Arc :: new ( pio) ;
417
+ exec_opts. io = ref_pio. io . clone ( ) ;
418
+ p. io = Some ( ref_pio. clone ( ) ) ;
419
+ ( None , Some ( ref_pio) )
399
420
} ;
400
421
//TODO checkpoint support
401
422
let exec_result = self
@@ -457,6 +478,15 @@ impl ProcessLifecycle<ExecProcess> for RuncExecLifecycle {
457
478
458
479
async fn delete ( & self , p : & mut ExecProcess ) -> Result < ( ) > {
459
480
self . exit_signal . signal ( ) ;
481
+ //close pipe read
482
+ if !p. stdio . is_null ( ) {
483
+ if let Some ( c) = p. io . clone ( ) {
484
+ if let Some ( io) = c. io . clone ( ) {
485
+ io. close_all_sid ( ) ;
486
+ }
487
+ }
488
+ }
489
+ debug ! ( "Do close io complete" ) ;
460
490
let exec_pid_path = Path :: new ( self . bundle . as_str ( ) ) . join ( format ! ( "{}.pid" , p. id) ) ;
461
491
remove_file ( exec_pid_path) . await . unwrap_or_default ( ) ;
462
492
Ok ( ( ) )
@@ -568,6 +598,7 @@ pub async fn copy_io(pio: &ProcessIO, stdio: &Stdio, exit_signal: Arc<ExitSignal
568
598
stdout,
569
599
exit_signal. clone ( ) ,
570
600
Some ( move || {
601
+ debug ! ( "stdout exit....................." ) ;
571
602
drop ( stdout_r) ;
572
603
} ) ,
573
604
) ;
@@ -594,6 +625,7 @@ pub async fn copy_io(pio: &ProcessIO, stdio: &Stdio, exit_signal: Arc<ExitSignal
594
625
stderr,
595
626
exit_signal,
596
627
Some ( move || {
628
+ debug ! ( "stderr exit....................." ) ;
597
629
drop ( stderr_r) ;
598
630
} ) ,
599
631
) ;
@@ -632,7 +664,7 @@ where
632
664
async fn copy_io_or_console < P > (
633
665
p : & mut ProcessTemplate < P > ,
634
666
socket : Option < ConsoleSocket > ,
635
- pio : Option < ProcessIO > ,
667
+ pio : Option < Arc < ProcessIO > > ,
636
668
exit_signal : Arc < ExitSignal > ,
637
669
) -> Result < ( ) > {
638
670
if p. stdio . terminal {
@@ -670,6 +702,7 @@ impl Spawner for ShimExecutor {
670
702
}
671
703
} ;
672
704
let pid = child. id ( ) . unwrap ( ) ;
705
+
673
706
let ( stdout, stderr, exit_code) = tokio:: join!(
674
707
read_std( child. stdout) ,
675
708
read_std( child. stderr) ,
0 commit comments