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 forfriend
visibility yet, though there's proposals for C++ likefriend
relationship. So a proc macroexport_as_pub()
is introduced to rewrite private data structs/fields aspub
on demand when the featureexport_as_pub
is 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
bindgen
by#[derive(SerializeFfi, DeserializeFfi, DeserializeFfiFam)]
to - Provide
pub
access 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
, fieldstate
and fieldfeatures
will be rewritten aspub
when theexport_as_pub
feature 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 VmmObject
and fieldfeatures
will be rewritten aspub
when theexport_as_pub
feature 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_derive
to 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_alias
struct.
# 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
Serialize
trait and add deserialize() method to thekvm_msrs
struct.
# 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