Guest and Host communication should be a simple affair — the venerable TCP/IP sockets should be the first answer to any remote communication. However, it’s not so simple once some special virtualisation-related constraints are added to the mix:
- the guest and host are different machines, managed differently
- the guest administrator and the host administrator may be different people
- the guest administrator might inadvertently block IP-based communication channels to the host via firewall rules, rendering the TCP/IP-based communication channels unusable
The last point needs some elaboration: system administrators want to be really conservative in what they “open” to the outside world. In this sense, the guest and host administrators are actively hostile to each other. Also, rightly, neither should trust each other, given that a lot of the data stored in operating systems are now stored within clouds and any leak of the data could prove disastrous to the administrators and their employers.
So what’s really needed is a special communication channel between guests and hosts that are not susceptible to being blocked out by guests or hosts as well as being a very special-purpose low-bandwidth channel that doesn’t look to re-implement TCP/IP. Some other requirements are mentioned on this page.
After several iterations, we settled on one particular implementation: virtio-serial. The virtio-serial infrastructure rides on top of virtio, a generic para-virtual bus that enables exposing custom devices to guests. virtio devices are abstracted enough so that guest drivers need not know what kind of bus they’re actually riding on: they are PCI devices on x86 and native devices on s390 under the hood. What this means is the same guest driver can be used to communicate with a virtio-serial device under x86 as well as s390. Behind the scenes, the virtio layer, depending on the guest architecture type, works with the host virtio-pci device or virtio-s390 device.
The host device is coded in qemu. One host virtio-serial device is capable of hosting multiple channels or ports on the same device. The number of ports that can ride on top of a virtio-serial device is currently arbitrarily limited to 31, but one device can very well support 2^31 ports. The device is available since upstream qemu release 0.13 as well as in Fedora from release 13 onwards.
The guest driver is written for Linux and Windows guests. The API exposed includes open, read, write, poll, close calls. For the Linux guest, ports can be opened in blocking as well as non-blocking modes. The driver is included upstream from Linux kernel version 2.6.35. Kernel 2.6.37 will also have asynchronous IO support — ie, SIGIO will be delivered to interested userspace apps whenever the host-side connection is established or closed, or when a port gets hot-unplugged.
Using the ports is simple: when using qemu from the command line directly, add:
-chardev socket,path=/tmp/port0,server,nowait,id=port0-char -device virtio-serial -device virtserialport,id=port1,name=org.fedoraproject.port.0,chardev=port0-char
There is sample C code for the guest as well as sample python code from the test suites. The original test suite, written to verify the functionality of the user-kernel interface, will in the near future be moved to autotest, enabling faster addition of more tests and tests that not just check for correctness, but also regressions and bugs.
virtio-serial is already in use by the Matahari, Spice, libguestfs and Anaconda projects. I’ll briefly mention how Anaconda is going to use virtio-serial: starting Fedora 14, guest installs of Fedora will automatically send Anaconda logs to the host if a virtio-serial port with the name of ‘org.fedoraproject.anaconda.log.0‘ is found. virt-install is modified to create such a virtio-serial port. This means debugging early anaconda output will be easier with the logs available on the host (and not worrying about guest file system corruptions during install or network drivers not available before a crash).
Further use: There are many more uses of virtio-serial, which should be pretty easy to code:
- shutting down or suspending VMs when a host is shut down
- clipboard copy/paste between hosts and guests (this is under progress by the Spice team)
- lock a desktop session in the guest when a vnc/spice connection is closed
- fetch cpu/memory/power usage rates at regular intervals for monitoring