[Spice-devel] RFC: spice vdagent protocol documentation
Yaniv Kaul
ykaul at redhat.com
Wed Sep 1 12:24:24 PDT 2010
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.
>
>
> 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