mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: notify virtio-console of pty resizes
When a pty is resized (using the TIOCSWINSZ ioctl -- see ioctl_tty(2)), the kernel will send a SIGWINCH signal to the pty's foreground process group to notify it of the resize. This is the only way to be notified by the kernel of a pty resize. We can't just make the cloud-hypervisor process's process group the foreground process group though, because a process can only set the foreground process group of its controlling terminal, and cloud-hypervisor's controlling terminal will often be the terminal the user is running it in. To work around this, we fork a subprocess in a new process group, and set its process group to be the foreground process group of the pty. The subprocess additionally must be running in a new session so that it can have a different controlling terminal. This subprocess writes a byte to a pipe every time the pty is resized, and the virtio-console device can listen for this in its epoll loop. Alternatives I considered were to have the subprocess just send SIGWINCH to its parent, and to use an eventfd instead of a pipe. I decided against the signal approach because re-purposing a signal that has a very specific meaning (even if this use was only slightly different to its normal meaning) felt unclean, and because it would have required using pidfds to avoid race conditions if cloud-hypervisor had terminated, which added complexity. I decided against using an eventfd because using a pipe instead allows the child to be notified (via poll(2)) when nothing is reading from the pipe any more, meaning it can be reliably notified of parent death and terminate itself immediately. I used clone3(2) instead of fork(2) because without CLONE_CLEAR_SIGHAND the subprocess would inherit signal-hook's signal handlers, and there's no other straightforward way to restore all signal handlers to their defaults in the child process. The only way to do it would be to iterate through all possible signals, or maintain a global list of monitored signals ourselves (vmm:vm::HANDLED_SIGNALS is insufficient because it doesn't take into account e.g. the SIGSYS signal handler that catches seccomp violations). Signed-off-by: Alyssa Ross <hi@alyssa.is>
This commit is contained in:
committed by
Rob Bradford
parent
98bfd1e988
commit
330b5ea3be
@@ -47,6 +47,7 @@ use vm_migration::{MigratableError, Pausable, Snapshot, Snapshottable, Transport
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
pub mod api;
|
||||
mod clone3;
|
||||
pub mod config;
|
||||
pub mod cpu;
|
||||
pub mod device_manager;
|
||||
@@ -55,6 +56,7 @@ pub mod interrupt;
|
||||
pub mod memory_manager;
|
||||
pub mod migration;
|
||||
pub mod seccomp_filters;
|
||||
mod sigwinch_listener;
|
||||
pub mod vm;
|
||||
|
||||
#[cfg(feature = "acpi")]
|
||||
@@ -405,6 +407,7 @@ impl Vmm {
|
||||
activate_evt,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
)?;
|
||||
if let Some(serial_pty) = vm.serial_pty() {
|
||||
self.epoll
|
||||
@@ -532,6 +535,10 @@ impl Vmm {
|
||||
let config = vm.get_config();
|
||||
let serial_pty = vm.serial_pty();
|
||||
let console_pty = vm.console_pty();
|
||||
let console_resize_pipe = vm
|
||||
.console_resize_pipe()
|
||||
.as_ref()
|
||||
.map(|pipe| pipe.try_clone().unwrap());
|
||||
self.vm_shutdown()?;
|
||||
|
||||
let exit_evt = self.exit_evt.try_clone().map_err(VmError::EventFdClone)?;
|
||||
@@ -556,6 +563,7 @@ impl Vmm {
|
||||
activate_evt,
|
||||
serial_pty,
|
||||
console_pty,
|
||||
console_resize_pipe,
|
||||
)?);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user