diff options
Diffstat (limited to 'ui')
-rw-r--r-- | ui/spice-core.c | 41 | ||||
-rw-r--r-- | ui/spice-display.c | 37 | ||||
-rw-r--r-- | ui/spice-display.h | 13 |
3 files changed, 82 insertions, 9 deletions
diff --git a/ui/spice-core.c b/ui/spice-core.c index 4fc48f8902..ba0d0bdbc2 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -37,6 +37,7 @@ #include "migration.h" #include "monitor.h" #include "hw/hw.h" +#include "spice-display.h" /* core bits */ @@ -45,6 +46,7 @@ static Notifier migration_state; static const char *auth = "spice"; static char *auth_passwd; static time_t auth_expires = TIME_MAX; +static int spice_migration_completed; int using_spice = 0; static QemuThread me; @@ -284,6 +286,7 @@ typedef struct SpiceMigration { } SpiceMigration; static void migrate_connect_complete_cb(SpiceMigrateInstance *sin); +static void migrate_end_complete_cb(SpiceMigrateInstance *sin); static const SpiceMigrateInterface migrate_interface = { .base.type = SPICE_INTERFACE_MIGRATION, @@ -291,7 +294,7 @@ static const SpiceMigrateInterface migrate_interface = { .base.major_version = SPICE_INTERFACE_MIGRATION_MAJOR, .base.minor_version = SPICE_INTERFACE_MIGRATION_MINOR, .migrate_connect_complete = migrate_connect_complete_cb, - .migrate_end_complete = NULL, + .migrate_end_complete = migrate_end_complete_cb, }; static SpiceMigration spice_migrate; @@ -304,6 +307,12 @@ static void migrate_connect_complete_cb(SpiceMigrateInstance *sin) } sm->connect_complete.cb = NULL; } + +static void migrate_end_complete_cb(SpiceMigrateInstance *sin) +{ + monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL); + spice_migration_completed = true; +} #endif /* config string parsing */ @@ -344,7 +353,8 @@ static const char *stream_video_names[] = { [ SPICE_STREAM_VIDEO_FILTER ] = "filter", }; #define parse_stream_video(_name) \ - name2enum(_name, stream_video_names, ARRAY_SIZE(stream_video_names)) + parse_name(_name, "stream video control", \ + stream_video_names, ARRAY_SIZE(stream_video_names)) static const char *compression_names[] = { [ SPICE_IMAGE_COMPRESS_OFF ] = "off", @@ -435,6 +445,7 @@ SpiceInfo *qmp_query_spice(Error **errp) } info->enabled = true; + info->migrated = spice_migration_completed; addr = qemu_opt_get(opts, "addr"); port = qemu_opt_get_number(opts, "port", 0); @@ -487,6 +498,8 @@ static void migration_state_notifier(Notifier *notifier, void *data) } else if (migration_has_finished(s)) { #ifndef SPICE_INTERFACE_MIGRATION spice_server_migrate_switch(spice_server); + monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL); + spice_migration_completed = true; #else spice_server_migrate_end(spice_server, true); } else if (migration_has_failed(s)) { @@ -545,6 +558,20 @@ static int add_channel(const char *name, const char *value, void *opaque) return 0; } +static void vm_change_state_handler(void *opaque, int running, + RunState state) +{ +#if SPICE_SERVER_VERSION >= 0x000b02 /* 0.11.2 */ + if (running) { + qemu_spice_display_start(); + spice_server_vm_start(spice_server); + } else { + spice_server_vm_stop(spice_server); + qemu_spice_display_stop(); + } +#endif +} + void qemu_spice_init(void) { QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head); @@ -558,6 +585,9 @@ void qemu_spice_init(void) int port, tls_port, len, addr_flags; spice_image_compression_t compression; spice_wan_compression_t wan_compr; +#if SPICE_SERVER_VERSION >= 0x000b02 /* 0.11.2 */ + bool seamless_migration; +#endif qemu_thread_get_self(&me); @@ -701,6 +731,10 @@ void qemu_spice_init(void) spice_server_set_uuid(spice_server, qemu_uuid); #endif +#if SPICE_SERVER_VERSION >= 0x000b02 /* 0.11.2 */ + seamless_migration = qemu_opt_get_bool(opts, "seamless-migration", 0); + spice_server_set_seamless_migration(spice_server, seamless_migration); +#endif if (0 != spice_server_init(spice_server, &core_interface)) { error_report("failed to initialize spice server"); exit(1); @@ -718,6 +752,8 @@ void qemu_spice_init(void) qemu_spice_input_init(); qemu_spice_audio_init(); + qemu_add_vm_change_state_handler(vm_change_state_handler, &spice_server); + g_free(x509_key_file); g_free(x509_cert_file); g_free(x509_cacert_file); @@ -740,6 +776,7 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin) spice_server = spice_server_new(); spice_server_init(spice_server, &core_interface); } + return spice_server_add_interface(spice_server, sin); } diff --git a/ui/spice-display.c b/ui/spice-display.c index 3e8f0b3ad5..99bc665bc7 100644 --- a/ui/spice-display.c +++ b/ui/spice-display.c @@ -126,18 +126,44 @@ void qemu_spice_wakeup(SimpleSpiceDisplay *ssd) ssd->worker->wakeup(ssd->worker); } -void qemu_spice_start(SimpleSpiceDisplay *ssd) +#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */ +static void qemu_spice_start(SimpleSpiceDisplay *ssd) { trace_qemu_spice_start(ssd->qxl.id); ssd->worker->start(ssd->worker); } -void qemu_spice_stop(SimpleSpiceDisplay *ssd) +static void qemu_spice_stop(SimpleSpiceDisplay *ssd) { trace_qemu_spice_stop(ssd->qxl.id); ssd->worker->stop(ssd->worker); } +#else + +static int spice_display_is_running; + +void qemu_spice_display_start(void) +{ + spice_display_is_running = true; +} + +void qemu_spice_display_stop(void) +{ + spice_display_is_running = false; +} + +#endif + +int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd) +{ +#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */ + return ssd->running; +#else + return spice_display_is_running; +#endif +} + static SimpleSpiceUpdate *qemu_spice_create_update(SimpleSpiceDisplay *ssd) { SimpleSpiceUpdate *update; @@ -272,6 +298,7 @@ void qemu_spice_destroy_host_primary(SimpleSpiceDisplay *ssd) void qemu_spice_vm_change_state_handler(void *opaque, int running, RunState state) { +#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */ SimpleSpiceDisplay *ssd = opaque; if (running) { @@ -281,6 +308,7 @@ void qemu_spice_vm_change_state_handler(void *opaque, int running, qemu_spice_stop(ssd); ssd->running = false; } +#endif } void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds) @@ -289,6 +317,9 @@ void qemu_spice_display_init_common(SimpleSpiceDisplay *ssd, DisplayState *ds) qemu_mutex_init(&ssd->lock); ssd->mouse_x = -1; ssd->mouse_y = -1; + if (ssd->num_surfaces == 0) { + ssd->num_surfaces = 1024; + } ssd->bufsize = (16 * 1024 * 1024); ssd->buf = g_malloc(ssd->bufsize); } @@ -399,7 +430,7 @@ static void interface_get_init_info(QXLInstance *sin, QXLDevInitInfo *info) info->num_memslots_groups = NUM_MEMSLOTS_GROUPS; info->internal_groupslot_id = 0; info->qxl_ram_size = ssd->bufsize; - info->n_surfaces = NUM_SURFACES; + info->n_surfaces = ssd->num_surfaces; } static int interface_get_command(QXLInstance *sin, struct QXLCommandExt *ext) diff --git a/ui/spice-display.h b/ui/spice-display.h index 12e50b6efc..512ab7831b 100644 --- a/ui/spice-display.h +++ b/ui/spice-display.h @@ -32,8 +32,6 @@ #define MEMSLOT_GROUP_GUEST 1 #define NUM_MEMSLOTS_GROUPS 2 -#define NUM_SURFACES 1024 - /* * Internal enum to differenciate between options for * io calls that have a sync (old) version and an _async (new) @@ -51,6 +49,7 @@ typedef enum qxl_async_io { enum { QXL_COOKIE_TYPE_IO, QXL_COOKIE_TYPE_RENDER_UPDATE_AREA, + QXL_COOKIE_TYPE_POST_LOAD_MONITORS_CONFIG, }; typedef struct QXLCookie { @@ -79,10 +78,13 @@ struct SimpleSpiceDisplay { QXLInstance qxl; uint32_t unique; QemuPfConv *conv; + int32_t num_surfaces; QXLRect dirty; int notify; +#if SPICE_SERVER_VERSION < 0x000b02 /* before 0.11.2 */ int running; +#endif /* * All struct members below this comment can be accessed from @@ -129,5 +131,8 @@ void qemu_spice_create_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id, void qemu_spice_destroy_primary_surface(SimpleSpiceDisplay *ssd, uint32_t id, qxl_async_io async); void qemu_spice_wakeup(SimpleSpiceDisplay *ssd); -void qemu_spice_start(SimpleSpiceDisplay *ssd); -void qemu_spice_stop(SimpleSpiceDisplay *ssd); +#if SPICE_SERVER_VERSION >= 0x000b02 /* before 0.11.2 */ +void qemu_spice_display_start(void); +void qemu_spice_display_stop(void); +#endif +int qemu_spice_display_is_running(SimpleSpiceDisplay *ssd); |