@@ -9,6 +9,7 @@ use std::{env, fs, thread};
99use anyhow:: { Context , Result , bail, ensure} ;
1010use clap:: { Args , ValueEnum } ;
1111use sysinfo:: { CpuRefreshKind , System } ;
12+ use vsock:: VsockStream ;
1213use wait_timeout:: ChildExt ;
1314use xshell:: cmd;
1415
@@ -79,6 +80,12 @@ pub enum Device {
7980
8081 /// virtio-net via PCI.
8182 VirtioNetPci ,
83+
84+ /// virtio-vsock via MMIO.
85+ VirtioVsockMmio ,
86+
87+ /// virtio-vsock via PCI.
88+ VirtioVsockPci ,
8289}
8390
8491impl Qemu {
@@ -152,12 +159,13 @@ impl Qemu {
152159 "mioudp" => test_mioudp ( guest_ip) ?,
153160 "poll" => test_poll ( guest_ip) ?,
154161 "stdin" => test_stdin ( & mut qemu. 0 ) ?,
162+ "vsock" => test_vsock ( ) ?,
155163 _ => { }
156164 }
157165
158166 if matches ! (
159167 image_name,
160- "axum-example" | "http_server" | "http_server_poll" | "http_server_select"
168+ "axum-example" | "http_server" | "http_server_poll" | "http_server_select" | "vsock"
161169 ) || self . devices . contains ( & Device :: CadenceGem )
162170 // sifive_u, on which we test CadenceGem, does not support software shutdowns, so we have to kill the machine ourselves.
163171 {
@@ -430,6 +438,16 @@ impl Qemu {
430438 "virtconsole,chardev=char0" . to_owned( ) ,
431439 ]
432440 }
441+ device @ ( Device :: VirtioVsockMmio | Device :: VirtioVsockPci ) => {
442+ let device_arg = match device {
443+ Device :: VirtioVsockMmio => "vhost-vsock-device" ,
444+ Device :: VirtioVsockPci => "vhost-vsock-pci,disable-legacy=on" ,
445+ _ => unreachable ! ( ) ,
446+ } ;
447+ let device_arg = format ! ( "{device_arg},guest-cid=3" ) ;
448+
449+ vec ! [ "-device" . to_owned( ) , device_arg]
450+ }
433451 } )
434452 . collect ( )
435453 }
@@ -545,6 +563,26 @@ fn test_stdin(child: &mut Child) -> Result<()> {
545563 Ok ( ( ) )
546564}
547565
566+ fn test_vsock ( ) -> Result < ( ) > {
567+ thread:: sleep ( Duration :: from_secs ( 10 ) ) ;
568+ let messages = [ "Hello, there!" , "Hello, again!" , "Bye-bye!" ] ;
569+
570+ let mut stream = VsockStream :: connect_with_cid_port ( 3 , 9975 ) ?;
571+ for message in messages {
572+ writeln ! ( & mut stream, "{message}" ) ?;
573+ thread:: sleep ( Duration :: from_secs ( 1 ) ) ;
574+ }
575+
576+ const BUF_SIZE : usize = 8 * 1024 ;
577+ let mut buf = vec ! [ 0 ; BUF_SIZE ] ;
578+ let n = stream. read ( & mut buf) ?;
579+ let s = str:: from_utf8 ( & buf[ 0 ..n] ) ?;
580+ let received_messages = s. trim ( ) . split ( '\n' ) . collect :: < Vec < _ > > ( ) ;
581+ assert_eq ! ( received_messages, messages) ;
582+
583+ Ok ( ( ) )
584+ }
585+
548586fn test_http_server ( guest_ip : IpAddr ) -> Result < ( ) > {
549587 thread:: sleep ( Duration :: from_secs ( 10 ) ) ;
550588 let url = format ! ( "http://{guest_ip}:9975" ) ;
0 commit comments