mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: Reject resizing below the boot size with an error
This was already handled with user memory zones but not with the default memory. Make a small refactoring to move the boot RAM check into MemoryManager rather than split across Vm and MemoryManager. Signed-off-by: Rob Bradford <rbradford@meta.com>
This commit is contained in:
@@ -356,6 +356,11 @@ pub enum Error {
|
|||||||
#[error("Impossible to resize guest memory if it is backed by user defined memory regions")]
|
#[error("Impossible to resize guest memory if it is backed by user defined memory regions")]
|
||||||
InvalidResizeWithMemoryZones,
|
InvalidResizeWithMemoryZones,
|
||||||
|
|
||||||
|
/// Forbidden operation. Impossible to resize guest memory below the boot
|
||||||
|
/// RAM as it is not removable with virtio-mem.
|
||||||
|
#[error("Invalid resize request: desired_size = {0} below boot size = {1}")]
|
||||||
|
InvalidResizeBelowBootSize(u64, u64),
|
||||||
|
|
||||||
/// It's invalid to try applying a NUMA policy to a memory zone that is
|
/// It's invalid to try applying a NUMA policy to a memory zone that is
|
||||||
/// memory mapped with MAP_SHARED.
|
/// memory mapped with MAP_SHARED.
|
||||||
#[error(
|
#[error(
|
||||||
@@ -2583,14 +2588,19 @@ impl MemoryManager {
|
|||||||
let mut region: Option<Arc<GuestRegionMmap>> = None;
|
let mut region: Option<Arc<GuestRegionMmap>> = None;
|
||||||
match self.hotplug_method {
|
match self.hotplug_method {
|
||||||
HotplugMethod::VirtioMem => {
|
HotplugMethod::VirtioMem => {
|
||||||
if desired_ram >= self.boot_ram {
|
if desired_ram < self.boot_ram {
|
||||||
if !self.dynamic {
|
return Err(Error::InvalidResizeBelowBootSize(
|
||||||
return Ok(region);
|
desired_ram,
|
||||||
}
|
self.boot_ram,
|
||||||
|
));
|
||||||
self.virtio_mem_resize(DEFAULT_MEMORY_ZONE, desired_ram - self.boot_ram)?;
|
|
||||||
self.current_ram = desired_ram;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !self.dynamic {
|
||||||
|
return Ok(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.virtio_mem_resize(DEFAULT_MEMORY_ZONE, desired_ram - self.boot_ram)?;
|
||||||
|
self.current_ram = desired_ram;
|
||||||
}
|
}
|
||||||
HotplugMethod::Acpi => {
|
HotplugMethod::Acpi => {
|
||||||
if desired_ram > self.current_ram {
|
if desired_ram > self.current_ram {
|
||||||
@@ -2607,7 +2617,7 @@ impl MemoryManager {
|
|||||||
Ok(region)
|
Ok(region)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize_zone(&mut self, id: &str, virtio_mem_size: u64) -> Result<(), Error> {
|
pub fn resize_zone(&mut self, zone: &MemoryZoneConfig, desired_ram: u64) -> Result<(), Error> {
|
||||||
if !self.user_provided_zones {
|
if !self.user_provided_zones {
|
||||||
error!(
|
error!(
|
||||||
"Not allowed to resize guest memory zone when no zone is \
|
"Not allowed to resize guest memory zone when no zone is \
|
||||||
@@ -2616,7 +2626,11 @@ impl MemoryManager {
|
|||||||
return Err(Error::ResizeZone);
|
return Err(Error::ResizeZone);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.virtio_mem_resize(id, virtio_mem_size)
|
if desired_ram < zone.size {
|
||||||
|
return Err(Error::InvalidResizeBelowBootSize(desired_ram, zone.size));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.virtio_mem_resize(&zone.id, desired_ram - zone.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_hardlink(f: &File) -> bool {
|
pub fn is_hardlink(f: &File) -> bool {
|
||||||
|
|||||||
+11
-20
@@ -2158,27 +2158,18 @@ impl Vm {
|
|||||||
if let Some(zones) = &mut memory_config.zones {
|
if let Some(zones) = &mut memory_config.zones {
|
||||||
for zone in zones.iter_mut() {
|
for zone in zones.iter_mut() {
|
||||||
if zone.id == id {
|
if zone.id == id {
|
||||||
if desired_memory >= zone.size {
|
self.memory_manager
|
||||||
let hotplugged_size = desired_memory - zone.size;
|
.lock()
|
||||||
self.memory_manager
|
.unwrap()
|
||||||
.lock()
|
.resize_zone(zone, desired_memory)
|
||||||
.unwrap()
|
.map_err(Error::MemoryManager)?;
|
||||||
.resize_zone(id, desired_memory - zone.size)
|
// We update the memory zone config regardless of the
|
||||||
.map_err(Error::MemoryManager)?;
|
// actual 'resize-zone' operation result (happened or
|
||||||
// We update the memory zone config regardless of the
|
// not), so that if the VM reboots it will be running
|
||||||
// actual 'resize-zone' operation result (happened or
|
// with the last configured memory zone size.
|
||||||
// not), so that if the VM reboots it will be running
|
zone.hotplugged_size = Some(desired_memory - zone.size);
|
||||||
// with the last configured memory zone size.
|
|
||||||
zone.hotplugged_size = Some(hotplugged_size);
|
|
||||||
|
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
|
||||||
error!(
|
|
||||||
"Invalid to ask less ({}) than boot RAM ({}) for \
|
|
||||||
this memory zone",
|
|
||||||
desired_memory, zone.size,
|
|
||||||
);
|
|
||||||
return Err(Error::ResizeZone);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user