diff --git a/Cargo.toml b/Cargo.toml index 86c2cc8..1db482c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ name = "axvmconfig" path = "src/main.rs" [dependencies] -axerrno = "0.1.0" +axerrno = "0.2.0" clap = {version = "4.5.23", optional = true, features = ["derive"]} enumerable = {version = "1.2", default-features = false} env_logger = {version = "0.11.3", optional = true} diff --git a/src/lib.rs b/src/lib.rs index 8e19403..ca424dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -259,6 +259,34 @@ pub struct PassThroughDeviceConfig { pub irq_id: usize, } +/// A part of `AxVMConfig`, which represents the configuration of a VirtIO block device for a virtual machine. +#[cfg_attr(feature = "std", derive(schemars::JsonSchema))] +#[derive(Debug, Default, Clone, serde::Serialize, serde::Deserialize)] +pub struct VirtioBlkMmioDeviceConfig { + /// The device ID. + pub device_id: String, + /// The MMIO base address. + pub mmio_base: String, + /// The MMIO size. + pub mmio_size: String, + /// The interrupt type. + pub interrupt_type: String, + /// The interrupt number. + pub interrupt_number: usize, + /// The guest device path. + pub guest_device_path: String, + /// The backend type. + pub backend_type: String, + /// The backend path. + pub backend_path: String, + /// The image size. + pub size: String, + /// Whether the device is readonly. + pub readonly: bool, + /// The serial number. + pub serial: String, +} + /// A part of `AxVMConfig`, which represents the configuration of a pass-through address for a virtual machine. #[cfg_attr(feature = "std", derive(schemars::JsonSchema))] #[derive(Debug, Default, Clone, PartialEq, serde::Serialize, serde::Deserialize)] @@ -367,6 +395,8 @@ pub struct VMDevicesConfig { /// How the VM should handle interrupts and interrupt controllers. #[serde(default)] pub interrupt_mode: VMInterruptMode, + /// VirtIO block device Information + pub virtio_blk_mmio: Option>, ///we would not like to pass through devices #[serde(default)] pub excluded_devices: Vec>, diff --git a/src/templates.rs b/src/templates.rs index 69df4a7..9405a49 100644 --- a/src/templates.rs +++ b/src/templates.rs @@ -2,7 +2,9 @@ //! //! This module provides functionality to generate VM configuration templates //! with sensible defaults based on user-provided parameters. -use crate::{AxVMCrateConfig, VMBaseConfig, VMDevicesConfig, VMKernelConfig}; +use crate::{ + AxVMCrateConfig, VMBaseConfig, VMDevicesConfig, VMKernelConfig, VirtioBlkMmioDeviceConfig, +}; /// Generate a VM configuration template with specified parameters. /// @@ -20,6 +22,7 @@ use crate::{AxVMCrateConfig, VMBaseConfig, VMDevicesConfig, VMKernelConfig}; /// * `kernel_load_addr` - Address where kernel should be loaded /// * `image_location` - Location of kernel image ("fs" or "memory") /// * `cmdline` - Optional kernel command line parameters +/// * `virtio_blk_mmio` - Optional VirtIO block device configuration /// /// # Returns /// * `AxVMCrateConfig` - Complete VM configuration structure @@ -33,6 +36,7 @@ pub fn get_vm_config_template( kernel_load_addr: usize, image_location: String, cmdline: Option, + virtio_blk_mmio: Option>, ) -> AxVMCrateConfig { AxVMCrateConfig { // Basic VM configuration @@ -66,6 +70,7 @@ pub fn get_vm_config_template( emu_devices: vec![], // No emulated devices by default passthrough_devices: vec![], // No passthrough devices by default interrupt_mode: Default::default(), // Use default interrupt mode + virtio_blk_mmio, // Use virtio_blk device excluded_devices: vec![], // No excluded devices by default passthrough_addresses: vec![], // No passthrough addresses by default }, diff --git a/src/tool.rs b/src/tool.rs index 30149e7..73e014d 100644 --- a/src/tool.rs +++ b/src/tool.rs @@ -10,7 +10,7 @@ use std::path::Path; use clap::{Args, Parser, Subcommand}; use crate::templates::get_vm_config_template; -use crate::AxVMCrateConfig; +use crate::{AxVMCrateConfig, VirtioBlkMmioDeviceConfig}; /// Main CLI structure for the axvmconfig tool /// @@ -93,6 +93,20 @@ pub struct TemplateArgs { /// The output path of the template file. #[arg(short = 'O', long, value_name = "DIR", value_hint = clap::ValueHint::DirPath)] output: Option, + + // Virtual block device related parameters + /// Enable virtual block device + #[arg(long)] + enable_virtio_blk: bool, + /// Virtual block device backend path + #[arg(long)] + virtio_blk_backend_path: Option, + /// Virtual block device MMIO base address + #[arg(long, default_value_t = String::from("0x10000000"))] + virtio_blk_mmio_base: String, + /// Virtual block device interrupt number + #[arg(long, default_value_t = 10)] + virtio_blk_irq: usize, } /// Parse numeric values from command line arguments @@ -173,6 +187,32 @@ pub fn run() { args.kernel_path.clone() }; + // Build virtual block device configuration (if enabled) + let virtio_blk_mmio = if args.enable_virtio_blk { + if let Some(backend_path) = args.virtio_blk_backend_path { + // Create block device configuration + let blk_device = VirtioBlkMmioDeviceConfig { + device_id: format!("virtio-blk-{}", args.id), + mmio_base: args.virtio_blk_mmio_base, + mmio_size: String::from("0x1000"), + interrupt_type: String::from("irq"), + interrupt_number: args.virtio_blk_irq, + guest_device_path: String::from("/dev/vda"), + backend_type: String::from("file"), + backend_path: backend_path, + size: String::from("0"), // Auto detect size + readonly: false, + serial: format!("blk{}", args.id), + }; + Some(vec![blk_device]) + } else { + eprintln!("Error: Backend path (virtio_blk_backend_path) must be specified when enabling virtual block device"); + std::process::exit(1); + } + } else { + None + }; + // Generate the VM configuration template with provided parameters let template = get_vm_config_template( args.id, @@ -184,6 +224,7 @@ pub fn run() { args.kernel_load_addr, args.image_location, args.cmdline, + virtio_blk_mmio, ); // Convert the configuration template to TOML format