Skip to content

Commit

Permalink
feat(xen): update xenclient and xenplatform to the latest structure
Browse files Browse the repository at this point in the history
  • Loading branch information
azenla committed Dec 14, 2024
1 parent f9d4508 commit 31533c0
Show file tree
Hide file tree
Showing 24 changed files with 2,143 additions and 1,089 deletions.
8 changes: 8 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ repository = "https://github.com/edera-dev/krata"

[workspace.dependencies]
async-trait = "0.1.83"
bit-vec = "0.8.0"
byteorder = "1"
c2rust-bitfields = "0.19.0"
elf = "0.7.4"
env_logger = "0.11.5"
flate2 = "1.0"
Expand Down
2 changes: 2 additions & 0 deletions crates/xen/xenclient/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ edition = "2021"
resolver = "2"

[dependencies]
async-trait = { workspace = true }
bit-vec = { workspace = true }
indexmap = { workspace = true }
log = { workspace = true }
krata-xencall = { path = "../xencall", version = "^0.0.23" }
Expand Down
65 changes: 32 additions & 33 deletions crates/xen/xenclient/examples/boot.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
use std::sync::Arc;
use std::{env, process};
use tokio::fs;
use uuid::Uuid;
use xenclient::error::Result;
use xenclient::{DomainConfig, XenClient};
use xenplatform::domain::BaseDomainConfig;

#[cfg(target_arch = "x86_64")]
type RuntimePlatform = xenplatform::x86pv::X86PvPlatform;

#[cfg(not(target_arch = "x86_64"))]
type RuntimePlatform = xenplatform::unsupported::UnsupportedPlatform;
use xenclient::tx::channel::ChannelDeviceConfig;
use xenclient::{config::DomainConfig, XenClient};
use xenplatform::domain::{
KernelFormat, PlatformDomainConfig, PlatformKernelConfig, PlatformOptions,
PlatformResourcesConfig,
};
use xenplatform::RuntimePlatformType;

#[tokio::main]
async fn main() -> Result<()> {
Expand All @@ -22,32 +22,31 @@ async fn main() -> Result<()> {
}
let kernel_image_path = args.get(1).expect("argument not specified");
let initrd_path = args.get(2).expect("argument not specified");
let client = XenClient::new(0, RuntimePlatform::new()).await?;
let config = DomainConfig {
base: BaseDomainConfig {
uuid: Uuid::new_v4(),
max_vcpus: 1,
target_vcpus: 1,
max_mem_mb: 512,
target_mem_mb: 512,
enable_iommu: true,
kernel: fs::read(&kernel_image_path).await?,
initrd: fs::read(&initrd_path).await?,
let client = XenClient::new().await?;

let mut config = DomainConfig::new();
config.platform(PlatformDomainConfig {
uuid: Uuid::new_v4(),
platform: RuntimePlatformType::Pv,
kernel: PlatformKernelConfig {
data: Arc::new(fs::read(&kernel_image_path).await?),
format: KernelFormat::ElfCompressed,
cmdline: "earlyprintk=xen earlycon=xen console=hvc0 init=/init".to_string(),
owner_domid: 0,
initrd: Some(Arc::new(fs::read(&initrd_path).await?)),
},
resources: PlatformResourcesConfig {
max_vcpus: 1,
assigned_vcpus: 1,
max_memory_mb: 512,
assigned_memory_mb: 512,
},
backend_domid: 0,
name: "xenclient-test".to_string(),
swap_console_backend: None,
disks: vec![],
channels: vec![],
vifs: vec![],
pcis: vec![],
filesystems: vec![],
extra_keys: vec![],
extra_rw_paths: vec![],
};
let created = client.create(&config).await?;
println!("created domain {}", created.domid);
options: PlatformOptions { iommu: true },
});
config.name("xenclient-test");
let mut channel = ChannelDeviceConfig::new();
channel.default_console().backend_initialized();
config.add_channel(channel);
let created = client.create(config).await?;
println!("created domain {}", created.platform.domid);
Ok(())
}
66 changes: 66 additions & 0 deletions crates/xen/xenclient/examples/boot_speed.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use std::sync::Arc;
use std::{env, process};
use tokio::fs;
use uuid::Uuid;
use xenclient::config::{DomainConfig, DomainResult};
use xenclient::error::Result;
use xenclient::tx::channel::ChannelDeviceConfig;
use xenclient::XenClient;
use xenplatform::domain::{
KernelFormat, PlatformDomainConfig, PlatformKernelConfig, PlatformOptions,
PlatformResourcesConfig,
};
use xenplatform::elfloader::ElfImageLoader;
use xenplatform::RuntimePlatformType;

#[tokio::main]
async fn main() -> Result<()> {
env_logger::init();

let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("usage: boot-speed <kernel-image>");
process::exit(1);
}
let kernel_path = args.get(1).expect("argument not specified");
let kernel = Arc::new(fs::read(kernel_path).await?);
let kernel = ElfImageLoader::load(kernel)?.into_elf_bytes();
let client = XenClient::new().await?;

for i in 0..5u32 {
let start = std::time::Instant::now();
let domain = create_domain(&client, kernel.clone(), i).await?;
let end = std::time::Instant::now();
let duration = end - start;
println!("boot setup time: {:?}", duration);
client.destroy(domain.platform.domid).await?;
}
Ok(())
}

async fn create_domain(client: &XenClient, kernel: Arc<Vec<u8>>, i: u32) -> Result<DomainResult> {
let mut config = DomainConfig::new();
config.platform(PlatformDomainConfig {
uuid: Uuid::new_v4(),
platform: RuntimePlatformType::Pv,
kernel: PlatformKernelConfig {
data: kernel,
format: KernelFormat::ElfUncompressed,
cmdline: "earlyprintk=xen earlycon=xen console=hvc0 init=/init".to_string(),
initrd: None,
},
resources: PlatformResourcesConfig {
max_vcpus: 1,
assigned_vcpus: 1,
max_memory_mb: 512,
assigned_memory_mb: 512,
},
options: PlatformOptions { iommu: true },
});
config.name(format!("xenboot-{}", i));
config.start(false);
let mut channel = ChannelDeviceConfig::new();
channel.default_console().backend_initialized();
config.add_channel(channel);
client.create(config).await
}
185 changes: 185 additions & 0 deletions crates/xen/xenclient/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
use std::collections::HashMap;

use xencall::XenCall;
pub use xenplatform::domain::PlatformDomainConfig;
use xenplatform::domain::PlatformDomainInfo;

use crate::{
error::Result,
tx::{
channel::ChannelDeviceConfig,
fs9p::Fs9pDeviceConfig,
pci::PciRootDeviceConfig,
vbd::VbdDeviceConfig,
vif::VifDeviceConfig,
{BlockDeviceResult, DeviceResult},
},
};

pub struct DomainConfig {
platform: Option<PlatformDomainConfig>,
name: Option<String>,
backend_domid: u32,
channels: Vec<ChannelDeviceConfig>,
vifs: Vec<VifDeviceConfig>,
vbds: Vec<VbdDeviceConfig>,
fs9ps: Vec<Fs9pDeviceConfig>,
pci: Option<PciRootDeviceConfig>,
extra_keys: HashMap<String, String>,
extra_rw_paths: Vec<String>,
start: bool,
}

impl Default for DomainConfig {
fn default() -> Self {
Self::new()
}
}

impl DomainConfig {
pub fn new() -> Self {
Self {
platform: None,
name: None,
backend_domid: 0,
channels: Vec::new(),
vifs: Vec::new(),
vbds: Vec::new(),
fs9ps: Vec::new(),
pci: None,
extra_keys: HashMap::new(),
extra_rw_paths: Vec::new(),
start: true,
}
}

pub fn platform(&mut self, platform: PlatformDomainConfig) -> &mut Self {
self.platform = Some(platform);
self
}

pub fn get_platform(&self) -> &Option<PlatformDomainConfig> {
&self.platform
}

pub fn name(&mut self, name: impl AsRef<str>) -> &mut Self {
self.name = Some(name.as_ref().to_string());
self
}

pub fn get_name(&self) -> &Option<String> {
&self.name
}

pub fn backend_domid(&mut self, backend_domid: u32) -> &mut Self {
self.backend_domid = backend_domid;
self
}

pub fn get_backend_domid(&self) -> u32 {
self.backend_domid
}

pub fn add_channel(&mut self, channel: ChannelDeviceConfig) -> &mut Self {
self.channels.push(channel);
self
}

pub fn get_channels(&self) -> &Vec<ChannelDeviceConfig> {
&self.channels
}

pub fn add_vif(&mut self, vif: VifDeviceConfig) -> &mut Self {
self.vifs.push(vif);
self
}

pub fn get_vifs(&self) -> &Vec<VifDeviceConfig> {
&self.vifs
}

pub fn add_vbd(&mut self, vbd: VbdDeviceConfig) -> &mut Self {
self.vbds.push(vbd);
self
}

pub fn get_vbds(&self) -> &Vec<VbdDeviceConfig> {
&self.vbds
}

pub fn add_fs9p(&mut self, fs9p: Fs9pDeviceConfig) -> &mut Self {
self.fs9ps.push(fs9p);
self
}

pub fn get_fs9ps(&self) -> &Vec<Fs9pDeviceConfig> {
&self.fs9ps
}

pub fn pci(&mut self, pci: PciRootDeviceConfig) -> &mut Self {
self.pci = Some(pci);
self
}

pub fn get_pci(&self) -> &Option<PciRootDeviceConfig> {
&self.pci
}

pub fn add_extra_key(&mut self, key: impl AsRef<str>, value: impl ToString) -> &mut Self {
self.extra_keys
.insert(key.as_ref().to_string(), value.to_string());
self
}

pub fn get_extra_keys(&self) -> &HashMap<String, String> {
&self.extra_keys
}

pub fn add_rw_path(&mut self, path: impl AsRef<str>) -> &mut Self {
self.extra_rw_paths.push(path.as_ref().to_string());
self
}

pub fn get_rw_paths(&self) -> &Vec<String> {
&self.extra_rw_paths
}

pub fn start(&mut self, start: bool) -> &mut Self {
self.start = start;
self
}

pub fn get_start(&self) -> bool {
self.start
}

pub fn done(self) -> Self {
self
}

pub(crate) async fn prepare(
&mut self,
domid: u32,
call: &XenCall,
platform: &PlatformDomainInfo,
) -> Result<()> {
if let Some(pci) = self.pci.as_mut() {
pci.prepare(domid, call).await?;
}

for channel in &mut self.channels {
channel.prepare(platform).await?;
}

Ok(())
}
}

pub struct DomainResult {
pub platform: PlatformDomainInfo,
pub channels: Vec<DeviceResult>,
pub vifs: Vec<DeviceResult>,
pub vbds: Vec<BlockDeviceResult>,
pub fs9ps: Vec<DeviceResult>,
pub pci: Option<DeviceResult>,
}
Loading

0 comments on commit 31533c0

Please sign in to comment.