Virtio-serial API: Difference between revisions
From KVM
(Add note on using poll inside signal handler) |
(→Guest API: add links to guest agent src code for reference) |
||
(9 intermediate revisions by 2 users not shown) | |||
Line 8: | Line 8: | ||
|Port discovery | |Port discovery | ||
|symlinks from <code> /dev/virtio-port/<portname> </code> to <code> /dev/vportNpn </code> as mentioned in [http://www.linux-kvm.org/page/VMchannel_Requirements#Invocation Invocation] and [http://fedoraproject.org/wiki/Features/VirtioSerial#How_To_Test How To Test] | |symlinks from <code> /dev/virtio-port/<portname> </code> to <code> /dev/vportNpn </code> as mentioned in [http://www.linux-kvm.org/page/VMchannel_Requirements#Invocation Invocation] and [http://fedoraproject.org/wiki/Features/VirtioSerial#How_To_Test How To Test] | ||
| | |In Windows, port enumeration can be done using SetupAPI functions. For | ||
more information please see [http://git.kernel.org/?p=virt/kvm/kvm-guest-drivers-windows.git;a=blob_plain;f=vioserial/app/device.cpp;hb=48b3a3f78fe4711d1561b32c9a1c0ca6471f85e3#GetDevicePath GetDevicePath] or visit MSDN site [http://msdn.microsoft.com/en-us/library/cc185682%28VS.85%29.aspx#Setup_API Setup API] | |||
|- | |- | ||
|Opening port | |Opening port | ||
Line 14: | Line 15: | ||
* Returns >= 0 on success. | * Returns >= 0 on success. | ||
* Only one open allowed at a time for a port. | * Only one open allowed at a time for a port. | ||
| | |<code>HANDLE WINAPI CreateFile( | ||
__in LPCTSTR lpFileName, | |||
__in DWORD dwDesiredAccess, | |||
__in DWORD dwShareMode, | |||
__in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, | |||
__in DWORD dwCreationDisposition, | |||
__in DWORD dwFlagsAndAttributes, | |||
__in_opt HANDLE hTemplateFile | |||
);</code> | |||
* If the function fails, the return value is INVALID_HANDLE_VALUE. | |||
|- | |- | ||
|Reading | |Reading | ||
Line 22: | Line 32: | ||
* Block or <code>-EAGAIN</code> if data not available. | * Block or <code>-EAGAIN</code> if data not available. | ||
* Errno will contain <code>-ENODEV</code> if port or device get hot-unplugged | * Errno will contain <code>-ENODEV</code> if port or device get hot-unplugged | ||
| | |<code>BOOL WINAPI ReadFile( | ||
__in HANDLE hFile, | |||
__out LPVOID lpBuffer, | |||
__in DWORD nNumberOfBytesToRead, | |||
__out_opt LPDWORD lpNumberOfBytesRead, | |||
__inout_opt LPOVERLAPPED lpOverlapped | |||
);</code> | |||
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise it can be NULL. | |||
|- | |- | ||
|Writing | |Writing | ||
Line 29: | Line 46: | ||
* If host is not connected, write blocks or returns <code>-EAGAIN</code>. | * If host is not connected, write blocks or returns <code>-EAGAIN</code>. | ||
* Errno will contain <code>-ENODEV</code> if port or device got hot-unplugged. | * Errno will contain <code>-ENODEV</code> if port or device got hot-unplugged. | ||
| | |<code>BOOL WINAPI WriteFile( | ||
__in HANDLE hFile, | |||
__in LPCVOID lpBuffer, | |||
__in DWORD nNumberOfBytesToWrite, | |||
__out_opt LPDWORD lpNumberOfBytesWritten, | |||
__inout_opt LPOVERLAPPED lpOverlapped | |||
);</code> | |||
* A pointer to an OVERLAPPED structure is required if the hFile parameter was opened with FILE_FLAG_OVERLAPPED, otherwise this parameter can be NULL. | |||
|- | |- | ||
|Poll | |Poll | ||
Line 40: | Line 64: | ||
* From kernel 2.6.37, <code>SIGIO</code> will be sent to guest apps that set <code>O_ASYNC</code> flag on the fd using <code>fcntl(2)</code>. | * From kernel 2.6.37, <code>SIGIO</code> will be sent to guest apps that set <code>O_ASYNC</code> flag on the fd using <code>fcntl(2)</code>. | ||
* <code>SIGIO</code> will be sent on host connection up, down and port unplug events. | * <code>SIGIO</code> will be sent on host connection up, down and port unplug events. | ||
* Use poll() within signal handler to identify which port(s) changed state and how. | * Use <code>poll()</code> within signal handler to identify which port(s) changed state and how. | ||
| | | | ||
|- | |- | ||
Line 46: | Line 70: | ||
For an example of a C program that uses the virtio-serial Linux guest API, see [http://fedorapeople.org/ | For an example of a C program that uses the virtio-serial Linux guest API, see [http://fedorapeople.org/cgit/amitshah/public_git/test-virtserial.git/tree/auto-virtserial-guest.c auto-virtserial-guest.c] and the [http://git.qemu.org/?p=qemu.git;a=blob;f=qga/channel-posix.c;hb=HEAD qemu guest agent]. The Windows guest API can be seen in action in the [http://git.qemu.org/?p=qemu.git;a=blob;f=qga/channel-win32.c;hb=HEAD qemu guest agent] as well. | ||
== Host API == | == Host API == | ||
There's an in-qemu host API exposed by the virtio-serial code. The following is true for the in-qemu API for qemu version 0.13 and for the qemu version found in Red Hat Enterprise Linux 6.0, straight from [http://git.qemu.org/qemu.git/ | There's an in-qemu host API exposed by the virtio-serial code. The following is true for the in-qemu API for qemu version 0.13 and for the qemu version found in Red Hat Enterprise Linux 6.0, straight from [http://git.qemu.org/?p=qemu.git;a=blob;f=hw/virtio-serial.h/virtio-serial.h;h=ff08c406819bfa62ea63ed81cd1d32e9fe18fec4;hb=stable-0.13 hw/virtio-serial.h]: | ||
{| | {| | ||
Line 107: | Line 130: | ||
|} | |} | ||
For an example use of this API, see [http://git.qemu.org/qemu.git/ | For an example use of this API, see [http://git.qemu.org/?p=qemu.git;a=blob;f=hw/virtio-serial.h/virtio-console.c;h=caea11f3a8642d7e6d6f75a91ec2a6354399e8c2;hb=stable-0.13 hw/virtio-console.c] | ||
=== Caveats === | |||
* Live Migration | |||
: When a VM uses the qemu chardev interface to talk to guest virtio-serial ports, the chardev file will be closed on the source (and may be opened on the destination). Host applications have to be aware of such migration and either collaborate with libvirt or have their own mechanism to re-connect to the destination host and continue the communication. | |||
: A future version of qemu may introduce 'migration notifiers' that may help chardevs let apps know of migration start / stop. | |||
* qemu chardevs | |||
: qemu's chardevs are notoriously out of date from the state-of-the-art and need a complete rewrite to be pleasurable to use. | |||
: However respecting the return values from the various read/write calls to chardevs will help in ensuring data is never lost. The various backends (unix, tcp sockets, file, etc.) do work well when used with care. |
Latest revision as of 02:51, 28 June 2016
Guest API
Function | Linux guest | Windows guest |
---|---|---|
Port discovery | symlinks from /dev/virtio-port/<portname> to /dev/vportNpn as mentioned in Invocation and How To Test
|
In Windows, port enumeration can be done using SetupAPI functions. For
more information please see GetDevicePath or visit MSDN site Setup API |
Opening port | open(2)
|
HANDLE WINAPI CreateFile(
|
Reading | read(2)
|
BOOL WINAPI ReadFile(
|
Writing | write(2)
|
BOOL WINAPI WriteFile(
|
Poll | poll()
| |
Asynchronous notifications | signal(7)
|
For an example of a C program that uses the virtio-serial Linux guest API, see auto-virtserial-guest.c and the qemu guest agent. The Windows guest API can be seen in action in the qemu guest agent as well.
Host API
There's an in-qemu host API exposed by the virtio-serial code. The following is true for the in-qemu API for qemu version 0.13 and for the qemu version found in Red Hat Enterprise Linux 6.0, straight from hw/virtio-serial.h:
|
In addition to this, the VirtIOSerialPortInfo struct has a function pointer for a callback to be called when guest writes some data to the port:
|
For an example use of this API, see hw/virtio-console.c
Caveats
- Live Migration
- When a VM uses the qemu chardev interface to talk to guest virtio-serial ports, the chardev file will be closed on the source (and may be opened on the destination). Host applications have to be aware of such migration and either collaborate with libvirt or have their own mechanism to re-connect to the destination host and continue the communication.
- A future version of qemu may introduce 'migration notifiers' that may help chardevs let apps know of migration start / stop.
- qemu chardevs
- qemu's chardevs are notoriously out of date from the state-of-the-art and need a complete rewrite to be pleasurable to use.
- However respecting the return values from the various read/write calls to chardevs will help in ensuring data is never lost. The various backends (unix, tcp sockets, file, etc.) do work well when used with care.