Blame 0004-spice-core-bits.patch

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