spice-qemu-char: add spiceport chardev
Add a new spice chardev to allow arbitrary communication between the
host and the Spice client via the spice server.
Examples:
This allows the Spice client to have a special port for the qemu
monitor:
... -chardev spiceport,name=org.qemu.monitor,id=monitorport
    -mon chardev=monitorport
v2:
- remove support for chardev to chardev linking
- conditionnaly compile with SPICE_SERVER_VERSION
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
			
			
This commit is contained in:
		
				
					committed by
					
						 Gerd Hoffmann
						Gerd Hoffmann
					
				
			
			
				
	
			
			
			
						parent
						
							71b423f4b9
						
					
				
				
					commit
					5a49d3e9a7
				
			| @@ -2762,6 +2762,9 @@ static const struct { | |||||||
| #endif | #endif | ||||||
| #ifdef CONFIG_SPICE | #ifdef CONFIG_SPICE | ||||||
|     { .name = "spicevmc",     .open = qemu_chr_open_spice }, |     { .name = "spicevmc",     .open = qemu_chr_open_spice }, | ||||||
|  | #if SPICE_SERVER_VERSION >= 0x000c02 | ||||||
|  |     { .name = "spiceport",    .open = qemu_chr_open_spice_port }, | ||||||
|  | #endif | ||||||
| #endif | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1749,6 +1749,7 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev, | |||||||
| #endif | #endif | ||||||
| #if defined(CONFIG_SPICE) | #if defined(CONFIG_SPICE) | ||||||
|     "-chardev spicevmc,id=id,name=name[,debug=debug]\n" |     "-chardev spicevmc,id=id,name=name[,debug=debug]\n" | ||||||
|  |     "-chardev spiceport,id=id,name=name[,debug=debug]\n" | ||||||
| #endif | #endif | ||||||
|     , QEMU_ARCH_ALL |     , QEMU_ARCH_ALL | ||||||
| ) | ) | ||||||
| @@ -1776,6 +1777,7 @@ Backend is one of: | |||||||
| @option{tty}, | @option{tty}, | ||||||
| @option{parport}, | @option{parport}, | ||||||
| @option{spicevmc}. | @option{spicevmc}. | ||||||
|  | @option{spiceport}. | ||||||
| The specific backend will determine the applicable options. | The specific backend will determine the applicable options. | ||||||
|  |  | ||||||
| All devices must have an id, which can be any string up to 127 characters long. | 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. | 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 | @end table | ||||||
| ETEXI | ETEXI | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
| #include "ui/qemu-spice.h" | #include "ui/qemu-spice.h" | ||||||
| #include <spice.h> | #include <spice.h> | ||||||
| #include <spice-experimental.h> | #include <spice-experimental.h> | ||||||
|  | #include <spice/protocol.h> | ||||||
|  |  | ||||||
| #include "osdep.h" | #include "osdep.h" | ||||||
|  |  | ||||||
| @@ -67,6 +68,27 @@ static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len) | |||||||
|     return bytes; |     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) | static void vmc_state(SpiceCharDeviceInstance *sin, int connected) | ||||||
| { | { | ||||||
|     SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); |     SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin); | ||||||
| @@ -103,6 +125,9 @@ static SpiceCharDeviceInterface vmc_interface = { | |||||||
|     .state              = vmc_state, |     .state              = vmc_state, | ||||||
|     .write              = vmc_write, |     .write              = vmc_write, | ||||||
|     .read               = vmc_read, |     .read               = vmc_read, | ||||||
|  | #if SPICE_SERVER_VERSION >= 0x000c02 | ||||||
|  |     .event              = vmc_event, | ||||||
|  | #endif | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -242,3 +267,23 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts) | |||||||
|  |  | ||||||
|     return chr; |     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; | ||||||
|  | } | ||||||
|  | #endif | ||||||
|   | |||||||
| @@ -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_read(int bytes, int len) "spice read %d of requested %d" | ||||||
| spice_vmc_register_interface(void *scd) "spice vmc registered interface %p" | spice_vmc_register_interface(void *scd) "spice vmc registered interface %p" | ||||||
| spice_vmc_unregister_interface(void *scd) "spice vmc unregistered 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 | # hw/lm32_pic.c | ||||||
| lm32_pic_raise_irq(void) "Raise CPU interrupt" | lm32_pic_raise_irq(void) "Raise CPU interrupt" | ||||||
|   | |||||||
| @@ -46,6 +46,9 @@ void do_info_spice_print(Monitor *mon, const QObject *data); | |||||||
| void do_info_spice(Monitor *mon, QObject **ret_data); | void do_info_spice(Monitor *mon, QObject **ret_data); | ||||||
|  |  | ||||||
| CharDriverState *qemu_chr_open_spice(QemuOpts *opts); | CharDriverState *qemu_chr_open_spice(QemuOpts *opts); | ||||||
|  | #if SPICE_SERVER_VERSION >= 0x000c02 | ||||||
|  | CharDriverState *qemu_chr_open_spice_port(QemuOpts *opts); | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #else  /* CONFIG_SPICE */ | #else  /* CONFIG_SPICE */ | ||||||
| #include "monitor.h" | #include "monitor.h" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user