[Spice-devel] RFC: spice vdagent protocol documentation

Hans de Goede hdegoede at redhat.com
Wed Sep 1 12:36:49 PDT 2010


Hi,

On 09/01/2010 09:24 PM, Yaniv Kaul wrote:
> On 9/1/2010 5:22 PM, Hans de Goede wrote:
>> Hi All,
>>
>> This is a first draft version / a first attempt to document the
>> spice vdagent protocol. This is meant to eventually go to the wiki.
>>
>> Question where on the wiki should I put this?
>>
>> spice vdagent protocol
>> -----------------------
>>
>> For certain features to work spice requires that the guest os is running
>> the spice agent (vdagent). This document describes how vdagent communicates
>> with the spice server and client.
>
> As those messages pass on the wire, all my below comments refer to the waste of bytes in the messages.
> 1. Most/all of those messages can be smaller, which is always nice.
> 2. ... which will also make more of them perhaps fit into a single packet, if multiple message can be sent together (and hopefully, they can be sent together, if you don't disable Nagle's algorithm - which I believe Spice may be doing today).
> 3. ... which might also make it, some day, ride on other messages, which are sent anyway between the server and the client (as a sub-message? in other channels as well?).
>
> Anyway, specific comments below.
>

Thanks for your feedback, but this is documentation of the existing protocol as
it is in use *today*, not a proposal for a new protocol. The RFC part
is meant to solicit comments about the documentation no matching the
protocol, sorry if that was not clear.

Regards,

Hans


>>
>>
>> 1. vdagent virtio serial port
>> -----------------------------
>>
>> All vdagent communications on the guest side run over a single pipe which
>> gets presented to the guest os as a virtio serial port. Under windows this
>> virtio serial port is identified by the following guid:
>> const GUID GUID_VIOSERIAL_PORT =
>> {0x6fde7521, 0x1b65, 0x48ae, 0xb6, 0x28, 0x80, 0xbe, 0x62, 0x1, 0x60, 0x26}
>>
>> Under Linux this virtio serial port has the following name:
>> /dev/virtio-ports/com.redhat.spice.0
>>
>>
>> 2. vdagent data chunks / ports
>> ------------------------------
>>
>> The vdagent is connect through the virtio serial port (vdagent channel) with
>> the spice server but it can receive messages from / send messages to both
>> the spice server and the spice client. To make this possible all messages on
>> the vdagent channel are prefixed with a VDIChunkHeader:
>> typedef struct SPICE_ATTR_PACKED VDIChunkHeader {
>> uint32_t port;
>
> uint16_t enough?
>
>> uint32_t size;
>> } VDIChunkHeader;
>>
>> Where size is the size of the VDAgentMessage being send / received including
>> the variable data part, iow it is sizeof(VDAgentMessage) + variable_data_len,
>> and port is one of:
>> enum {
>> VDP_CLIENT_PORT = 1,
>> VDP_SERVER_PORT,
>> };
>>
>> When the vdagent receives messages port indicates where the message came from.
>> When sending messages port indicates the intended receiver. When a message is
>> a reply / ack of a received message port should have the same value as it had
>> in the received message the message being send is a reply to.
>>
>> When the spice server receives a message it removes the chunk header and
>> then depending on the port in the chunk header, forwards it to the client,
>> handles it itself, or if the port is not a valid value logs an error and
>> drops the message.
>>
>> Note currently there are no messages from the agent which are meant for the
>> server so all messages send by the agent with a port of VDP_SERVER_PORT get
>> dropped silently.
>>
>>
>> 3. vdagent message struct
>> -------------------------
>>
>> Messages send / received by the agent are encapsulated in the VDAgentMessage
>> struct:
>> typedef struct SPICE_ATTR_PACKED VDAgentMessage {
>> uint32_t protocol;
>
> uint8_t enough?
>
>> uint32_t type;
>
> uint8_t enough?
>
>> uint64_t opaque;
>> uint32_t size;
>> uint8_t data[0];
>> } VDAgentMessage;
>>
>> Where protocol is always VD_AGENT_PROTOCOL.
>>
>> Type is a value from the following enum:
>> enum {
>> VD_AGENT_MOUSE_STATE = 1,
>> VD_AGENT_MONITORS_CONFIG,
>> VD_AGENT_REPLY,
>> VD_AGENT_CLIPBOARD,
>> VD_AGENT_DISPLAY_CONFIG,
>> VD_AGENT_ANNOUNCE_CAPABILITIES,
>> VD_AGENT_END_MESSAGE,
>> };
>>
>> Opaque is a place holder for message types which only need to pass a single
>> integer as message data, for message types which have more data it is
>> always set to 0.
>>
>> Size is the size of the variable length data. Note that the size of the
>> complete message in the channel is
>> sizeof(VDIChunkHeader) + sizeof(VDAgentMessage) + variable_data_len
>>
>> Data is the start of the variable length data, the contents of this depends
>> on the message types, for most messages it is a message type specific
>> struct such as VDAgentMouseState. Note that data is declared as a 0 sized
>> array meaning that it does not take up any size in the struct, it is simply
>> there to be able to easily determine the start address of the data.
>>
>>
>> 4. vdagent messages
>> -------------------
>>
>> 4.1 VD_AGENT_MOUSE_STATE
>>
>> Spice supports two mouse modes, server and client.
>>
>> In server mode the the QEMU ps/2 mouse emulation is used for sending mouse
>> state to the guest. Upon user click inside the Spice client window, the client
>> mouse is captured and the client sends mouse moves as delta coordinates.
>>
>> In client mode mouse coordinates are send as absolute values to the guest,
>> this requires using either usb table emulation, or sending them to the
>> vdagent which will them notify the guest os of the mouse position (and of
>> button clicks).
>>
>> The VD_AGENT_MOUSE_STATE message contains mouse state updates send by the
>> spice server when the mouse is in client mode. The variable data of these
>> messages consists of the following structure:
>>
>> typedef struct SPICE_ATTR_PACKED VDAgentMouseState {
>> uint32_t x;
>> uint32_t y;
>> uint32_t buttons;
>
> uint8_t enough?
>
>> uint8_t display_id;
>> } VDAgentMouseState;
>
> - Especially this message, it would be nice to send along the display channel.
> - Perhaps we can use POINT16 to send it?
> - Can the server change the buttons state?
>
>>
>> Note these messages are send by the spice server, not by the spice client as
>> the server does all the mouse handling (like switching between client and
>> server mode as the vdagent connects / disconnects).
>>
>> 4.2 VD_AGENT_MONITORS_CONFIG
>>
>> This message gets send by the client to the agent when the client is run
>> in fullscreen auto configuration mode. This message contains information
>> about the monitors attached to the client machine. Upon receiving this
>> message the agent should reconfigure the output(s) of the qxl vga devices
>> in the guest to match those in the message in as far as possible. For
>> example if the client has more outputs then there are configured in the
>> vm the outputs which are present should be configured to match what is
>> in the message.
>>
>> The variable data of these messages consists of the following structure:
>>
>> typedef struct SPICE_ATTR_PACKED VDAgentMonitorsConfig {
>> uint32_t num_of_monitors;
>
> uint8_t enough?
>
>> uint32_t flags;
>
> uint8_t enough? or perhaps one uint8_t size_of_flags_bitmap, then another 8/16/32bit, accordingly?
>
>
>> VDAgentMonConfig monitors[0];
>> } VDAgentMonitorsConfig;
>>
>> Followed by num_of_monitors times the following structure:
>>
>> typedef struct SPICE_ATTR_PACKED VDAgentMonConfig {
>> uint32_t height;
>> uint32_t width;
>> uint32_t depth;
>> int32_t x;
>> int32_t y;
>> } VDAgentMonConfig;
>>
>
> All look big to me.
> And so on.
> Y.
>
>> When the agent is done configuring the outputs it should send back in
>> VD_AGENT_REPLY message with a type set to VD_AGENT_MONITORS_CONFIG
>> and error set to VD_AGENT_SUCCESS or VD_AGENT_ERROR to indicate success
>> resp. error in configuring the outputs.
>>
>> 4.3 VD_AGENT_REPLY
>>
>> This message gets send by the vdagent to the spice client to signal
>> it is done handling a VD_AGENT_MONITORS_CONFIG or VD_AGENT_DISPLAY_CONFIG,
>> and if it succeeded or not:
>>
>> typedef struct SPICE_ATTR_PACKED VDAgentReply {
>> uint32_t type;
>> uint32_t error;
>> } VDAgentReply;
>>
>> enum {
>> VD_AGENT_SUCCESS = 1,
>> VD_AGENT_ERROR,
>> };
>>
>> 4.4 VD_AGENT_CLIPBOARD
>>
>> Still in flux
>>
>> 4.5 VD_AGENT_DISPLAY_CONFIG
>>
>> This message gets send by the spice client to the vdagent to notify it of
>> any special performance related settings. The client can ask the vdagent
>> to disable various features of the guest os like font anti aliasing to improve
>> performance. vdagent should do a best effort here, esp. as most settings
>> are rather windows centric and should return a success status using
>> VD_AGENT_REPLY unless something really went wrong.
>>
>> typedef struct SPICE_ATTR_PACKED VDAgentDisplayConfig {
>> uint32_t flags;
>> uint32_t depth;
>> } VDAgentDisplayConfig;
>>
>> enum {
>> VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_WALLPAPER = (1 << 0),
>> VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_FONT_SMOOTH = (1 << 1),
>> VD_AGENT_DISPLAY_CONFIG_FLAG_DISABLE_ANIMATION = (1 << 2),
>> VD_AGENT_DISPLAY_CONFIG_FLAG_SET_COLOR_DEPTH = (1 << 3),
>> };
>>
>> 4.6 VD_AGENT_ANNOUNCE_CAPABILITIES
>>
>> This message can (and should) be send by both the client and the vdagent,
>> it announces which messages / capabilities (one capability can encompass
>> multiple messages) the sending side may send and/or knows how to handle
>> when received. The purpose of this message is to allow different client
>> and vdagent versions to work together:
>>
>> typedef struct SPICE_ATTR_PACKED VDAgentAnnounceCapabilities {
>> uint32_t request;
>> uint32_t caps[0];
>> } VDAgentAnnounceCapabilities;
>>
>> The request field is a boolean which indicates if the receiver of the
>> message should send back an VD_AGENT_ANNOUNCE_CAPABILITIES message as
>> the sender wants to know its capabilities too. It should be true when
>> initiating a capabilities exchange, and set to false when sending an
>> announce capabilities as a reply to a received one.
>>
>> The caps member of the struct is the beginning of a variable length array
>> holding the capabilities bit, the length of this array can be determined
>> using the VD_AGENT_CAPS_SIZE_FROM_MSG_SIZE macro on the VDAgentMessage
>> msg size member. The indexes for the different capabilities are in an enum
>> defining VD_AGENT_CAP_ constants and there are VD_AGENT_HAS_CAPABILITY
>> and VD_AGENT_SET_CAPABILITY macros to test / set the capability bits
>> in the array.
>>
>> Regards,
>>
>> Hans
>> _______________________________________________
>> Spice-devel mailing list
>> Spice-devel at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/spice-devel
>


More information about the Spice-devel mailing list