From 274de024c5322d95c0f19106a62a27ca2326592d Mon Sep 17 00:00:00 2001 From: Zhongtao Hu Date: Wed, 21 Sep 2022 02:00:59 +0800 Subject: [PATCH] docs: add README for runtime-rs hypervisor crate add README for runtime-rs hypervisor crate Fixes:#4634 Signed-off-by: Zhongtao Hu --- src/runtime-rs/crates/hypervisor/README.md | 94 +++++++++++ .../docs/images/hypervisor-config.svg | 150 ++++++++++++++++++ src/runtime-rs/docs/images/vm-start.svg | 60 +++++++ 3 files changed, 304 insertions(+) create mode 100644 src/runtime-rs/crates/hypervisor/README.md create mode 100644 src/runtime-rs/docs/images/hypervisor-config.svg create mode 100644 src/runtime-rs/docs/images/vm-start.svg diff --git a/src/runtime-rs/crates/hypervisor/README.md b/src/runtime-rs/crates/hypervisor/README.md new file mode 100644 index 0000000000..8d43baa702 --- /dev/null +++ b/src/runtime-rs/crates/hypervisor/README.md @@ -0,0 +1,94 @@ +# Multi-vmm support for runtime-rs +Some key points for supporting multi-vmm in rust runtime. +## 1. Hypervisor Config + +The diagram below gives an overview for the hypervisor config + +![hypervisor config](../../docs/images/hypervisor-config.svg) + +VMM's config info will be loaded when initialize the runtime instance, there are some important functions need to be focused on. +### `VirtContainer::init()` + +This function initialize the runtime handler. It will register the plugins into the HYPERVISOR_PLUGINS. Different plugins are needed for different hypervisors. +```rust +#[async_trait] +impl RuntimeHandler for VirtContainer { + fn init() -> Result<()> { + // register + let dragonball_config = Arc::new(DragonballConfig::new()); + register_hypervisor_plugin("dragonball", dragonball_config); + Ok(()) + } +} +``` + +[This is the plugin method for QEMU. Other VMM plugin methods haven't support currently.](../../../libs/kata-types/src/config/hypervisor/qemu.rs) +QEMU plugin defines the methods to adjust and validate the hypervisor config file, those methods could be modified if it is needed. + +After that, when loading the TOML config, the plugins will be called to adjust and validate the config file. +```rust +async fn try_init(&mut self, spec: &oci::Spec) -> Result<()> {、 + ... + let config = load_config(spec).context("load config")?; + ... +} +``` + +### new_instance + +This function will create a runtime_instance which include the operations for container and sandbox. At the same time, a hypervisor instance will be created. QEMU instance will be created here as well, and set the hypervisor config file +```rust +async fn new_hypervisor(toml_config: &TomlConfig) -> Result> { + let hypervisor_name = &toml_config.runtime.hypervisor_name; + let hypervisor_config = toml_config + .hypervisor + .get(hypervisor_name) + .ok_or_else(|| anyhow!("failed to get hypervisor for {}", &hypervisor_name)) + .context("get hypervisor")?; + + // TODO: support other hypervisor + match hypervisor_name.as_str() { + HYPERVISOR_DRAGONBALL => { + let mut hypervisor = Dragonball::new(); + hypervisor + .set_hypervisor_config(hypervisor_config.clone()) + .await; + Ok(Arc::new(hypervisor)) + } + _ => Err(anyhow!("Unsupported hypervisor {}", &hypervisor_name)), + } +} +``` + +## 2. Hypervisor Trait + +[To support multi-vmm, the hypervisor trait need to be implemented.](./src/lib.rs) +```rust +pub trait Hypervisor: Send + Sync { + // vm manager + async fn prepare_vm(&self, id: &str, netns: Option) -> Result<()>; + async fn start_vm(&self, timeout: i32) -> Result<()>; + async fn stop_vm(&self) -> Result<()>; + async fn pause_vm(&self) -> Result<()>; + async fn save_vm(&self) -> Result<()>; + async fn resume_vm(&self) -> Result<()>; + + // device manager + async fn add_device(&self, device: device::Device) -> Result<()>; + async fn remove_device(&self, device: device::Device) -> Result<()>; + + // utils + async fn get_agent_socket(&self) -> Result; + async fn disconnect(&self); + async fn hypervisor_config(&self) -> HypervisorConfig; + async fn get_thread_ids(&self) -> Result; + async fn get_pids(&self) -> Result>; + async fn cleanup(&self) -> Result<()>; + async fn check(&self) -> Result<()>; + async fn get_jailer_root(&self) -> Result; + async fn save_state(&self) -> Result; + } +``` +In current design, VM will be started in the following steps. + +![vmm start](../../docs/images/vm-start.svg) diff --git a/src/runtime-rs/docs/images/hypervisor-config.svg b/src/runtime-rs/docs/images/hypervisor-config.svg new file mode 100644 index 0000000000..a396cd04b3 --- /dev/null +++ b/src/runtime-rs/docs/images/hypervisor-config.svg @@ -0,0 +1,150 @@ +confighypervisor_modHYPERVISOR_PLUGINSConfigPluginname()adjust_config()validate()get_min_memory()get_max_cpus()ConfigOpsadjust_config()validate()TomlConfigagent: HashMap<String, Agent>hypervisor: HashMap<String, Hypervisor>runtime: Runtimeload_from_file()load_raw_from_file()load()validate()get_default_config_file()blockdev_infoboot_infocpu_infodebug_infodevice_infomachine_infomemory_infonetwork_infosecurity_infoshared_fsHypervisorvalidate_hypervisor_path()validate_hypervisor_ctlpath()validate_jailer_path()adjust_config()validate()dragonballnew()register()name()adjust_config()validate()get_min_memory()get_max_cpus()qemunew()register()name()adjust_config()validate()get_min_memory()get_max_cpus()cloudHypervisornew()register()name()adjust_config()validate()get_min_memory()get_max_cpus() \ No newline at end of file diff --git a/src/runtime-rs/docs/images/vm-start.svg b/src/runtime-rs/docs/images/vm-start.svg new file mode 100644 index 0000000000..ad85bf32f3 --- /dev/null +++ b/src/runtime-rs/docs/images/vm-start.svg @@ -0,0 +1,60 @@ +hypervisorhypervisorsandbox startsandbox startagentagentresource_managerresource_managerresource_manager_innerresource_manager_innershare_fsshare_fsnetworknetwork1prepare_vm()fill the hypervisor struct,set the vmm state, or anything needed before start vm2prepare_before_start_vm()3prepare_before_start_vm()4setup_device_before_start_vm ()5prepare_virtiofs()prepare share_fs device6add_device()add share_fs device to the pending list7new()scan the network namespace to get the endpoint and create the network pair8setup()setup the network model for each network pair9add_device()add tap/Macvtap device to the pending list10start_vm()hypervisor start here11get_agent_socket()12start()13setup_after_start_vm()14setup_after_start_vm()15setup_device_after_start_vm()setup virtiofs16add_device()Share the source path into the guest17handle_interfaces()18handle_neighbours()19handle_routes()Update the network like neighbours, interface and routes20create_sandbox() \ No newline at end of file