diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-12-18 15:41:21 -0600 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-12-18 15:41:21 -0600 |
commit | 510981a097bf16ef4747c9a1dfe806edfc117177 (patch) | |
tree | 3b6557eb1896fc1ac06685d319329cfcb5c7074e | |
parent | c3a1ecd0fc565c913efc59663e7ac34b9c3c2291 (diff) | |
parent | 700f6b6a921861a8946377a9531b6d1e8b09bb51 (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.txt | 19 | ||||
-rw-r--r-- | hw/qxl-render.c | 11 | ||||
-rw-r--r-- | qemu-char.c | 3 | ||||
-rw-r--r-- | qemu-options.hx | 13 | ||||
-rw-r--r-- | spice-qemu-char.c | 107 | ||||
-rw-r--r-- | trace-events | 1 | ||||
-rw-r--r-- | ui/qemu-spice.h | 4 | ||||
-rw-r--r-- | ui/spice-core.c | 6 |
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); |