From 47e294fcddc4136feda480da802d0f08135295bf Mon Sep 17 00:00:00 2001 From: AlexandreBrg Date: Tue, 4 Jan 2022 21:58:05 +0100 Subject: [PATCH] lumper: Add serial console file option * New cli option --console STRING * Lumper guest output now goes to a file if console file specified Signed-off-by: AlexandreBrg --- src/main.rs | 7 ++++++- src/vmm/src/devices/serial.rs | 8 ++++---- src/vmm/src/lib.rs | 26 +++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 135afec..a82fa8c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,6 +21,10 @@ struct VMMOpts { /// A level of verbosity, and can be used multiple times #[clap(short, long, parse(from_occurrences))] verbose: i32, + + /// Stdout console file path + #[clap(long)] + console: Option } #[derive(Debug)] @@ -42,7 +46,8 @@ fn main() -> Result<(), Error> { // * Number of virtual CPUs // * Memory size (in MB) // * Path to a Linux kernel - vmm.configure(opts.cpus, opts.memory, &opts.kernel) + // * Optional path to console file + vmm.configure(opts.cpus, opts.memory, &opts.kernel, opts.console) .map_err(Error::VmmConfigure)?; // Run the VMM diff --git a/src/vmm/src/devices/serial.rs b/src/vmm/src/devices/serial.rs index e21ca9c..e1a2725 100644 --- a/src/vmm/src/devices/serial.rs +++ b/src/vmm/src/devices/serial.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 -use std::io::{stdout, Error, Result, Stdout}; +use std::io::{Error, Result, Write}; use std::ops::Deref; use vm_superio::serial::NoEvents; @@ -41,16 +41,16 @@ pub(crate) struct LumperSerial { eventfd: EventFdTrigger, // serial is the actual serial device. - pub serial: Serial, + pub serial: Serial>, } impl LumperSerial { - pub fn new() -> Result { + pub fn new(output: Box) -> Result { let eventfd = EventFdTrigger::new(libc::EFD_NONBLOCK).unwrap(); Ok(LumperSerial { eventfd: eventfd.try_clone()?, - serial: Serial::new(eventfd.try_clone()?, stdout()), + serial: Serial::new(eventfd.try_clone()?, Box::new(output)), }) } diff --git a/src/vmm/src/lib.rs b/src/vmm/src/lib.rs index 55d8511..160dd2f 100644 --- a/src/vmm/src/lib.rs +++ b/src/vmm/src/lib.rs @@ -8,22 +8,24 @@ extern crate linux_loader; extern crate vm_memory; extern crate vm_superio; +use std::io::stdout; use std::os::unix::io::AsRawFd; use std::os::unix::prelude::RawFd; use std::sync::{Arc, Mutex}; use std::thread; use std::{io, path::PathBuf}; +use std::fs::File; use kvm_bindings::{kvm_userspace_memory_region, KVM_MAX_CPUID_ENTRIES}; use kvm_ioctls::{Kvm, VmFd}; use linux_loader::loader::{self, KernelLoaderResult}; use vm_memory::{Address, GuestAddress, GuestMemory, GuestMemoryMmap, GuestMemoryRegion}; use vmm_sys_util::terminal::Terminal; - mod cpu; use cpu::{cpuid, mptable, Vcpu}; mod devices; use devices::serial::LumperSerial; + mod epoll_context; use epoll_context::{EpollContext, EPOLL_EVENTS_LEN}; mod kernel; @@ -62,6 +64,8 @@ pub enum Error { StdinWrite(vm_superio::serial::Error), /// Terminal configuration error TerminalConfigure(kvm_ioctls::Error), + /// Console configuration error + ConsoleError(io::Error), } /// Dedicated [`Result`](https://doc.rust-lang.org/std/result/) type. @@ -96,7 +100,7 @@ impl VMM { guest_memory: GuestMemoryMmap::default(), vcpus: vec![], serial: Arc::new(Mutex::new( - LumperSerial::new().map_err(Error::SerialCreation)?, + LumperSerial::new(Box::new(stdout())).map_err(Error::SerialCreation)?, )), epoll, }; @@ -160,6 +164,21 @@ impl VMM { Ok(()) } + pub fn configure_console( + &mut self, + console_path: Option + ) -> Result<()> { + if let Some(console_path) = console_path { + // We create the file if it does not exist, else we open + let file = File::create(&console_path).map_err(Error::ConsoleError)?; + + let mut serial = self.serial.lock().unwrap(); + *serial = LumperSerial::new(Box::new(file)).map_err(Error::SerialCreation)?; + } + + Ok(()) + } + pub fn configure_vcpus( &mut self, num_vcpus: u8, @@ -247,7 +266,8 @@ impl VMM { } } - pub fn configure(&mut self, num_vcpus: u8, mem_size_mb: u32, kernel_path: &str) -> Result<()> { + pub fn configure(&mut self, num_vcpus: u8, mem_size_mb: u32, kernel_path: &str, console: Option) -> Result<()> { + self.configure_console(console)?; self.configure_memory(mem_size_mb)?; let kernel_load = kernel::kernel_setup(&self.guest_memory, PathBuf::from(kernel_path))?; self.configure_io()?;