aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-12-18 15:41:21 -0600
committerAnthony Liguori <aliguori@us.ibm.com>2012-12-18 15:41:21 -0600
commit510981a097bf16ef4747c9a1dfe806edfc117177 (patch)
tree3b6557eb1896fc1ac06685d319329cfcb5c7074e
parentc3a1ecd0fc565c913efc59663e7ac34b9c3c2291 (diff)
parent700f6b6a921861a8946377a9531b6d1e8b09bb51 (diff)
Merge remote-tracking branch 'spice/spice.v66' into staging
* spice/spice.v66: docs: add spice-port-fqdn.txt spice-qemu-char: register spicevmc ports during qemu_spice_init() spice-qemu-char: keep a list of spice chardev spice-qemu-char: add spiceport chardev spice-qemu-char: factor out CharDriverState creation spice-qemu-char: write to chardev whatever amount it can read qxl+vnc: register a vm state change handler for dummy spice_server qxl: save qemu_create_displaysurface_from result Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
-rw-r--r--docs/spice-port-fqdn.txt19
-rw-r--r--hw/qxl-render.c11
-rw-r--r--qemu-char.c3
-rw-r--r--qemu-options.hx13
-rw-r--r--spice-qemu-char.c107
-rw-r--r--trace-events1
-rw-r--r--ui/qemu-spice.h4
-rw-r--r--ui/spice-core.c6
8 files changed, 141 insertions, 23 deletions
diff --git a/docs/spice-port-fqdn.txt b/docs/spice-port-fqdn.txt
new file mode 100644
index 0000000000..50778952e5
--- /dev/null
+++ b/docs/spice-port-fqdn.txt
@@ -0,0 +1,19 @@
+A Spice port channel is an arbitrary communication between the Spice
+server host side and the client side.
+
+Thanks to the associated reverse fully qualified domain name (fqdn),
+a Spice client can handle the various ports appropriately.
+
+The following fqdn names are reserved by the QEMU project:
+
+org.qemu.monitor.hmp.0
+ QEMU human monitor
+
+org.qemu.monitor.qmp.0:
+ QEMU control monitor
+
+org.qemu.console.serial.0
+ QEMU virtual serial port
+
+org.qemu.console.debug.0
+ QEMU debug console
diff --git a/hw/qxl-render.c b/hw/qxl-render.c
index 98ecb21405..88e63f8085 100644
--- a/hw/qxl-render.c
+++ b/hw/qxl-render.c
@@ -113,11 +113,12 @@ static void qxl_render_update_area_unlocked(PCIQXLDevice *qxl)
qxl->guest_primary.bits_pp);
if (qxl->guest_primary.qxl_stride > 0) {
qemu_free_displaysurface(vga->ds);
- qemu_create_displaysurface_from(qxl->guest_primary.surface.width,
- qxl->guest_primary.surface.height,
- qxl->guest_primary.bits_pp,
- qxl->guest_primary.abs_stride,
- qxl->guest_primary.data);
+ vga->ds->surface = qemu_create_displaysurface_from
+ (qxl->guest_primary.surface.width,
+ qxl->guest_primary.surface.height,
+ qxl->guest_primary.bits_pp,
+ qxl->guest_primary.abs_stride,
+ qxl->guest_primary.data);
} else {
qemu_resize_displaysurface(vga->ds,
qxl->guest_primary.surface.width,
diff --git a/qemu-char.c b/qemu-char.c
index 242b799909..9940701d6a 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2762,6 +2762,9 @@ static const struct {
#endif
#ifdef CONFIG_SPICE
{ .name = "spicevmc", .open = qemu_chr_open_spice },
+#if SPICE_SERVER_VERSION >= 0x000c02
+ { .name = "spiceport", .open = qemu_chr_open_spice_port },
+#endif
#endif
};
diff --git a/qemu-options.hx b/qemu-options.hx
index 231cc4f55f..9df0cde64c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1749,6 +1749,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
#endif
#if defined(CONFIG_SPICE)
"-chardev spicevmc,id=id,name=name[,debug=debug]\n"
+ "-chardev spiceport,id=id,name=name[,debug=debug]\n"
#endif
, QEMU_ARCH_ALL
)
@@ -1776,6 +1777,7 @@ Backend is one of:
@option{tty},
@option{parport},
@option{spicevmc}.
+@option{spiceport}.
The specific backend will determine the applicable options.
All devices must have an id, which can be any string up to 127 characters long.
@@ -1961,6 +1963,17 @@ required.
Connect to a spice virtual machine channel, such as vdiport.
+@item -chardev spiceport ,id=@var{id} ,debug=@var{debug}, name=@var{name}
+
+@option{spiceport} is only available when spice support is built in.
+
+@option{debug} debug level for spicevmc
+
+@option{name} name of spice port to connect to
+
+Connect to a spice port, allowing a Spice client to handle the traffic
+identified by a name (preferably a fqdn).
+
@end table
ETEXI
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
index 09aa22d566..b2586c263d 100644
--- a/spice-qemu-char.c
+++ b/spice-qemu-char.c
@@ -3,6 +3,7 @@
#include "ui/qemu-spice.h"
#include <spice.h>
#include <spice-experimental.h>
+#include <spice/protocol.h>
#include "osdep.h"
@@ -14,8 +15,6 @@
} \
} while (0)
-#define VMC_MAX_HOST_WRITE 2048
-
typedef struct SpiceCharDriver {
CharDriverState* chr;
SpiceCharDeviceInstance sin;
@@ -25,8 +24,12 @@ typedef struct SpiceCharDriver {
uint8_t *datapos;
ssize_t bufsize, datalen;
uint32_t debug;
+ QLIST_ENTRY(SpiceCharDriver) next;
} SpiceCharDriver;
+static QLIST_HEAD(, SpiceCharDriver) spice_chars =
+ QLIST_HEAD_INITIALIZER(spice_chars);
+
static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
{
SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
@@ -35,8 +38,8 @@ static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
uint8_t* p = (uint8_t*)buf;
while (len > 0) {
- last_out = MIN(len, VMC_MAX_HOST_WRITE);
- if (qemu_chr_be_can_write(scd->chr) < last_out) {
+ last_out = MIN(len, qemu_chr_be_can_write(scd->chr));
+ if (last_out <= 0) {
break;
}
qemu_chr_be_write(scd->chr, p, last_out);
@@ -69,6 +72,27 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
return bytes;
}
+#if SPICE_SERVER_VERSION >= 0x000c02
+static void vmc_event(SpiceCharDeviceInstance *sin, uint8_t event)
+{
+ SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
+ int chr_event;
+
+ switch (event) {
+ case SPICE_PORT_EVENT_BREAK:
+ chr_event = CHR_EVENT_BREAK;
+ break;
+ default:
+ dprintf(scd, 2, "%s: unknown %d\n", __func__, event);
+ return;
+ }
+
+ dprintf(scd, 2, "%s: %d\n", __func__, event);
+ trace_spice_vmc_event(chr_event);
+ qemu_chr_be_event(scd->chr, chr_event);
+}
+#endif
+
static void vmc_state(SpiceCharDeviceInstance *sin, int connected)
{
SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
@@ -105,6 +129,9 @@ static SpiceCharDeviceInterface vmc_interface = {
.state = vmc_state,
.write = vmc_write,
.read = vmc_read,
+#if SPICE_SERVER_VERSION >= 0x000c02
+ .event = vmc_event,
+#endif
};
@@ -156,6 +183,7 @@ static void spice_chr_close(struct CharDriverState *chr)
printf("%s\n", __func__);
vmc_unregister_interface(s);
+ QLIST_REMOVE(s, next);
g_free(s);
}
@@ -188,13 +216,34 @@ static void print_allowed_subtypes(void)
fprintf(stderr, "\n");
}
-CharDriverState *qemu_chr_open_spice(QemuOpts *opts)
+static CharDriverState *chr_open(QemuOpts *opts, const char *subtype)
{
CharDriverState *chr;
SpiceCharDriver *s;
- const char* name = qemu_opt_get(opts, "name");
uint32_t debug = qemu_opt_get_number(opts, "debug", 0);
- const char** psubtype = spice_server_char_device_recognized_subtypes();
+
+ chr = g_malloc0(sizeof(CharDriverState));
+ s = g_malloc0(sizeof(SpiceCharDriver));
+ s->chr = chr;
+ s->debug = debug;
+ s->active = false;
+ s->sin.subtype = subtype;
+ chr->opaque = s;
+ chr->chr_write = spice_chr_write;
+ chr->chr_close = spice_chr_close;
+ chr->chr_guest_open = spice_chr_guest_open;
+ chr->chr_guest_close = spice_chr_guest_close;
+
+ QLIST_INSERT_HEAD(&spice_chars, s, next);
+
+ return chr;
+}
+
+CharDriverState *qemu_chr_open_spice(QemuOpts *opts)
+{
+ CharDriverState *chr;
+ const char *name = qemu_opt_get(opts, "name");
+ const char **psubtype = spice_server_char_device_recognized_subtypes();
const char *subtype = NULL;
if (name == NULL) {
@@ -214,17 +263,7 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts)
return NULL;
}
- chr = g_malloc0(sizeof(CharDriverState));
- s = g_malloc0(sizeof(SpiceCharDriver));
- s->chr = chr;
- s->debug = debug;
- s->active = false;
- s->sin.subtype = subtype;
- chr->opaque = s;
- chr->chr_write = spice_chr_write;
- chr->chr_close = spice_chr_close;
- chr->chr_guest_open = spice_chr_guest_open;
- chr->chr_guest_close = spice_chr_guest_close;
+ chr = chr_open(opts, subtype);
#if SPICE_SERVER_VERSION < 0x000901
/* See comment in vmc_state() */
@@ -235,3 +274,35 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts)
return chr;
}
+
+#if SPICE_SERVER_VERSION >= 0x000c02
+CharDriverState *qemu_chr_open_spice_port(QemuOpts *opts)
+{
+ CharDriverState *chr;
+ SpiceCharDriver *s;
+ const char *name = qemu_opt_get(opts, "name");
+
+ if (name == NULL) {
+ fprintf(stderr, "spice-qemu-char: missing name parameter\n");
+ return NULL;
+ }
+
+ chr = chr_open(opts, "port");
+ s = chr->opaque;
+ s->sin.portname = name;
+
+ return chr;
+}
+
+void qemu_spice_register_ports(void)
+{
+ SpiceCharDriver *s;
+
+ QLIST_FOREACH(s, &spice_chars, next) {
+ if (s->sin.portname == NULL) {
+ continue;
+ }
+ vmc_register_interface(s);
+ }
+}
+#endif
diff --git a/trace-events b/trace-events
index 6cb450a993..bb7621eeb6 100644
--- a/trace-events
+++ b/trace-events
@@ -535,6 +535,7 @@ spice_vmc_write(ssize_t out, int len) "spice wrottn %zd of requested %d"
spice_vmc_read(int bytes, int len) "spice read %d of requested %d"
spice_vmc_register_interface(void *scd) "spice vmc registered interface %p"
spice_vmc_unregister_interface(void *scd) "spice vmc unregistered interface %p"
+spice_vmc_event(int event) "spice vmc event %d"
# hw/lm32_pic.c
lm32_pic_raise_irq(void) "Raise CPU interrupt"
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 3299da87d6..642f012690 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -46,6 +46,10 @@ void do_info_spice_print(Monitor *mon, const QObject *data);
void do_info_spice(Monitor *mon, QObject **ret_data);
CharDriverState *qemu_chr_open_spice(QemuOpts *opts);
+#if SPICE_SERVER_VERSION >= 0x000c02
+CharDriverState *qemu_chr_open_spice_port(QemuOpts *opts);
+void qemu_spice_register_ports(void);
+#endif
#else /* CONFIG_SPICE */
#include "monitor.h"
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 261c6f2c11..ac46deb2be 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -714,6 +714,10 @@ void qemu_spice_init(void)
g_free(x509_key_file);
g_free(x509_cert_file);
g_free(x509_cacert_file);
+
+#if SPICE_SERVER_VERSION >= 0x000c02
+ qemu_spice_register_ports();
+#endif
}
int qemu_spice_add_interface(SpiceBaseInstance *sin)
@@ -732,6 +736,8 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin)
*/
spice_server = spice_server_new();
spice_server_init(spice_server, &core_interface);
+ qemu_add_vm_change_state_handler(vm_change_state_handler,
+ &spice_server);
}
return spice_server_add_interface(spice_server, sin);