mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-03 05:10:55 +00:00
@ -6,8 +6,9 @@ use krata::{
|
|||||||
events::EventStream,
|
events::EventStream,
|
||||||
v1::{
|
v1::{
|
||||||
common::{
|
common::{
|
||||||
zone_image_spec::Image, OciImageFormat, ZoneImageSpec, ZoneOciImageSpec, ZoneSpec,
|
zone_image_spec::Image, OciImageFormat, ZoneImageSpec, ZoneOciImageSpec,
|
||||||
ZoneSpecDevice, ZoneState, ZoneTaskSpec, ZoneTaskSpecEnvVar,
|
ZoneResourceSpec, ZoneSpec, ZoneSpecDevice, ZoneState, ZoneTaskSpec,
|
||||||
|
ZoneTaskSpecEnvVar,
|
||||||
},
|
},
|
||||||
control::{
|
control::{
|
||||||
control_service_client::ControlServiceClient, watch_events_reply::Event,
|
control_service_client::ControlServiceClient, watch_events_reply::Event,
|
||||||
@ -41,12 +42,19 @@ pub struct ZoneLaunchCommand {
|
|||||||
#[arg(short, long, default_value_t = 1, help = "vCPUs available to the zone")]
|
#[arg(short, long, default_value_t = 1, help = "vCPUs available to the zone")]
|
||||||
cpus: u32,
|
cpus: u32,
|
||||||
#[arg(
|
#[arg(
|
||||||
short,
|
short = 'M',
|
||||||
long,
|
long = "max-memory",
|
||||||
default_value_t = 512,
|
default_value_t = 512,
|
||||||
help = "Memory available to the zone, in megabytes"
|
help = "Maximum memory available to the zone, in megabytes"
|
||||||
)]
|
)]
|
||||||
mem: u64,
|
max_memory: u64,
|
||||||
|
#[arg(
|
||||||
|
short = 'm',
|
||||||
|
long = "target-memory",
|
||||||
|
default_value_t = 512,
|
||||||
|
help = "Memory target for the zone, in megabytes"
|
||||||
|
)]
|
||||||
|
target_memory: u64,
|
||||||
#[arg[short = 'D', long = "device", help = "Devices to request for the zone"]]
|
#[arg[short = 'D', long = "device", help = "Devices to request for the zone"]]
|
||||||
device: Vec<String>,
|
device: Vec<String>,
|
||||||
#[arg[short, long, help = "Environment variables set in the zone"]]
|
#[arg[short, long, help = "Environment variables set in the zone"]]
|
||||||
@ -120,8 +128,11 @@ impl ZoneLaunchCommand {
|
|||||||
image: Some(image),
|
image: Some(image),
|
||||||
kernel,
|
kernel,
|
||||||
initrd,
|
initrd,
|
||||||
cpus: self.cpus,
|
initial_resources: Some(ZoneResourceSpec {
|
||||||
mem: self.mem,
|
cpus: self.cpus,
|
||||||
|
max_memory: self.max_memory,
|
||||||
|
target_memory: self.target_memory,
|
||||||
|
}),
|
||||||
task: Some(ZoneTaskSpec {
|
task: Some(ZoneTaskSpec {
|
||||||
environment: env_map(&self.env.unwrap_or_default())
|
environment: env_map(&self.env.unwrap_or_default())
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -14,6 +14,7 @@ use crate::cli::zone::logs::ZoneLogsCommand;
|
|||||||
use crate::cli::zone::metrics::ZoneMetricsCommand;
|
use crate::cli::zone::metrics::ZoneMetricsCommand;
|
||||||
use crate::cli::zone::resolve::ZoneResolveCommand;
|
use crate::cli::zone::resolve::ZoneResolveCommand;
|
||||||
use crate::cli::zone::top::ZoneTopCommand;
|
use crate::cli::zone::top::ZoneTopCommand;
|
||||||
|
use crate::cli::zone::update_resources::ZoneUpdateResourcesCommand;
|
||||||
use crate::cli::zone::watch::ZoneWatchCommand;
|
use crate::cli::zone::watch::ZoneWatchCommand;
|
||||||
|
|
||||||
pub mod attach;
|
pub mod attach;
|
||||||
@ -25,6 +26,7 @@ pub mod logs;
|
|||||||
pub mod metrics;
|
pub mod metrics;
|
||||||
pub mod resolve;
|
pub mod resolve;
|
||||||
pub mod top;
|
pub mod top;
|
||||||
|
mod update_resources;
|
||||||
pub mod watch;
|
pub mod watch;
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
@ -56,6 +58,7 @@ pub enum ZoneCommands {
|
|||||||
Resolve(ZoneResolveCommand),
|
Resolve(ZoneResolveCommand),
|
||||||
Top(ZoneTopCommand),
|
Top(ZoneTopCommand),
|
||||||
Watch(ZoneWatchCommand),
|
Watch(ZoneWatchCommand),
|
||||||
|
UpdateResources(ZoneUpdateResourcesCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZoneCommands {
|
impl ZoneCommands {
|
||||||
@ -84,6 +87,8 @@ impl ZoneCommands {
|
|||||||
ZoneCommands::Top(top) => top.run(client, events).await,
|
ZoneCommands::Top(top) => top.run(client, events).await,
|
||||||
|
|
||||||
ZoneCommands::Exec(exec) => exec.run(client).await,
|
ZoneCommands::Exec(exec) => exec.run(client).await,
|
||||||
|
|
||||||
|
ZoneCommands::UpdateResources(update_resources) => update_resources.run(client).await,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
76
crates/ctl/src/cli/zone/update_resources.rs
Normal file
76
crates/ctl/src/cli/zone/update_resources.rs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
use anyhow::Result;
|
||||||
|
use clap::Parser;
|
||||||
|
use krata::v1::{
|
||||||
|
common::ZoneResourceSpec,
|
||||||
|
control::{control_service_client::ControlServiceClient, UpdateZoneResourcesRequest},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::cli::resolve_zone;
|
||||||
|
use krata::v1::control::GetZoneRequest;
|
||||||
|
use tonic::{transport::Channel, Request};
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[command(about = "Update the available resources to a zone")]
|
||||||
|
pub struct ZoneUpdateResourcesCommand {
|
||||||
|
#[arg(help = "Zone to update resources of, either the name or the uuid")]
|
||||||
|
zone: String,
|
||||||
|
#[arg(short, long, default_value_t = 0, help = "vCPUs available to the zone")]
|
||||||
|
cpus: u32,
|
||||||
|
#[arg(
|
||||||
|
short = 'M',
|
||||||
|
long = "max-memory",
|
||||||
|
default_value_t = 0,
|
||||||
|
help = "Maximum memory available to the zone, in megabytes"
|
||||||
|
)]
|
||||||
|
max_memory: u64,
|
||||||
|
#[arg(
|
||||||
|
short = 'm',
|
||||||
|
long = "target-memory",
|
||||||
|
default_value_t = 0,
|
||||||
|
help = "Memory target for the zone, in megabytes"
|
||||||
|
)]
|
||||||
|
target_memory: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ZoneUpdateResourcesCommand {
|
||||||
|
pub async fn run(self, mut client: ControlServiceClient<Channel>) -> Result<()> {
|
||||||
|
let zone_id = resolve_zone(&mut client, &self.zone).await?;
|
||||||
|
let zone = client
|
||||||
|
.get_zone(GetZoneRequest { zone_id })
|
||||||
|
.await?
|
||||||
|
.into_inner()
|
||||||
|
.zone
|
||||||
|
.unwrap_or_default();
|
||||||
|
let active_resources = zone
|
||||||
|
.status
|
||||||
|
.clone()
|
||||||
|
.unwrap_or_default()
|
||||||
|
.resource_status
|
||||||
|
.unwrap_or_default()
|
||||||
|
.active_resources
|
||||||
|
.unwrap_or_default();
|
||||||
|
client
|
||||||
|
.update_zone_resources(Request::new(UpdateZoneResourcesRequest {
|
||||||
|
zone_id: zone.id.clone(),
|
||||||
|
resources: Some(ZoneResourceSpec {
|
||||||
|
max_memory: if self.max_memory == 0 {
|
||||||
|
active_resources.max_memory
|
||||||
|
} else {
|
||||||
|
self.max_memory
|
||||||
|
},
|
||||||
|
target_memory: if self.target_memory == 0 {
|
||||||
|
active_resources.target_memory
|
||||||
|
} else {
|
||||||
|
self.target_memory
|
||||||
|
},
|
||||||
|
cpus: if self.cpus == 0 {
|
||||||
|
active_resources.cpus
|
||||||
|
} else {
|
||||||
|
self.cpus
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use async_stream::try_stream;
|
use async_stream::try_stream;
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
|
use krata::v1::common::ZoneResourceStatus;
|
||||||
use krata::v1::control::{
|
use krata::v1::control::{
|
||||||
GetZoneReply, GetZoneRequest, SetHostPowerManagementPolicyReply,
|
GetZoneReply, GetZoneRequest, SetHostPowerManagementPolicyReply,
|
||||||
SetHostPowerManagementPolicyRequest,
|
SetHostPowerManagementPolicyRequest,
|
||||||
@ -25,8 +26,8 @@ use krata::{
|
|||||||
HostCpuTopologyInfo, HostStatusReply, HostStatusRequest, ListDevicesReply,
|
HostCpuTopologyInfo, HostStatusReply, HostStatusRequest, ListDevicesReply,
|
||||||
ListDevicesRequest, ListZonesReply, ListZonesRequest, PullImageReply, PullImageRequest,
|
ListDevicesRequest, ListZonesReply, ListZonesRequest, PullImageReply, PullImageRequest,
|
||||||
ReadZoneMetricsReply, ReadZoneMetricsRequest, ResolveZoneIdReply, ResolveZoneIdRequest,
|
ReadZoneMetricsReply, ReadZoneMetricsRequest, ResolveZoneIdReply, ResolveZoneIdRequest,
|
||||||
SnoopIdmReply, SnoopIdmRequest, WatchEventsReply, WatchEventsRequest, ZoneConsoleReply,
|
SnoopIdmReply, SnoopIdmRequest, UpdateZoneResourcesReply, UpdateZoneResourcesRequest,
|
||||||
ZoneConsoleRequest,
|
WatchEventsReply, WatchEventsRequest, ZoneConsoleReply, ZoneConsoleRequest,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -165,6 +166,7 @@ impl ControlService for DaemonControlService {
|
|||||||
network_status: None,
|
network_status: None,
|
||||||
exit_status: None,
|
exit_status: None,
|
||||||
error_status: None,
|
error_status: None,
|
||||||
|
resource_status: None,
|
||||||
host: self.glt.host_uuid().to_string(),
|
host: self.glt.host_uuid().to_string(),
|
||||||
domid: u32::MAX,
|
domid: u32::MAX,
|
||||||
}),
|
}),
|
||||||
@ -623,4 +625,67 @@ impl ControlService for DaemonControlService {
|
|||||||
zone: zone.cloned(),
|
zone: zone.cloned(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn update_zone_resources(
|
||||||
|
&self,
|
||||||
|
request: Request<UpdateZoneResourcesRequest>,
|
||||||
|
) -> Result<Response<UpdateZoneResourcesReply>, Status> {
|
||||||
|
let request = request.into_inner();
|
||||||
|
let uuid = Uuid::from_str(&request.zone_id).map_err(|error| ApiError {
|
||||||
|
message: error.to_string(),
|
||||||
|
})?;
|
||||||
|
let Some(mut zone) = self.zones.read(uuid).await.map_err(ApiError::from)? else {
|
||||||
|
return Err(ApiError {
|
||||||
|
message: "zone not found".to_string(),
|
||||||
|
}
|
||||||
|
.into());
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(ref mut status) = zone.status else {
|
||||||
|
return Err(ApiError {
|
||||||
|
message: "zone state not available".to_string(),
|
||||||
|
}
|
||||||
|
.into());
|
||||||
|
};
|
||||||
|
|
||||||
|
if status.state() != ZoneState::Created {
|
||||||
|
return Err(ApiError {
|
||||||
|
message: "zone is in an invalid state".to_string(),
|
||||||
|
}
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
if status.domid == 0 || status.domid == u32::MAX {
|
||||||
|
return Err(ApiError {
|
||||||
|
message: "zone domid is invalid".to_string(),
|
||||||
|
}
|
||||||
|
.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let resources = request.resources.unwrap_or_default();
|
||||||
|
|
||||||
|
self.runtime
|
||||||
|
.set_max_memory(status.domid, resources.max_memory * 1024 * 1024)
|
||||||
|
.await
|
||||||
|
.map_err(|error| ApiError {
|
||||||
|
message: format!("failed to set maximum memory: {}", error),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
self.runtime
|
||||||
|
.set_target_memory(status.domid, resources.target_memory * 1024 * 1024)
|
||||||
|
.await
|
||||||
|
.map_err(|error| ApiError {
|
||||||
|
message: format!("failed to set target memory: {}", error),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
status.resource_status = Some(ZoneResourceStatus {
|
||||||
|
active_resources: Some(resources),
|
||||||
|
});
|
||||||
|
|
||||||
|
self.zones
|
||||||
|
.update(uuid, zone)
|
||||||
|
.await
|
||||||
|
.map_err(ApiError::from)?;
|
||||||
|
Ok(Response::new(UpdateZoneResourcesReply {}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,7 @@ impl DaemonEventGenerator {
|
|||||||
network_status: zone.status.clone().unwrap_or_default().network_status,
|
network_status: zone.status.clone().unwrap_or_default().network_status,
|
||||||
exit_status: Some(ZoneExitStatus { code }),
|
exit_status: Some(ZoneExitStatus { code }),
|
||||||
error_status: None,
|
error_status: None,
|
||||||
|
resource_status: zone.status.clone().unwrap_or_default().resource_status,
|
||||||
host: zone.status.clone().map(|x| x.host).unwrap_or_default(),
|
host: zone.status.clone().map(|x| x.host).unwrap_or_default(),
|
||||||
domid: zone.status.clone().map(|x| x.domid).unwrap_or(u32::MAX),
|
domid: zone.status.clone().map(|x| x.domid).unwrap_or(u32::MAX),
|
||||||
});
|
});
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use krata::launchcfg::LaunchPackedFormat;
|
use krata::launchcfg::LaunchPackedFormat;
|
||||||
use krata::v1::common::ZoneOciImageSpec;
|
|
||||||
use krata::v1::common::{OciImageFormat, Zone, ZoneState, ZoneStatus};
|
use krata::v1::common::{OciImageFormat, Zone, ZoneState, ZoneStatus};
|
||||||
|
use krata::v1::common::{ZoneOciImageSpec, ZoneResourceStatus};
|
||||||
use krataoci::packer::{service::OciPackerService, OciPackedFormat};
|
use krataoci::packer::{service::OciPackerService, OciPackedFormat};
|
||||||
use kratart::launch::{PciBdf, PciDevice, PciRdmReservePolicy, ZoneLaunchNetwork};
|
use kratart::launch::{PciBdf, PciDevice, PciRdmReservePolicy, ZoneLaunchNetwork};
|
||||||
use kratart::{launch::ZoneLaunchRequest, Runtime};
|
use kratart::{launch::ZoneLaunchRequest, Runtime};
|
||||||
@ -176,6 +176,7 @@ impl ZoneCreator<'_> {
|
|||||||
|
|
||||||
let reservation = self.ip_assignment.assign(uuid).await?;
|
let reservation = self.ip_assignment.assign(uuid).await?;
|
||||||
|
|
||||||
|
let initial_resources = spec.initial_resources.unwrap_or_default();
|
||||||
let info = self
|
let info = self
|
||||||
.runtime
|
.runtime
|
||||||
.launch(ZoneLaunchRequest {
|
.launch(ZoneLaunchRequest {
|
||||||
@ -189,8 +190,9 @@ impl ZoneCreator<'_> {
|
|||||||
image,
|
image,
|
||||||
kernel,
|
kernel,
|
||||||
initrd,
|
initrd,
|
||||||
vcpus: spec.cpus,
|
cpus: initial_resources.cpus,
|
||||||
mem: spec.mem,
|
max_memory: initial_resources.max_memory,
|
||||||
|
target_memory: initial_resources.target_memory,
|
||||||
pcis,
|
pcis,
|
||||||
env: task
|
env: task
|
||||||
.environment
|
.environment
|
||||||
@ -219,6 +221,9 @@ impl ZoneCreator<'_> {
|
|||||||
network_status: Some(ip_reservation_to_network_status(&reservation)),
|
network_status: Some(ip_reservation_to_network_status(&reservation)),
|
||||||
exit_status: None,
|
exit_status: None,
|
||||||
error_status: None,
|
error_status: None,
|
||||||
|
resource_status: Some(ZoneResourceStatus {
|
||||||
|
active_resources: Some(initial_resources),
|
||||||
|
}),
|
||||||
host: self.zlt.host_uuid().to_string(),
|
host: self.zlt.host_uuid().to_string(),
|
||||||
domid: info.domid,
|
domid: info.domid,
|
||||||
});
|
});
|
||||||
|
@ -328,6 +328,7 @@ impl ZoneReconciler {
|
|||||||
network_status: None,
|
network_status: None,
|
||||||
exit_status: None,
|
exit_status: None,
|
||||||
error_status: None,
|
error_status: None,
|
||||||
|
resource_status: None,
|
||||||
host: self.zlt.host_uuid().to_string(),
|
host: self.zlt.host_uuid().to_string(),
|
||||||
domid: domid.unwrap_or(u32::MAX),
|
domid: domid.unwrap_or(u32::MAX),
|
||||||
});
|
});
|
||||||
|
@ -21,11 +21,16 @@ message ZoneSpec {
|
|||||||
ZoneImageSpec kernel = 3;
|
ZoneImageSpec kernel = 3;
|
||||||
// If not specified, defaults to the daemon default initrd.
|
// If not specified, defaults to the daemon default initrd.
|
||||||
ZoneImageSpec initrd = 4;
|
ZoneImageSpec initrd = 4;
|
||||||
uint32 cpus = 5;
|
ZoneResourceSpec initial_resources = 5;
|
||||||
uint64 mem = 6;
|
ZoneTaskSpec task = 6;
|
||||||
ZoneTaskSpec task = 7;
|
repeated ZoneSpecAnnotation annotations = 7;
|
||||||
repeated ZoneSpecAnnotation annotations = 8;
|
repeated ZoneSpecDevice devices = 8;
|
||||||
repeated ZoneSpecDevice devices = 9;
|
}
|
||||||
|
|
||||||
|
message ZoneResourceSpec {
|
||||||
|
uint64 max_memory = 1;
|
||||||
|
uint64 target_memory = 2;
|
||||||
|
uint32 cpus = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ZoneImageSpec {
|
message ZoneImageSpec {
|
||||||
@ -74,6 +79,7 @@ message ZoneStatus {
|
|||||||
ZoneErrorStatus error_status = 4;
|
ZoneErrorStatus error_status = 4;
|
||||||
string host = 5;
|
string host = 5;
|
||||||
uint32 domid = 6;
|
uint32 domid = 6;
|
||||||
|
ZoneResourceStatus resource_status = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ZoneState {
|
enum ZoneState {
|
||||||
@ -103,6 +109,10 @@ message ZoneErrorStatus {
|
|||||||
string message = 1;
|
string message = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message ZoneResourceStatus {
|
||||||
|
ZoneResourceSpec active_resources = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message ZoneMetricNode {
|
message ZoneMetricNode {
|
||||||
string name = 1;
|
string name = 1;
|
||||||
google.protobuf.Value value = 2;
|
google.protobuf.Value value = 2;
|
||||||
|
@ -26,6 +26,8 @@ service ControlService {
|
|||||||
|
|
||||||
rpc GetZone(GetZoneRequest) returns (GetZoneReply);
|
rpc GetZone(GetZoneRequest) returns (GetZoneReply);
|
||||||
|
|
||||||
|
rpc UpdateZoneResources(UpdateZoneResourcesRequest) returns (UpdateZoneResourcesReply);
|
||||||
|
|
||||||
rpc ListZones(ListZonesRequest) returns (ListZonesReply);
|
rpc ListZones(ListZonesRequest) returns (ListZonesReply);
|
||||||
|
|
||||||
rpc AttachZoneConsole(stream ZoneConsoleRequest) returns (stream ZoneConsoleReply);
|
rpc AttachZoneConsole(stream ZoneConsoleRequest) returns (stream ZoneConsoleReply);
|
||||||
@ -242,3 +244,10 @@ message SetHostPowerManagementPolicyRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
message SetHostPowerManagementPolicyReply {}
|
message SetHostPowerManagementPolicyReply {}
|
||||||
|
|
||||||
|
message UpdateZoneResourcesRequest {
|
||||||
|
string zone_id = 1;
|
||||||
|
krata.v1.common.ZoneResourceSpec resources = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateZoneResourcesReply {}
|
||||||
|
@ -30,8 +30,9 @@ pub struct ZoneLaunchRequest {
|
|||||||
pub initrd: Vec<u8>,
|
pub initrd: Vec<u8>,
|
||||||
pub uuid: Option<Uuid>,
|
pub uuid: Option<Uuid>,
|
||||||
pub name: Option<String>,
|
pub name: Option<String>,
|
||||||
pub vcpus: u32,
|
pub cpus: u32,
|
||||||
pub mem: u64,
|
pub target_memory: u64,
|
||||||
|
pub max_memory: u64,
|
||||||
pub env: HashMap<String, String>,
|
pub env: HashMap<String, String>,
|
||||||
pub run: Option<Vec<String>>,
|
pub run: Option<Vec<String>>,
|
||||||
pub pcis: Vec<PciDevice>,
|
pub pcis: Vec<PciDevice>,
|
||||||
@ -194,8 +195,9 @@ impl ZoneLauncher {
|
|||||||
|
|
||||||
let config = DomainConfig {
|
let config = DomainConfig {
|
||||||
base: BaseDomainConfig {
|
base: BaseDomainConfig {
|
||||||
max_vcpus: request.vcpus,
|
max_vcpus: request.cpus,
|
||||||
mem_mb: request.mem,
|
max_mem_mb: request.max_memory,
|
||||||
|
target_mem_mb: request.target_memory,
|
||||||
kernel: request.kernel,
|
kernel: request.kernel,
|
||||||
initrd: request.initrd,
|
initrd: request.initrd,
|
||||||
cmdline,
|
cmdline,
|
||||||
|
@ -226,6 +226,36 @@ impl Runtime {
|
|||||||
Ok(uuid)
|
Ok(uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn set_max_memory(&self, domid: u32, max_memory_bytes: u64) -> Result<()> {
|
||||||
|
self.context
|
||||||
|
.xen
|
||||||
|
.call
|
||||||
|
.set_max_mem(domid, max_memory_bytes / 1024)
|
||||||
|
.await?;
|
||||||
|
let domain_path = self.context.xen.store.get_domain_path(domid).await?;
|
||||||
|
let max_memory_path = format!("{}/memory/static-max", domain_path);
|
||||||
|
self.context
|
||||||
|
.xen
|
||||||
|
.store
|
||||||
|
.write_string(max_memory_path, &(max_memory_bytes / 1024).to_string())
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_target_memory(&self, domid: u32, target_memory_bytes: u64) -> Result<()> {
|
||||||
|
let domain_path = self.context.xen.store.get_domain_path(domid).await?;
|
||||||
|
let target_memory_path = format!("{}/memory/target", domain_path);
|
||||||
|
self.context
|
||||||
|
.xen
|
||||||
|
.store
|
||||||
|
.write_string(
|
||||||
|
target_memory_path,
|
||||||
|
&(target_memory_bytes / 1024).to_string(),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn list(&self) -> Result<Vec<ZoneInfo>> {
|
pub async fn list(&self) -> Result<Vec<ZoneInfo>> {
|
||||||
self.context.list().await
|
self.context.list().await
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,8 @@ async fn main() -> Result<()> {
|
|||||||
base: BaseDomainConfig {
|
base: BaseDomainConfig {
|
||||||
uuid: Uuid::new_v4(),
|
uuid: Uuid::new_v4(),
|
||||||
max_vcpus: 1,
|
max_vcpus: 1,
|
||||||
mem_mb: 512,
|
max_mem_mb: 512,
|
||||||
|
target_mem_mb: 512,
|
||||||
enable_iommu: true,
|
enable_iommu: true,
|
||||||
kernel: fs::read(&kernel_image_path).await?,
|
kernel: fs::read(&kernel_image_path).await?,
|
||||||
initrd: fs::read(&initrd_path).await?,
|
initrd: fs::read(&initrd_path).await?,
|
||||||
|
@ -156,13 +156,13 @@ impl ClientTransaction {
|
|||||||
self.tx
|
self.tx
|
||||||
.write_string(
|
.write_string(
|
||||||
format!("{}/memory/static-max", self.dom_path).as_str(),
|
format!("{}/memory/static-max", self.dom_path).as_str(),
|
||||||
&(base.mem_mb * 1024).to_string(),
|
&(base.max_mem_mb * 1024).to_string(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
self.tx
|
self.tx
|
||||||
.write_string(
|
.write_string(
|
||||||
format!("{}/memory/target", self.dom_path).as_str(),
|
format!("{}/memory/target", self.dom_path).as_str(),
|
||||||
&(base.mem_mb * 1024).to_string(),
|
&(base.target_mem_mb * 1024).to_string(),
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
self.tx
|
self.tx
|
||||||
|
@ -162,11 +162,13 @@ impl<I: BootImageLoader, P: BootSetupPlatform> BootSetup<I, P> {
|
|||||||
pub async fn initialize(
|
pub async fn initialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
initrd: &[u8],
|
initrd: &[u8],
|
||||||
mem_mb: u64,
|
target_mem_mb: u64,
|
||||||
|
max_mem_mb: u64,
|
||||||
max_vcpus: u32,
|
max_vcpus: u32,
|
||||||
cmdline: &str,
|
cmdline: &str,
|
||||||
) -> Result<BootDomain> {
|
) -> Result<BootDomain> {
|
||||||
let total_pages = mem_mb << (20 - self.platform.page_shift());
|
let target_pages = target_mem_mb << (20 - self.platform.page_shift());
|
||||||
|
let total_pages = max_mem_mb << (20 - self.platform.page_shift());
|
||||||
let image_info = self.image_loader.parse(self.platform.hvm()).await?;
|
let image_info = self.image_loader.parse(self.platform.hvm()).await?;
|
||||||
let mut domain = BootDomain {
|
let mut domain = BootDomain {
|
||||||
domid: self.domid,
|
domid: self.domid,
|
||||||
@ -175,7 +177,7 @@ impl<I: BootImageLoader, P: BootSetupPlatform> BootSetup<I, P> {
|
|||||||
virt_pgtab_end: 0,
|
virt_pgtab_end: 0,
|
||||||
pfn_alloc_end: 0,
|
pfn_alloc_end: 0,
|
||||||
total_pages,
|
total_pages,
|
||||||
target_pages: total_pages,
|
target_pages,
|
||||||
page_size: self.platform.page_size(),
|
page_size: self.platform.page_size(),
|
||||||
image_info,
|
image_info,
|
||||||
console_evtchn: 0,
|
console_evtchn: 0,
|
||||||
|
@ -29,7 +29,7 @@ impl<P: BootSetupPlatform> BaseDomainManager<P> {
|
|||||||
let domid = self.call.create_domain(domain).await?;
|
let domid = self.call.create_domain(domain).await?;
|
||||||
self.call.set_max_vcpus(domid, config.max_vcpus).await?;
|
self.call.set_max_vcpus(domid, config.max_vcpus).await?;
|
||||||
self.call
|
self.call
|
||||||
.set_max_mem(domid, (config.mem_mb * 1024) + 2048)
|
.set_max_mem(domid, (config.max_mem_mb * 1024) + 2048)
|
||||||
.await?;
|
.await?;
|
||||||
let loader = ElfImageLoader::load_file_kernel(&config.kernel)?;
|
let loader = ElfImageLoader::load_file_kernel(&config.kernel)?;
|
||||||
let platform = (*self.platform).clone();
|
let platform = (*self.platform).clone();
|
||||||
@ -37,7 +37,8 @@ impl<P: BootSetupPlatform> BaseDomainManager<P> {
|
|||||||
let mut domain = boot
|
let mut domain = boot
|
||||||
.initialize(
|
.initialize(
|
||||||
&config.initrd,
|
&config.initrd,
|
||||||
config.mem_mb,
|
config.target_mem_mb,
|
||||||
|
config.max_mem_mb,
|
||||||
config.max_vcpus,
|
config.max_vcpus,
|
||||||
&config.cmdline,
|
&config.cmdline,
|
||||||
)
|
)
|
||||||
@ -63,7 +64,8 @@ pub struct BaseDomainConfig {
|
|||||||
pub uuid: Uuid,
|
pub uuid: Uuid,
|
||||||
pub owner_domid: u32,
|
pub owner_domid: u32,
|
||||||
pub max_vcpus: u32,
|
pub max_vcpus: u32,
|
||||||
pub mem_mb: u64,
|
pub max_mem_mb: u64,
|
||||||
|
pub target_mem_mb: u64,
|
||||||
pub kernel: Vec<u8>,
|
pub kernel: Vec<u8>,
|
||||||
pub initrd: Vec<u8>,
|
pub initrd: Vec<u8>,
|
||||||
pub cmdline: String,
|
pub cmdline: String,
|
||||||
|
Reference in New Issue
Block a user