From c3506d3bc0da60c98377ce3959c5e43f4646b71b Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Tue, 19 Feb 2019 06:59:58 -0800 Subject: [PATCH] vhost-user: Make number of queues configurable We need the vhost-user protocol crate to be more generic to allow communication with a configurable amount of virtqueues. This is a workaround for the virtio-fs backend. According to the vhost-user specification, the master should issue get_queue_num() to get the maximum number of queues supported by the slave. With current virtio-fs implementations, it needs multiple virtques, but it doesn't support the get_queue_num() request and not set the MQ feature bit too. So this is a workaround to hard-code the max_queue_num on the master side. Signed-off-by: Sebastien Boeuf --- src/vhost_user/master.rs | 23 +++++++++++++---------- src/vhost_user/mod.rs | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/vhost_user/master.rs b/src/vhost_user/master.rs index 5be1aff..02eb715 100644 --- a/src/vhost_user/master.rs +++ b/src/vhost_user/master.rs @@ -62,7 +62,7 @@ pub struct Master { impl Master { /// Create a new instance. - fn new(ep: Endpoint) -> Self { + fn new(ep: Endpoint, max_queue_num: u64) -> Self { Master { node: Arc::new(Mutex::new(MasterInternal { main_sock: ep, @@ -71,23 +71,26 @@ impl Master { protocol_features: 0, acked_protocol_features: 0, protocol_features_ready: false, - max_queue_num: 1, + max_queue_num, error: None, })), } } /// Create a new instance from a Unix stream socket. - pub fn from_stream(sock: UnixStream) -> Self { - Self::new(Endpoint::::from_stream(sock)) + pub fn from_stream(sock: UnixStream, max_queue_num: u64) -> Self { + Self::new(Endpoint::::from_stream(sock), max_queue_num) } /// Create a new vhost-user master endpoint. /// /// # Arguments /// * `path` - path of Unix domain socket listener to connect to - pub fn connect(path: &str) -> Result { - Ok(Self::new(Endpoint::::connect(path)?)) + pub fn connect(path: &str, max_queue_num: u64) -> Result { + Ok(Self::new( + Endpoint::::connect(path)?, + max_queue_num, + )) } } @@ -617,7 +620,7 @@ mod tests { fn create_pair(path: &str) -> (Master, Endpoint) { let listener = Listener::new(path, true).unwrap(); listener.set_nonblocking(true).unwrap(); - let master = Master::connect(path).unwrap(); + let master = Master::connect(path, 2).unwrap(); let slave = listener.accept().unwrap().unwrap(); (master, Endpoint::from_stream(slave)) } @@ -627,7 +630,7 @@ mod tests { let listener = Listener::new(UNIX_SOCKET_MASTER, true).unwrap(); listener.set_nonblocking(true).unwrap(); - let mut master = Master::connect(UNIX_SOCKET_MASTER).unwrap(); + let mut master = Master::connect(UNIX_SOCKET_MASTER, 1).unwrap(); let mut slave = Endpoint::::from_stream(listener.accept().unwrap().unwrap()); // Send two messages continuously @@ -651,13 +654,13 @@ mod tests { fn test_create_failure() { let _ = Listener::new(UNIX_SOCKET_MASTER2, true).unwrap(); let _ = Listener::new(UNIX_SOCKET_MASTER2, false).is_err(); - assert!(Master::connect(UNIX_SOCKET_MASTER2).is_err()); + assert!(Master::connect(UNIX_SOCKET_MASTER2, 1).is_err()); let listener = Listener::new(UNIX_SOCKET_MASTER2, true).unwrap(); assert!(Listener::new(UNIX_SOCKET_MASTER2, false).is_err()); listener.set_nonblocking(true).unwrap(); - let _master = Master::connect(UNIX_SOCKET_MASTER2).unwrap(); + let _master = Master::connect(UNIX_SOCKET_MASTER2, 1).unwrap(); let _slave = listener.accept().unwrap().unwrap(); } diff --git a/src/vhost_user/mod.rs b/src/vhost_user/mod.rs index a4531f8..a452232 100644 --- a/src/vhost_user/mod.rs +++ b/src/vhost_user/mod.rs @@ -178,7 +178,7 @@ mod tests { backend: Arc>, ) -> (Master, SlaveReqHandler) { let mut slave_listener = SlaveListener::new(path, true, backend).unwrap(); - let master = Master::connect(path).unwrap(); + let master = Master::connect(path, 1).unwrap(); (master, slave_listener.accept().unwrap().unwrap()) }