A common requirement for virtual machine snapshot, live migration and live upgrading is to serialize and deserialize VMM internal objects and data structures. The rust community has the excellent serde/serde_derive framework for data serialization/deserialization. But the serde/serde_derive framework have very heavy dependency chain, and it's a common concern of the rust-vmm project to reduce dependency chain as small as possible. So this helper crate uses rust features to opt-in/opt-out data serialization/deserialization code and dependencies.
Currently following features are supported:
-
Feature
export_as_pub. The data serializer often needs to access private data structures or private fields in data structures. But rust has no support forfriendvisibility yet, though there's proposals for C++ likefriendrelationship. So a proc macroexport_as_pub()is introduced to rewrite private data structs/fields aspubon demand when the featureexport_as_pubis enabled. Otherwiseexport_as_pub()becomes a null operation. -
Feature
serde_derive. When this feature is enabled, the proc_macro_derive for De/Serialize is reexported from the serde_derive crate, otherwise#[derive(Serialize, Deserialize)]becomes a null operation. -
Feature
serde_derive_ffi. Often the bindgen utiltily is used to auto-generate FFI bindings for Linux syscalls and system libraries. And data structures with flexible array member are often used for input and/or output parameters. So three derive macros, SerializeFfi, DeserializeFfi and DeserializeFfiFam, are introduced to serialize data structures generated by bindgen.
There are three possible scenarios when serializing/deserializing VMM data structures:
- De/Serialize data structures from bindings generated by
bindgenby#[derive(SerializeFfi, DeserializeFfi, DeserializeFfiFam)]to - Provide
pubaccess to data structures/fields from rust-vmm crates by#[export_as_pub(fields)]. Then we may implement different de/serialization implementations for snapshot, live migration and live upgrade. - De/Serialize data structures from non-rust-vmm crates by remote deriving or manual coding.
- Export all fields of a data struct as
pub. Thestruct VmmObject, fieldstateand fieldfeatureswill be rewritten aspubwhen theexport_as_pubfeature is enabled.
extern crate vmm_serde;
#[vmm_serde::export_as_pub()]
pub(crate) struct VmmObject {
state: u32,
pub(crate) features: u64,
}- Export selected fields of a data structure as
pub. Thestruct VmmObjectand fieldfeatureswill be rewritten aspubwhen theexport_as_pubfeature is enabled.
extern crate vmm_serde;
[vmm_serde::export_as_pub(features)]
pub(crate) struct VmmObject {
state: u32,
pub(crate) features: u64,
}
- Opt-in/Opt-out #[derive(Serialize, Deserialize)]. Use feature
serde_deriveto opt-in/opt-out Serialize/Deserialize.
extern crate vmm_serde;
use vmm_serde::{Serialize, Deserialize};
#[derive(Serialize, Deserialize)]
pub struct VmmObject {
state: u32,
}
- Serialize/Deserialize Fix-sized FFI Data Structure. Implement Serialize/Deserialize traits for
the
kvm_memory_aliasstruct.
# extern crate vmm_serde;
# use vmm_serde::*;
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, PartialEq, SerializeFfi, DeserializeFfi)]
pub struct kvm_memory_alias {
pub slot: u32,
pub flags: u32,
pub guest_phys_addr: u64,
pub memory_size: u64,
pub target_phys_addr: u64,
}
- Serialize/Deserialize FFI Data Structure with Flexible Array Member. Implment
Serializetrait and add deserialize() method to thekvm_msrsstruct.
# extern crate vmm_serde;
# use vmm_serde::*;
#[repr(C)]
#[derive(Default, Debug, SerializeFfi, DeserializeFfi)]
pub struct __IncompleteArrayField<T>(::std::marker::PhantomData<T>, [T; 0]);
impl<T> __IncompleteArrayField<T> {
#[inline]
pub fn new() -> Self {
__IncompleteArrayField(::std::marker::PhantomData, [])
}
}
#[repr(C)]
#[derive(Debug, Default, SerializeFfi, DeserializeFfiFam)]
pub struct kvm_msrs {
pub nmsrs: u32,
pub pad: u32,
pub entries: __IncompleteArrayField<u64>,
}
impl SizeofFamStruct for kvm_msrs {
fn size_of(&self) -> usize {
self.nmsrs as usize * std::mem::size_of::<u64>() + std::mem::size_of::<Self>()
}
}
This project is licensed under
- Apache License, Version 2.0
- BSD 3 Clause