mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
virtio-devices: fix broken vsock doc comments
These need to be //! comments, because they apply to the module as a whole, not to whatever directly follows the comment. Using /// comments here resulted in documentation being attached to the wrong thing, or not rendered at all. I've also checked the Markdown formatting of these comments as rendered by rustdoc, and fixed it where appropriate. Signed-off-by: Alyssa Ross <hi@alyssa.is>
This commit is contained in:
@@ -1,28 +1,28 @@
|
|||||||
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
/// The main job of `VsockConnection` is to forward data traffic, back and forth, between a
|
//! The main job of `VsockConnection` is to forward data traffic, back and forth, between a
|
||||||
/// guest-side AF_VSOCK socket and a host-side generic `Read + Write + AsRawFd` stream, while
|
//! guest-side AF_VSOCK socket and a host-side generic `Read + Write + AsRawFd` stream, while
|
||||||
/// also managing its internal state.
|
//! also managing its internal state.
|
||||||
/// To that end, `VsockConnection` implements:
|
//! To that end, `VsockConnection` implements:
|
||||||
/// - `VsockChannel` for:
|
//! - `VsockChannel` for:
|
||||||
/// - moving data from the host stream to a guest-provided RX buffer, via `recv_pkt()`; and
|
//! - moving data from the host stream to a guest-provided RX buffer, via `recv_pkt()`; and
|
||||||
/// - moving data from a guest-provided TX buffer to the host stream, via `send_pkt()`; and
|
//! - moving data from a guest-provided TX buffer to the host stream, via `send_pkt()`; and
|
||||||
/// - updating its internal state, by absorbing control packets (anything other than
|
//! - updating its internal state, by absorbing control packets (anything other than
|
||||||
/// VSOCK_OP_RW).
|
//! VSOCK_OP_RW).
|
||||||
/// - `VsockEpollListener` for getting notified about the availability of data or free buffer
|
//! - `VsockEpollListener` for getting notified about the availability of data or free buffer
|
||||||
/// space at the host stream.
|
//! space at the host stream.
|
||||||
///
|
//!
|
||||||
/// Note: there is a certain asymmetry to the RX and TX data flows:
|
//! Note: there is a certain asymmetry to the RX and TX data flows:
|
||||||
/// - RX transfers do not need any data buffering, since data is read straight from the
|
//! - RX transfers do not need any data buffering, since data is read straight from the
|
||||||
/// host stream and into the guest-provided RX buffer;
|
//! host stream and into the guest-provided RX buffer;
|
||||||
/// - TX transfers may require some data to be buffered by `VsockConnection`, if the host
|
//! - TX transfers may require some data to be buffered by `VsockConnection`, if the host
|
||||||
/// peer can't keep up with reading the data that we're writing. This is because, once
|
//! peer can't keep up with reading the data that we're writing. This is because, once
|
||||||
/// the guest driver provides some data in a virtio TX buffer, the vsock device must
|
//! the guest driver provides some data in a virtio TX buffer, the vsock device must
|
||||||
/// consume it. If that data can't be forwarded straight to the host stream, we'll
|
//! consume it. If that data can't be forwarded straight to the host stream, we'll
|
||||||
/// have to store it in a buffer (and flush it at a later time). Vsock flow control
|
//! have to store it in a buffer (and flush it at a later time). Vsock flow control
|
||||||
/// ensures that our TX buffer doesn't overflow.
|
//! ensures that our TX buffer doesn't overflow.
|
||||||
///
|
//
|
||||||
// The code in this file is best read with a fresh memory of the vsock protocol inner-workings.
|
// The code in this file is best read with a fresh memory of the vsock protocol inner-workings.
|
||||||
// To help with that, here is a
|
// To help with that, here is a
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
/// This module implements our vsock connection state machine. The heavy lifting is done by
|
//! This module implements our vsock connection state machine. The heavy lifting is done by
|
||||||
/// `connection::VsockConnection`, while this file only defines some constants and helper structs.
|
//! `connection::VsockConnection`, while this file only defines some constants and helper structs.
|
||||||
///
|
|
||||||
mod connection;
|
mod connection;
|
||||||
mod txbuf;
|
mod txbuf;
|
||||||
|
|
||||||
|
|||||||
@@ -2,19 +2,19 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
/// `VsockPacket` provides a thin wrapper over the buffers exchanged via virtio queues.
|
//! `VsockPacket` provides a thin wrapper over the buffers exchanged via virtio queues.
|
||||||
/// There are two components to a vsock packet, each using its own descriptor in a
|
//! There are two components to a vsock packet, each using its own descriptor in a
|
||||||
/// virtio queue:
|
//! virtio queue:
|
||||||
/// - the packet header; and
|
//! - the packet header; and
|
||||||
/// - the packet data/buffer.
|
//! - the packet data/buffer.
|
||||||
/// There is a 1:1 relation between descriptor chains and packets: the first (chain head) holds
|
//! There is a 1:1 relation between descriptor chains and packets: the first (chain head) holds
|
||||||
/// the header, and an optional second descriptor holds the data. The second descriptor is only
|
//! the header, and an optional second descriptor holds the data. The second descriptor is only
|
||||||
/// present for data packets (VSOCK_OP_RW).
|
//! present for data packets (VSOCK_OP_RW).
|
||||||
///
|
//!
|
||||||
/// `VsockPacket` wraps these two buffers and provides direct access to the data stored
|
//! `VsockPacket` wraps these two buffers and provides direct access to the data stored
|
||||||
/// in guest memory. This is done to avoid unnecessarily copying data from guest memory
|
//! in guest memory. This is done to avoid unnecessarily copying data from guest memory
|
||||||
/// to temporary buffers, before passing it on to the vsock backend.
|
//! to temporary buffers, before passing it on to the vsock backend.
|
||||||
///
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
/// This module implements the Unix Domain Sockets backend for vsock - a mediator between
|
//! This module implements the Unix Domain Sockets backend for vsock - a mediator between
|
||||||
/// guest-side AF_VSOCK sockets and host-side AF_UNIX sockets. The heavy lifting is performed by
|
//! guest-side AF_VSOCK sockets and host-side AF_UNIX sockets. The heavy lifting is performed by
|
||||||
/// `muxer::VsockMuxer`, a connection multiplexer that uses `super::csm::VsockConnection` for
|
//! `muxer::VsockMuxer`, a connection multiplexer that uses `super::csm::VsockConnection` for
|
||||||
/// handling vsock connection states.
|
//! handling vsock connection states.
|
||||||
/// Check out `muxer.rs` for a more detailed explanation of the inner workings of this backend.
|
//!
|
||||||
///
|
//! Check out `muxer.rs` for a more detailed explanation of the inner workings of this backend.
|
||||||
|
|
||||||
mod muxer;
|
mod muxer;
|
||||||
mod muxer_killq;
|
mod muxer_killq;
|
||||||
mod muxer_rxq;
|
mod muxer_rxq;
|
||||||
|
|||||||
@@ -2,35 +2,42 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
/// `VsockMuxer` is the device-facing component of the Unix domain sockets vsock backend. I.e.
|
//! `VsockMuxer` is the device-facing component of the Unix domain sockets vsock backend. I.e.
|
||||||
/// by implementing the `VsockBackend` trait, it abstracts away the gory details of translating
|
//! by implementing the `VsockBackend` trait, it abstracts away the gory details of translating
|
||||||
/// between AF_VSOCK and AF_UNIX, and presents a clean interface to the rest of the vsock
|
//! between AF_VSOCK and AF_UNIX, and presents a clean interface to the rest of the vsock
|
||||||
/// device model.
|
//! device model.
|
||||||
///
|
//!
|
||||||
/// The vsock muxer has two main roles:
|
//! The vsock muxer has two main roles:
|
||||||
/// 1. Vsock connection multiplexer:
|
//!
|
||||||
/// It's the muxer's job to create, manage, and terminate `VsockConnection` objects. The
|
//! ## Vsock connection multiplexer
|
||||||
/// muxer also routes packets to their owning connections. It does so via a connection
|
//!
|
||||||
/// `HashMap`, keyed by what is basically a (host_port, guest_port) tuple.
|
//! It's the muxer's job to create, manage, and terminate `VsockConnection` objects. The
|
||||||
/// Vsock packet traffic needs to be inspected, in order to detect connection request
|
//! muxer also routes packets to their owning connections. It does so via a connection
|
||||||
/// packets (leading to the creation of a new connection), and connection reset packets
|
//! `HashMap`, keyed by what is basically a (host_port, guest_port) tuple.
|
||||||
/// (leading to the termination of an existing connection). All other packets, though, must
|
//!
|
||||||
/// belong to an existing connection and, as such, the muxer simply forwards them.
|
//! Vsock packet traffic needs to be inspected, in order to detect connection request
|
||||||
/// 2. Event dispatcher
|
//! packets (leading to the creation of a new connection), and connection reset packets
|
||||||
/// There are three event categories that the vsock backend is interested it:
|
//! (leading to the termination of an existing connection). All other packets, though, must
|
||||||
/// 1. A new host-initiated connection is ready to be accepted from the listening host Unix
|
//! belong to an existing connection and, as such, the muxer simply forwards them.
|
||||||
/// socket;
|
//!
|
||||||
/// 2. Data is available for reading from a newly-accepted host-initiated connection (i.e.
|
//! ## Event dispatcher
|
||||||
/// the host is ready to issue a vsock connection request, informing us of the
|
//!
|
||||||
/// destination port to which it wants to connect);
|
//! There are three event categories that the vsock backend is interested it:
|
||||||
/// 3. Some event was triggered for a connected Unix socket, that belongs to a
|
//! 1. A new host-initiated connection is ready to be accepted from the listening host Unix
|
||||||
/// `VsockConnection`.
|
//! socket;
|
||||||
/// The muxer gets notified about all of these events, because, as a `VsockEpollListener`
|
//! 2. Data is available for reading from a newly-accepted host-initiated connection (i.e.
|
||||||
/// implementor, it gets to register a nested epoll FD into the main VMM epolling loop. All
|
//! the host is ready to issue a vsock connection request, informing us of the
|
||||||
/// other pollable FDs are then registered under this nested epoll FD.
|
//! destination port to which it wants to connect);
|
||||||
/// To route all these events to their handlers, the muxer uses another `HashMap` object,
|
//! 3. Some event was triggered for a connected Unix socket, that belongs to a
|
||||||
/// mapping `RawFd`s to `EpollListener`s.
|
//! `VsockConnection`.
|
||||||
///
|
//!
|
||||||
|
//! The muxer gets notified about all of these events, because, as a `VsockEpollListener`
|
||||||
|
//! implementor, it gets to register a nested epoll FD into the main VMM epolling loop. All
|
||||||
|
//! other pollable FDs are then registered under this nested epoll FD.
|
||||||
|
//!
|
||||||
|
//! To route all these events to their handlers, the muxer uses another `HashMap` object,
|
||||||
|
//! mapping `RawFd`s to `EpollListener`s.
|
||||||
|
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Read};
|
use std::io::{self, Read};
|
||||||
|
|||||||
@@ -2,29 +2,29 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
/// `MuxerKillQ` implements a helper object that `VsockMuxer` can use for scheduling forced
|
//! `MuxerKillQ` implements a helper object that `VsockMuxer` can use for scheduling forced
|
||||||
/// connection termination. I.e. after one peer issues a clean shutdown request
|
//! connection termination. I.e. after one peer issues a clean shutdown request
|
||||||
/// (VSOCK_OP_SHUTDOWN), the concerned connection is queued for termination (VSOCK_OP_RST) in
|
//! (VSOCK_OP_SHUTDOWN), the concerned connection is queued for termination (VSOCK_OP_RST) in
|
||||||
/// the near future (herein implemented via an expiring timer).
|
//! the near future (herein implemented via an expiring timer).
|
||||||
///
|
//!
|
||||||
/// Whenever the muxer needs to schedule a connection for termination, it pushes it (or rather
|
//! Whenever the muxer needs to schedule a connection for termination, it pushes it (or rather
|
||||||
/// an identifier - the connection key) to this queue. A subsequent pop() operation will
|
//! an identifier - the connection key) to this queue. A subsequent pop() operation will
|
||||||
/// succeed if and only if the first connection in the queue is ready to be terminated (i.e.
|
//! succeed if and only if the first connection in the queue is ready to be terminated (i.e.
|
||||||
/// its kill timer expired).
|
//! its kill timer expired).
|
||||||
///
|
//!
|
||||||
/// Without using this queue, the muxer would have to walk its entire connection pool
|
//! Without using this queue, the muxer would have to walk its entire connection pool
|
||||||
/// (hashmap), whenever it needs to check for expired kill timers. With this queue, both
|
//! (hashmap), whenever it needs to check for expired kill timers. With this queue, both
|
||||||
/// scheduling and termination are performed in constant time. However, since we don't want to
|
//! scheduling and termination are performed in constant time. However, since we don't want to
|
||||||
/// waste space on a kill queue that's as big as the connection hashmap itself, it is possible
|
//! waste space on a kill queue that's as big as the connection hashmap itself, it is possible
|
||||||
/// that this queue may become full at times. We call this kill queue "synchronized" if we are
|
//! that this queue may become full at times. We call this kill queue "synchronized" if we are
|
||||||
/// certain that all connections that are awaiting termination are present in the queue. This
|
//! certain that all connections that are awaiting termination are present in the queue. This
|
||||||
/// means a simple constant-time pop() operation is enough to check whether any connections
|
//! means a simple constant-time pop() operation is enough to check whether any connections
|
||||||
/// need to be terminated. When the kill queue becomes full, though, pushing fails, so
|
//! need to be terminated. When the kill queue becomes full, though, pushing fails, so
|
||||||
/// connections that should be terminated are left out. The queue is not synchronized anymore.
|
//! connections that should be terminated are left out. The queue is not synchronized anymore.
|
||||||
/// When that happens, the muxer will first drain the queue, and then replace it with a new
|
//! When that happens, the muxer will first drain the queue, and then replace it with a new
|
||||||
/// queue, created by walking the connection pool, looking for connections that will be
|
//! queue, created by walking the connection pool, looking for connections that will be
|
||||||
/// expiring in the future.
|
//! expiring in the future.
|
||||||
///
|
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
|||||||
@@ -2,20 +2,20 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
/// `MuxerRxQ` implements a helper object that `VsockMuxer` can use for queuing RX (host -> guest)
|
//! `MuxerRxQ` implements a helper object that `VsockMuxer` can use for queuing RX (host -> guest)
|
||||||
/// packets (or rather instructions on how to build said packets).
|
//! packets (or rather instructions on how to build said packets).
|
||||||
///
|
//!
|
||||||
/// Under ideal operation, every connection, that has pending RX data, will be present in the muxer
|
//! Under ideal operation, every connection, that has pending RX data, will be present in the muxer
|
||||||
/// RX queue. However, since the RX queue is smaller than the connection pool, it may, under some
|
//! RX queue. However, since the RX queue is smaller than the connection pool, it may, under some
|
||||||
/// conditions, become full, meaning that it can no longer account for all the connections that can
|
//! conditions, become full, meaning that it can no longer account for all the connections that can
|
||||||
/// yield RX data. When that happens, we say that it is no longer "synchronized" (i.e. with the
|
//! yield RX data. When that happens, we say that it is no longer "synchronized" (i.e. with the
|
||||||
/// connection pool). A desynchronized RX queue still holds valid data, and the muxer will
|
//! connection pool). A desynchronized RX queue still holds valid data, and the muxer will
|
||||||
/// continue to pop packets from it. However, when a desynchronized queue is drained, additional
|
//! continue to pop packets from it. However, when a desynchronized queue is drained, additional
|
||||||
/// data may still be available, so the muxer will have to perform a more costly walk of the entire
|
//! data may still be available, so the muxer will have to perform a more costly walk of the entire
|
||||||
/// connection pool to find it. This walk is performed here, as part of building an RX queue from
|
//! connection pool to find it. This walk is performed here, as part of building an RX queue from
|
||||||
/// the connection pool. When an out-of-sync is drained, the muxer will discard it, and attempt to
|
//! the connection pool. When an out-of-sync is drained, the muxer will discard it, and attempt to
|
||||||
/// rebuild a synced one.
|
//! rebuild a synced one.
|
||||||
///
|
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
use super::super::VsockChannel;
|
use super::super::VsockChannel;
|
||||||
|
|||||||
Reference in New Issue
Block a user