runtime-rs: add basic empty boilerplate for qemu driver

This does almost literally nothing so far apart from getting and setting
HypervisorConfig.  It's mostly copied from/inspired by dragonball.

Signed-off-by: Pavel Mores <pmores@redhat.com>
This commit is contained in:
Pavel Mores 2022-11-15 16:46:35 +01:00
parent ac1b2d2a18
commit 1413dfe91c
3 changed files with 262 additions and 0 deletions

View File

@ -14,6 +14,7 @@ pub mod hypervisor_persist;
pub use device::*;
pub mod dragonball;
mod kernel_param;
pub mod qemu;
pub use kernel_param::Param;
mod utils;
use std::collections::HashMap;
@ -28,6 +29,8 @@ const VM_ROOTFS_DRIVER_BLK: &str = "virtio-blk";
const VM_ROOTFS_DRIVER_PMEM: &str = "virtio-pmem";
pub const HYPERVISOR_DRAGONBALL: &str = "dragonball";
pub const HYPERVISOR_QEMU: &str = "qemu";
#[derive(PartialEq)]
pub(crate) enum VmmState {
NotReady,

View File

@ -0,0 +1,125 @@
// Copyright (c) 2022 Red Hat
//
// SPDX-License-Identifier: Apache-2.0
//
use anyhow::Result;
use crate::{HypervisorConfig, VcpuThreadIds};
use kata_types::capabilities::{Capabilities, CapabilityBits};
const VSOCK_SCHEME: &str = "vsock";
const VSOCK_AGENT_CID: u32 = 3;
const VSOCK_AGENT_PORT: u32 = 1024;
unsafe impl Send for QemuInner {}
unsafe impl Sync for QemuInner {}
pub struct QemuInner {
config: HypervisorConfig,
}
impl QemuInner {
pub fn new() -> QemuInner {
QemuInner {
config: Default::default(),
}
}
pub(crate) async fn prepare_vm(&mut self, _id: &str, _netns: Option<String>) -> Result<()> {
info!(sl!(), "Preparing QEMU VM");
Ok(())
}
pub(crate) async fn start_vm(&mut self, _timeout: i32) -> Result<()> {
info!(sl!(), "Starting QEMU VM");
Ok(())
}
pub(crate) fn stop_vm(&mut self) -> Result<()> {
info!(sl!(), "Stopping QEMU VM");
todo!()
}
pub(crate) fn pause_vm(&self) -> Result<()> {
info!(sl!(), "Pausing QEMU VM");
todo!()
}
pub(crate) fn resume_vm(&self) -> Result<()> {
info!(sl!(), "Resuming QEMU VM");
todo!()
}
pub(crate) async fn save_vm(&self) -> Result<()> {
todo!()
}
/// TODO: using a single hardcoded CID is clearly not adequate in the long
/// run. Use the recently added VsockConfig infrastructure to fix this.
pub(crate) async fn get_agent_socket(&self) -> Result<String> {
info!(sl!(), "QemuInner::get_agent_socket()");
Ok(format!(
"{}://{}:{}",
VSOCK_SCHEME, VSOCK_AGENT_CID, VSOCK_AGENT_PORT
))
}
pub(crate) async fn disconnect(&mut self) {
info!(sl!(), "QemuInner::disconnect()");
todo!()
}
pub(crate) async fn get_thread_ids(&self) -> Result<VcpuThreadIds> {
info!(sl!(), "QemuInner::get_thread_ids()");
todo!()
}
pub(crate) async fn cleanup(&self) -> Result<()> {
info!(sl!(), "QemuInner::cleanup()");
todo!()
}
pub(crate) async fn get_pids(&self) -> Result<Vec<u32>> {
info!(sl!(), "QemuInner::get_pids()");
todo!()
}
pub(crate) async fn check(&self) -> Result<()> {
todo!()
}
pub(crate) async fn get_jailer_root(&self) -> Result<String> {
todo!()
}
pub(crate) async fn capabilities(&self) -> Result<Capabilities> {
let mut caps = Capabilities::default();
caps.set(CapabilityBits::FsSharingSupport);
Ok(caps)
}
pub fn set_hypervisor_config(&mut self, config: HypervisorConfig) {
self.config = config;
}
pub fn hypervisor_config(&self) -> HypervisorConfig {
info!(sl!(), "QemuInner::hypervisor_config()");
self.config.clone()
}
}
use crate::device::Device;
// device manager part of Hypervisor
impl QemuInner {
pub(crate) async fn add_device(&mut self, device: Device) -> Result<()> {
info!(sl!(), "QemuInner::add_device() {}", device);
todo!()
}
pub(crate) async fn remove_device(&mut self, device: Device) -> Result<()> {
info!(sl!(), "QemuInner::remove_device() {} ", device);
todo!()
}
}

View File

@ -0,0 +1,134 @@
// Copyright (c) 2022 Red Hat
//
// SPDX-License-Identifier: Apache-2.0
//
mod inner;
use crate::device::Device;
use crate::hypervisor_persist::HypervisorState;
use crate::Hypervisor;
use crate::{HypervisorConfig, VcpuThreadIds};
use inner::QemuInner;
use kata_types::capabilities::Capabilities;
use anyhow::Result;
use async_trait::async_trait;
use std::sync::Arc;
use tokio::sync::RwLock;
pub struct Qemu {
inner: Arc<RwLock<QemuInner>>,
}
impl Default for Qemu {
fn default() -> Self {
Self::new()
}
}
impl Qemu {
pub fn new() -> Self {
Self {
inner: Arc::new(RwLock::new(QemuInner::new())),
}
}
pub async fn set_hypervisor_config(&mut self, config: HypervisorConfig) {
let mut inner = self.inner.write().await;
inner.set_hypervisor_config(config)
}
}
#[async_trait]
impl Hypervisor for Qemu {
async fn prepare_vm(&self, id: &str, netns: Option<String>) -> Result<()> {
let mut inner = self.inner.write().await;
inner.prepare_vm(id, netns).await
}
async fn start_vm(&self, timeout: i32) -> Result<()> {
let mut inner = self.inner.write().await;
inner.start_vm(timeout).await
}
async fn stop_vm(&self) -> Result<()> {
let mut inner = self.inner.write().await;
inner.stop_vm()
}
async fn pause_vm(&self) -> Result<()> {
let inner = self.inner.read().await;
inner.pause_vm()
}
async fn resume_vm(&self) -> Result<()> {
let inner = self.inner.read().await;
inner.resume_vm()
}
async fn save_vm(&self) -> Result<()> {
let inner = self.inner.read().await;
inner.save_vm().await
}
async fn add_device(&self, device: Device) -> Result<()> {
let mut inner = self.inner.write().await;
inner.add_device(device).await
}
async fn remove_device(&self, device: Device) -> Result<()> {
let mut inner = self.inner.write().await;
inner.remove_device(device).await
}
async fn get_agent_socket(&self) -> Result<String> {
let inner = self.inner.read().await;
inner.get_agent_socket().await
}
async fn disconnect(&self) {
let mut inner = self.inner.write().await;
inner.disconnect().await
}
async fn hypervisor_config(&self) -> HypervisorConfig {
let inner = self.inner.read().await;
inner.hypervisor_config()
}
async fn get_thread_ids(&self) -> Result<VcpuThreadIds> {
let inner = self.inner.read().await;
inner.get_thread_ids().await
}
async fn cleanup(&self) -> Result<()> {
let inner = self.inner.read().await;
inner.cleanup().await
}
async fn get_pids(&self) -> Result<Vec<u32>> {
let inner = self.inner.read().await;
inner.get_pids().await
}
async fn check(&self) -> Result<()> {
let inner = self.inner.read().await;
inner.check().await
}
async fn get_jailer_root(&self) -> Result<String> {
let inner = self.inner.read().await;
inner.get_jailer_root().await
}
async fn save_state(&self) -> Result<HypervisorState> {
todo!()
}
async fn capabilities(&self) -> Result<Capabilities> {
let inner = self.inner.read().await;
inner.capabilities().await
}
}