mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-11-04 19:11:11 +00:00
memory: Allow memory to be backed by a file
In the context of vhost-user, we need the guest RAM to be backed by a file in order to be accessed by an external process. This patch adds the new flag "file=" to the "--memory" option so that we can specify from the command line if the memory needs to be backed, and by which specific file. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
2ede30b6d3
commit
53085c7ccc
19
src/main.rs
19
src/main.rs
@ -26,7 +26,10 @@ fn main() {
|
||||
.arg(
|
||||
Arg::with_name("memory")
|
||||
.long("memory")
|
||||
.help("Amount of RAM (in MiB)")
|
||||
.help(
|
||||
"Memory parameters \"size=<guest_memory_size>,\
|
||||
file=<backing_file_path>\"",
|
||||
)
|
||||
.default_value(config::DEFAULT_MEMORY),
|
||||
)
|
||||
.arg(
|
||||
@ -118,7 +121,7 @@ fn main() {
|
||||
"Cloud Hypervisor Guest\n\tvCPUs: {}\n\tMemory: {} MB\
|
||||
\n\tKernel: {:?}\n\tKernel cmdline: {}\n\tDisk(s): {:?}",
|
||||
u8::from(&vm_config.cpus),
|
||||
u64::from(&vm_config.memory),
|
||||
vm_config.memory.size,
|
||||
vm_config.kernel.path,
|
||||
vm_config.cmdline.args.as_str(),
|
||||
vm_config.disks,
|
||||
@ -242,7 +245,7 @@ mod tests {
|
||||
let (disks, fw_path) = prepare_files();
|
||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||
.args(&["--cpus", "1"])
|
||||
.args(&["--memory", "512"])
|
||||
.args(&["--memory", "size=512"])
|
||||
.args(&["--kernel", fw_path.as_str()])
|
||||
.args(&["--disk", disks[0], disks[1]])
|
||||
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
|
||||
@ -270,7 +273,7 @@ mod tests {
|
||||
let (disks, fw_path) = prepare_files();
|
||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||
.args(&["--cpus", "2"])
|
||||
.args(&["--memory", "512"])
|
||||
.args(&["--memory", "size=512"])
|
||||
.args(&["--kernel", fw_path.as_str()])
|
||||
.args(&["--disk", disks[0], disks[1]])
|
||||
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
|
||||
@ -295,7 +298,7 @@ mod tests {
|
||||
let (disks, fw_path) = prepare_files();
|
||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||
.args(&["--cpus", "1"])
|
||||
.args(&["--memory", "5120"])
|
||||
.args(&["--memory", "size=5120"])
|
||||
.args(&["--kernel", fw_path.as_str()])
|
||||
.args(&["--disk", disks[0], disks[1]])
|
||||
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
|
||||
@ -320,7 +323,7 @@ mod tests {
|
||||
let (disks, fw_path) = prepare_files();
|
||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||
.args(&["--cpus", "1"])
|
||||
.args(&["--memory", "512"])
|
||||
.args(&["--memory", "size=512"])
|
||||
.args(&["--kernel", fw_path.as_str()])
|
||||
.args(&["--disk", disks[0], disks[1]])
|
||||
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
|
||||
@ -358,7 +361,7 @@ mod tests {
|
||||
|
||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||
.args(&["--cpus", "1"])
|
||||
.args(&["--memory", "512"])
|
||||
.args(&["--memory", "size=512"])
|
||||
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
||||
.args(&["--disk", disks[0], disks[1]])
|
||||
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
|
||||
@ -400,7 +403,7 @@ mod tests {
|
||||
|
||||
let mut child = Command::new("target/debug/cloud-hypervisor")
|
||||
.args(&["--cpus", "1"])
|
||||
.args(&["--memory", "512"])
|
||||
.args(&["--memory", "size=512"])
|
||||
.args(&["--kernel", kernel_path.to_str().unwrap()])
|
||||
.args(&["--disk", disks[0], disks[1]])
|
||||
.args(&["--net", "tap=,mac=,ip=192.168.2.1,mask=255.255.255.0"])
|
||||
|
@ -13,7 +13,7 @@ use std::result;
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
pub const DEFAULT_VCPUS: &str = "1";
|
||||
pub const DEFAULT_MEMORY: &str = "512";
|
||||
pub const DEFAULT_MEMORY: &str = "size=512";
|
||||
pub const DEFAULT_RNG_SOURCE: &str = "/dev/urandom";
|
||||
const CMDLINE_OFFSET: GuestAddress = GuestAddress(0x20000);
|
||||
|
||||
@ -22,8 +22,10 @@ const CMDLINE_OFFSET: GuestAddress = GuestAddress(0x20000);
|
||||
pub enum Error<'a> {
|
||||
/// Failed parsing cpus parameters.
|
||||
ParseCpusParams(std::num::ParseIntError),
|
||||
/// Failed parsing memory parameters.
|
||||
ParseMemoryParams(std::num::ParseIntError),
|
||||
/// Failed parsing memory size parameter.
|
||||
ParseMemorySizeParam(std::num::ParseIntError),
|
||||
/// Failed parsing memory file parameter.
|
||||
ParseMemoryFileParam,
|
||||
/// Failed parsing kernel parameters.
|
||||
ParseKernelParams,
|
||||
/// Failed parsing kernel command line parameters.
|
||||
@ -76,19 +78,45 @@ impl From<&CpusConfig> for u8 {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MemoryConfig(pub u64);
|
||||
|
||||
impl MemoryConfig {
|
||||
pub fn parse(memory: &str) -> Result<Self> {
|
||||
Ok(MemoryConfig(
|
||||
memory.parse::<u64>().map_err(Error::ParseMemoryParams)?,
|
||||
))
|
||||
}
|
||||
pub struct MemoryConfig<'a> {
|
||||
pub size: u64,
|
||||
pub file: Option<&'a Path>,
|
||||
}
|
||||
|
||||
impl From<&MemoryConfig> for u64 {
|
||||
fn from(val: &MemoryConfig) -> Self {
|
||||
val.0
|
||||
impl<'a> MemoryConfig<'a> {
|
||||
pub fn parse(memory: &'a str) -> Result<Self> {
|
||||
// Split the parameters based on the comma delimiter
|
||||
let params_list: Vec<&str> = memory.split(',').collect();
|
||||
|
||||
let mut size_str: &str = "";
|
||||
let mut file_str: &str = "";
|
||||
let mut backed = false;
|
||||
|
||||
for param in params_list.iter() {
|
||||
if param.starts_with("size=") {
|
||||
size_str = ¶m[5..];
|
||||
} else if param.starts_with("file=") {
|
||||
backed = true;
|
||||
file_str = ¶m[5..];
|
||||
}
|
||||
}
|
||||
|
||||
let file = if backed {
|
||||
if file_str.is_empty() {
|
||||
return Err(Error::ParseMemoryFileParam);
|
||||
}
|
||||
|
||||
Some(Path::new(file_str))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(MemoryConfig {
|
||||
size: size_str
|
||||
.parse::<u64>()
|
||||
.map_err(Error::ParseMemorySizeParam)?,
|
||||
file,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,7 +296,7 @@ impl<'a> FsConfig<'a> {
|
||||
|
||||
pub struct VmConfig<'a> {
|
||||
pub cpus: CpusConfig,
|
||||
pub memory: MemoryConfig,
|
||||
pub memory: MemoryConfig<'a>,
|
||||
pub kernel: KernelConfig<'a>,
|
||||
pub cmdline: CmdlineConfig,
|
||||
pub disks: Vec<DiskConfig<'a>>,
|
||||
|
@ -843,24 +843,29 @@ impl<'a> Vm<'a> {
|
||||
let fd = Arc::new(fd);
|
||||
|
||||
// Init guest memory
|
||||
let arch_mem_regions = arch::arch_memory_regions(u64::from(&config.memory) << 20);
|
||||
let arch_mem_regions = arch::arch_memory_regions(config.memory.size << 20);
|
||||
|
||||
let mut mem_regions = Vec::<(GuestAddress, usize, Option<FileOffset>)>::new();
|
||||
for region in arch_mem_regions.iter() {
|
||||
let file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.custom_flags(O_TMPFILE)
|
||||
.open("/dev/shm")
|
||||
.map_err(Error::SharedFileCreate)?;
|
||||
let guest_memory = match config.memory.file {
|
||||
Some(file) => {
|
||||
let mut mem_regions = Vec::<(GuestAddress, usize, Option<FileOffset>)>::new();
|
||||
for region in arch_mem_regions.iter() {
|
||||
let file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.custom_flags(O_TMPFILE)
|
||||
.open(file)
|
||||
.map_err(Error::SharedFileCreate)?;
|
||||
|
||||
file.set_len(region.1 as u64)
|
||||
.map_err(Error::SharedFileSetLen)?;
|
||||
file.set_len(region.1 as u64)
|
||||
.map_err(Error::SharedFileSetLen)?;
|
||||
|
||||
mem_regions.push((region.0, region.1, Some(FileOffset::new(file, 0))));
|
||||
}
|
||||
mem_regions.push((region.0, region.1, Some(FileOffset::new(file, 0))));
|
||||
}
|
||||
|
||||
let guest_memory = GuestMemoryMmap::with_files(&mem_regions).map_err(Error::GuestMemory)?;
|
||||
GuestMemoryMmap::with_files(&mem_regions).map_err(Error::GuestMemory)?
|
||||
}
|
||||
None => GuestMemoryMmap::new(&arch_mem_regions).map_err(Error::GuestMemory)?,
|
||||
};
|
||||
|
||||
guest_memory
|
||||
.with_regions(|index, region| {
|
||||
|
Loading…
Reference in New Issue
Block a user