Skip to content

Commit 218d87c

Browse files
committed
add QueueStateSer
This provides serialization capabilities to QueueState, and is defined in the virtio-queue-ser crate. QueueStateSer mirrors the state structure from virtio-queue, and derives the required (de)serialization/versioning traits (i.e. Serialize, Deserialize, Versionize). Signed-off-by: Laura Loghin <[email protected]>
1 parent c1c4c03 commit 218d87c

File tree

5 files changed

+149
-1
lines changed

5 files changed

+149
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[workspace]
22
members = [
33
"crates/virtio-queue",
4+
"crates/virtio-queue-ser",
45
"crates/virtio-device",
56
"crates/devices/*",
67
]

crates/virtio-queue-ser/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "virtio-queue-ser"
3+
version = "0.1.0"
4+
authors = ["rust-vmm AWS maintainers <[email protected]>"]
5+
description = "Serialization for virtio queue state"
6+
repository = "https://github.com/rust-vmm/vm-virtio"
7+
keywords = ["queue", "serialization", "versioning"]
8+
readme = "README.md"
9+
license = "Apache-2.0 OR BSD-3-Clause"
10+
edition = "2018"
11+
12+
[dependencies]
13+
serde = { version = ">=1.0.27", features = ["derive"] }
14+
versionize = ">=0.1.6"
15+
versionize_derive = ">=0.1.3"
16+
virtio-queue = { path = "../../crates/virtio-queue" }
17+
vm-memory = "0.7.0"

crates/virtio-queue-ser/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
4+
5+
//! Adds serialization capabilities to the state objects from `virtio-queue`.
6+
//!
7+
//! Provides wrappers over the state objects from `virtio-queue` crate that
8+
//! implement the `Serialize`, `Deserialize` and `Versionize` traits.
9+
10+
#![deny(missing_docs)]
11+
12+
mod state;
13+
14+
pub use state::QueueStateSer;
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
4+
5+
use std::num::Wrapping;
6+
7+
use serde::{Deserialize, Serialize};
8+
use versionize::{VersionMap, Versionize, VersionizeResult};
9+
use versionize_derive::Versionize;
10+
use virtio_queue::QueueState;
11+
use vm_memory::GuestAddress;
12+
13+
/// /// Wrapper over a `QueueState` that has serialization capabilities.
14+
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, Versionize)]
15+
pub struct QueueStateSer {
16+
/// The maximum size in elements offered by the device.
17+
pub max_size: u16,
18+
/// Tail position of the available ring.
19+
pub next_avail: Wrapping<u16>,
20+
/// Head position of the used ring.
21+
pub next_used: Wrapping<u16>,
22+
/// VIRTIO_F_RING_EVENT_IDX negotiated.
23+
pub event_idx_enabled: bool,
24+
/// The last used value when using VIRTIO_F_EVENT_IDX.
25+
pub signalled_used: Option<Wrapping<u16>>,
26+
/// The queue size in elements the driver selected.
27+
pub size: u16,
28+
/// Indicates if the queue finished with the configuration.
29+
pub ready: bool,
30+
/// Guest physical address of the descriptor table.
31+
pub desc_table: u64,
32+
/// Guest physical address of the available ring.
33+
pub avail_ring: u64,
34+
/// Guest physical address of the used ring.
35+
pub used_ring: u64,
36+
}
37+
38+
// The following `From` implementations can be used to convert from a `QueueStateSer` to the
39+
// `QueueState` from the base crate and vice versa.
40+
impl From<&QueueStateSer> for QueueState {
41+
fn from(state: &QueueStateSer) -> Self {
42+
QueueState {
43+
max_size: state.max_size,
44+
next_avail: state.next_avail,
45+
next_used: state.next_used,
46+
event_idx_enabled: state.event_idx_enabled,
47+
signalled_used: state.signalled_used,
48+
size: state.size,
49+
ready: state.ready,
50+
desc_table: GuestAddress(state.desc_table),
51+
avail_ring: GuestAddress(state.avail_ring),
52+
used_ring: GuestAddress(state.used_ring),
53+
}
54+
}
55+
}
56+
57+
impl From<&QueueState> for QueueStateSer {
58+
fn from(state: &QueueState) -> Self {
59+
QueueStateSer {
60+
max_size: state.max_size,
61+
next_avail: state.next_avail,
62+
next_used: state.next_used,
63+
event_idx_enabled: state.event_idx_enabled,
64+
signalled_used: state.signalled_used,
65+
size: state.size,
66+
ready: state.ready,
67+
desc_table: state.desc_table.0,
68+
avail_ring: state.avail_ring.0,
69+
used_ring: state.used_ring.0,
70+
}
71+
}
72+
}
73+
74+
impl Default for QueueStateSer {
75+
fn default() -> Self {
76+
QueueStateSer::from(&QueueState::default())
77+
}
78+
}
79+
80+
#[cfg(test)]
81+
mod tests {
82+
use super::*;
83+
84+
#[test]
85+
fn test_state_ser() {
86+
const SOME_VALUE: u16 = 16;
87+
88+
let state = QueueState {
89+
max_size: SOME_VALUE * 2,
90+
next_avail: Wrapping(SOME_VALUE - 1),
91+
next_used: Wrapping(SOME_VALUE + 1),
92+
event_idx_enabled: false,
93+
signalled_used: None,
94+
size: SOME_VALUE,
95+
ready: false,
96+
desc_table: GuestAddress(SOME_VALUE as u64),
97+
avail_ring: GuestAddress(SOME_VALUE as u64),
98+
used_ring: GuestAddress(SOME_VALUE as u64),
99+
};
100+
101+
let ser_state = QueueStateSer::from(&state);
102+
103+
let state_after_restore = QueueState::from(&ser_state);
104+
105+
// Check that the old and the new state are identical when using the intermediate
106+
// `QueueStateSer` object as well.
107+
assert_eq!(state, state_after_restore);
108+
109+
// Test the `Default` implementation of `QueueStateSer`.
110+
let default_queue_state_ser = QueueStateSer::default();
111+
assert_eq!(
112+
QueueState::from(&default_queue_state_ser),
113+
QueueState::default()
114+
);
115+
}
116+
}

crates/virtio-queue/src/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::defs::{
2222
use crate::{error, AvailIter, Descriptor, Error, QueueStateGuard, QueueStateT, VirtqUsedElem};
2323

2424
/// Struct to maintain information and manipulate state of a virtio queue.
25-
#[derive(Clone, Debug)]
25+
#[derive(Clone, Debug, Default, PartialEq)]
2626
pub struct QueueState {
2727
/// The maximum size in elements offered by the device.
2828
pub max_size: u16,

0 commit comments

Comments
 (0)