334 lines
8.5 KiB
Diff
334 lines
8.5 KiB
Diff
From 67361a4ad5c99c5dfecdb9d2fc1ba794c38c44ff Mon Sep 17 00:00:00 2001
|
|
From: Gerd Hoffmann <kraxel@redhat.com>
|
|
Date: Thu, 11 Mar 2010 11:13:27 -0300
|
|
Subject: [PATCH 04/39] spice: core bits
|
|
|
|
Add -spice command line switch. Has support setting passwd and port for
|
|
now. With this patch applied the spice client can successfully connect
|
|
to qemu. You can't do anything useful yet though.
|
|
---
|
|
Makefile.objs | 2 +
|
|
qemu-config.c | 23 ++++++++
|
|
qemu-config.h | 1 +
|
|
qemu-options.hx | 8 +++
|
|
qemu-spice.h | 22 ++++++++
|
|
spice.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
vl.c | 15 ++++++
|
|
7 files changed, 222 insertions(+), 0 deletions(-)
|
|
create mode 100644 qemu-spice.h
|
|
create mode 100644 spice.c
|
|
|
|
diff --git a/Makefile.objs b/Makefile.objs
|
|
index 147051f..569b458 100644
|
|
--- a/Makefile.objs
|
|
+++ b/Makefile.objs
|
|
@@ -89,6 +89,8 @@ common-obj-y += pflib.o
|
|
common-obj-$(CONFIG_BRLAPI) += baum.o
|
|
common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
|
|
|
|
+common-obj-$(CONFIG_SPICE) += spice.o
|
|
+
|
|
audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
|
|
audio-obj-$(CONFIG_SDL) += sdlaudio.o
|
|
audio-obj-$(CONFIG_OSS) += ossaudio.o
|
|
diff --git a/qemu-config.c b/qemu-config.c
|
|
index 08ee553..8a894cf 100644
|
|
--- a/qemu-config.c
|
|
+++ b/qemu-config.c
|
|
@@ -346,6 +346,26 @@ QemuOptsList qemu_cpudef_opts = {
|
|
},
|
|
};
|
|
|
|
+#ifdef CONFIG_SPICE
|
|
+QemuOptsList qemu_spice_opts = {
|
|
+ .name = "spice",
|
|
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_spice_opts.head),
|
|
+ .desc = {
|
|
+ {
|
|
+ .name = "port",
|
|
+ .type = QEMU_OPT_NUMBER,
|
|
+ },{
|
|
+ .name = "password",
|
|
+ .type = QEMU_OPT_STRING,
|
|
+ },{
|
|
+ .name = "disable-ticketing",
|
|
+ .type = QEMU_OPT_BOOL,
|
|
+ },
|
|
+ { /* end if list */ }
|
|
+ },
|
|
+};
|
|
+#endif
|
|
+
|
|
static QemuOptsList *vm_config_groups[] = {
|
|
&qemu_drive_opts,
|
|
&qemu_chardev_opts,
|
|
@@ -356,6 +376,9 @@ static QemuOptsList *vm_config_groups[] = {
|
|
&qemu_global_opts,
|
|
&qemu_mon_opts,
|
|
&qemu_cpudef_opts,
|
|
+#ifdef CONFIG_SPICE
|
|
+ &qemu_spice_opts,
|
|
+#endif
|
|
NULL,
|
|
};
|
|
|
|
diff --git a/qemu-config.h b/qemu-config.h
|
|
index dca69d4..3a90213 100644
|
|
--- a/qemu-config.h
|
|
+++ b/qemu-config.h
|
|
@@ -14,6 +14,7 @@ extern QemuOptsList qemu_rtc_opts;
|
|
extern QemuOptsList qemu_global_opts;
|
|
extern QemuOptsList qemu_mon_opts;
|
|
extern QemuOptsList qemu_cpudef_opts;
|
|
+extern QemuOptsList qemu_spice_opts;
|
|
|
|
QemuOptsList *qemu_find_opts(const char *group);
|
|
int qemu_set_option(const char *str);
|
|
diff --git a/qemu-options.hx b/qemu-options.hx
|
|
index 66c84a0..85551cc 100644
|
|
--- a/qemu-options.hx
|
|
+++ b/qemu-options.hx
|
|
@@ -676,6 +676,14 @@ STEXI
|
|
Enable SDL.
|
|
ETEXI
|
|
|
|
+#ifdef CONFIG_SPICE
|
|
+DEF("spice", HAS_ARG, QEMU_OPTION_spice,
|
|
+ "-spice <args> use spice\n", QEMU_ARCH_ALL)
|
|
+STEXI
|
|
+Use Spice.
|
|
+ETEXI
|
|
+#endif
|
|
+
|
|
DEF("portrait", 0, QEMU_OPTION_portrait,
|
|
"-portrait rotate graphical output 90 deg left (only PXA LCD)\n",
|
|
QEMU_ARCH_ALL)
|
|
diff --git a/qemu-spice.h b/qemu-spice.h
|
|
new file mode 100644
|
|
index 0000000..5597576
|
|
--- /dev/null
|
|
+++ b/qemu-spice.h
|
|
@@ -0,0 +1,22 @@
|
|
+#ifndef QEMU_SPICE_H
|
|
+#define QEMU_SPICE_H
|
|
+
|
|
+#ifdef CONFIG_SPICE
|
|
+
|
|
+#include <spice.h>
|
|
+
|
|
+#include "qemu-option.h"
|
|
+#include "qemu-config.h"
|
|
+
|
|
+extern SpiceServer *spice_server;
|
|
+extern int using_spice;
|
|
+
|
|
+void qemu_spice_init(void);
|
|
+
|
|
+#else /* CONFIG_SPICE */
|
|
+
|
|
+#define using_spice 0
|
|
+
|
|
+#endif /* CONFIG_SPICE */
|
|
+
|
|
+#endif /* QEMU_SPICE_H */
|
|
diff --git a/spice.c b/spice.c
|
|
new file mode 100644
|
|
index 0000000..50fa5ca
|
|
--- /dev/null
|
|
+++ b/spice.c
|
|
@@ -0,0 +1,151 @@
|
|
+#include <stdlib.h>
|
|
+#include <stdio.h>
|
|
+#include <string.h>
|
|
+
|
|
+#include <spice.h>
|
|
+#include <spice-experimental.h>
|
|
+
|
|
+#include "qemu-common.h"
|
|
+#include "qemu-spice.h"
|
|
+#include "qemu-timer.h"
|
|
+#include "qemu-queue.h"
|
|
+#include "monitor.h"
|
|
+
|
|
+/* core bits */
|
|
+
|
|
+SpiceServer *spice_server;
|
|
+int using_spice = 0;
|
|
+
|
|
+struct SpiceTimer {
|
|
+ QEMUTimer *timer;
|
|
+ QTAILQ_ENTRY(SpiceTimer) next;
|
|
+};
|
|
+static QTAILQ_HEAD(, SpiceTimer) timers = QTAILQ_HEAD_INITIALIZER(timers);
|
|
+
|
|
+static SpiceTimer *timer_add(SpiceTimerFunc func, void *opaque)
|
|
+{
|
|
+ SpiceTimer *timer;
|
|
+
|
|
+ timer = qemu_mallocz(sizeof(*timer));
|
|
+ timer->timer = qemu_new_timer(rt_clock, func, opaque);
|
|
+ QTAILQ_INSERT_TAIL(&timers, timer, next);
|
|
+ return timer;
|
|
+}
|
|
+
|
|
+static void timer_start(SpiceTimer *timer, uint32_t ms)
|
|
+{
|
|
+ qemu_mod_timer(timer->timer, qemu_get_clock(rt_clock) + ms);
|
|
+}
|
|
+
|
|
+static void timer_cancel(SpiceTimer *timer)
|
|
+{
|
|
+ qemu_del_timer(timer->timer);
|
|
+}
|
|
+
|
|
+static void timer_remove(SpiceTimer *timer)
|
|
+{
|
|
+ qemu_del_timer(timer->timer);
|
|
+ qemu_free_timer(timer->timer);
|
|
+ QTAILQ_REMOVE(&timers, timer, next);
|
|
+ free(timer);
|
|
+}
|
|
+
|
|
+struct SpiceWatch {
|
|
+ int fd;
|
|
+ int event_mask;
|
|
+ SpiceWatchFunc func;
|
|
+ void *opaque;
|
|
+ QTAILQ_ENTRY(SpiceWatch) next;
|
|
+};
|
|
+static QTAILQ_HEAD(, SpiceWatch) watches = QTAILQ_HEAD_INITIALIZER(watches);
|
|
+
|
|
+static void watch_read(void *opaque)
|
|
+{
|
|
+ SpiceWatch *watch = opaque;
|
|
+ watch->func(watch->fd, SPICE_WATCH_EVENT_READ, watch->opaque);
|
|
+}
|
|
+
|
|
+static void watch_write(void *opaque)
|
|
+{
|
|
+ SpiceWatch *watch = opaque;
|
|
+ watch->func(watch->fd, SPICE_WATCH_EVENT_WRITE, watch->opaque);
|
|
+}
|
|
+
|
|
+static void watch_update_mask(SpiceWatch *watch, int event_mask)
|
|
+{
|
|
+ IOHandler *on_read = NULL;
|
|
+ IOHandler *on_write = NULL;
|
|
+
|
|
+ watch->event_mask = event_mask;
|
|
+ if (watch->event_mask & SPICE_WATCH_EVENT_READ)
|
|
+ on_read = watch_read;
|
|
+ if (watch->event_mask & SPICE_WATCH_EVENT_WRITE)
|
|
+ on_read = watch_write;
|
|
+ qemu_set_fd_handler(watch->fd, on_read, on_write, watch);
|
|
+}
|
|
+
|
|
+static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *opaque)
|
|
+{
|
|
+ SpiceWatch *watch;
|
|
+
|
|
+ watch = qemu_mallocz(sizeof(*watch));
|
|
+ watch->fd = fd;
|
|
+ watch->func = func;
|
|
+ watch->opaque = opaque;
|
|
+ QTAILQ_INSERT_TAIL(&watches, watch, next);
|
|
+
|
|
+ watch_update_mask(watch, event_mask);
|
|
+ return watch;
|
|
+}
|
|
+
|
|
+static void watch_remove(SpiceWatch *watch)
|
|
+{
|
|
+ watch_update_mask(watch, 0);
|
|
+ QTAILQ_REMOVE(&watches, watch, next);
|
|
+ qemu_free(watch);
|
|
+}
|
|
+
|
|
+static SpiceCoreInterface core_interface = {
|
|
+ .base.type = SPICE_INTERFACE_CORE,
|
|
+ .base.description = "qemu core services",
|
|
+ .base.major_version = SPICE_INTERFACE_CORE_MAJOR,
|
|
+ .base.minor_version = SPICE_INTERFACE_CORE_MINOR,
|
|
+
|
|
+ .timer_add = timer_add,
|
|
+ .timer_start = timer_start,
|
|
+ .timer_cancel = timer_cancel,
|
|
+ .timer_remove = timer_remove,
|
|
+
|
|
+ .watch_add = watch_add,
|
|
+ .watch_update_mask = watch_update_mask,
|
|
+ .watch_remove = watch_remove,
|
|
+};
|
|
+
|
|
+/* functions for the rest of qemu */
|
|
+
|
|
+void qemu_spice_init(void)
|
|
+{
|
|
+ QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head);
|
|
+ const char *password;
|
|
+ int port;
|
|
+
|
|
+ if (!opts)
|
|
+ return;
|
|
+ port = qemu_opt_get_number(opts, "port", 0);
|
|
+ if (!port)
|
|
+ return;
|
|
+ password = qemu_opt_get(opts, "password");
|
|
+
|
|
+ spice_server = spice_server_new();
|
|
+ spice_server_set_port(spice_server, port);
|
|
+ if (password)
|
|
+ spice_server_set_ticket(spice_server, password, 0, 0, 0);
|
|
+ if (qemu_opt_get_bool(opts, "disable-ticketing", 0))
|
|
+ spice_server_set_noauth(spice_server);
|
|
+
|
|
+ /* TODO: make configurable via cmdline */
|
|
+ spice_server_set_image_compression(spice_server, SPICE_IMAGE_COMPRESS_AUTO_GLZ);
|
|
+
|
|
+ spice_server_init(spice_server, &core_interface);
|
|
+ using_spice = 1;
|
|
+}
|
|
diff --git a/vl.c b/vl.c
|
|
index de8bad1..97897e0 100644
|
|
--- a/vl.c
|
|
+++ b/vl.c
|
|
@@ -162,6 +162,8 @@ int main(int argc, char **argv)
|
|
#include "cpus.h"
|
|
#include "arch_init.h"
|
|
|
|
+#include "qemu-spice.h"
|
|
+
|
|
//#define DEBUG_NET
|
|
//#define DEBUG_SLIRP
|
|
|
|
@@ -2677,6 +2679,15 @@ int main(int argc, char **argv, char **envp)
|
|
}
|
|
break;
|
|
}
|
|
+#ifdef CONFIG_SPICE
|
|
+ case QEMU_OPTION_spice:
|
|
+ opts = qemu_opts_parse(&qemu_spice_opts, optarg, 0);
|
|
+ if (!opts) {
|
|
+ fprintf(stderr, "parse error: %s\n", optarg);
|
|
+ exit(1);
|
|
+ }
|
|
+ break;
|
|
+#endif
|
|
case QEMU_OPTION_writeconfig:
|
|
{
|
|
FILE *fp;
|
|
@@ -2951,6 +2962,10 @@ int main(int argc, char **argv, char **envp)
|
|
}
|
|
qemu_add_globals();
|
|
|
|
+#ifdef CONFIG_SPICE
|
|
+ qemu_spice_init();
|
|
+#endif
|
|
+
|
|
machine->init(ram_size, boot_devices,
|
|
kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
|
|
|
|
--
|
|
1.7.2.3
|
|
|