vmm: Open the serial PTY in non-blocking mode

This prevents the boot of the guest kernel from being blocked by
blocking I/O on the serial output since the data will be buffered into
the SerialBuffer.

Fixes: #3004

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2021-08-31 16:07:25 +01:00
parent d92707afc5
commit 66f0b5b2b6

View File

@ -473,7 +473,7 @@ pub fn get_win_size() -> (u16, u16) {
const TIOCSPTLCK: libc::c_int = 0x4004_5431;
const TIOCGTPEER: libc::c_int = 0x5441;
pub fn create_pty() -> io::Result<(File, File, PathBuf)> {
pub fn create_pty(non_blocking: bool) -> io::Result<(File, File, PathBuf)> {
// Try to use /dev/pts/ptmx first then fall back to /dev/ptmx
// This is done to try and use the devpts filesystem that
// could be available for use in the process's namespace first.
@ -481,17 +481,19 @@ pub fn create_pty() -> io::Result<(File, File, PathBuf)> {
// kernels could have things setup differently.
// See https://www.kernel.org/doc/Documentation/filesystems/devpts.txt
// for further details.
let custom_flags = libc::O_NOCTTY | if non_blocking { libc::O_NONBLOCK } else { 0 };
let main = match OpenOptions::new()
.read(true)
.write(true)
.custom_flags(libc::O_NOCTTY)
.custom_flags(custom_flags)
.open("/dev/pts/ptmx")
{
Ok(f) => f,
_ => OpenOptions::new()
.read(true)
.write(true)
.custom_flags(libc::O_NOCTTY)
.custom_flags(custom_flags)
.open("/dev/ptmx")?,
};
let mut unlock: libc::c_ulong = 0;
@ -1713,7 +1715,7 @@ impl DeviceManager {
Some(Box::new(buffer))
} else {
let (main, mut sub, path) =
create_pty().map_err(DeviceManagerError::SerialPtyOpen)?;
create_pty(true).map_err(DeviceManagerError::SerialPtyOpen)?;
self.set_raw_mode(&mut sub)
.map_err(DeviceManagerError::SetPtyRaw)?;
self.config.lock().unwrap().serial.file = Some(path.clone());
@ -1747,7 +1749,7 @@ impl DeviceManager {
Some(Box::new(writer))
} else {
let (main, mut sub, path) =
create_pty().map_err(DeviceManagerError::ConsolePtyOpen)?;
create_pty(false).map_err(DeviceManagerError::ConsolePtyOpen)?;
self.set_raw_mode(&mut sub)
.map_err(DeviceManagerError::SetPtyRaw)?;
self.config.lock().unwrap().console.file = Some(path.clone());