vsock: run rustfmt

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
This commit is contained in:
Manos Pitsidianakis 2025-07-17 17:41:33 +03:00 committed by Stefano Garzarella
parent 3e1ea87bdc
commit f77506a809
6 changed files with 125 additions and 75 deletions

View File

@ -18,9 +18,6 @@ use std::{
thread,
};
#[cfg(feature = "backend_vsock")]
use crate::vhu_vsock::VsockProxyInfo;
use crate::vhu_vsock::{BackendType, CidMap, VhostUserVsockBackend, VsockConfig};
use clap::{Args, Parser};
use figment::{
providers::{Format, Yaml},
@ -32,6 +29,10 @@ use thiserror::Error as ThisError;
use vhost_user_backend::VhostUserDaemon;
use vm_memory::{GuestMemoryAtomic, GuestMemoryMmap};
#[cfg(feature = "backend_vsock")]
use crate::vhu_vsock::VsockProxyInfo;
use crate::vhu_vsock::{BackendType, CidMap, VhostUserVsockBackend, VsockConfig};
const DEFAULT_GUEST_CID: u64 = 3;
const DEFAULT_TX_BUFFER_SIZE: u32 = 64 * 1024;
const DEFAULT_QUEUE_SIZE: usize = 1024;
@ -71,7 +72,8 @@ enum BackendError {
#[derive(Args, Clone, Debug)]
struct VsockParam {
/// Context identifier of the guest which uniquely identifies the device for its lifetime.
/// Context identifier of the guest which uniquely identifies the device for
/// its lifetime.
#[arg(
long,
default_value_t = DEFAULT_GUEST_CID,
@ -80,7 +82,8 @@ struct VsockParam {
)]
guest_cid: u64,
/// Unix socket to which a hypervisor connects to and sets up the control path with the device.
/// Unix socket to which a hypervisor connects to and sets up the control
/// path with the device.
#[arg(long, conflicts_with = "config", conflicts_with = "vm")]
socket: PathBuf,
@ -129,7 +132,8 @@ struct VsockParam {
queue_size: usize,
/// The list of group names to which the device belongs.
/// A group is a set of devices that allow sibling communication between their guests.
/// A group is a set of devices that allow sibling communication between
/// their guests.
#[arg(
long,
default_value_t = String::from(DEFAULT_GROUP_NAME),
@ -160,23 +164,39 @@ struct VsockArgs {
#[command(flatten)]
param: Option<VsockParam>,
/// Device parameters corresponding to a VM in the form of comma separated key=value pairs.
/// The allowed keys are: guest_cid, socket, uds_path, tx_buffer_size, queue_size and group.
/// Device parameters corresponding to a VM in the form of comma separated
/// key=value pairs.
///
/// The allowed keys are: guest_cid, socket, uds_path, tx_buffer_size,
/// queue_size and group.
///
/// Example:
/// --vm guest-cid=3,socket=/tmp/vhost3.socket,uds-path=/tmp/vm3.vsock,tx-buffer-size=65536,queue-size=1024,groups=group1+group2
/// Multiple instances of this argument can be provided to configure devices for multiple guests.
/// --vm guest-cid=3,socket=/tmp/vhost3.socket,uds-path=/tmp/vm3.vsock,
/// tx-buffer-size=65536,queue-size=1024,groups=group1+group2
///
/// Multiple instances of this argument can be provided to configure devices
/// for multiple guests.
#[cfg(not(feature = "backend_vsock"))]
#[arg(long, conflicts_with = "config", verbatim_doc_comment, value_parser = parse_vm_params)]
vm: Option<Vec<VsockConfig>>,
/// Device parameters corresponding to a VM in the form of comma separated key=value pairs.
/// The allowed keys are: guest_cid, socket, uds_path, forward_cid, forward_listen, tx_buffer_size, queue_size and group.
/// uds_path and (forward_cid, forward_listen) are mutually exclusive. Use uds_path when you want unix domain socket
/// backend, otherwise forward_cid, forward_listen for vsock backend.
/// Device parameters corresponding to a VM in the form of comma separated
/// key=value pairs.
///
/// The allowed keys are: guest_cid, socket, uds_path, forward_cid,
/// forward_listen, tx_buffer_size, queue_size and group. uds_path and
/// (forward_cid, forward_listen) are mutually exclusive. Use uds_path when
/// you want unix domain socket backend, otherwise forward_cid,
/// forward_listen for vsock backend.
///
/// Example:
/// --vm guest-cid=3,socket=/tmp/vhost3.socket,uds-path=/tmp/vm3.vsock,tx-buffer-size=65536,queue-size=1024,groups=group1+group2
/// --vm guest-cid=3,socket=/tmp/vhost3.socket,forward-cid=1,forward-listen=9001,queue-size=1024
/// Multiple instances of this argument can be provided to configure devices for multiple guests.
/// --vm guest-cid=3,socket=/tmp/vhost3.socket,uds-path=/tmp/vm3.vsock,
/// tx-buffer-size=65536,queue-size=1024,groups=group1+group2
/// --vm guest-cid=3,socket=/tmp/vhost3.socket,forward-cid=1,
/// forward-listen=9001,queue-size=1024
///
/// Multiple instances of this argument can be provided to configure devices
/// for multiple guests.
#[cfg(feature = "backend_vsock")]
#[arg(long, conflicts_with = "config", verbatim_doc_comment, value_parser = parse_vm_params)]
vm: Option<Vec<VsockConfig>>,
@ -337,7 +357,8 @@ impl TryFrom<VsockArgs> for Vec<VsockConfig> {
type Error = CliError;
fn try_from(cmd_args: VsockArgs) -> Result<Self, CliError> {
// we try to use the configuration first, if failed, then fall back to the manual settings.
// we try to use the configuration first, if failed, then fall back to the
// manual settings.
match cmd_args.parse_config() {
Some(c) => c,
_ => match cmd_args.vm {
@ -475,13 +496,13 @@ fn main() {
#[cfg(test)]
mod tests {
use super::*;
use std::{fs::File, io::Write, path::Path};
use assert_matches::assert_matches;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use tempfile::tempdir;
use super::*;
impl VsockArgs {
fn from_args_unix(
guest_cid: u64,
@ -964,7 +985,8 @@ mod tests {
let mut epoll_handlers = daemon.get_epoll_handlers();
// VhostUserVsockBackend support a single thread that handles the TX and RX queues
// VhostUserVsockBackend support a single thread that handles the TX and RX
// queues
assert_eq!(backend.threads.len(), 1);
assert_eq!(epoll_handlers.len(), backend.threads.len());

View File

@ -130,13 +130,14 @@ impl ReadVolatile for StreamType {
let dst = guard.as_ptr().cast::<libc::c_void>();
// SAFETY: We got a valid file descriptor from `AsRawFd`. The memory pointed to by `dst` is
// valid for writes of length `buf.len() by the invariants upheld by the constructor
// of `VolatileSlice`.
// SAFETY: We got a valid file descriptor from `AsRawFd`. The memory pointed to
// by `dst` is valid for writes of length `buf.len() by the
// invariants upheld by the constructor of `VolatileSlice`.
let bytes_read = unsafe { libc::read(fd, dst, buf.len()) };
if bytes_read < 0 {
// We don't know if a partial read might have happened, so mark everything as dirty
// We don't know if a partial read might have happened, so mark everything as
// dirty
buf.bitmap().mark_dirty(0, buf.len());
Err(VolatileMemoryError::IOError(std::io::Error::last_os_error()))
@ -165,9 +166,9 @@ impl WriteVolatile for StreamType {
let src = guard.as_ptr().cast::<libc::c_void>();
// SAFETY: We got a valid file descriptor from `AsRawFd`. The memory pointed to by `src` is
// valid for reads of length `buf.len() by the invariants upheld by the constructor
// of `VolatileSlice`.
// SAFETY: We got a valid file descriptor from `AsRawFd`. The memory pointed to
// by `src` is valid for reads of length `buf.len() by the
// invariants upheld by the constructor of `VolatileSlice`.
let bytes_written = unsafe { libc::write(fd, src, buf.len()) };
if bytes_written < 0 {
@ -208,11 +209,14 @@ pub(crate) struct VsockThreadBackend {
/// Set of allocated local ports.
pub local_port_set: HashSet<u32>,
tx_buffer_size: u32,
/// Maps the guest CID to the corresponding backend. Used for sibling VM communication.
/// Maps the guest CID to the corresponding backend. Used for sibling VM
/// communication.
pub cid_map: Arc<RwLock<CidMap>>,
/// Queue of raw vsock packets received from sibling VMs to be sent to the guest.
/// Queue of raw vsock packets received from sibling VMs to be sent to the
/// guest.
pub raw_pkts_queue: Arc<RwLock<RawPktsQ>>,
/// Set of groups assigned to the device which it is allowed to communicate with.
/// Set of groups assigned to the device which it is allowed to communicate
/// with.
groups_set: Arc<RwLock<HashSet<String>>>,
}
@ -410,7 +414,8 @@ impl VsockThreadBackend {
Ok(())
}
/// Deliver a raw vsock packet sent from a sibling VM to the guest vsock driver.
/// Deliver a raw vsock packet sent from a sibling VM to the guest vsock
/// driver.
///
/// Returns:
/// - `Ok(())` if packet was successfully filled in
@ -432,13 +437,16 @@ impl VsockThreadBackend {
Ok(())
}
/// Handle a new guest initiated connection, i.e from the peer, the guest driver.
/// Handle a new guest initiated connection, i.e from the peer, the guest
/// driver.
///
/// In case of proxying using unix domain socket, attempts to connect to a host side unix socket
/// listening on a path corresponding to the destination port as follows:
/// In case of proxying using unix domain socket, attempts to connect to a
/// host side unix socket listening on a path corresponding to the
/// destination port as follows:
/// - "{self.host_sock_path}_{local_port}""
///
/// In case of proxying using vosck, attempts to connect to the {forward_cid, local_port}
/// In case of proxying using vosck, attempts to connect to the
/// {forward_cid, local_port}
fn handle_new_guest_conn<B: BitmapSlice>(&mut self, pkt: &VsockPacket<B>) {
match &self.backend_info {
BackendType::UnixDomainSocket(uds_path) => {
@ -509,16 +517,18 @@ impl VsockThreadBackend {
#[cfg(test)]
mod tests {
use super::*;
#[cfg(feature = "backend_vsock")]
use crate::vhu_vsock::VsockProxyInfo;
use crate::vhu_vsock::{BackendType, VhostUserVsockBackend, VsockConfig, VSOCK_OP_RW};
use std::os::unix::net::UnixListener;
use tempfile::tempdir;
use virtio_vsock::packet::{VsockPacket, PKT_HEADER_SIZE};
#[cfg(feature = "backend_vsock")]
use vsock::{VsockListener, VMADDR_CID_ANY, VMADDR_CID_LOCAL};
use super::*;
#[cfg(feature = "backend_vsock")]
use crate::vhu_vsock::VsockProxyInfo;
use crate::vhu_vsock::{BackendType, VhostUserVsockBackend, VsockConfig, VSOCK_OP_RW};
const DATA_LEN: usize = 16;
const CONN_TX_BUF_SIZE: u32 = 64 * 1024;
const QUEUE_SIZE: usize = 1024;

View File

@ -85,7 +85,8 @@ impl LocalTxBuf {
// Increment head by amount of data that has been flushed to the stream
self.head += Wrapping(written as u32);
// If written length is less than the expected length we can try again in the future
// If written length is less than the expected length we can try again in the
// future
if written < len {
return Ok(written);
}

View File

@ -12,7 +12,7 @@ use thiserror::Error as ThisError;
use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
use vhost_user_backend::{VhostUserBackend, VringRwLock};
use virtio_bindings::bindings::{
virtio_config::VIRTIO_F_NOTIFY_ON_EMPTY, virtio_config::VIRTIO_F_VERSION_1,
virtio_config::{VIRTIO_F_NOTIFY_ON_EMPTY, VIRTIO_F_VERSION_1},
virtio_ring::VIRTIO_RING_F_EVENT_IDX,
};
use vm_memory::{ByteValued, GuestMemoryAtomic, GuestMemoryMmap, Le64};
@ -21,8 +21,7 @@ use vmm_sys_util::{
eventfd::{EventFd, EFD_NONBLOCK},
};
use crate::thread_backend::RawPktsQ;
use crate::vhu_vsock_thread::*;
use crate::{thread_backend::RawPktsQ, vhu_vsock_thread::*};
pub(crate) type CidMap =
HashMap<u64, (Arc<RwLock<RawPktsQ>>, Arc<RwLock<HashSet<String>>>, EventFd)>;
@ -65,9 +64,11 @@ pub(crate) const VSOCK_OP_CREDIT_UPDATE: u16 = 6;
/// Vsock packet operation ID - Flow control credit request
pub(crate) const VSOCK_OP_CREDIT_REQUEST: u16 = 7;
/// Vsock packet flags - `VSOCK_OP_SHUTDOWN`: Packet sender will receive no more data
/// Vsock packet flags - `VSOCK_OP_SHUTDOWN`: Packet sender will receive no more
/// data
pub(crate) const VSOCK_FLAGS_SHUTDOWN_RCV: u32 = 1;
/// Vsock packet flags - `VSOCK_OP_SHUTDOWN`: Packet sender will send no more data
/// Vsock packet flags - `VSOCK_OP_SHUTDOWN`: Packet sender will send no more
/// data
pub(crate) const VSOCK_FLAGS_SHUTDOWN_SEND: u32 = 2;
// Queue mask to select vrings.
@ -396,12 +397,14 @@ impl VhostUserBackend for VhostUserVsockBackend {
#[cfg(test)]
mod tests {
use super::*;
use std::convert::TryInto;
use tempfile::tempdir;
use vhost_user_backend::VringT;
use vm_memory::GuestAddress;
use super::*;
const CONN_TX_BUF_SIZE: u32 = 64 * 1024;
const QUEUE_SIZE: usize = 1024;

View File

@ -81,11 +81,13 @@ pub(crate) struct VhostUserVsockThread {
local_port: Wrapping<u32>,
/// The tx buffer size
tx_buffer_size: u32,
/// EventFd to notify this thread for custom events. Currently used to notify
/// this thread to process raw vsock packets sent from a sibling VM.
/// EventFd to notify this thread for custom events. Currently used to
/// notify this thread to process raw vsock packets sent from a sibling
/// VM.
pub sibling_event_fd: EventFd,
/// Keeps track of which RX queue was processed first in the last iteration.
/// Used to alternate between the RX queues to prevent the starvation of one by the other.
/// Used to alternate between the RX queues to prevent the starvation of one
/// by the other.
last_processed: RxQueueType,
}
@ -647,7 +649,8 @@ impl VhostUserVsockThread {
Ok(())
}
/// Wrapper to process rx queue based on whether event idx is enabled or not.
/// Wrapper to process rx queue based on whether event idx is enabled or
/// not.
fn process_unix_sockets(&mut self, vring: &VringRwLock, event_idx: bool) -> Result<()> {
if event_idx {
// To properly handle EVENT_IDX we need to keep calling
@ -671,7 +674,8 @@ impl VhostUserVsockThread {
Ok(())
}
/// Wrapper to process raw vsock packets queue based on whether event idx is enabled or not.
/// Wrapper to process raw vsock packets queue based on whether event idx is
/// enabled or not.
pub fn process_raw_pkts(&mut self, vring: &VringRwLock, event_idx: bool) -> Result<()> {
if event_idx {
loop {
@ -772,7 +776,8 @@ impl VhostUserVsockThread {
Ok(())
}
/// Wrapper to process tx queue based on whether event idx is enabled or not.
/// Wrapper to process tx queue based on whether event idx is enabled or
/// not.
pub fn process_tx(&mut self, vring_lock: &VringRwLock, event_idx: bool) -> Result<()> {
if event_idx {
// To properly handle EVENT_IDX we need to keep calling
@ -813,19 +818,22 @@ impl Drop for VhostUserVsockThread {
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(feature = "backend_vsock")]
use crate::vhu_vsock::VsockProxyInfo;
use std::collections::HashMap;
use std::io::Read;
use std::io::Write;
use std::path::PathBuf;
use std::{
collections::HashMap,
io::{Read, Write},
path::PathBuf,
};
use tempfile::tempdir;
use vm_memory::GuestAddress;
use vmm_sys_util::eventfd::EventFd;
#[cfg(feature = "backend_vsock")]
use vsock::{VsockStream, VMADDR_CID_LOCAL};
use super::*;
#[cfg(feature = "backend_vsock")]
use crate::vhu_vsock::VsockProxyInfo;
const CONN_TX_BUF_SIZE: u32 = 64 * 1024;
impl VhostUserVsockThread {

View File

@ -188,7 +188,8 @@ impl<S: AsRawFd + ReadVolatile + Write + WriteVolatile + IsHybridVsock> VsockCon
self.stream.as_raw_fd(),
epoll::Events::EPOLLIN | epoll::Events::EPOLLOUT,
) {
// TODO: let's move this logic out of this func, and handle it properly
// TODO: let's move this logic out of this func, and handle it
// properly
error!("epoll_register failed: {:?}, but proceed further.", e);
}
};
@ -393,17 +394,18 @@ impl<S: AsRawFd + ReadVolatile + Write + WriteVolatile + IsHybridVsock> VsockCon
#[cfg(test)]
mod tests {
use byteorder::{ByteOrder, LittleEndian};
use std::{
collections::VecDeque,
io::{Read, Result as IoResult},
ops::Deref,
sync::{Arc, Mutex},
};
use super::*;
use crate::vhu_vsock::{VSOCK_HOST_CID, VSOCK_OP_RW, VSOCK_TYPE_STREAM};
use std::collections::VecDeque;
use std::io::{Read, Result as IoResult};
use std::ops::Deref;
use std::sync::{Arc, Mutex};
use byteorder::{ByteOrder, LittleEndian};
use virtio_bindings::bindings::virtio_ring::{VRING_DESC_F_NEXT, VRING_DESC_F_WRITE};
use virtio_queue::{
desc::split::Descriptor as SplitDescriptor, desc::RawDescriptor, mock::MockSplitQueue,
desc::{split::Descriptor as SplitDescriptor, RawDescriptor},
mock::MockSplitQueue,
DescriptorChain, Queue, QueueOwnedT,
};
use vm_memory::{
@ -411,6 +413,9 @@ mod tests {
GuestMemoryMmap,
};
use super::*;
use crate::vhu_vsock::{VSOCK_HOST_CID, VSOCK_OP_RW, VSOCK_TYPE_STREAM};
const CONN_TX_BUF_SIZE: u32 = 64 * 1024;
struct HeadParams {
@ -534,9 +539,9 @@ mod tests {
// Creates a socket pair
//
// The read buffer of one socket is the write socket of the other (and vice versa).
// One socket can be passed to the backend while the other can be used to fake writes
// or to verify data that the backend wrote.
// The read buffer of one socket is the write socket of the other (and vice
// versa). One socket can be passed to the backend while the other can
// be used to fake writes or to verify data that the backend wrote.
fn pair() -> (VsockDummySocket, VsockDummySocket) {
let buf1 = Arc::new(Mutex::new(VecDeque::new()));
let buf2 = Arc::new(Mutex::new(VecDeque::new()));
@ -570,7 +575,8 @@ mod tests {
) -> std::result::Result<usize, vm_memory::VolatileMemoryError> {
// VecDequeue has no fancy unsafe tricks that vm-memory can abstract.
// One could do fairly efficient stuff using the moving From<Vec> imp...
// But this is just for tests, so lets clone, convert to Vec, append, convert back and replace.
// But this is just for tests, so lets clone, convert to Vec, append, convert
// back and replace.
let mut write_buffer = self.write_buffer.lock().unwrap();
let mut vec = Vec::from(write_buffer.clone());
let n = vec.write_volatile(buf)?;