[Differential] D7185: Add virtio-console support to bhyve
Paul Vixie
paul at redbarn.org
Mon Jul 11 21:53:57 UTC 2016
Jakub Klama wrote:
> nmdm(4) emulates a serial port. how could one pass ioctls and signals via serial port?
i think if bhyve arranged for its virtio_console device to be its
control terminal, it would receive SIGWINCH from the host kernel, which
it could propagate to the guest's /dev/console, after first doing a
TIOCGWINSZ to find the new size and making that available to the guest's
/dev/console driver's TIOCGWINSZ.
rtty would have to do the same.
>> yikes. so you've got to reinvent what TIOCPKT does, but differently?
>
> how could one pass ioctls via unix domain socket?
you can't. that's why i'm saying "but differently".
so what's supposed to happen is that a window size event is propagated
through a tty-like device (nmdm, pty, pts) by setting the new window
size with TIOCSWINSZ and then causing the process group of the control
tty to receive a SIGWINCH, which receives the new window size with
TIOCGWINSZ. this works on pty and pts, because the software that
connects the master and slave sides of those pseudo terminal devices is
window size aware. in sys/kern/tty_pts.c we see the following:
/* Just redirect this ioctl to the slave device. */
tty_lock(tp);
error = tty_ioctl(tp, cmd, data, fp->f_flag, td);
tty_unlock(tp);
if (error == ENOIOCTL)
error = ENOTTY;
this is after a switch statement that fails to enumerate TIOCSWINSZ, so
it falls through to this code in sys/kern/tty.c:
case TIOCGWINSZ:
/* Obtain window size. */
*(struct winsize*)data = tp->t_winsize;
return (0);
case TIOCSWINSZ:
/* Set window size. */
tty_set_winsize(tp, data);
return (0);
ssh (slogin), rlogin, telnet, but sadly not rtty, all catch SIGWINCH,
then they do TIOCGWINSZ to retrieve the kernel's idea of new window
size, then they propagate this to their other-side (sshd, rlogind,
telnetd) using a control-packet that's unique to each protocol. the
other-side hears the control message and calls TIOCSWINSZ to tell the
other-side kernel about the new window size. when this happens, the code
shown above for TIOCSWINSZ that calls tty_set_winsize() causes the
SIGWINCH to be sent to the process group of the tty:
void
tty_set_winsize(struct tty *tp, const struct winsize *wsz)
{
if (memcmp(&tp->t_winsize, wsz, sizeof(*wsz)) == 0)
return;
tp->t_winsize = *wsz;
tty_signal_pgrp(tp, SIGWINCH);
}
so in the bhyve case, the bhyve process and its console driver is acting
as both a tty client (because it connects to one in the host) and as a
tty server (because it offers one in the guest), and it is therefore in
the role that rlogin+rlogind, or telnet+telnetd, or ssh+sshd, would be
in. and in that role, you hear SIGWINCH, you ask for TIOCGWINSZ, you
propagate this value in an implementation-dependent way, and you perform
the effect of TIOCSWINSZ to your guest.
so, i still don't understand why you created a vertio_console driver
that opens a socket in the host file system and speaks a new protocol
over that. you can, from within bhyve, do what rlogin+rlogind, or
ssh+sshd, or telnet+telnetd do. if nmdm isn't propagating window size
changes yet, either you or i can fix that. and i can fix rtty. inventing
a new data path with a new (and as-yet-undefined) protocol should be a
last resort. we're no where near last-resort yet.
--
P Vixie
More information about the freebsd-virtualization
mailing list