Skip to content

Commit 3adf9b5

Browse files
authored
feat(xen): update xenclient and xenplatform to the latest structure (#433)
1 parent f9d4508 commit 3adf9b5

24 files changed

Lines changed: 2143 additions & 1089 deletions

Cargo.lock

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ repository = "https://github.com/edera-dev/krata"
1717

1818
[workspace.dependencies]
1919
async-trait = "0.1.83"
20+
bit-vec = "0.8.0"
2021
byteorder = "1"
21-
c2rust-bitfields = "0.19.0"
2222
elf = "0.7.4"
2323
env_logger = "0.11.5"
2424
flate2 = "1.0"

crates/xen/xenclient/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ edition = "2021"
99
resolver = "2"
1010

1111
[dependencies]
12+
async-trait = { workspace = true }
13+
bit-vec = { workspace = true }
1214
indexmap = { workspace = true }
1315
log = { workspace = true }
1416
krata-xencall = { path = "../xencall", version = "^0.0.23" }
Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1+
use std::sync::Arc;
12
use std::{env, process};
23
use tokio::fs;
34
use uuid::Uuid;
45
use xenclient::error::Result;
5-
use xenclient::{DomainConfig, XenClient};
6-
use xenplatform::domain::BaseDomainConfig;
7-
8-
#[cfg(target_arch = "x86_64")]
9-
type RuntimePlatform = xenplatform::x86pv::X86PvPlatform;
10-
11-
#[cfg(not(target_arch = "x86_64"))]
12-
type RuntimePlatform = xenplatform::unsupported::UnsupportedPlatform;
6+
use xenclient::tx::channel::ChannelDeviceConfig;
7+
use xenclient::{config::DomainConfig, XenClient};
8+
use xenplatform::domain::{
9+
KernelFormat, PlatformDomainConfig, PlatformKernelConfig, PlatformOptions,
10+
PlatformResourcesConfig,
11+
};
12+
use xenplatform::RuntimePlatformType;
1313

1414
#[tokio::main]
1515
async fn main() -> Result<()> {
@@ -22,32 +22,31 @@ async fn main() -> Result<()> {
2222
}
2323
let kernel_image_path = args.get(1).expect("argument not specified");
2424
let initrd_path = args.get(2).expect("argument not specified");
25-
let client = XenClient::new(0, RuntimePlatform::new()).await?;
26-
let config = DomainConfig {
27-
base: BaseDomainConfig {
28-
uuid: Uuid::new_v4(),
29-
max_vcpus: 1,
30-
target_vcpus: 1,
31-
max_mem_mb: 512,
32-
target_mem_mb: 512,
33-
enable_iommu: true,
34-
kernel: fs::read(&kernel_image_path).await?,
35-
initrd: fs::read(&initrd_path).await?,
25+
let client = XenClient::new().await?;
26+
27+
let mut config = DomainConfig::new();
28+
config.platform(PlatformDomainConfig {
29+
uuid: Uuid::new_v4(),
30+
platform: RuntimePlatformType::Pv,
31+
kernel: PlatformKernelConfig {
32+
data: Arc::new(fs::read(&kernel_image_path).await?),
33+
format: KernelFormat::ElfCompressed,
3634
cmdline: "earlyprintk=xen earlycon=xen console=hvc0 init=/init".to_string(),
37-
owner_domid: 0,
35+
initrd: Some(Arc::new(fs::read(&initrd_path).await?)),
36+
},
37+
resources: PlatformResourcesConfig {
38+
max_vcpus: 1,
39+
assigned_vcpus: 1,
40+
max_memory_mb: 512,
41+
assigned_memory_mb: 512,
3842
},
39-
backend_domid: 0,
40-
name: "xenclient-test".to_string(),
41-
swap_console_backend: None,
42-
disks: vec![],
43-
channels: vec![],
44-
vifs: vec![],
45-
pcis: vec![],
46-
filesystems: vec![],
47-
extra_keys: vec![],
48-
extra_rw_paths: vec![],
49-
};
50-
let created = client.create(&config).await?;
51-
println!("created domain {}", created.domid);
43+
options: PlatformOptions { iommu: true },
44+
});
45+
config.name("xenclient-test");
46+
let mut channel = ChannelDeviceConfig::new();
47+
channel.default_console().backend_initialized();
48+
config.add_channel(channel);
49+
let created = client.create(config).await?;
50+
println!("created domain {}", created.platform.domid);
5251
Ok(())
5352
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use std::sync::Arc;
2+
use std::{env, process};
3+
use tokio::fs;
4+
use uuid::Uuid;
5+
use xenclient::config::{DomainConfig, DomainResult};
6+
use xenclient::error::Result;
7+
use xenclient::tx::channel::ChannelDeviceConfig;
8+
use xenclient::XenClient;
9+
use xenplatform::domain::{
10+
KernelFormat, PlatformDomainConfig, PlatformKernelConfig, PlatformOptions,
11+
PlatformResourcesConfig,
12+
};
13+
use xenplatform::elfloader::ElfImageLoader;
14+
use xenplatform::RuntimePlatformType;
15+
16+
#[tokio::main]
17+
async fn main() -> Result<()> {
18+
env_logger::init();
19+
20+
let args: Vec<String> = env::args().collect();
21+
if args.len() != 2 {
22+
println!("usage: boot-speed <kernel-image>");
23+
process::exit(1);
24+
}
25+
let kernel_path = args.get(1).expect("argument not specified");
26+
let kernel = Arc::new(fs::read(kernel_path).await?);
27+
let kernel = ElfImageLoader::load(kernel)?.into_elf_bytes();
28+
let client = XenClient::new().await?;
29+
30+
for i in 0..5u32 {
31+
let start = std::time::Instant::now();
32+
let domain = create_domain(&client, kernel.clone(), i).await?;
33+
let end = std::time::Instant::now();
34+
let duration = end - start;
35+
println!("boot setup time: {:?}", duration);
36+
client.destroy(domain.platform.domid).await?;
37+
}
38+
Ok(())
39+
}
40+
41+
async fn create_domain(client: &XenClient, kernel: Arc<Vec<u8>>, i: u32) -> Result<DomainResult> {
42+
let mut config = DomainConfig::new();
43+
config.platform(PlatformDomainConfig {
44+
uuid: Uuid::new_v4(),
45+
platform: RuntimePlatformType::Pv,
46+
kernel: PlatformKernelConfig {
47+
data: kernel,
48+
format: KernelFormat::ElfUncompressed,
49+
cmdline: "earlyprintk=xen earlycon=xen console=hvc0 init=/init".to_string(),
50+
initrd: None,
51+
},
52+
resources: PlatformResourcesConfig {
53+
max_vcpus: 1,
54+
assigned_vcpus: 1,
55+
max_memory_mb: 512,
56+
assigned_memory_mb: 512,
57+
},
58+
options: PlatformOptions { iommu: true },
59+
});
60+
config.name(format!("xenboot-{}", i));
61+
config.start(false);
62+
let mut channel = ChannelDeviceConfig::new();
63+
channel.default_console().backend_initialized();
64+
config.add_channel(channel);
65+
client.create(config).await
66+
}

crates/xen/xenclient/src/config.rs

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
use std::collections::HashMap;
2+
3+
use xencall::XenCall;
4+
pub use xenplatform::domain::PlatformDomainConfig;
5+
use xenplatform::domain::PlatformDomainInfo;
6+
7+
use crate::{
8+
error::Result,
9+
tx::{
10+
channel::ChannelDeviceConfig,
11+
fs9p::Fs9pDeviceConfig,
12+
pci::PciRootDeviceConfig,
13+
vbd::VbdDeviceConfig,
14+
vif::VifDeviceConfig,
15+
{BlockDeviceResult, DeviceResult},
16+
},
17+
};
18+
19+
pub struct DomainConfig {
20+
platform: Option<PlatformDomainConfig>,
21+
name: Option<String>,
22+
backend_domid: u32,
23+
channels: Vec<ChannelDeviceConfig>,
24+
vifs: Vec<VifDeviceConfig>,
25+
vbds: Vec<VbdDeviceConfig>,
26+
fs9ps: Vec<Fs9pDeviceConfig>,
27+
pci: Option<PciRootDeviceConfig>,
28+
extra_keys: HashMap<String, String>,
29+
extra_rw_paths: Vec<String>,
30+
start: bool,
31+
}
32+
33+
impl Default for DomainConfig {
34+
fn default() -> Self {
35+
Self::new()
36+
}
37+
}
38+
39+
impl DomainConfig {
40+
pub fn new() -> Self {
41+
Self {
42+
platform: None,
43+
name: None,
44+
backend_domid: 0,
45+
channels: Vec::new(),
46+
vifs: Vec::new(),
47+
vbds: Vec::new(),
48+
fs9ps: Vec::new(),
49+
pci: None,
50+
extra_keys: HashMap::new(),
51+
extra_rw_paths: Vec::new(),
52+
start: true,
53+
}
54+
}
55+
56+
pub fn platform(&mut self, platform: PlatformDomainConfig) -> &mut Self {
57+
self.platform = Some(platform);
58+
self
59+
}
60+
61+
pub fn get_platform(&self) -> &Option<PlatformDomainConfig> {
62+
&self.platform
63+
}
64+
65+
pub fn name(&mut self, name: impl AsRef<str>) -> &mut Self {
66+
self.name = Some(name.as_ref().to_string());
67+
self
68+
}
69+
70+
pub fn get_name(&self) -> &Option<String> {
71+
&self.name
72+
}
73+
74+
pub fn backend_domid(&mut self, backend_domid: u32) -> &mut Self {
75+
self.backend_domid = backend_domid;
76+
self
77+
}
78+
79+
pub fn get_backend_domid(&self) -> u32 {
80+
self.backend_domid
81+
}
82+
83+
pub fn add_channel(&mut self, channel: ChannelDeviceConfig) -> &mut Self {
84+
self.channels.push(channel);
85+
self
86+
}
87+
88+
pub fn get_channels(&self) -> &Vec<ChannelDeviceConfig> {
89+
&self.channels
90+
}
91+
92+
pub fn add_vif(&mut self, vif: VifDeviceConfig) -> &mut Self {
93+
self.vifs.push(vif);
94+
self
95+
}
96+
97+
pub fn get_vifs(&self) -> &Vec<VifDeviceConfig> {
98+
&self.vifs
99+
}
100+
101+
pub fn add_vbd(&mut self, vbd: VbdDeviceConfig) -> &mut Self {
102+
self.vbds.push(vbd);
103+
self
104+
}
105+
106+
pub fn get_vbds(&self) -> &Vec<VbdDeviceConfig> {
107+
&self.vbds
108+
}
109+
110+
pub fn add_fs9p(&mut self, fs9p: Fs9pDeviceConfig) -> &mut Self {
111+
self.fs9ps.push(fs9p);
112+
self
113+
}
114+
115+
pub fn get_fs9ps(&self) -> &Vec<Fs9pDeviceConfig> {
116+
&self.fs9ps
117+
}
118+
119+
pub fn pci(&mut self, pci: PciRootDeviceConfig) -> &mut Self {
120+
self.pci = Some(pci);
121+
self
122+
}
123+
124+
pub fn get_pci(&self) -> &Option<PciRootDeviceConfig> {
125+
&self.pci
126+
}
127+
128+
pub fn add_extra_key(&mut self, key: impl AsRef<str>, value: impl ToString) -> &mut Self {
129+
self.extra_keys
130+
.insert(key.as_ref().to_string(), value.to_string());
131+
self
132+
}
133+
134+
pub fn get_extra_keys(&self) -> &HashMap<String, String> {
135+
&self.extra_keys
136+
}
137+
138+
pub fn add_rw_path(&mut self, path: impl AsRef<str>) -> &mut Self {
139+
self.extra_rw_paths.push(path.as_ref().to_string());
140+
self
141+
}
142+
143+
pub fn get_rw_paths(&self) -> &Vec<String> {
144+
&self.extra_rw_paths
145+
}
146+
147+
pub fn start(&mut self, start: bool) -> &mut Self {
148+
self.start = start;
149+
self
150+
}
151+
152+
pub fn get_start(&self) -> bool {
153+
self.start
154+
}
155+
156+
pub fn done(self) -> Self {
157+
self
158+
}
159+
160+
pub(crate) async fn prepare(
161+
&mut self,
162+
domid: u32,
163+
call: &XenCall,
164+
platform: &PlatformDomainInfo,
165+
) -> Result<()> {
166+
if let Some(pci) = self.pci.as_mut() {
167+
pci.prepare(domid, call).await?;
168+
}
169+
170+
for channel in &mut self.channels {
171+
channel.prepare(platform).await?;
172+
}
173+
174+
Ok(())
175+
}
176+
}
177+
178+
pub struct DomainResult {
179+
pub platform: PlatformDomainInfo,
180+
pub channels: Vec<DeviceResult>,
181+
pub vifs: Vec<DeviceResult>,
182+
pub vbds: Vec<BlockDeviceResult>,
183+
pub fs9ps: Vec<DeviceResult>,
184+
pub pci: Option<DeviceResult>,
185+
}

0 commit comments

Comments
 (0)