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. */
        error = tty_ioctl(tp, cmd, data, fp->f_flag, td);
        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:

tty_set_winsize(struct tty *tp, const struct winsize *wsz)

        if (memcmp(&tp->t_winsize, wsz, sizeof(*wsz)) == 0)
        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
freebsd-virtualization@freebsd.org mailing list
To unsubscribe, send any mail to 

Reply via email to