vmm: Add new "null" serial/console output mode

Poor performance was observed when booting kernels with "console=ttyS0"
and the serial port disabled.

This change introduces a "null" console output mode and makes it the
default for the serial console. In this case the serial port
is advertised as per other output modes but there is no input and any
output is dropped.

Fixes: #163

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford
2019-08-09 08:56:10 +01:00
committed by Sebastien Boeuf
parent f910476dd7
commit d9a355f85a
4 changed files with 135 additions and 10 deletions

View File

@@ -137,13 +137,13 @@ fn main() {
.arg(
Arg::with_name("serial")
.long("serial")
.help("Control serial port: off|tty|file=/path/to/a/file")
.default_value("off"),
.help("Control serial port: off|null|tty|file=/path/to/a/file")
.default_value("null"),
)
.arg(
Arg::with_name("console")
.long("console")
.help("Control (virtio) console: off|tty|file=/path/to/a/file")
.help("Control (virtio) console: off|null|tty|file=/path/to/a/file")
.default_value("tty"),
)
.arg(
@@ -1322,7 +1322,7 @@ mod tests {
}
#[test]
fn test_serial_disable() {
fn test_serial_off() {
test_block!(tb, "", {
let mut clear = ClearDiskConfig::new();
let guest = Guest::new(&mut clear);
@@ -1380,6 +1380,124 @@ mod tests {
});
}
#[test]
fn test_serial_null() {
test_block!(tb, "", {
let mut clear = ClearDiskConfig::new();
let guest = Guest::new(&mut clear);
let mut child = Command::new("target/debug/cloud-hypervisor")
.args(&["--cpus", "1"])
.args(&["--memory", "size=512M"])
.args(&["--kernel", guest.fw_path.as_str()])
.args(&[
"--disk",
guest
.disk_config
.disk(DiskType::OperatingSystem)
.unwrap()
.as_str(),
guest
.disk_config
.disk(DiskType::CloudInit)
.unwrap()
.as_str(),
])
.args(&["--net", guest.default_net_string().as_str()])
.args(&["--serial", "null"])
.args(&["--console", "off"])
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
thread::sleep(std::time::Duration::new(20, 0));
// Test that there is a ttyS0
aver_eq!(
tb,
guest
.ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'ttyS0'")
.trim()
.parse::<u32>()
.unwrap(),
1
);
guest.ssh_command("sudo reboot");
thread::sleep(std::time::Duration::new(10, 0));
let _ = child.kill();
match child.wait_with_output() {
Ok(out) => {
aver!(
tb,
!String::from_utf8_lossy(&out.stdout).contains("cloud login:")
);
}
Err(_) => aver!(tb, false),
}
Ok(())
});
}
#[test]
fn test_serial_tty() {
test_block!(tb, "", {
let mut clear = ClearDiskConfig::new();
let guest = Guest::new(&mut clear);
let mut child = Command::new("target/debug/cloud-hypervisor")
.args(&["--cpus", "1"])
.args(&["--memory", "size=512M"])
.args(&["--kernel", guest.fw_path.as_str()])
.args(&[
"--disk",
guest
.disk_config
.disk(DiskType::OperatingSystem)
.unwrap()
.as_str(),
guest
.disk_config
.disk(DiskType::CloudInit)
.unwrap()
.as_str(),
])
.args(&["--net", guest.default_net_string().as_str()])
.args(&["--serial", "tty"])
.args(&["--console", "off"])
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.unwrap();
thread::sleep(std::time::Duration::new(20, 0));
// Test that there is a ttyS0
aver_eq!(
tb,
guest
.ssh_command("cat /proc/interrupts | grep 'IO-APIC' | grep -c 'ttyS0'")
.trim()
.parse::<u32>()
.unwrap(),
1
);
guest.ssh_command("sudo reboot");
thread::sleep(std::time::Duration::new(10, 0));
let _ = child.kill();
match child.wait_with_output() {
Ok(out) => {
aver!(
tb,
String::from_utf8_lossy(&out.stdout).contains("cloud login:")
);
}
Err(_) => aver!(tb, false),
}
Ok(())
});
}
#[test]
fn test_serial_file() {
test_block!(tb, "", {