diff --git a/alioth-cli/src/boot.rs b/alioth-cli/src/boot/boot.rs similarity index 75% rename from alioth-cli/src/boot.rs rename to alioth-cli/src/boot/boot.rs index b6e143ae..2a473273 100644 --- a/alioth-cli/src/boot.rs +++ b/alioth-cli/src/boot/boot.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +mod config; + use std::collections::HashMap; use std::ffi::CString; use std::mem; @@ -25,23 +27,28 @@ use alioth::errors::{DebugTrace, trace_error}; use alioth::hv::Hvf; #[cfg(target_os = "linux")] use alioth::hv::Kvm; -use alioth::hv::{Coco, HvConfig}; +use alioth::hv::{Coco, HvConfig, Hypervisor}; use alioth::loader::{Executable, Payload}; use alioth::mem::{MemBackend, MemConfig}; #[cfg(target_os = "linux")] use alioth::vfio::{CdevParam, ContainerParam, GroupParam, IoasParam}; +#[cfg(target_os = "linux")] +use alioth::virtio::DeviceId; use alioth::virtio::dev::balloon::BalloonParam; use alioth::virtio::dev::blk::BlkFileParam; use alioth::virtio::dev::entropy::EntropyParam; +#[cfg(target_os = "linux")] +use alioth::virtio::vu::frontend::VuFrontendParam; use alioth::virtio::worker::WorkerApi; use alioth::vm::Machine; -use alioth::vm::config::{BlkParam, Config, FsParam, NetParam, VsockParam}; use clap::Args; use serde_aco::help_text; use snafu::{ResultExt, Snafu}; use crate::objects::{DOC_OBJECTS, parse_objects}; +use self::config::{BlkParam, Config, FsParam, NetParam, VsockParam}; + #[trace_error] #[derive(Snafu, DebugTrace)] #[snafu(module, context(suffix(false)))] @@ -338,6 +345,111 @@ fn parse_args(mut args: BootArgs, objects: HashMap<&str, &str>) -> Result(hypervisor: &H, config: Config) -> Result, alioth::vm::Error> { + let vm = Machine::new(hypervisor, config.board)?; + + #[cfg(target_arch = "x86_64")] + vm.add_com1()?; + #[cfg(target_arch = "aarch64")] + vm.add_pl011()?; + #[cfg(target_arch = "aarch64")] + vm.add_pl031(); + + if config.pvpanic { + vm.add_pvpanic()?; + } + + #[cfg(target_arch = "x86_64")] + if config.payload.firmware.is_some() || !config.fw_cfg.is_empty() { + vm.add_fw_cfg(config.fw_cfg.into_iter())?; + }; + + if let Some(param) = config.entropy { + vm.add_virtio_dev("virtio-entropy", param)?; + } + + for (index, param) in config.net.into_iter().enumerate() { + match param { + #[cfg(target_os = "linux")] + NetParam::Tap(tap_param) => vm.add_virtio_dev(format!("virtio-net-{index}"), tap_param), + #[cfg(target_os = "linux")] + NetParam::Vu(sock) => { + let param = VuFrontendParam { + id: DeviceId::Net, + socket: sock.socket, + }; + vm.add_virtio_dev(format!("vu-net-{index}"), param) + } + #[cfg(target_os = "macos")] + NetParam::Vmnet(p) => vm.add_virtio_dev(format!("virtio-net-{index}"), p), + }?; + } + + for (index, param) in config.blk.into_iter().enumerate() { + match param { + BlkParam::File(p) => vm.add_virtio_dev(format!("virtio-blk-{index}"), p), + #[cfg(target_os = "linux")] + BlkParam::Vu(s) => { + let p = VuFrontendParam { + id: DeviceId::Block, + socket: s.socket, + }; + vm.add_virtio_dev(format!("vu-net-{index}"), p) + } + }?; + } + + for (index, param) in config.fs.into_iter().enumerate() { + match param { + FsParam::Dir(p) => vm.add_virtio_dev(format!("virtio-fs-{index}"), p), + #[cfg(target_os = "linux")] + FsParam::Vu(p) => vm.add_virtio_dev(format!("vu-fs-{index}"), p), + }?; + } + + if let Some(param) = config.vsock { + match param { + #[cfg(target_os = "linux")] + VsockParam::Vhost(p) => vm.add_virtio_dev("vhost-vsock", p), + VsockParam::Uds(p) => vm.add_virtio_dev("uds-vsock", p), + #[cfg(target_os = "linux")] + VsockParam::Vu(s) => { + let p = VuFrontendParam { + id: DeviceId::Socket, + socket: s.socket, + }; + vm.add_virtio_dev("vu-vsock", p) + } + }?; + } + + if let Some(param) = config.balloon { + vm.add_virtio_dev("virtio-balloon", param)?; + } + + #[cfg(target_os = "linux")] + for param in config.vfio_ioas.into_iter() { + vm.add_vfio_ioas(param)?; + } + #[cfg(target_os = "linux")] + for (index, param) in config.vfio_cdev.into_iter().enumerate() { + vm.add_vfio_cdev(format!("vfio-{index}").into(), param)?; + } + + #[cfg(target_os = "linux")] + for param in config.vfio_container.into_iter() { + vm.add_vfio_container(param)?; + } + #[cfg(target_os = "linux")] + for (index, param) in config.vfio_group.into_iter().enumerate() { + vm.add_vfio_devs_in_group(&index.to_string(), param)?; + } + + vm.add_payload(config.payload); + + Ok(vm) +} + pub fn boot(mut args: BootArgs) -> Result<(), Error> { let object_args = mem::take(&mut args.objects); let objects = parse_objects(&object_args)?; @@ -356,7 +468,7 @@ pub fn boot(mut args: BootArgs) -> Result<(), Error> { let config = parse_args(args, objects)?; - let vm = Machine::new(hypervisor, config).context(error::CreateVm)?; + let vm = create(&hypervisor, config).context(error::CreateVm)?; vm.boot().context(error::BootVm)?; vm.wait().context(error::WaitVm)?; diff --git a/alioth-cli/src/boot_test.rs b/alioth-cli/src/boot/boot_test.rs similarity index 99% rename from alioth-cli/src/boot_test.rs rename to alioth-cli/src/boot/boot_test.rs index f73fb8a4..41c8c046 100644 --- a/alioth-cli/src/boot_test.rs +++ b/alioth-cli/src/boot/boot_test.rs @@ -35,7 +35,6 @@ use alioth::virtio::dev::net::tap::NetTapParam; use alioth::virtio::dev::net::vmnet::NetVmnetParam; use alioth::virtio::dev::vsock::UdsVsockParam; use alioth::virtio::worker::WorkerApi; -use alioth::vm::config::{BlkParam, Config, FsParam, NetParam, VsockParam}; use pretty_assertions::assert_eq; use rstest::rstest; @@ -44,6 +43,8 @@ use crate::boot::{ parse_payload_arg, }; +use super::{BlkParam, Config, FsParam, NetParam, VsockParam}; + #[test] fn test_parse_args() { let args = BootArgs { diff --git a/alioth/src/vm/config.rs b/alioth-cli/src/boot/config.rs similarity index 84% rename from alioth/src/vm/config.rs rename to alioth-cli/src/boot/config.rs index 925cc9ff..0d26f72f 100644 --- a/alioth/src/vm/config.rs +++ b/alioth-cli/src/boot/config.rs @@ -15,25 +15,23 @@ #[cfg(target_os = "linux")] use std::path::Path; -use serde::Deserialize; -use serde_aco::Help; - -use crate::board::BoardConfig; +use alioth::board::BoardConfig; #[cfg(target_arch = "x86_64")] -use crate::device::fw_cfg::FwCfgItemParam; -use crate::loader::Payload; -use crate::virtio::dev::balloon::BalloonParam; -use crate::virtio::dev::blk::BlkFileParam; -use crate::virtio::dev::entropy::EntropyParam; -use crate::virtio::dev::fs::shared_dir::SharedDirParam; +use alioth::device::fw_cfg::FwCfgItemParam; +use alioth::loader::Payload; +#[cfg(target_os = "linux")] +use alioth::vfio::{CdevParam, ContainerParam, GroupParam, IoasParam}; +use alioth::virtio::dev::balloon::BalloonParam; +use alioth::virtio::dev::blk::BlkFileParam; +use alioth::virtio::dev::entropy::EntropyParam; +use alioth::virtio::dev::fs::shared_dir::SharedDirParam; #[cfg(target_os = "macos")] -use crate::virtio::dev::net::vmnet::NetVmnetParam; -use crate::virtio::dev::vsock::UdsVsockParam; +use alioth::virtio::dev::net::vmnet::NetVmnetParam; +use alioth::virtio::dev::vsock::UdsVsockParam; #[cfg(target_os = "linux")] -use crate::{ - vfio::{CdevParam, ContainerParam, GroupParam, IoasParam}, - virtio::dev::{fs::vu::VuFsParam, net::tap::NetTapParam, vsock::VhostVsockParam}, -}; +use alioth::virtio::dev::{fs::vu::VuFsParam, net::tap::NetTapParam, vsock::VhostVsockParam}; +use serde::Deserialize; +use serde_aco::Help; #[cfg(target_os = "linux")] #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Help)] diff --git a/alioth-cli/src/main.rs b/alioth-cli/src/main.rs index 203e4917..ff30f9ea 100644 --- a/alioth-cli/src/main.rs +++ b/alioth-cli/src/main.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +#[path = "boot/boot.rs"] mod boot; mod img; mod objects; diff --git a/alioth/src/vm/vm.rs b/alioth/src/vm/vm.rs index 0ab00683..8a12d3d4 100644 --- a/alioth/src/vm/vm.rs +++ b/alioth/src/vm/vm.rs @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -pub mod config; - #[cfg(target_os = "linux")] use std::path::Path; use std::sync::Arc; @@ -29,7 +27,7 @@ use snafu::{ResultExt, Snafu}; use crate::arch::layout::{PL011_START, PL031_START}; #[cfg(target_arch = "x86_64")] use crate::arch::layout::{PORT_COM1, PORT_FW_CFG_SELECTOR}; -use crate::board::{ArchBoard, Board}; +use crate::board::{ArchBoard, Board, BoardConfig}; #[cfg(target_arch = "x86_64")] use crate::device::fw_cfg::{FwCfg, FwCfgItemParam}; #[cfg(target_arch = "aarch64")] @@ -55,21 +53,13 @@ use crate::vfio::container::{Container, UpdateContainerMapping}; #[cfg(target_os = "linux")] use crate::vfio::group::{DevFd, Group}; #[cfg(target_os = "linux")] -use crate::vfio::iommu::UpdateIommuIoas; -#[cfg(target_os = "linux")] -use crate::vfio::iommu::{Ioas, Iommu}; +use crate::vfio::iommu::{Ioas, Iommu, UpdateIommuIoas}; #[cfg(target_os = "linux")] use crate::vfio::pci::VfioPciDev; #[cfg(target_os = "linux")] use crate::vfio::{CdevParam, ContainerParam, GroupParam, IoasParam}; -#[cfg(target_os = "linux")] -use crate::virtio::DeviceId; use crate::virtio::dev::{DevParam, Virtio, VirtioDevice}; use crate::virtio::pci::VirtioPciDevice; -#[cfg(target_os = "linux")] -use crate::virtio::vu::frontend::VuFrontendParam; - -use self::config::{BlkParam, Config, FsParam, NetParam, VsockParam}; #[trace_error] #[derive(Snafu, DebugTrace)] @@ -127,21 +117,20 @@ pub type VirtioPciDev = VirtioPciDevice< impl Machine where - H: Hypervisor + 'static, + H: Hypervisor, { - pub fn new(hv: H, config: Config) -> Result { - let mut board_config = config.board; - board_config.config_fixup()?; + pub fn new(hv: &H, mut config: BoardConfig) -> Result { + config.config_fixup()?; let vm_config = VmConfig { - coco: board_config.coco.clone(), + coco: config.coco.clone(), }; let mut vm = hv.create_vm(&vm_config)?; let vm_memory = vm.create_vm_memory()?; let memory = Memory::new(vm_memory); - let arch = ArchBoard::new(&hv, &vm, &board_config)?; + let arch = ArchBoard::new(hv, &vm, &config)?; - let board = Arc::new(Board::new(vm, memory, arch, board_config)); + let board = Arc::new(Board::new(vm, memory, arch, config)); let (event_tx, event_rx) = mpsc::channel(); @@ -171,107 +160,6 @@ where iommu: Mutex::new(None), }; - #[cfg(target_arch = "x86_64")] - vm.add_com1()?; - #[cfg(target_arch = "aarch64")] - vm.add_pl011()?; - #[cfg(target_arch = "aarch64")] - vm.add_pl031(); - - if config.pvpanic { - vm.add_pvpanic()?; - } - - #[cfg(target_arch = "x86_64")] - if config.payload.firmware.is_some() || !config.fw_cfg.is_empty() { - vm.add_fw_cfg(config.fw_cfg.into_iter())?; - }; - - if let Some(param) = config.entropy { - vm.add_virtio_dev("virtio-entropy", param)?; - } - - for (index, param) in config.net.into_iter().enumerate() { - match param { - #[cfg(target_os = "linux")] - NetParam::Tap(tap_param) => { - vm.add_virtio_dev(format!("virtio-net-{index}"), tap_param) - } - #[cfg(target_os = "linux")] - NetParam::Vu(sock) => { - let param = VuFrontendParam { - id: DeviceId::Net, - socket: sock.socket, - }; - vm.add_virtio_dev(format!("vu-net-{index}"), param) - } - #[cfg(target_os = "macos")] - NetParam::Vmnet(p) => vm.add_virtio_dev(format!("virtio-net-{index}"), p), - }?; - } - - for (index, param) in config.blk.into_iter().enumerate() { - match param { - BlkParam::File(p) => vm.add_virtio_dev(format!("virtio-blk-{index}"), p), - #[cfg(target_os = "linux")] - BlkParam::Vu(s) => { - let p = VuFrontendParam { - id: DeviceId::Block, - socket: s.socket, - }; - vm.add_virtio_dev(format!("vu-net-{index}"), p) - } - }?; - } - - for (index, param) in config.fs.into_iter().enumerate() { - match param { - FsParam::Dir(p) => vm.add_virtio_dev(format!("virtio-fs-{index}"), p), - #[cfg(target_os = "linux")] - FsParam::Vu(p) => vm.add_virtio_dev(format!("vu-fs-{index}"), p), - }?; - } - - if let Some(param) = config.vsock { - match param { - #[cfg(target_os = "linux")] - VsockParam::Vhost(p) => vm.add_virtio_dev("vhost-vsock", p), - VsockParam::Uds(p) => vm.add_virtio_dev("uds-vsock", p), - #[cfg(target_os = "linux")] - VsockParam::Vu(s) => { - let p = VuFrontendParam { - id: DeviceId::Socket, - socket: s.socket, - }; - vm.add_virtio_dev("vu-vsock", p) - } - }?; - } - - if let Some(param) = config.balloon { - vm.add_virtio_dev("virtio-balloon", param)?; - } - - #[cfg(target_os = "linux")] - for param in config.vfio_ioas.into_iter() { - vm.add_vfio_ioas(param)?; - } - #[cfg(target_os = "linux")] - for (index, param) in config.vfio_cdev.into_iter().enumerate() { - vm.add_vfio_cdev(format!("vfio-{index}").into(), param)?; - } - - #[cfg(target_os = "linux")] - for param in config.vfio_container.into_iter() { - vm.add_vfio_container(param)?; - } - #[cfg(target_os = "linux")] - for (index, param) in config.vfio_group.into_iter().enumerate() { - vm.add_vfio_devs_in_group(&index.to_string(), param)?; - } - - vm.add_payload(config.payload); - Ok(vm) } @@ -419,7 +307,7 @@ where #[cfg(target_os = "linux")] impl Machine where - H: Hypervisor + 'static, + H: Hypervisor, { const DEFAULT_NAME: &str = "default";