[Spice-devel] RFC: spice vdagent protocol documentation

Alon Levy alevy at redhat.com
Wed Sep 1 07:42:33 PDT 2010


----- "Hans de Goede" <hdegoede at redhat.com> 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.
> 
> 
> 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}
> 

With newer drivers there is a symbolic link in windows as well, I think \\\\.\\com.redhat.spice.0,
we just don't use it in vdservice because it wasn't there before and no one bothered to change it
back to a simple filename. But the GUID should not be documented.

> 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

There is a confusion in terms here, some due to me not separating the channel
concept out of the qemu code. Spice has channels which are basically a pipe
that accepts a specific protocol (all channels share a basic subset of messages too).
The vdagent doesn't actually have a channel of it's own, it has a number of messages
that exist in the main channel I think.

> 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;
>      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;
>      uint32_t type;
>      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

s/table/tablet/

> 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 display_id;
> } VDAgentMouseState;
> 
> 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
s/send/sent/ (also in some following places, I didn't bother marking all)

> 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;
>      uint32_t flags;
>      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;
> 
> 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.
> 

That's kinda of a currently-we-dont-have-a-linux-vdagent issue, no? I mean,
wallpaper - not os specific
color depth - not os specific
font-smooth - no idea if there is a X equivalent, but could be
animation - not os specific (of course it becomes one for gnome, one for kde, etc, maybe there is a freedesktop standard way to change this somewhere).

> 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

Great work. Btw, we do have the sources for the pdf's lying somewhere, I guess
it would be good to consolidate those things. Arnon, I know you told me you know
where they are already, can you forward that data to 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