From f674019ea1283425cce06c05ce539ae3a5361e35 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 27 Sep 2019 11:40:50 +0200 Subject: [PATCH] vmm: {De}serialize VmConfig We use the serde crate to serialize and deserialize the VmVConfig structure. This structure will be passed from the HTTP API caller as a JSON payload and we need to deserialize it into a VmConfig. For a convenient use of the HTTP API, we also provide Default traits implementations for some of the VmConfig fields (vCPUs, memory, etc...). Signed-off-by: Samuel Ortiz --- Cargo.lock | 14 +++++++++ src/main.rs | 7 +++-- vmm/Cargo.toml | 3 ++ vmm/src/config.rs | 80 ++++++++++++++++++++++++++++++++++++----------- vmm/src/lib.rs | 4 +++ 5 files changed, 87 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 528326a13..a670506fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -767,6 +767,16 @@ name = "serde" version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "serde_derive" +version = "1.0.101" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "serde_json" version = "1.0.41" @@ -1084,6 +1094,9 @@ dependencies = [ "net_util 0.1.0", "pci 0.1.0", "qcow 0.1.0", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", "signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", "threadpool 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "vfio 0.0.1", @@ -1226,6 +1239,7 @@ dependencies = [ "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" +"checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" "checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" "checksum signal-hook 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4f61c4d59f3aaa9f61bba6450a9b80ba48362fd7d651689e7a10c453b1f6dc68" "checksum signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1797d48f38f91643908bb14e35e79928f9f4b3cefb2420a564dde0991b4358dc" diff --git a/src/main.rs b/src/main.rs index 65868a2e6..70c011baa 100755 --- a/src/main.rs +++ b/src/main.rs @@ -79,6 +79,9 @@ fn main() { } } + let default_vcpus = format! {"{}", config::DEFAULT_VCPUS}; + let default_memory = &format! {"size={}M", config::DEFAULT_MEMORY_MB}; + let cmd_arguments = App::new("cloud-hypervisor") .version(crate_version!()) .author(crate_authors!()) @@ -89,7 +92,7 @@ fn main() { Arg::with_name("cpus") .long("cpus") .help("Number of virtual CPUs") - .default_value(config::DEFAULT_VCPUS) + .default_value(&default_vcpus) .group("vm-config"), ) .arg( @@ -99,7 +102,7 @@ fn main() { "Memory parameters \"size=,\ file=\"", ) - .default_value(config::DEFAULT_MEMORY) + .default_value(&default_memory) .group("vm-config"), ) .arg( diff --git a/vmm/Cargo.toml b/vmm/Cargo.toml index 40f5e3a5e..6c4109ded 100644 --- a/vmm/Cargo.toml +++ b/vmm/Cargo.toml @@ -25,6 +25,9 @@ micro_http = { path = "../micro_http" } net_util = { path = "../net_util" } pci = {path = "../pci", optional = true} qcow = { path = "../qcow" } +serde = {version = ">=1.0.27", features = ["rc"] } +serde_derive = ">=1.0.27" +serde_json = ">=1.0.9" vfio = { path = "../vfio", optional = true } vm-virtio = { path = "../vm-virtio" } vm-allocator = { path = "../vm-allocator" } diff --git a/vmm/src/config.rs b/vmm/src/config.rs index cc656a790..c5c889fa0 100644 --- a/vmm/src/config.rs +++ b/vmm/src/config.rs @@ -12,8 +12,8 @@ use std::net::Ipv4Addr; use std::path::PathBuf; use std::result; -pub const DEFAULT_VCPUS: &str = "1"; -pub const DEFAULT_MEMORY: &str = "size=512M"; +pub const DEFAULT_VCPUS: u8 = 1; +pub const DEFAULT_MEMORY_MB: u64 = 512; pub const DEFAULT_RNG_SOURCE: &str = "/dev/urandom"; /// Errors associated with VM configuration parameters. @@ -114,7 +114,7 @@ fn parse_size(size: &str) -> Result { Ok(res << shift) } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct CpusConfig(pub u8); impl CpusConfig { @@ -131,7 +131,13 @@ impl From<&CpusConfig> for u8 { } } -#[derive(Clone, Debug)] +impl Default for CpusConfig { + fn default() -> Self { + CpusConfig(DEFAULT_VCPUS) + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct MemoryConfig { pub size: u64, pub file: Option, @@ -172,12 +178,21 @@ impl MemoryConfig { } } -#[derive(Clone, Debug)] +impl Default for MemoryConfig { + fn default() -> Self { + MemoryConfig { + size: DEFAULT_MEMORY_MB << 20, + file: None, + } + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct KernelConfig { pub path: PathBuf, } -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct CmdlineConfig { pub args: String, } @@ -192,7 +207,7 @@ impl CmdlineConfig { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct DiskConfig { pub path: PathBuf, } @@ -205,7 +220,7 @@ impl DiskConfig { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct NetConfig { pub tap: Option, pub ip: Ipv4Addr, @@ -257,7 +272,7 @@ impl NetConfig { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct RngConfig { pub src: PathBuf, } @@ -270,7 +285,15 @@ impl RngConfig { } } -#[derive(Clone, Debug)] +impl Default for RngConfig { + fn default() -> Self { + RngConfig { + src: PathBuf::from(DEFAULT_RNG_SOURCE), + } + } +} + +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct FsConfig { pub tag: String, pub sock: PathBuf, @@ -358,7 +381,7 @@ impl FsConfig { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct PmemConfig { pub file: PathBuf, pub size: u64, @@ -391,7 +414,7 @@ impl PmemConfig { } } -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Deserialize, Serialize)] pub enum ConsoleOutputMode { Off, Tty, @@ -408,7 +431,7 @@ impl ConsoleOutputMode { } } -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct ConsoleConfig { pub file: Option, pub mode: ConsoleOutputMode, @@ -440,9 +463,23 @@ impl ConsoleConfig { Err(Error::ParseConsoleParam) } } + + pub fn default_serial() -> Self { + ConsoleConfig { + file: None, + mode: ConsoleOutputMode::Null, + } + } + + pub fn default_console() -> Self { + ConsoleConfig { + file: None, + mode: ConsoleOutputMode::Tty, + } + } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct DeviceConfig { pub path: PathBuf, } @@ -455,14 +492,14 @@ impl DeviceConfig { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct VuConfig { pub sock: String, pub num_queues: usize, pub queue_size: u16, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct VhostUserNetConfig { pub mac: MacAddr, pub vu_cfg: VuConfig, @@ -521,7 +558,7 @@ impl VhostUserNetConfig { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct VsockConfig { pub cid: u64, pub sock: PathBuf, @@ -554,7 +591,7 @@ impl VsockConfig { } } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Deserialize, Serialize)] pub struct VhostUserBlkConfig { pub wce: bool, pub vu_cfg: VuConfig, @@ -610,18 +647,23 @@ impl VhostUserBlkConfig { } } -#[derive(Clone)] +#[derive(Clone, Deserialize, Serialize)] pub struct VmConfig { + #[serde(default)] pub cpus: CpusConfig, + #[serde(default)] pub memory: MemoryConfig, pub kernel: Option, pub cmdline: CmdlineConfig, pub disks: Option>, pub net: Option>, + #[serde(default)] pub rng: RngConfig, pub fs: Option>, pub pmem: Option>, + #[serde(default = "ConsoleConfig::default_serial")] pub serial: ConsoleConfig, + #[serde(default = "ConsoleConfig::default_console")] pub console: ConsoleConfig, pub devices: Option>, pub vhost_user_net: Option>, diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index ef0c480ef..26f069dd2 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -8,6 +8,10 @@ extern crate lazy_static; #[macro_use] extern crate log; +extern crate serde; +#[macro_use] +extern crate serde_derive; +extern crate serde_json; extern crate vmm_sys_util; use crate::api::{ApiError, ApiRequest, ApiResponse, ApiResponsePayload};