@@ -15,11 +15,7 @@ limitations under the License.
15
15
*/
16
16
17
17
use std:: {
18
- io:: { BufRead , BufReader , Write } ,
19
- os:: unix:: {
20
- io:: { IntoRawFd , RawFd } ,
21
- net:: UnixStream ,
22
- } ,
18
+ os:: unix:: io:: { IntoRawFd , RawFd } ,
23
19
time:: Duration ,
24
20
} ;
25
21
@@ -34,12 +30,17 @@ use nix::{
34
30
time:: { clock_gettime, ClockId } ,
35
31
unistd:: close,
36
32
} ;
37
- use tokio:: time:: timeout;
33
+ use tokio:: {
34
+ io:: { AsyncReadExt , AsyncWriteExt } ,
35
+ net:: UnixStream ,
36
+ time:: timeout,
37
+ } ;
38
38
use ttrpc:: { context:: with_timeout, r#async:: Client } ;
39
39
use vmm_common:: api:: { sandbox:: * , sandbox_ttrpc:: SandboxServiceClient } ;
40
40
41
41
use crate :: network:: { NetworkInterface , Route } ;
42
42
43
+ const HVSOCK_RETRY_TIMEOUT_IN_MS : u64 = 10 ;
43
44
const TIME_SYNC_PERIOD : u64 = 60 ;
44
45
const TIME_DIFF_TOLERANCE_IN_MS : u64 = 10 ;
45
46
@@ -67,11 +68,7 @@ async fn new_ttrpc_client(address: &str) -> Result<Client> {
67
68
68
69
let client = timeout ( Duration :: from_secs ( ctx_timeout) , fut)
69
70
. await
70
- . map_err ( |_| {
71
- let e = anyhow ! ( "{}s timeout connecting socket: {}" , ctx_timeout, last_err) ;
72
- error ! ( "{}" , e) ;
73
- e
74
- } ) ?;
71
+ . map_err ( |_| anyhow ! ( "{}s timeout connecting socket: {}" , ctx_timeout, last_err) ) ?;
75
72
Ok ( client)
76
73
}
77
74
@@ -165,28 +162,41 @@ async fn connect_to_hvsocket(address: &str) -> Result<RawFd> {
165
162
if v. len ( ) < 2 {
166
163
return Err ( anyhow ! ( "hvsock address {} should not less than 2" , address) . into ( ) ) ;
167
164
}
168
- ( v[ 0 ] . to_string ( ) , v[ 1 ] . to_string ( ) )
165
+ ( v[ 0 ] , v[ 1 ] )
169
166
} ;
170
167
171
- tokio:: task:: spawn_blocking ( move || {
172
- let mut stream =
173
- UnixStream :: connect ( & addr) . map_err ( |e| anyhow ! ( "failed to connect hvsock: {}" , e) ) ?;
174
- stream
175
- . write_all ( format ! ( "CONNECT {}\n " , port) . as_bytes ( ) )
176
- . map_err ( |e| anyhow ! ( "hvsock connected but failed to write CONNECT: {}" , e) ) ?;
177
-
178
- let mut response = String :: new ( ) ;
179
- BufReader :: new ( & stream)
180
- . read_line ( & mut response)
181
- . map_err ( |e| anyhow ! ( "CONNECT sent but failed to get response: {}" , e) ) ?;
182
- if response. starts_with ( "OK" ) {
183
- Ok ( stream. into_raw_fd ( ) )
184
- } else {
185
- Err ( anyhow ! ( "CONNECT sent but response is not OK: {}" , response) . into ( ) )
168
+ let fut = async {
169
+ let mut stream = UnixStream :: connect ( addr) . await ?;
170
+
171
+ match stream. write ( format ! ( "CONNECT {}\n " , port) . as_bytes ( ) ) . await {
172
+ Ok ( _) => {
173
+ let mut buf = [ 0 ; 4096 ] ;
174
+ match stream. read ( & mut buf) . await {
175
+ Ok ( 0 ) => Err ( anyhow ! ( "stream closed" ) ) ,
176
+ Ok ( n) => {
177
+ if String :: from_utf8 ( buf[ ..n] . to_vec ( ) )
178
+ . unwrap_or_default ( )
179
+ . contains ( "OK" )
180
+ {
181
+ return Ok ( stream. into_std ( ) ?. into_raw_fd ( ) ) ;
182
+ }
183
+ Err ( anyhow ! ( "failed to connect" ) )
184
+ }
185
+ Err ( ref e) if e. kind ( ) == std:: io:: ErrorKind :: WouldBlock => {
186
+ Err ( anyhow ! ( "{}" , e) )
187
+ }
188
+ Err ( e) => Err ( anyhow ! ( "failed to read from hvsock: {}" , e) ) ,
189
+ }
190
+ }
191
+ Err ( ref e) if e. kind ( ) == std:: io:: ErrorKind :: WouldBlock => Err ( anyhow ! ( "{}" , e) ) ,
192
+ Err ( e) => Err ( anyhow ! ( "failed to write CONNECT to hvsock: {}" , e) ) ,
186
193
}
187
- } )
188
- . await
189
- . map_err ( |e| anyhow ! ( "failed to spawn blocking task: {}" , e) ) ?
194
+ . map_err ( Error :: Other )
195
+ } ;
196
+
197
+ timeout ( Duration :: from_millis ( HVSOCK_RETRY_TIMEOUT_IN_MS ) , fut)
198
+ . await
199
+ . map_err ( |_| anyhow ! ( "hvsock retry {}ms timeout" , HVSOCK_RETRY_TIMEOUT_IN_MS ) ) ?
190
200
}
191
201
192
202
pub fn unix_sock ( r#abstract : bool , socket_path : & str ) -> Result < UnixAddr > {
0 commit comments