Skip to content
4 changes: 3 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ fn get_cli_options_sorted(
.default_value("true"),
Arg::new("serial")
.long("serial")
.help("Control serial port: off|null|pty|tty|file=</path/to/a/file>|socket=</path/to/a/file>")
.help("Control serial port: off|null|pty|tty|file=</path/to/a/file>|socket=</path/to/a/file>|tcp=<host:port>")
.default_value("null")
.group("vm-config"),
Arg::new("tpm")
Expand Down Expand Up @@ -1002,12 +1002,14 @@ mod unit_tests {
mode: ConsoleOutputMode::Null,
iommu: false,
socket: None,
url: None,
},
console: ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Tty,
iommu: false,
socket: None,
url: None,
},
#[cfg(target_arch = "x86_64")]
debug_console: DebugConsoleConfig::default(),
Expand Down
29 changes: 29 additions & 0 deletions vmm/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ pub enum ValidationError {
/// Missing file value for console
#[error("Path missing when using file console mode")]
ConsoleFileMissing,
/// Missing TCP address for console
#[error("Address missing when using TCP console mode")]
ConsoleTcpAddressMissing,
/// Missing socket path for console
#[error("Path missing when using socket console mode")]
ConsoleSocketPathMissing,
Expand Down Expand Up @@ -1825,11 +1828,13 @@ impl ConsoleConfig {
.add_valueless("null")
.add("file")
.add("iommu")
.add("tcp")
.add("socket");
parser.parse(console).map_err(Error::ParseConsole)?;

let mut file: Option<PathBuf> = default_consoleconfig_file();
let mut socket: Option<PathBuf> = None;
let mut url: Option<String> = None;
let mut mode: ConsoleOutputMode = ConsoleOutputMode::Off;

if parser.is_set("off") {
Expand All @@ -1839,6 +1844,19 @@ impl ConsoleConfig {
mode = ConsoleOutputMode::Tty
} else if parser.is_set("null") {
mode = ConsoleOutputMode::Null
} else if parser.is_set("tcp") {
mode = ConsoleOutputMode::Tcp;
url = Some(
parser
.get("tcp")
.ok_or(Error::Validation(ValidationError::ConsoleTcpAddressMissing))?,
);
if parser.is_set("file") {
file =
Some(PathBuf::from(parser.get("file").ok_or(
Error::Validation(ValidationError::ConsoleFileMissing),
)?));
}
} else if parser.is_set("file") {
mode = ConsoleOutputMode::File;
file =
Expand All @@ -1864,6 +1882,7 @@ impl ConsoleConfig {
mode,
iommu,
socket,
url,
})
}
}
Expand Down Expand Up @@ -3726,6 +3745,7 @@ mod tests {
iommu: false,
file: None,
socket: None,
url: None,
}
);
assert_eq!(
Expand All @@ -3735,6 +3755,7 @@ mod tests {
iommu: false,
file: None,
socket: None,
url: None,
}
);
assert_eq!(
Expand All @@ -3744,6 +3765,7 @@ mod tests {
iommu: false,
file: None,
socket: None,
url: None,
}
);
assert_eq!(
Expand All @@ -3753,6 +3775,7 @@ mod tests {
iommu: false,
file: None,
socket: None,
url: None,
}
);
assert_eq!(
Expand All @@ -3762,6 +3785,7 @@ mod tests {
iommu: false,
file: Some(PathBuf::from("/tmp/console")),
socket: None,
url: None,
}
);
assert_eq!(
Expand All @@ -3771,6 +3795,7 @@ mod tests {
iommu: true,
file: None,
socket: None,
url: None,
}
);
assert_eq!(
Expand All @@ -3780,6 +3805,7 @@ mod tests {
iommu: true,
file: Some(PathBuf::from("/tmp/console")),
socket: None,
url: None,
}
);
assert_eq!(
Expand All @@ -3789,6 +3815,7 @@ mod tests {
iommu: true,
file: None,
socket: Some(PathBuf::from("/tmp/serial.sock")),
url: None,
}
);
Ok(())
Expand Down Expand Up @@ -4155,12 +4182,14 @@ mod tests {
mode: ConsoleOutputMode::Null,
iommu: false,
socket: None,
url: None,
},
console: ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Tty,
iommu: false,
socket: None,
url: None,
},
#[cfg(target_arch = "x86_64")]
debug_console: DebugConsoleConfig::default(),
Expand Down
23 changes: 23 additions & 0 deletions vmm/src/console_devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

use std::fs::{File, OpenOptions, read_link};
use std::mem::zeroed;
use std::net::TcpListener;
use std::os::fd::{AsRawFd, FromRawFd, RawFd};
use std::os::unix::fs::OpenOptionsExt;
use std::os::unix::net::UnixListener;
Expand Down Expand Up @@ -40,6 +41,10 @@ pub enum ConsoleDeviceError {
#[error("No socket option support for console device")]
NoSocketOptionSupportForConsoleDevice,

/// Error parsing the TCP address
#[error("Wrong TCP address format: {0}")]
WrongTcpAddressFormat(std::string::String),

/// Error setting pty raw mode
#[error("Error setting pty raw mode")]
SetPtyRaw(#[source] vmm_sys_util::errno::Error),
Expand All @@ -62,6 +67,7 @@ pub enum ConsoleOutput {
Tty(Arc<File>),
Null,
Socket(Arc<UnixListener>),
Tcp(Arc<TcpListener>, Option<Arc<File>>),
Off,
}

Expand Down Expand Up @@ -227,6 +233,7 @@ pub(crate) fn pre_create_console_devices(vmm: &mut Vmm) -> ConsoleDeviceResult<C
ConsoleOutputMode::Socket => {
return Err(ConsoleDeviceError::NoSocketOptionSupportForConsoleDevice);
}
ConsoleOutputMode::Tcp => ConsoleOutput::Null,
ConsoleOutputMode::Null => ConsoleOutput::Null,
ConsoleOutputMode::Off => ConsoleOutput::Off,
},
Expand Down Expand Up @@ -264,6 +271,21 @@ pub(crate) fn pre_create_console_devices(vmm: &mut Vmm) -> ConsoleDeviceResult<C
.map_err(ConsoleDeviceError::CreateConsoleDevice)?;
ConsoleOutput::Socket(Arc::new(listener))
}
ConsoleOutputMode::Tcp => {
let url = vmconfig.serial.url.as_ref().unwrap();
let socket_addr: std::net::SocketAddr = url
.parse()
.map_err(|_| ConsoleDeviceError::WrongTcpAddressFormat(url.to_string()))?;
let listener = TcpListener::bind(socket_addr)
.map_err(ConsoleDeviceError::CreateConsoleDevice)?;

let mut f = None;
if let Some(p) = &vmconfig.serial.file {
let file = File::create(p).map_err(ConsoleDeviceError::CreateConsoleDevice)?;
f = Some(Arc::new(file));
}
ConsoleOutput::Tcp(Arc::new(listener), f)
}
ConsoleOutputMode::Null => ConsoleOutput::Null,
ConsoleOutputMode::Off => ConsoleOutput::Off,
},
Expand All @@ -290,6 +312,7 @@ pub(crate) fn pre_create_console_devices(vmm: &mut Vmm) -> ConsoleDeviceResult<C
ConsoleOutputMode::Socket => {
return Err(ConsoleDeviceError::NoSocketOptionSupportForConsoleDevice);
}
ConsoleOutputMode::Tcp => ConsoleOutput::Null,
ConsoleOutputMode::Null => ConsoleOutput::Null,
ConsoleOutputMode::Off => ConsoleOutput::Off,
},
Expand Down
10 changes: 9 additions & 1 deletion vmm/src/device_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2350,6 +2350,9 @@ impl DeviceManager {
ConsoleOutput::Socket(_) => {
return Err(DeviceManagerError::NoSocketOptionSupportForConsoleDevice);
}
ConsoleOutput::Tcp(_, _) => {
return Err(DeviceManagerError::NoSocketOptionSupportForConsoleDevice);
}
ConsoleOutput::Null => Endpoint::Null,
ConsoleOutput::Off => return Ok(None),
};
Expand Down Expand Up @@ -2424,12 +2427,16 @@ impl DeviceManager {
| ConsoleOutput::Null
| ConsoleOutput::Pty(_)
| ConsoleOutput::Socket(_) => None,
ConsoleOutput::Tcp(_, _) => None,
};

if !matches!(console_info.serial_main_fd, ConsoleOutput::Off) {
let serial = self.add_serial_device(interrupt_manager, serial_writer)?;
self.serial_manager = match console_info.serial_main_fd {
ConsoleOutput::Pty(_) | ConsoleOutput::Tty(_) | ConsoleOutput::Socket(_) => {
ConsoleOutput::Pty(_)
| ConsoleOutput::Tty(_)
| ConsoleOutput::Socket(_)
| ConsoleOutput::Tcp(_, _) => {
let serial_manager = SerialManager::new(
serial,
console_info.serial_main_fd,
Expand Down Expand Up @@ -2462,6 +2469,7 @@ impl DeviceManager {
| ConsoleOutput::Null
| ConsoleOutput::Pty(_)
| ConsoleOutput::Socket(_) => None,
ConsoleOutput::Tcp(_, _) => None,
};
if let Some(writer) = debug_console_writer {
let _ = self.add_debug_console_device(writer)?;
Expand Down
4 changes: 3 additions & 1 deletion vmm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,7 @@ impl Vmm {
false
} else {
let iteration = s.iteration - AUTO_CONVERGE_ITERATION_DELAY;
iteration % AUTO_CONVERGE_ITERATION_INCREASE == 0
iteration.is_multiple_of(AUTO_CONVERGE_ITERATION_INCREASE)
}
}

Expand Down Expand Up @@ -2656,12 +2656,14 @@ mod unit_tests {
mode: ConsoleOutputMode::Null,
iommu: false,
socket: None,
url: None,
},
console: ConsoleConfig {
file: None,
mode: ConsoleOutputMode::Tty,
iommu: false,
socket: None,
url: None,
},
#[cfg(target_arch = "x86_64")]
debug_console: DebugConsoleConfig::default(),
Expand Down
1 change: 1 addition & 0 deletions vmm/src/seccomp_filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,7 @@ fn vcpu_thread_rules(
(libc::SYS_rt_sigreturn, vec![]),
(libc::SYS_sched_yield, vec![]),
(libc::SYS_sendmsg, vec![]),
(libc::SYS_sendto, vec![]),
(libc::SYS_shutdown, vec![]),
(libc::SYS_sigaltstack, vec![]),
(libc::SYS_tgkill, vec![]),
Expand Down
Loading
Loading