All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/6] spice patch queue
@ 2011-01-10 13:31 Gerd Hoffmann
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 1/6] add migration state change notifiers Gerd Hoffmann
                   ` (5 more replies)
  0 siblings, 6 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-10 13:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

  Hi,

Here is a bunch of spice patches accumuled this year, they all
have been on the list for review.

please pull,
  Gerd

The following changes since commit 8aaf42ed0f203da63860b0a3ab3ff2bdfe9b4cb0:

  slirp: fix unaligned access in bootp code (2011-01-10 10:56:25 +0100)

are available in the git repository at:
  git://anongit.freedesktop.org/spice/qemu spice.v27.pull

Alon Levy (1):
      spice: add chardev (v4)

Gerd Hoffmann (4):
      add migration state change notifiers
      spice: client migration.
      spice: MAINTAINERS update
      spice/qxl: zap spice 0.4 migration compatibility bits

Marc-André Lureau (1):
      vnc/spice: fix "never" and "now" expire_time

 MAINTAINERS       |    8 ++
 Makefile.objs     |    2 +-
 hmp-commands.hx   |   20 ++++++
 hw/qxl.c          |   79 +++--------------------
 hw/qxl.h          |    4 -
 migration.c       |   28 ++++++++
 migration.h       |    5 ++
 monitor.c         |    4 +-
 qemu-char.c       |    4 +
 qemu-config.c     |    6 ++
 qemu-options.hx   |   16 ++++-
 qmp-commands.hx   |   35 ++++++++++
 spice-qemu-char.c |  185 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 ui/qemu-spice.h   |    4 +
 ui/spice-core.c   |   40 ++++++++++++
 15 files changed, 363 insertions(+), 77 deletions(-)
 create mode 100644 spice-qemu-char.c

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 1/6] add migration state change notifiers
  2011-01-10 13:31 [Qemu-devel] [PULL 0/6] spice patch queue Gerd Hoffmann
@ 2011-01-10 13:31 ` Gerd Hoffmann
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 2/6] spice: client migration Gerd Hoffmann
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-10 13:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

This patch adds functions to register and unregister notifiers for
migration state changes and a function to query the migration state.
The notifier is called on every state change.  Once after establishing a
new migration object (which is in active state then) and once when the
state changes from active to completed, canceled or error.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 migration.c |   28 ++++++++++++++++++++++++++++
 migration.h |    5 +++++
 2 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/migration.c b/migration.c
index e5ba51c..3f88666 100644
--- a/migration.c
+++ b/migration.c
@@ -36,6 +36,9 @@ static int64_t max_throttle = (32 << 20);
 
 static MigrationState *current_migration;
 
+static NotifierList migration_state_notifiers =
+    NOTIFIER_LIST_INITIALIZER(migration_state_notifiers);
+
 int qemu_start_incoming_migration(const char *uri)
 {
     const char *p;
@@ -117,6 +120,7 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
     }
 
     current_migration = s;
+    notifier_list_notify(&migration_state_notifiers);
     return 0;
 }
 
@@ -268,6 +272,7 @@ void migrate_fd_error(FdMigrationState *s)
 {
     DPRINTF("setting error state\n");
     s->state = MIG_STATE_ERROR;
+    notifier_list_notify(&migration_state_notifiers);
     migrate_fd_cleanup(s);
 }
 
@@ -325,6 +330,7 @@ ssize_t migrate_fd_put_buffer(void *opaque, const void *data, size_t size)
             monitor_resume(s->mon);
         }
         s->state = MIG_STATE_ERROR;
+        notifier_list_notify(&migration_state_notifiers);
     }
 
     return ret;
@@ -385,6 +391,7 @@ void migrate_fd_put_ready(void *opaque)
             state = MIG_STATE_ERROR;
         }
         s->state = state;
+        notifier_list_notify(&migration_state_notifiers);
     }
 }
 
@@ -404,6 +411,7 @@ void migrate_fd_cancel(MigrationState *mig_state)
     DPRINTF("cancelling migration\n");
 
     s->state = MIG_STATE_CANCELLED;
+    notifier_list_notify(&migration_state_notifiers);
     qemu_savevm_state_cancel(s->mon, s->file);
 
     migrate_fd_cleanup(s);
@@ -417,6 +425,7 @@ void migrate_fd_release(MigrationState *mig_state)
    
     if (s->state == MIG_STATE_ACTIVE) {
         s->state = MIG_STATE_CANCELLED;
+        notifier_list_notify(&migration_state_notifiers);
         migrate_fd_cleanup(s);
     }
     qemu_free(s);
@@ -448,3 +457,22 @@ int migrate_fd_close(void *opaque)
     qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
     return s->close(s);
 }
+
+void add_migration_state_change_notifier(Notifier *notify)
+{
+    notifier_list_add(&migration_state_notifiers, notify);
+}
+
+void remove_migration_state_change_notifier(Notifier *notify)
+{
+    notifier_list_remove(&migration_state_notifiers, notify);
+}
+
+int get_migration_state(void)
+{
+    if (current_migration) {
+        return migrate_fd_get_status(current_migration);
+    } else {
+        return MIG_STATE_ERROR;
+    }
+}
diff --git a/migration.h b/migration.h
index d13ed4f..2170792 100644
--- a/migration.h
+++ b/migration.h
@@ -16,6 +16,7 @@
 
 #include "qdict.h"
 #include "qemu-common.h"
+#include "notify.h"
 
 #define MIG_STATE_ERROR		-1
 #define MIG_STATE_COMPLETED	0
@@ -134,4 +135,8 @@ static inline FdMigrationState *migrate_to_fms(MigrationState *mig_state)
     return container_of(mig_state, FdMigrationState, mig_state);
 }
 
+void add_migration_state_change_notifier(Notifier *notify);
+void remove_migration_state_change_notifier(Notifier *notify);
+int get_migration_state(void);
+
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 2/6] spice: client migration.
  2011-01-10 13:31 [Qemu-devel] [PULL 0/6] spice patch queue Gerd Hoffmann
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 1/6] add migration state change notifiers Gerd Hoffmann
@ 2011-01-10 13:31 ` Gerd Hoffmann
  2011-01-10 15:49   ` Daniel P. Berrange
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 3/6] spice: MAINTAINERS update Gerd Hoffmann
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-10 13:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Handle spice client migration, i.e. inform a spice client connected
about the new host and connection parameters, so it can move over the
connection automatically.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hmp-commands.hx |   20 ++++++++++++++++++++
 qmp-commands.hx |   35 +++++++++++++++++++++++++++++++++++
 ui/qemu-spice.h |    1 +
 ui/spice-core.c |   40 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 96 insertions(+), 0 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index df134f8..e6d8f36 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -815,6 +815,26 @@ ETEXI
     },
 
 STEXI
+@item spice_migrate_info @var{hostname} @var{port} @var{tls-port} @var{cert-subject}
+@findex spice_migrate_info
+Set the spice connection info for the migration target.  The spice
+server will ask the spice client to automatically reconnect using the
+new parameters (if specified) once the vm migration finished
+successfully.
+ETEXI
+
+#if defined(CONFIG_SPICE)
+    {
+        .name       = "spice_migrate_info",
+        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
+        .params     = "hostname port tls-port cert-subject",
+        .help       = "send migration info to spice client",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = mon_spice_migrate,
+    },
+#endif
+
+STEXI
 @item snapshot_blkdev
 @findex snapshot_blkdev
 Snapshot device, using snapshot file as target if provided
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 56c4d8b..24ada04 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -503,6 +503,41 @@ EQMP
     },
 
 SQMP
+spice_migrate_info
+------------------
+
+Set the spice connection info for the migration target.  The spice
+server will ask the spice client to automatically reconnect using the
+new parameters (if specified) once the vm migration finished
+successfully.
+
+Arguments:
+
+- "hostname":     migration target hostname (json-string)
+- "port":         spice tcp port for plaintext channels (json-int, optional)
+- "tls-port":     spice tcp port for tls-secured channels (json-int, optional)
+- "cert-subject": server certificate subject (json-string, optional)
+
+Example:
+
+-> { "execute": "spice_migrate_info",
+     "arguments": { "hostname": "virt42.lab.kraxel.org", "port": 1234 } }
+<- { "return": {} }
+
+EQMP
+
+#if defined(CONFIG_SPICE)
+    {
+        .name       = "spice_migrate_info",
+        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
+        .params     = "hostname port tls-port cert-subject",
+        .help       = "send migration info to spice client",
+        .user_print = monitor_user_noop,
+        .mhandler.cmd_new = mon_spice_migrate,
+    },
+#endif
+
+SQMP
 migrate_set_speed
 -----------------
 
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 48239c3..13de5ad 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -38,6 +38,7 @@ int qemu_spice_set_pw_expire(time_t expires);
 
 void do_info_spice_print(Monitor *mon, const QObject *data);
 void do_info_spice(Monitor *mon, QObject **ret_data);
+int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
 
 #else  /* CONFIG_SPICE */
 
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 27a1ced..95116cc 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -30,11 +30,15 @@
 #include "qbool.h"
 #include "qstring.h"
 #include "qjson.h"
+#include "notify.h"
+#include "migration.h"
 #include "monitor.h"
+#include "hw/hw.h"
 
 /* core bits */
 
 static SpiceServer *spice_server;
+static Notifier migration_state;
 static const char *auth = "spice";
 static char *auth_passwd;
 static time_t auth_expires = TIME_MAX;
@@ -416,6 +420,39 @@ void do_info_spice(Monitor *mon, QObject **ret_data)
     *ret_data = QOBJECT(server);
 }
 
+static void migration_state_notifier(Notifier *notifier)
+{
+    int state = get_migration_state();
+
+    if (state == MIG_STATE_COMPLETED) {
+#if SPICE_SERVER_VERSION >= 0x000701 /* 0.7.1 */
+        spice_server_migrate_switch(spice_server);
+#endif
+    }
+}
+
+int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    const char *hostname = qdict_get_str(qdict, "hostname");
+    const char *subject  = qdict_get_try_str(qdict, "cert-subject");
+    int port             = qdict_get_try_int(qdict, "port", -1);
+    int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
+    int ret;
+
+    if (!spice_server) {
+        qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
+        return -1;
+    }
+
+    ret = spice_server_migrate_info(spice_server, hostname,
+                                    port, tls_port, subject);
+    if (ret != 0) {
+        qerror_report(QERR_UNDEFINED_ERROR);
+        return -1;
+    }
+    return 0;
+}
+
 static int add_channel(const char *name, const char *value, void *opaque)
 {
     int security = 0;
@@ -573,6 +610,9 @@ void qemu_spice_init(void)
     spice_server_init(spice_server, &core_interface);
     using_spice = 1;
 
+    migration_state.notify = migration_state_notifier;
+    add_migration_state_change_notifier(&migration_state);
+
     qemu_spice_input_init();
     qemu_spice_audio_init();
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 3/6] spice: MAINTAINERS update
  2011-01-10 13:31 [Qemu-devel] [PULL 0/6] spice patch queue Gerd Hoffmann
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 1/6] add migration state change notifiers Gerd Hoffmann
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 2/6] spice: client migration Gerd Hoffmann
@ 2011-01-10 13:31 ` Gerd Hoffmann
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 4/6] vnc/spice: fix "never" and "now" expire_time Gerd Hoffmann
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-10 13:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 MAINTAINERS |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 59effc7..25103dd 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -383,6 +383,14 @@ S: Odd Fixes
 F: gdbstub*
 F: gdb-xml/
 
+SPICE
+M: Gerd Hoffmann <kraxel@redhat.com>
+S: Supported
+F: ui/qemu-spice.h
+F: ui/spice-*.c
+F: audio/spiceaudio.c
+F: hw/qxl*
+
 Graphics
 M: Anthony Liguori <aliguori@us.ibm.com>
 S: Maintained
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 4/6] vnc/spice: fix "never" and "now" expire_time
  2011-01-10 13:31 [Qemu-devel] [PULL 0/6] spice patch queue Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 3/6] spice: MAINTAINERS update Gerd Hoffmann
@ 2011-01-10 13:31 ` Gerd Hoffmann
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 5/6] spice/qxl: zap spice 0.4 migration compatibility bits Gerd Hoffmann
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 6/6] spice: add chardev (v4) Gerd Hoffmann
  5 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-10 13:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Gerd Hoffmann

From: Marc-André Lureau <marcandre.lureau@redhat.com>


Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 monitor.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/monitor.c b/monitor.c
index f258000..038d532 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1136,9 +1136,9 @@ static int expire_password(Monitor *mon, const QDict *qdict, QObject **ret_data)
     time_t when;
     int rc;
 
-    if (strcmp(whenstr, "now")) {
+    if (strcmp(whenstr, "now") == 0) {
         when = 0;
-    } else if (strcmp(whenstr, "never")) {
+    } else if (strcmp(whenstr, "never") == 0) {
         when = TIME_MAX;
     } else if (whenstr[0] == '+') {
         when = time(NULL) + strtoull(whenstr+1, NULL, 10);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 5/6] spice/qxl: zap spice 0.4 migration compatibility bits
  2011-01-10 13:31 [Qemu-devel] [PULL 0/6] spice patch queue Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 4/6] vnc/spice: fix "never" and "now" expire_time Gerd Hoffmann
@ 2011-01-10 13:31 ` Gerd Hoffmann
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 6/6] spice: add chardev (v4) Gerd Hoffmann
  5 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-10 13:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Live migration from and to spice 0.4 qxl devices isn't going to work.
Rip out the bits which attempt to support that.  Zap the subsection
logic which is obsolete now.  Bumb the version to make a clean cut.
This should obviously go in before 0.14 is released.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 hw/qxl.c |   79 ++++++++------------------------------------------------------
 hw/qxl.h |    4 ---
 2 files changed, 10 insertions(+), 73 deletions(-)

diff --git a/hw/qxl.c b/hw/qxl.c
index 207aa63..81be592 100644
--- a/hw/qxl.c
+++ b/hw/qxl.c
@@ -1418,43 +1418,10 @@ static int qxl_post_load(void *opaque, int version)
     }
     dprint(d, 1, "%s: done\n", __FUNCTION__);
 
-    /* spice 0.4 compatibility -- accept but ignore */
-    qemu_free(d->worker_data);
-    d->worker_data = NULL;
-    d->worker_data_size = 0;
-
     return 0;
 }
 
-#define QXL_SAVE_VERSION 20
-
-static bool qxl_test_worker_data(void *opaque, int version_id)
-{
-    PCIQXLDevice* d = opaque;
-
-    if (d->revision != 1) {
-        return false;
-    }
-    if (!d->worker_data_size) {
-        return false;
-    }
-    if (!d->worker_data) {
-        d->worker_data = qemu_malloc(d->worker_data_size);
-    }
-    return true;
-}
-
-static bool qxl_test_spice04(void *opaque, int version_id)
-{
-    PCIQXLDevice* d = opaque;
-    return d->revision == 1;
-}
-
-static bool qxl_test_spice06(void *opaque)
-{
-    PCIQXLDevice* d = opaque;
-    return d->revision > 1;
-}
+#define QXL_SAVE_VERSION 21
 
 static VMStateDescription qxl_memslot = {
     .name               = "qxl-memslot",
@@ -1486,24 +1453,6 @@ static VMStateDescription qxl_surface = {
     }
 };
 
-static VMStateDescription qxl_vmstate_spice06 = {
-    .name               = "qxl/spice06",
-    .version_id         = QXL_SAVE_VERSION,
-    .minimum_version_id = QXL_SAVE_VERSION,
-    .fields = (VMStateField []) {
-        VMSTATE_INT32_EQUAL(num_memslots, PCIQXLDevice),
-        VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, 0,
-                             qxl_memslot, struct guest_slots),
-        VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0,
-                       qxl_surface, QXLSurfaceCreate),
-        VMSTATE_INT32_EQUAL(num_surfaces, PCIQXLDevice),
-        VMSTATE_ARRAY(guest_surfaces.cmds, PCIQXLDevice, NUM_SURFACES, 0,
-                      vmstate_info_uint64, uint64_t),
-        VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
-        VMSTATE_END_OF_LIST()
-    },
-};
-
 static VMStateDescription qxl_vmstate = {
     .name               = "qxl",
     .version_id         = QXL_SAVE_VERSION,
@@ -1519,25 +1468,17 @@ static VMStateDescription qxl_vmstate = {
         VMSTATE_UINT32(last_release_offset, PCIQXLDevice),
         VMSTATE_UINT32(mode, PCIQXLDevice),
         VMSTATE_UINT32(ssd.unique, PCIQXLDevice),
-
-        /* spice 0.4 sends/expects them */
-        VMSTATE_VBUFFER_UINT32(vga.vram_ptr, PCIQXLDevice, 0, qxl_test_spice04, 0,
-                               vga.vram_size),
-        VMSTATE_UINT32_TEST(worker_data_size, PCIQXLDevice, qxl_test_spice04),
-        VMSTATE_VBUFFER_UINT32(worker_data, PCIQXLDevice, 0, qxl_test_worker_data, 0,
-                               worker_data_size),
-
+        VMSTATE_INT32_EQUAL(num_memslots, PCIQXLDevice),
+        VMSTATE_STRUCT_ARRAY(guest_slots, PCIQXLDevice, NUM_MEMSLOTS, 0,
+                             qxl_memslot, struct guest_slots),
+        VMSTATE_STRUCT(guest_primary.surface, PCIQXLDevice, 0,
+                       qxl_surface, QXLSurfaceCreate),
+        VMSTATE_INT32_EQUAL(num_surfaces, PCIQXLDevice),
+        VMSTATE_ARRAY(guest_surfaces.cmds, PCIQXLDevice, NUM_SURFACES, 0,
+                      vmstate_info_uint64, uint64_t),
+        VMSTATE_UINT64(guest_cursor, PCIQXLDevice),
         VMSTATE_END_OF_LIST()
     },
-    .subsections = (VMStateSubsection[]) {
-        {
-            /* additional spice 0.6 state */
-            .vmsd   = &qxl_vmstate_spice06,
-            .needed = qxl_test_spice06,
-        },{
-            /* end of list */
-        },
-    },
 };
 
 static PCIDeviceInfo qxl_info_primary = {
diff --git a/hw/qxl.h b/hw/qxl.h
index 98e11ce..f6c450d 100644
--- a/hw/qxl.h
+++ b/hw/qxl.h
@@ -80,10 +80,6 @@ typedef struct PCIQXLDevice {
 
     /* io bar */
     uint32_t           io_base;
-
-    /* spice 0.4 loadvm compatibility */
-    void               *worker_data;
-    uint32_t           worker_data_size;
 } PCIQXLDevice;
 
 #define PANIC_ON(x) if ((x)) {                         \
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 6/6] spice: add chardev (v4)
  2011-01-10 13:31 [Qemu-devel] [PULL 0/6] spice patch queue Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 5/6] spice/qxl: zap spice 0.4 migration compatibility bits Gerd Hoffmann
@ 2011-01-10 13:31 ` Gerd Hoffmann
  5 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-10 13:31 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alon Levy, Gerd Hoffmann

From: Alon Levy <alevy@redhat.com>

Adding a chardev backend for spice, where spice determines what
to do with it based on the name attribute given during chardev creation.
For usage by spice vdagent in conjunction with a properly named
virtio-serial device, and future smartcard channel usage.

Example usage:
 qemu -device virtio-serial -chardev spicevmc,name=vdagent,id=vdagent \
 -device virtserialport,chardev=vdagent,name=com.redhat.spice.0

v3->v4:
 * updated commit message

v1->v3 changes: (v2 had a wrong commit message)
 * removed spice-qemu-char.h, folded into ui/qemu-spice.h
 * removed dead IOCTL code
 * removed comment
 * removed ifdef CONFIG_SPICE from qemu-config.c and qemu-options.hx help.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.objs     |    2 +-
 qemu-char.c       |    4 +
 qemu-config.c     |    6 ++
 qemu-options.hx   |   16 ++++-
 spice-qemu-char.c |  185 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 ui/qemu-spice.h   |    3 +
 6 files changed, 214 insertions(+), 2 deletions(-)
 create mode 100644 spice-qemu-char.c

diff --git a/Makefile.objs b/Makefile.objs
index d6b3d60..d01a644 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -105,7 +105,7 @@ common-obj-$(CONFIG_BRLAPI) += baum.o
 common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
 common-obj-$(CONFIG_WIN32) += version.o
 
-common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o
+common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o spice-qemu-char.o
 
 audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 audio-obj-$(CONFIG_SDL) += sdlaudio.o
diff --git a/qemu-char.c b/qemu-char.c
index edc9ad6..acc7130 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -97,6 +97,7 @@
 #endif
 
 #include "qemu_socket.h"
+#include "ui/qemu-spice.h"
 
 #define READ_BUF_LEN 4096
 
@@ -2495,6 +2496,9 @@ static const struct {
     || defined(__FreeBSD_kernel__)
     { .name = "parport",   .open = qemu_chr_open_pp },
 #endif
+#ifdef CONFIG_SPICE
+    { .name = "spicevmc",     .open = qemu_chr_open_spice },
+#endif
 };
 
 CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
diff --git a/qemu-config.c b/qemu-config.c
index 965fa46..323d3c2 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -146,6 +146,12 @@ static QemuOptsList qemu_chardev_opts = {
         },{
             .name = "signal",
             .type = QEMU_OPT_BOOL,
+        },{
+            .name = "name",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "debug",
+            .type = QEMU_OPT_NUMBER,
         },
         { /* end of list */ }
     },
diff --git a/qemu-options.hx b/qemu-options.hx
index 898561d..e0b76bd 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1368,6 +1368,9 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
     "-chardev parport,id=id,path=path[,mux=on|off]\n"
 #endif
+#if defined(CONFIG_SPICE)
+    "-chardev spicevmc,id=id,debug=debug,name=name\n"
+#endif
     , QEMU_ARCH_ALL
 )
 
@@ -1392,7 +1395,8 @@ Backend is one of:
 @option{stdio},
 @option{braille},
 @option{tty},
-@option{parport}.
+@option{parport}
+@option{spicevmc}.
 The specific backend will determine the applicable options.
 
 All devices must have an id, which can be any string up to 127 characters long.
@@ -1568,6 +1572,16 @@ Connect to a local parallel port.
 @option{path} specifies the path to the parallel port device. @option{path} is
 required.
 
+#if defined(CONFIG_SPICE)
+@item -chardev spicevmc ,id=@var{id} ,debug=@var{debug}, name=@var{name}
+
+@option{debug} debug level for spicevmc
+
+@option{name} name of spice channel to connect to
+
+Connect to a spice virtual machine channel, such as vdiport.
+#endif
+
 @end table
 ETEXI
 
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
new file mode 100644
index 0000000..0ffa674
--- /dev/null
+++ b/spice-qemu-char.c
@@ -0,0 +1,185 @@
+#include "config-host.h"
+#include "ui/qemu-spice.h"
+#include <spice.h>
+#include <spice-experimental.h>
+
+#include "osdep.h"
+
+#define dprintf(_scd, _level, _fmt, ...)                                \
+    do {                                                                \
+        static unsigned __dprintf_counter = 0;                          \
+        if (_scd->debug >= _level) {                                    \
+            fprintf(stderr, "scd: %3d: " _fmt, ++__dprintf_counter, ## __VA_ARGS__);\
+        }                                                               \
+    } while (0)
+
+#define VMC_MAX_HOST_WRITE    2048
+
+typedef struct SpiceCharDriver {
+    CharDriverState*      chr;
+    SpiceCharDeviceInstance     sin;
+    char                  *subtype;
+    bool                  active;
+    uint8_t               *buffer;
+    uint8_t               *datapos;
+    ssize_t               bufsize, datalen;
+    uint32_t              debug;
+} SpiceCharDriver;
+
+static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
+{
+    SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
+    ssize_t out = 0;
+    ssize_t last_out;
+    uint8_t* p = (uint8_t*)buf;
+
+    while (len > 0) {
+        last_out = MIN(len, VMC_MAX_HOST_WRITE);
+        qemu_chr_read(scd->chr, p, last_out);
+        if (last_out > 0) {
+            out += last_out;
+            len -= last_out;
+            p += last_out;
+        } else {
+            break;
+        }
+    }
+
+    dprintf(scd, 3, "%s: %lu/%zd\n", __func__, out, len + out);
+    return out;
+}
+
+static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
+{
+    SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
+    int bytes = MIN(len, scd->datalen);
+
+    dprintf(scd, 2, "%s: %p %d/%d/%zd\n", __func__, scd->datapos, len, bytes, scd->datalen);
+    if (bytes > 0) {
+        memcpy(buf, scd->datapos, bytes);
+        scd->datapos += bytes;
+        scd->datalen -= bytes;
+        assert(scd->datalen >= 0);
+        if (scd->datalen == 0) {
+            scd->datapos = 0;
+        }
+    }
+    return bytes;
+}
+
+static SpiceCharDeviceInterface vmc_interface = {
+    .base.type          = SPICE_INTERFACE_CHAR_DEVICE,
+    .base.description   = "spice virtual channel char device",
+    .base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
+    .base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
+    .write              = vmc_write,
+    .read               = vmc_read,
+};
+
+
+static void vmc_register_interface(SpiceCharDriver *scd)
+{
+    if (scd->active) {
+        return;
+    }
+    dprintf(scd, 1, "%s\n", __func__);
+    scd->sin.base.sif = &vmc_interface.base;
+    qemu_spice_add_interface(&scd->sin.base);
+    scd->active = true;
+}
+
+static void vmc_unregister_interface(SpiceCharDriver *scd)
+{
+    if (!scd->active) {
+        return;
+    }
+    dprintf(scd, 1, "%s\n", __func__);
+    spice_server_remove_interface(&scd->sin.base);
+    scd->active = false;
+}
+
+
+static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    SpiceCharDriver *s = chr->opaque;
+
+    dprintf(s, 2, "%s: %d\n", __func__, len);
+    vmc_register_interface(s);
+    assert(s->datalen == 0);
+    if (s->bufsize < len) {
+        s->bufsize = len;
+        s->buffer = qemu_realloc(s->buffer, s->bufsize);
+    }
+    memcpy(s->buffer, buf, len);
+    s->datapos = s->buffer;
+    s->datalen = len;
+    spice_server_char_device_wakeup(&s->sin);
+    return len;
+}
+
+static void spice_chr_close(struct CharDriverState *chr)
+{
+    SpiceCharDriver *s = chr->opaque;
+
+    printf("%s\n", __func__);
+    vmc_unregister_interface(s);
+    qemu_free(s);
+}
+
+static void print_allowed_subtypes(void)
+{
+    const char** psubtype;
+    int i;
+
+    fprintf(stderr, "allowed names: ");
+    for(i=0, psubtype = spice_server_char_device_recognized_subtypes();
+        *psubtype != NULL; ++psubtype, ++i) {
+        if (i == 0) {
+            fprintf(stderr, "%s", *psubtype);
+        } else {
+            fprintf(stderr, ", %s", *psubtype);
+        }
+    }
+    fprintf(stderr, "\n");
+}
+
+CharDriverState *qemu_chr_open_spice(QemuOpts *opts)
+{
+    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();
+    const char *subtype = NULL;
+
+    if (name == NULL) {
+        fprintf(stderr, "spice-qemu-char: missing name parameter\n");
+        print_allowed_subtypes();
+        return NULL;
+    }
+    for(;*psubtype != NULL; ++psubtype) {
+        if (strcmp(name, *psubtype) == 0) {
+            subtype = *psubtype;
+            break;
+        }
+    }
+    if (subtype == NULL) {
+        fprintf(stderr, "spice-qemu-char: unsupported name\n");
+        print_allowed_subtypes();
+        return NULL;
+    }
+
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    s = qemu_mallocz(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;
+
+    qemu_chr_generic_open(chr);
+
+    return chr;
+}
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 13de5ad..f234c4d 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -24,6 +24,7 @@
 
 #include "qemu-option.h"
 #include "qemu-config.h"
+#include "qemu-char.h"
 
 extern int using_spice;
 
@@ -40,6 +41,8 @@ void do_info_spice_print(Monitor *mon, const QObject *data);
 void do_info_spice(Monitor *mon, QObject **ret_data);
 int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
 
+CharDriverState *qemu_chr_open_spice(QemuOpts *opts);
+
 #else  /* CONFIG_SPICE */
 
 #define using_spice 0
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/6] spice: client migration.
  2011-01-10 13:31 ` [Qemu-devel] [PATCH 2/6] spice: client migration Gerd Hoffmann
@ 2011-01-10 15:49   ` Daniel P. Berrange
  2011-01-10 15:57     ` Alon Levy
  0 siblings, 1 reply; 17+ messages in thread
From: Daniel P. Berrange @ 2011-01-10 15:49 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Mon, Jan 10, 2011 at 02:31:47PM +0100, Gerd Hoffmann wrote:
> Handle spice client migration, i.e. inform a spice client connected
> about the new host and connection parameters, so it can move over the
> connection automatically.
> 
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  hmp-commands.hx |   20 ++++++++++++++++++++
>  qmp-commands.hx |   35 +++++++++++++++++++++++++++++++++++
>  ui/qemu-spice.h |    1 +
>  ui/spice-core.c |   40 ++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 96 insertions(+), 0 deletions(-)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index df134f8..e6d8f36 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -815,6 +815,26 @@ ETEXI
>      },
>  
>  STEXI
> +@item spice_migrate_info @var{hostname} @var{port} @var{tls-port} @var{cert-subject}
> +@findex spice_migrate_info
> +Set the spice connection info for the migration target.  The spice
> +server will ask the spice client to automatically reconnect using the
> +new parameters (if specified) once the vm migration finished
> +successfully.
> +ETEXI


> +
> +#if defined(CONFIG_SPICE)
> +    {
> +        .name       = "spice_migrate_info",
> +        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
> +        .params     = "hostname port tls-port cert-subject",
> +        .help       = "send migration info to spice client",
> +        .user_print = monitor_user_noop,
> +        .mhandler.cmd_new = mon_spice_migrate,
> +    },
> +#endif
> +
> +STEXI
>  @item snapshot_blkdev
>  @findex snapshot_blkdev
>  Snapshot device, using snapshot file as target if provided
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 56c4d8b..24ada04 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -503,6 +503,41 @@ EQMP
>      },
>  
>  SQMP
> +spice_migrate_info
> +------------------
> +
> +Set the spice connection info for the migration target.  The spice
> +server will ask the spice client to automatically reconnect using the
> +new parameters (if specified) once the vm migration finished
> +successfully.
> +
> +Arguments:
> +
> +- "hostname":     migration target hostname (json-string)
> +- "port":         spice tcp port for plaintext channels (json-int, optional)
> +- "tls-port":     spice tcp port for tls-secured channels (json-int, optional)
> +- "cert-subject": server certificate subject (json-string, optional)
> +
> +Example:
> +
> +-> { "execute": "spice_migrate_info",
> +     "arguments": { "hostname": "virt42.lab.kraxel.org", "port": 1234 } }
> +<- { "return": {} }

I'm wondering whether we should make this command more
generic, because I could likely write up a VNC extension
that provides the same functionality that SPICE has here.
so, 'graphics_migrate_info @var{spice|vnc|...} ...other vars..'

Regards,
Daniel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/6] spice: client migration.
  2011-01-10 15:49   ` Daniel P. Berrange
@ 2011-01-10 15:57     ` Alon Levy
  2011-01-10 16:08       ` Gerd Hoffmann
  0 siblings, 1 reply; 17+ messages in thread
From: Alon Levy @ 2011-01-10 15:57 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: Gerd Hoffmann, qemu-devel

On Mon, Jan 10, 2011 at 03:49:34PM +0000, Daniel P. Berrange wrote:
> On Mon, Jan 10, 2011 at 02:31:47PM +0100, Gerd Hoffmann wrote:
> > Handle spice client migration, i.e. inform a spice client connected
> > about the new host and connection parameters, so it can move over the
> > connection automatically.
> > 
> > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> > ---
> >  hmp-commands.hx |   20 ++++++++++++++++++++
> >  qmp-commands.hx |   35 +++++++++++++++++++++++++++++++++++
> >  ui/qemu-spice.h |    1 +
> >  ui/spice-core.c |   40 ++++++++++++++++++++++++++++++++++++++++
> >  4 files changed, 96 insertions(+), 0 deletions(-)
> > 
> > diff --git a/hmp-commands.hx b/hmp-commands.hx
> > index df134f8..e6d8f36 100644
> > --- a/hmp-commands.hx
> > +++ b/hmp-commands.hx
> > @@ -815,6 +815,26 @@ ETEXI
> >      },
> >  
> >  STEXI
> > +@item spice_migrate_info @var{hostname} @var{port} @var{tls-port} @var{cert-subject}
> > +@findex spice_migrate_info
> > +Set the spice connection info for the migration target.  The spice
> > +server will ask the spice client to automatically reconnect using the
> > +new parameters (if specified) once the vm migration finished
> > +successfully.
> > +ETEXI
> 
> 
> > +
> > +#if defined(CONFIG_SPICE)
> > +    {
> > +        .name       = "spice_migrate_info",
> > +        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
> > +        .params     = "hostname port tls-port cert-subject",
> > +        .help       = "send migration info to spice client",
> > +        .user_print = monitor_user_noop,
> > +        .mhandler.cmd_new = mon_spice_migrate,
> > +    },
> > +#endif
> > +
> > +STEXI
> >  @item snapshot_blkdev
> >  @findex snapshot_blkdev
> >  Snapshot device, using snapshot file as target if provided
> > diff --git a/qmp-commands.hx b/qmp-commands.hx
> > index 56c4d8b..24ada04 100644
> > --- a/qmp-commands.hx
> > +++ b/qmp-commands.hx
> > @@ -503,6 +503,41 @@ EQMP
> >      },
> >  
> >  SQMP
> > +spice_migrate_info
> > +------------------
> > +
> > +Set the spice connection info for the migration target.  The spice
> > +server will ask the spice client to automatically reconnect using the
> > +new parameters (if specified) once the vm migration finished
> > +successfully.
> > +
> > +Arguments:
> > +
> > +- "hostname":     migration target hostname (json-string)
> > +- "port":         spice tcp port for plaintext channels (json-int, optional)
> > +- "tls-port":     spice tcp port for tls-secured channels (json-int, optional)
> > +- "cert-subject": server certificate subject (json-string, optional)
> > +
> > +Example:
> > +
> > +-> { "execute": "spice_migrate_info",
> > +     "arguments": { "hostname": "virt42.lab.kraxel.org", "port": 1234 } }
> > +<- { "return": {} }
> 
> I'm wondering whether we should make this command more
> generic, because I could likely write up a VNC extension
> that provides the same functionality that SPICE has here.
> so, 'graphics_migrate_info @var{spice|vnc|...} ...other vars..'

Considering it isn't actually just graphics how about client_migrate_info?

> 
> Regards,
> Daniel
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/6] spice: client migration.
  2011-01-10 15:57     ` Alon Levy
@ 2011-01-10 16:08       ` Gerd Hoffmann
  2011-01-10 16:18         ` Daniel P. Berrange
  0 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-10 16:08 UTC (permalink / raw)
  To: Daniel P. Berrange, qemu-devel

On 01/10/11 16:57, Alon Levy wrote:
>>> +spice_migrate_info
>>> +------------------
>>> +
>>> +Set the spice connection info for the migration target.  The spice
>>> +server will ask the spice client to automatically reconnect using the
>>> +new parameters (if specified) once the vm migration finished
>>> +successfully.
>>> +
>>> +Arguments:
>>> +
>>> +- "hostname":     migration target hostname (json-string)
>>> +- "port":         spice tcp port for plaintext channels (json-int, optional)
>>> +- "tls-port":     spice tcp port for tls-secured channels (json-int, optional)
>>> +- "cert-subject": server certificate subject (json-string, optional)
>>> +
>>> +Example:
>>> +
>>> +->  { "execute": "spice_migrate_info",
>>> +     "arguments": { "hostname": "virt42.lab.kraxel.org", "port": 1234 } }
>>> +<- { "return": {} }
>>
>> I'm wondering whether we should make this command more
>> generic, because I could likely write up a VNC extension
>> that provides the same functionality that SPICE has here.
>> so, 'graphics_migrate_info @var{spice|vnc|...} ...other vars..'
>
> Considering it isn't actually just graphics how about client_migrate_info?

I like client_migrate_info and it fits both spice+vnc naming too.

Given that vnc just needs hostname and port (which are present already) 
and the arguments not used by vnc are optional all we need to do is 
rename the command and add a "protocol" argument similar to 
"set_password", correct?

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/6] spice: client migration.
  2011-01-10 16:08       ` Gerd Hoffmann
@ 2011-01-10 16:18         ` Daniel P. Berrange
  2011-01-10 16:37           ` Gerd Hoffmann
  0 siblings, 1 reply; 17+ messages in thread
From: Daniel P. Berrange @ 2011-01-10 16:18 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Mon, Jan 10, 2011 at 05:08:40PM +0100, Gerd Hoffmann wrote:
> On 01/10/11 16:57, Alon Levy wrote:
> >>>+spice_migrate_info
> >>>+------------------
> >>>+
> >>>+Set the spice connection info for the migration target.  The spice
> >>>+server will ask the spice client to automatically reconnect using the
> >>>+new parameters (if specified) once the vm migration finished
> >>>+successfully.
> >>>+
> >>>+Arguments:
> >>>+
> >>>+- "hostname":     migration target hostname (json-string)
> >>>+- "port":         spice tcp port for plaintext channels (json-int, optional)
> >>>+- "tls-port":     spice tcp port for tls-secured channels (json-int, optional)
> >>>+- "cert-subject": server certificate subject (json-string, optional)
> >>>+
> >>>+Example:
> >>>+
> >>>+->  { "execute": "spice_migrate_info",
> >>>+     "arguments": { "hostname": "virt42.lab.kraxel.org", "port": 1234 } }
> >>>+<- { "return": {} }
> >>
> >>I'm wondering whether we should make this command more
> >>generic, because I could likely write up a VNC extension
> >>that provides the same functionality that SPICE has here.
> >>so, 'graphics_migrate_info @var{spice|vnc|...} ...other vars..'
> >
> >Considering it isn't actually just graphics how about client_migrate_info?
> 
> I like client_migrate_info and it fits both spice+vnc naming too.
> 
> Given that vnc just needs hostname and port (which are present
> already) and the arguments not used by vnc are optional all we need
> to do is rename the command and add a "protocol" argument similar to
> "set_password", correct?

Yeah, that sounds sufficient to me.

Regards,
Daniel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/6] spice: client migration.
  2011-01-10 16:18         ` Daniel P. Berrange
@ 2011-01-10 16:37           ` Gerd Hoffmann
  2011-01-10 19:26             ` Alon Levy
  0 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-10 16:37 UTC (permalink / raw)
  To: Daniel P. Berrange; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 537 bytes --]

   Hi,

>> I like client_migrate_info and it fits both spice+vnc naming too.
>>
>> Given that vnc just needs hostname and port (which are present
>> already) and the arguments not used by vnc are optional all we need
>> to do is rename the command and add a "protocol" argument similar to
>> "set_password", correct?
>
> Yeah, that sounds sufficient to me.

Quick incremental patch attached.  Became a bit larger than initially 
expected due to some code reorganization (move out of ui/spice-core.c) 
needed.

comments?

cheers,
   Gerd

[-- Attachment #2: fix --]
[-- Type: text/plain, Size: 7310 bytes --]

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e6d8f36..05b777b 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -815,24 +815,21 @@ ETEXI
     },
 
 STEXI
-@item spice_migrate_info @var{hostname} @var{port} @var{tls-port} @var{cert-subject}
-@findex spice_migrate_info
-Set the spice connection info for the migration target.  The spice
-server will ask the spice client to automatically reconnect using the
-new parameters (if specified) once the vm migration finished
-successfully.
+@item client_migrate_info @var{protocol} @var{hostname} @var{port} @var{tls-port} @var{cert-subject}
+@findex client_migrate_info
+Set the spice/vnc connection info for the migration target.  The spice/vnc
+server will ask the spice/vnc client to automatically reconnect using the
+new parameters (if specified) once the vm migration finished successfully.
 ETEXI
 
-#if defined(CONFIG_SPICE)
     {
-        .name       = "spice_migrate_info",
-        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
-        .params     = "hostname port tls-port cert-subject",
-        .help       = "send migration info to spice client",
+        .name       = "client_migrate_info",
+        .args_type  = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
+        .params     = "protocol hostname port tls-port cert-subject",
+        .help       = "send migration info to spice/vnc client",
         .user_print = monitor_user_noop,
-        .mhandler.cmd_new = mon_spice_migrate,
+        .mhandler.cmd_new = client_migrate_info,
     },
-#endif
 
 STEXI
 @item snapshot_blkdev
diff --git a/monitor.c b/monitor.c
index 038d532..6f5ee14 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1173,6 +1173,33 @@ static int expire_password(Monitor *mon, const QDict *qdict, QObject **ret_data)
     return -1;
 }
 
+static int client_migrate_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
+{
+    const char *protocol = qdict_get_str(qdict, "protocol");
+    const char *hostname = qdict_get_str(qdict, "hostname");
+    const char *subject  = qdict_get_try_str(qdict, "cert-subject");
+    int port             = qdict_get_try_int(qdict, "port", -1);
+    int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
+    int ret;
+
+    if (strcmp(protocol, "spice") == 0) {
+        if (!using_spice) {
+            qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
+            return -1;
+        }
+
+        ret = qemu_spice_migrate_info(hostname, port, tls_port, subject);
+        if (ret != 0) {
+            qerror_report(QERR_UNDEFINED_ERROR);
+            return -1;
+        }
+        return 0;
+    }
+
+    qerror_report(QERR_INVALID_PARAMETER, "protocol");
+    return -1;
+}
+
 static int do_screen_dump(Monitor *mon, const QDict *qdict, QObject **ret_data)
 {
     vga_hw_screen_dump(qdict_get_str(qdict, "filename"));
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 24ada04..2ed8f44 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -503,39 +503,39 @@ EQMP
     },
 
 SQMP
-spice_migrate_info
+client_migrate_info
 ------------------
 
-Set the spice connection info for the migration target.  The spice
-server will ask the spice client to automatically reconnect using the
-new parameters (if specified) once the vm migration finished
-successfully.
+Set the spice/vnc connection info for the migration target.  The spice/vnc
+server will ask the spice/vnc client to automatically reconnect using the
+new parameters (if specified) once the vm migration finished successfully.
 
 Arguments:
 
+- "protocol":     protocol: "spice" or "vnc" (json-string)
 - "hostname":     migration target hostname (json-string)
-- "port":         spice tcp port for plaintext channels (json-int, optional)
+- "port":         spice/vnc tcp port for plaintext channels (json-int, optional)
 - "tls-port":     spice tcp port for tls-secured channels (json-int, optional)
 - "cert-subject": server certificate subject (json-string, optional)
 
 Example:
 
--> { "execute": "spice_migrate_info",
-     "arguments": { "hostname": "virt42.lab.kraxel.org", "port": 1234 } }
+-> { "execute": "client_migrate_info",
+     "arguments": { "protocol": "spice",
+                    "hostname": "virt42.lab.kraxel.org",
+                    "port": 1234 } }
 <- { "return": {} }
 
 EQMP
 
-#if defined(CONFIG_SPICE)
     {
-        .name       = "spice_migrate_info",
-        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
-        .params     = "hostname port tls-port cert-subject",
-        .help       = "send migration info to spice client",
+        .name       = "client_migrate_info",
+        .args_type  = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
+        .params     = "protocol hostname port tls-port cert-subject",
+        .help       = "send migration info to spice/vnc client",
         .user_print = monitor_user_noop,
-        .mhandler.cmd_new = mon_spice_migrate,
+        .mhandler.cmd_new = client_migrate_info,
     },
-#endif
 
 SQMP
 migrate_set_speed
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index f234c4d..78df3b4 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -36,10 +36,11 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin);
 int qemu_spice_set_passwd(const char *passwd,
                           bool fail_if_connected, bool disconnect_if_connected);
 int qemu_spice_set_pw_expire(time_t expires);
+int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
+                            const char *subject);
 
 void do_info_spice_print(Monitor *mon, const QObject *data);
 void do_info_spice(Monitor *mon, QObject **ret_data);
-int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
 
 CharDriverState *qemu_chr_open_spice(QemuOpts *opts);
 
@@ -48,6 +49,7 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts);
 #define using_spice 0
 #define qemu_spice_set_passwd(_p, _f1, _f2) (-1)
 #define qemu_spice_set_pw_expire(_e) (-1)
+#define qemu_spice_migrate_info(_h, _p, _t, _s) (-1)
 
 #endif /* CONFIG_SPICE */
 
diff --git a/ui/spice-core.c b/ui/spice-core.c
index 95116cc..1aa1a5e 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -431,26 +431,11 @@ static void migration_state_notifier(Notifier *notifier)
     }
 }
 
-int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
+int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
+                            const char *subject)
 {
-    const char *hostname = qdict_get_str(qdict, "hostname");
-    const char *subject  = qdict_get_try_str(qdict, "cert-subject");
-    int port             = qdict_get_try_int(qdict, "port", -1);
-    int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
-    int ret;
-
-    if (!spice_server) {
-        qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
-        return -1;
-    }
-
-    ret = spice_server_migrate_info(spice_server, hostname,
-                                    port, tls_port, subject);
-    if (ret != 0) {
-        qerror_report(QERR_UNDEFINED_ERROR);
-        return -1;
-    }
-    return 0;
+    return spice_server_migrate_info(spice_server, hostname,
+                                     port, tls_port, subject);
 }
 
 static int add_channel(const char *name, const char *value, void *opaque)

^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/6] spice: client migration.
  2011-01-10 16:37           ` Gerd Hoffmann
@ 2011-01-10 19:26             ` Alon Levy
  2011-01-10 19:39               ` Daniel P. Berrange
  2011-01-11  8:15               ` Gerd Hoffmann
  0 siblings, 2 replies; 17+ messages in thread
From: Alon Levy @ 2011-01-10 19:26 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: qemu-devel

On Mon, Jan 10, 2011 at 05:37:18PM +0100, Gerd Hoffmann wrote:
>   Hi,
> 
> >>I like client_migrate_info and it fits both spice+vnc naming too.
> >>
> >>Given that vnc just needs hostname and port (which are present
> >>already) and the arguments not used by vnc are optional all we need
> >>to do is rename the command and add a "protocol" argument similar to
> >>"set_password", correct?
> >
> >Yeah, that sounds sufficient to me.
> 
> Quick incremental patch attached.  Became a bit larger than
> initially expected due to some code reorganization (move out of
> ui/spice-core.c) needed.
> 
> comments?

Couldn't we just apply the migration info to all connected clients?
I mean, it doesn't make sense to have a connection open that you don't
want to migrate, and if we do want that we could always add that as
an optional last argument. i.e.

client_migrate_info <host> <port> <sport> <cert-subject> [<connection>]

(unrelated: are we assuming the same ca for both hosts? that isn't totally
obvious)

If you omit connection, we connect to all.

This way the user doesn't have to say spice/vnc again after already having
set it once at command line.

The way arguments work in qemu right now adding an optional argument isn't
that easy iirc, but I suggest just starting with "migrate all" functionality.

> 
> cheers,
>   Gerd

> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index e6d8f36..05b777b 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -815,24 +815,21 @@ ETEXI
>      },
>  
>  STEXI
> -@item spice_migrate_info @var{hostname} @var{port} @var{tls-port} @var{cert-subject}
> -@findex spice_migrate_info
> -Set the spice connection info for the migration target.  The spice
> -server will ask the spice client to automatically reconnect using the
> -new parameters (if specified) once the vm migration finished
> -successfully.
> +@item client_migrate_info @var{protocol} @var{hostname} @var{port} @var{tls-port} @var{cert-subject}
> +@findex client_migrate_info
> +Set the spice/vnc connection info for the migration target.  The spice/vnc
> +server will ask the spice/vnc client to automatically reconnect using the
> +new parameters (if specified) once the vm migration finished successfully.
>  ETEXI
>  
> -#if defined(CONFIG_SPICE)
>      {
> -        .name       = "spice_migrate_info",
> -        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
> -        .params     = "hostname port tls-port cert-subject",
> -        .help       = "send migration info to spice client",
> +        .name       = "client_migrate_info",
> +        .args_type  = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
> +        .params     = "protocol hostname port tls-port cert-subject",
> +        .help       = "send migration info to spice/vnc client",
>          .user_print = monitor_user_noop,
> -        .mhandler.cmd_new = mon_spice_migrate,
> +        .mhandler.cmd_new = client_migrate_info,
>      },
> -#endif
>  
>  STEXI
>  @item snapshot_blkdev
> diff --git a/monitor.c b/monitor.c
> index 038d532..6f5ee14 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -1173,6 +1173,33 @@ static int expire_password(Monitor *mon, const QDict *qdict, QObject **ret_data)
>      return -1;
>  }
>  
> +static int client_migrate_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
> +{
> +    const char *protocol = qdict_get_str(qdict, "protocol");
> +    const char *hostname = qdict_get_str(qdict, "hostname");
> +    const char *subject  = qdict_get_try_str(qdict, "cert-subject");
> +    int port             = qdict_get_try_int(qdict, "port", -1);
> +    int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
> +    int ret;
> +
> +    if (strcmp(protocol, "spice") == 0) {
> +        if (!using_spice) {
> +            qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
> +            return -1;
> +        }
> +
> +        ret = qemu_spice_migrate_info(hostname, port, tls_port, subject);
> +        if (ret != 0) {
> +            qerror_report(QERR_UNDEFINED_ERROR);
> +            return -1;
> +        }
> +        return 0;
> +    }
> +
> +    qerror_report(QERR_INVALID_PARAMETER, "protocol");
> +    return -1;
> +}
> +
>  static int do_screen_dump(Monitor *mon, const QDict *qdict, QObject **ret_data)
>  {
>      vga_hw_screen_dump(qdict_get_str(qdict, "filename"));
> diff --git a/qmp-commands.hx b/qmp-commands.hx
> index 24ada04..2ed8f44 100644
> --- a/qmp-commands.hx
> +++ b/qmp-commands.hx
> @@ -503,39 +503,39 @@ EQMP
>      },
>  
>  SQMP
> -spice_migrate_info
> +client_migrate_info
>  ------------------
>  
> -Set the spice connection info for the migration target.  The spice
> -server will ask the spice client to automatically reconnect using the
> -new parameters (if specified) once the vm migration finished
> -successfully.
> +Set the spice/vnc connection info for the migration target.  The spice/vnc
> +server will ask the spice/vnc client to automatically reconnect using the
> +new parameters (if specified) once the vm migration finished successfully.
>  
>  Arguments:
>  
> +- "protocol":     protocol: "spice" or "vnc" (json-string)
>  - "hostname":     migration target hostname (json-string)
> -- "port":         spice tcp port for plaintext channels (json-int, optional)
> +- "port":         spice/vnc tcp port for plaintext channels (json-int, optional)
>  - "tls-port":     spice tcp port for tls-secured channels (json-int, optional)
>  - "cert-subject": server certificate subject (json-string, optional)
>  
>  Example:
>  
> --> { "execute": "spice_migrate_info",
> -     "arguments": { "hostname": "virt42.lab.kraxel.org", "port": 1234 } }
> +-> { "execute": "client_migrate_info",
> +     "arguments": { "protocol": "spice",
> +                    "hostname": "virt42.lab.kraxel.org",
> +                    "port": 1234 } }
>  <- { "return": {} }
>  
>  EQMP
>  
> -#if defined(CONFIG_SPICE)
>      {
> -        .name       = "spice_migrate_info",
> -        .args_type  = "hostname:s,port:i?,tls-port:i?,cert-subject:s?",
> -        .params     = "hostname port tls-port cert-subject",
> -        .help       = "send migration info to spice client",
> +        .name       = "client_migrate_info",
> +        .args_type  = "protocol:s,hostname:s,port:i?,tls-port:i?,cert-subject:s?",
> +        .params     = "protocol hostname port tls-port cert-subject",
> +        .help       = "send migration info to spice/vnc client",
>          .user_print = monitor_user_noop,
> -        .mhandler.cmd_new = mon_spice_migrate,
> +        .mhandler.cmd_new = client_migrate_info,
>      },
> -#endif
>  
>  SQMP
>  migrate_set_speed
> diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
> index f234c4d..78df3b4 100644
> --- a/ui/qemu-spice.h
> +++ b/ui/qemu-spice.h
> @@ -36,10 +36,11 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin);
>  int qemu_spice_set_passwd(const char *passwd,
>                            bool fail_if_connected, bool disconnect_if_connected);
>  int qemu_spice_set_pw_expire(time_t expires);
> +int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
> +                            const char *subject);
>  
>  void do_info_spice_print(Monitor *mon, const QObject *data);
>  void do_info_spice(Monitor *mon, QObject **ret_data);
> -int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data);
>  
>  CharDriverState *qemu_chr_open_spice(QemuOpts *opts);
>  
> @@ -48,6 +49,7 @@ CharDriverState *qemu_chr_open_spice(QemuOpts *opts);
>  #define using_spice 0
>  #define qemu_spice_set_passwd(_p, _f1, _f2) (-1)
>  #define qemu_spice_set_pw_expire(_e) (-1)
> +#define qemu_spice_migrate_info(_h, _p, _t, _s) (-1)
>  
>  #endif /* CONFIG_SPICE */
>  
> diff --git a/ui/spice-core.c b/ui/spice-core.c
> index 95116cc..1aa1a5e 100644
> --- a/ui/spice-core.c
> +++ b/ui/spice-core.c
> @@ -431,26 +431,11 @@ static void migration_state_notifier(Notifier *notifier)
>      }
>  }
>  
> -int mon_spice_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data)
> +int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
> +                            const char *subject)
>  {
> -    const char *hostname = qdict_get_str(qdict, "hostname");
> -    const char *subject  = qdict_get_try_str(qdict, "cert-subject");
> -    int port             = qdict_get_try_int(qdict, "port", -1);
> -    int tls_port         = qdict_get_try_int(qdict, "tls-port", -1);
> -    int ret;
> -
> -    if (!spice_server) {
> -        qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
> -        return -1;
> -    }
> -
> -    ret = spice_server_migrate_info(spice_server, hostname,
> -                                    port, tls_port, subject);
> -    if (ret != 0) {
> -        qerror_report(QERR_UNDEFINED_ERROR);
> -        return -1;
> -    }
> -    return 0;
> +    return spice_server_migrate_info(spice_server, hostname,
> +                                     port, tls_port, subject);
>  }
>  
>  static int add_channel(const char *name, const char *value, void *opaque)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/6] spice: client migration.
  2011-01-10 19:26             ` Alon Levy
@ 2011-01-10 19:39               ` Daniel P. Berrange
  2011-01-11  8:15               ` Gerd Hoffmann
  1 sibling, 0 replies; 17+ messages in thread
From: Daniel P. Berrange @ 2011-01-10 19:39 UTC (permalink / raw)
  To: Gerd Hoffmann, qemu-devel

On Mon, Jan 10, 2011 at 09:26:12PM +0200, Alon Levy wrote:
> On Mon, Jan 10, 2011 at 05:37:18PM +0100, Gerd Hoffmann wrote:
> >   Hi,
> > 
> > >>I like client_migrate_info and it fits both spice+vnc naming too.
> > >>
> > >>Given that vnc just needs hostname and port (which are present
> > >>already) and the arguments not used by vnc are optional all we need
> > >>to do is rename the command and add a "protocol" argument similar to
> > >>"set_password", correct?
> > >
> > >Yeah, that sounds sufficient to me.
> > 
> > Quick incremental patch attached.  Became a bit larger than
> > initially expected due to some code reorganization (move out of
> > ui/spice-core.c) needed.
> > 
> > comments?
> 
> Couldn't we just apply the migration info to all connected clients?
> I mean, it doesn't make sense to have a connection open that you don't
> want to migrate, and if we do want that we could always add that as
> an optional last argument. i.e.
> 
> client_migrate_info <host> <port> <sport> <cert-subject> [<connection>]
> 
> (unrelated: are we assuming the same ca for both hosts? that isn't totally
> obvious)

That shouldn't matter either way. Whether there is the same CA or
different CAs, the key factor is that the client must have the CA
used in each host in its trusted set. Only once it has decided it
trusts the CA, does it go on to use the cert-subject data for the
next step of validation.

> If you omit connection, we connect to all.
> 
> This way the user doesn't have to say spice/vnc again after already having
> set it once at command line.

If you have both spice and VNC displays active, then you need to
specify different ports for each. You might also have them listening
on different IP addresses, and potentially using different certs
(though the latter is unlikely). So I think we do need to specify
this data separately for each network service that needs migration
support

Regards,
Daniel

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 2/6] spice: client migration.
  2011-01-10 19:26             ` Alon Levy
  2011-01-10 19:39               ` Daniel P. Berrange
@ 2011-01-11  8:15               ` Gerd Hoffmann
  1 sibling, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-11  8:15 UTC (permalink / raw)
  To: Daniel P. Berrange, qemu-devel

   Hi,

> This way the user doesn't have to say spice/vnc again after already having
> set it once at command line.

Doesn't fly.  You can activate *both* vnc and spice, and in that case 
management has to send two client_migrate_info commands, one for spice 
and one for vnc.  Also this is consistent with the set_password and 
expire_password commands which have protocol as first argument too.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [Qemu-devel] [PATCH 6/6] spice: add chardev (v4)
  2011-01-11 12:08 ` [Qemu-devel] [PATCH 6/6] spice: add chardev (v4) Gerd Hoffmann
@ 2011-01-11 17:08   ` Blue Swirl
  0 siblings, 0 replies; 17+ messages in thread
From: Blue Swirl @ 2011-01-11 17:08 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Alon Levy, qemu-devel

On Tue, Jan 11, 2011 at 12:08 PM, Gerd Hoffmann <kraxel@redhat.com> wrote:
> From: Alon Levy <alevy@redhat.com>
>
> Adding a chardev backend for spice, where spice determines what
> to do with it based on the name attribute given during chardev creation.
> For usage by spice vdagent in conjunction with a properly named
> virtio-serial device, and future smartcard channel usage.
>
> Example usage:
>  qemu -device virtio-serial -chardev spicevmc,name=vdagent,id=vdagent \
>  -device virtserialport,chardev=vdagent,name=com.redhat.spice.0
>
> v3->v4:
>  * updated commit message
>
> v1->v3 changes: (v2 had a wrong commit message)
>  * removed spice-qemu-char.h, folded into ui/qemu-spice.h
>  * removed dead IOCTL code
>  * removed comment
>  * removed ifdef CONFIG_SPICE from qemu-config.c and qemu-options.hx help.
>
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
> ---
>  Makefile.objs     |    2 +-
>  qemu-char.c       |    4 +
>  qemu-config.c     |    6 ++
>  qemu-options.hx   |   16 ++++-
>  spice-qemu-char.c |  185 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  ui/qemu-spice.h   |    3 +
>  6 files changed, 214 insertions(+), 2 deletions(-)
>  create mode 100644 spice-qemu-char.c
>
> diff --git a/Makefile.objs b/Makefile.objs
> index c3e52c5..b9e9ef6 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -105,7 +105,7 @@ common-obj-$(CONFIG_BRLAPI) += baum.o
>  common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
>  common-obj-$(CONFIG_WIN32) += version.o
>
> -common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o
> +common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o spice-qemu-char.o
>
>  audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
>  audio-obj-$(CONFIG_SDL) += sdlaudio.o
> diff --git a/qemu-char.c b/qemu-char.c
> index edc9ad6..acc7130 100644
> --- a/qemu-char.c
> +++ b/qemu-char.c
> @@ -97,6 +97,7 @@
>  #endif
>
>  #include "qemu_socket.h"
> +#include "ui/qemu-spice.h"
>
>  #define READ_BUF_LEN 4096
>
> @@ -2495,6 +2496,9 @@ static const struct {
>     || defined(__FreeBSD_kernel__)
>     { .name = "parport",   .open = qemu_chr_open_pp },
>  #endif
> +#ifdef CONFIG_SPICE
> +    { .name = "spicevmc",     .open = qemu_chr_open_spice },
> +#endif
>  };
>
>  CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
> diff --git a/qemu-config.c b/qemu-config.c
> index 965fa46..323d3c2 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -146,6 +146,12 @@ static QemuOptsList qemu_chardev_opts = {
>         },{
>             .name = "signal",
>             .type = QEMU_OPT_BOOL,
> +        },{
> +            .name = "name",
> +            .type = QEMU_OPT_STRING,
> +        },{
> +            .name = "debug",
> +            .type = QEMU_OPT_NUMBER,
>         },
>         { /* end of list */ }
>     },
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 898561d..e0b76bd 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -1368,6 +1368,9 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
>  #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
>     "-chardev parport,id=id,path=path[,mux=on|off]\n"
>  #endif
> +#if defined(CONFIG_SPICE)
> +    "-chardev spicevmc,id=id,debug=debug,name=name\n"
> +#endif
>     , QEMU_ARCH_ALL
>  )
>
> @@ -1392,7 +1395,8 @@ Backend is one of:
>  @option{stdio},
>  @option{braille},
>  @option{tty},
> -@option{parport}.
> +@option{parport}

Missing a comma.

> +@option{spicevmc}.
>  The specific backend will determine the applicable options.
>
>  All devices must have an id, which can be any string up to 127 characters long.
> @@ -1568,6 +1572,16 @@ Connect to a local parallel port.
>  @option{path} specifies the path to the parallel port device. @option{path} is
>  required.
>
> +#if defined(CONFIG_SPICE)
> +@item -chardev spicevmc ,id=@var{id} ,debug=@var{debug}, name=@var{name}
> +
> +@option{debug} debug level for spicevmc
> +
> +@option{name} name of spice channel to connect to
> +
> +Connect to a spice virtual machine channel, such as vdiport.
> +#endif
> +
>  @end table
>  ETEXI
>
> diff --git a/spice-qemu-char.c b/spice-qemu-char.c
> new file mode 100644
> index 0000000..0ffa674
> --- /dev/null
> +++ b/spice-qemu-char.c
> @@ -0,0 +1,185 @@
> +#include "config-host.h"
> +#include "ui/qemu-spice.h"
> +#include <spice.h>
> +#include <spice-experimental.h>
> +
> +#include "osdep.h"
> +
> +#define dprintf(_scd, _level, _fmt, ...)                                \
> +    do {                                                                \
> +        static unsigned __dprintf_counter = 0;                          \
> +        if (_scd->debug >= _level) {                                    \
> +            fprintf(stderr, "scd: %3d: " _fmt, ++__dprintf_counter, ## __VA_ARGS__);\
> +        }                                                               \
> +    } while (0)

Tracepoints?

^ permalink raw reply	[flat|nested] 17+ messages in thread

* [Qemu-devel] [PATCH 6/6] spice: add chardev (v4)
  2011-01-11 12:08 [Qemu-devel] [PULL v2 0/6] spice patch queue Gerd Hoffmann
@ 2011-01-11 12:08 ` Gerd Hoffmann
  2011-01-11 17:08   ` Blue Swirl
  0 siblings, 1 reply; 17+ messages in thread
From: Gerd Hoffmann @ 2011-01-11 12:08 UTC (permalink / raw)
  To: qemu-devel; +Cc: Alon Levy, Gerd Hoffmann

From: Alon Levy <alevy@redhat.com>

Adding a chardev backend for spice, where spice determines what
to do with it based on the name attribute given during chardev creation.
For usage by spice vdagent in conjunction with a properly named
virtio-serial device, and future smartcard channel usage.

Example usage:
 qemu -device virtio-serial -chardev spicevmc,name=vdagent,id=vdagent \
 -device virtserialport,chardev=vdagent,name=com.redhat.spice.0

v3->v4:
 * updated commit message

v1->v3 changes: (v2 had a wrong commit message)
 * removed spice-qemu-char.h, folded into ui/qemu-spice.h
 * removed dead IOCTL code
 * removed comment
 * removed ifdef CONFIG_SPICE from qemu-config.c and qemu-options.hx help.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile.objs     |    2 +-
 qemu-char.c       |    4 +
 qemu-config.c     |    6 ++
 qemu-options.hx   |   16 ++++-
 spice-qemu-char.c |  185 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 ui/qemu-spice.h   |    3 +
 6 files changed, 214 insertions(+), 2 deletions(-)
 create mode 100644 spice-qemu-char.c

diff --git a/Makefile.objs b/Makefile.objs
index c3e52c5..b9e9ef6 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -105,7 +105,7 @@ common-obj-$(CONFIG_BRLAPI) += baum.o
 common-obj-$(CONFIG_POSIX) += migration-exec.o migration-unix.o migration-fd.o
 common-obj-$(CONFIG_WIN32) += version.o
 
-common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o
+common-obj-$(CONFIG_SPICE) += ui/spice-core.o ui/spice-input.o ui/spice-display.o spice-qemu-char.o
 
 audio-obj-y = audio.o noaudio.o wavaudio.o mixeng.o
 audio-obj-$(CONFIG_SDL) += sdlaudio.o
diff --git a/qemu-char.c b/qemu-char.c
index edc9ad6..acc7130 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -97,6 +97,7 @@
 #endif
 
 #include "qemu_socket.h"
+#include "ui/qemu-spice.h"
 
 #define READ_BUF_LEN 4096
 
@@ -2495,6 +2496,9 @@ static const struct {
     || defined(__FreeBSD_kernel__)
     { .name = "parport",   .open = qemu_chr_open_pp },
 #endif
+#ifdef CONFIG_SPICE
+    { .name = "spicevmc",     .open = qemu_chr_open_spice },
+#endif
 };
 
 CharDriverState *qemu_chr_open_opts(QemuOpts *opts,
diff --git a/qemu-config.c b/qemu-config.c
index 965fa46..323d3c2 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -146,6 +146,12 @@ static QemuOptsList qemu_chardev_opts = {
         },{
             .name = "signal",
             .type = QEMU_OPT_BOOL,
+        },{
+            .name = "name",
+            .type = QEMU_OPT_STRING,
+        },{
+            .name = "debug",
+            .type = QEMU_OPT_NUMBER,
         },
         { /* end of list */ }
     },
diff --git a/qemu-options.hx b/qemu-options.hx
index 898561d..e0b76bd 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1368,6 +1368,9 @@ DEF("chardev", HAS_ARG, QEMU_OPTION_chardev,
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__DragonFly__)
     "-chardev parport,id=id,path=path[,mux=on|off]\n"
 #endif
+#if defined(CONFIG_SPICE)
+    "-chardev spicevmc,id=id,debug=debug,name=name\n"
+#endif
     , QEMU_ARCH_ALL
 )
 
@@ -1392,7 +1395,8 @@ Backend is one of:
 @option{stdio},
 @option{braille},
 @option{tty},
-@option{parport}.
+@option{parport}
+@option{spicevmc}.
 The specific backend will determine the applicable options.
 
 All devices must have an id, which can be any string up to 127 characters long.
@@ -1568,6 +1572,16 @@ Connect to a local parallel port.
 @option{path} specifies the path to the parallel port device. @option{path} is
 required.
 
+#if defined(CONFIG_SPICE)
+@item -chardev spicevmc ,id=@var{id} ,debug=@var{debug}, name=@var{name}
+
+@option{debug} debug level for spicevmc
+
+@option{name} name of spice channel to connect to
+
+Connect to a spice virtual machine channel, such as vdiport.
+#endif
+
 @end table
 ETEXI
 
diff --git a/spice-qemu-char.c b/spice-qemu-char.c
new file mode 100644
index 0000000..0ffa674
--- /dev/null
+++ b/spice-qemu-char.c
@@ -0,0 +1,185 @@
+#include "config-host.h"
+#include "ui/qemu-spice.h"
+#include <spice.h>
+#include <spice-experimental.h>
+
+#include "osdep.h"
+
+#define dprintf(_scd, _level, _fmt, ...)                                \
+    do {                                                                \
+        static unsigned __dprintf_counter = 0;                          \
+        if (_scd->debug >= _level) {                                    \
+            fprintf(stderr, "scd: %3d: " _fmt, ++__dprintf_counter, ## __VA_ARGS__);\
+        }                                                               \
+    } while (0)
+
+#define VMC_MAX_HOST_WRITE    2048
+
+typedef struct SpiceCharDriver {
+    CharDriverState*      chr;
+    SpiceCharDeviceInstance     sin;
+    char                  *subtype;
+    bool                  active;
+    uint8_t               *buffer;
+    uint8_t               *datapos;
+    ssize_t               bufsize, datalen;
+    uint32_t              debug;
+} SpiceCharDriver;
+
+static int vmc_write(SpiceCharDeviceInstance *sin, const uint8_t *buf, int len)
+{
+    SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
+    ssize_t out = 0;
+    ssize_t last_out;
+    uint8_t* p = (uint8_t*)buf;
+
+    while (len > 0) {
+        last_out = MIN(len, VMC_MAX_HOST_WRITE);
+        qemu_chr_read(scd->chr, p, last_out);
+        if (last_out > 0) {
+            out += last_out;
+            len -= last_out;
+            p += last_out;
+        } else {
+            break;
+        }
+    }
+
+    dprintf(scd, 3, "%s: %lu/%zd\n", __func__, out, len + out);
+    return out;
+}
+
+static int vmc_read(SpiceCharDeviceInstance *sin, uint8_t *buf, int len)
+{
+    SpiceCharDriver *scd = container_of(sin, SpiceCharDriver, sin);
+    int bytes = MIN(len, scd->datalen);
+
+    dprintf(scd, 2, "%s: %p %d/%d/%zd\n", __func__, scd->datapos, len, bytes, scd->datalen);
+    if (bytes > 0) {
+        memcpy(buf, scd->datapos, bytes);
+        scd->datapos += bytes;
+        scd->datalen -= bytes;
+        assert(scd->datalen >= 0);
+        if (scd->datalen == 0) {
+            scd->datapos = 0;
+        }
+    }
+    return bytes;
+}
+
+static SpiceCharDeviceInterface vmc_interface = {
+    .base.type          = SPICE_INTERFACE_CHAR_DEVICE,
+    .base.description   = "spice virtual channel char device",
+    .base.major_version = SPICE_INTERFACE_CHAR_DEVICE_MAJOR,
+    .base.minor_version = SPICE_INTERFACE_CHAR_DEVICE_MINOR,
+    .write              = vmc_write,
+    .read               = vmc_read,
+};
+
+
+static void vmc_register_interface(SpiceCharDriver *scd)
+{
+    if (scd->active) {
+        return;
+    }
+    dprintf(scd, 1, "%s\n", __func__);
+    scd->sin.base.sif = &vmc_interface.base;
+    qemu_spice_add_interface(&scd->sin.base);
+    scd->active = true;
+}
+
+static void vmc_unregister_interface(SpiceCharDriver *scd)
+{
+    if (!scd->active) {
+        return;
+    }
+    dprintf(scd, 1, "%s\n", __func__);
+    spice_server_remove_interface(&scd->sin.base);
+    scd->active = false;
+}
+
+
+static int spice_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
+{
+    SpiceCharDriver *s = chr->opaque;
+
+    dprintf(s, 2, "%s: %d\n", __func__, len);
+    vmc_register_interface(s);
+    assert(s->datalen == 0);
+    if (s->bufsize < len) {
+        s->bufsize = len;
+        s->buffer = qemu_realloc(s->buffer, s->bufsize);
+    }
+    memcpy(s->buffer, buf, len);
+    s->datapos = s->buffer;
+    s->datalen = len;
+    spice_server_char_device_wakeup(&s->sin);
+    return len;
+}
+
+static void spice_chr_close(struct CharDriverState *chr)
+{
+    SpiceCharDriver *s = chr->opaque;
+
+    printf("%s\n", __func__);
+    vmc_unregister_interface(s);
+    qemu_free(s);
+}
+
+static void print_allowed_subtypes(void)
+{
+    const char** psubtype;
+    int i;
+
+    fprintf(stderr, "allowed names: ");
+    for(i=0, psubtype = spice_server_char_device_recognized_subtypes();
+        *psubtype != NULL; ++psubtype, ++i) {
+        if (i == 0) {
+            fprintf(stderr, "%s", *psubtype);
+        } else {
+            fprintf(stderr, ", %s", *psubtype);
+        }
+    }
+    fprintf(stderr, "\n");
+}
+
+CharDriverState *qemu_chr_open_spice(QemuOpts *opts)
+{
+    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();
+    const char *subtype = NULL;
+
+    if (name == NULL) {
+        fprintf(stderr, "spice-qemu-char: missing name parameter\n");
+        print_allowed_subtypes();
+        return NULL;
+    }
+    for(;*psubtype != NULL; ++psubtype) {
+        if (strcmp(name, *psubtype) == 0) {
+            subtype = *psubtype;
+            break;
+        }
+    }
+    if (subtype == NULL) {
+        fprintf(stderr, "spice-qemu-char: unsupported name\n");
+        print_allowed_subtypes();
+        return NULL;
+    }
+
+    chr = qemu_mallocz(sizeof(CharDriverState));
+    s = qemu_mallocz(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;
+
+    qemu_chr_generic_open(chr);
+
+    return chr;
+}
diff --git a/ui/qemu-spice.h b/ui/qemu-spice.h
index 05dc50a..916e5dc 100644
--- a/ui/qemu-spice.h
+++ b/ui/qemu-spice.h
@@ -24,6 +24,7 @@
 
 #include "qemu-option.h"
 #include "qemu-config.h"
+#include "qemu-char.h"
 
 extern int using_spice;
 
@@ -41,6 +42,8 @@ int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
 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);
+
 #else  /* CONFIG_SPICE */
 
 #define using_spice 0
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2011-01-11 17:10 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-10 13:31 [Qemu-devel] [PULL 0/6] spice patch queue Gerd Hoffmann
2011-01-10 13:31 ` [Qemu-devel] [PATCH 1/6] add migration state change notifiers Gerd Hoffmann
2011-01-10 13:31 ` [Qemu-devel] [PATCH 2/6] spice: client migration Gerd Hoffmann
2011-01-10 15:49   ` Daniel P. Berrange
2011-01-10 15:57     ` Alon Levy
2011-01-10 16:08       ` Gerd Hoffmann
2011-01-10 16:18         ` Daniel P. Berrange
2011-01-10 16:37           ` Gerd Hoffmann
2011-01-10 19:26             ` Alon Levy
2011-01-10 19:39               ` Daniel P. Berrange
2011-01-11  8:15               ` Gerd Hoffmann
2011-01-10 13:31 ` [Qemu-devel] [PATCH 3/6] spice: MAINTAINERS update Gerd Hoffmann
2011-01-10 13:31 ` [Qemu-devel] [PATCH 4/6] vnc/spice: fix "never" and "now" expire_time Gerd Hoffmann
2011-01-10 13:31 ` [Qemu-devel] [PATCH 5/6] spice/qxl: zap spice 0.4 migration compatibility bits Gerd Hoffmann
2011-01-10 13:31 ` [Qemu-devel] [PATCH 6/6] spice: add chardev (v4) Gerd Hoffmann
2011-01-11 12:08 [Qemu-devel] [PULL v2 0/6] spice patch queue Gerd Hoffmann
2011-01-11 12:08 ` [Qemu-devel] [PATCH 6/6] spice: add chardev (v4) Gerd Hoffmann
2011-01-11 17:08   ` Blue Swirl

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.