diff options
Diffstat (limited to 'ui/spice-core.c')
-rw-r--r-- | ui/spice-core.c | 109 |
1 files changed, 52 insertions, 57 deletions
diff --git a/ui/spice-core.c b/ui/spice-core.c index 4fc48f8902..d83de2a46e 100644 --- a/ui/spice-core.c +++ b/ui/spice-core.c @@ -19,24 +19,25 @@ #include <spice-experimental.h> #include <netdb.h> -#include "sysemu.h" +#include "sysemu/sysemu.h" #include "qemu-common.h" -#include "qemu-spice.h" -#include "qemu-thread.h" -#include "qemu-timer.h" -#include "qemu-queue.h" +#include "ui/qemu-spice.h" +#include "qemu/thread.h" +#include "qemu/timer.h" +#include "qemu/queue.h" #include "qemu-x509.h" -#include "qemu_socket.h" +#include "qemu/sockets.h" #include "qmp-commands.h" -#include "qint.h" -#include "qbool.h" -#include "qstring.h" -#include "qjson.h" -#include "notify.h" -#include "migration.h" -#include "monitor.h" +#include "qapi/qmp/qint.h" +#include "qapi/qmp/qbool.h" +#include "qapi/qmp/qstring.h" +#include "qapi/qmp/qjson.h" +#include "qemu/notify.h" +#include "migration/migration.h" +#include "monitor/monitor.h" #include "hw/hw.h" +#include "ui/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; @@ -221,7 +223,6 @@ static void channel_event(int event, SpiceChannelEventInfo *info) client = qdict_new(); server = qdict_new(); -#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT if (info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) { add_addr_info(client, (struct sockaddr *)&info->paddr_ext, info->plen_ext); @@ -230,12 +231,7 @@ static void channel_event(int event, SpiceChannelEventInfo *info) } else { error_report("spice: %s, extended address is expected", __func__); -#endif - add_addr_info(client, &info->paddr, info->plen); - add_addr_info(server, &info->laddr, info->llen); -#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT } -#endif if (event == SPICE_CHANNEL_EVENT_INITIALIZED) { qdict_put(server, "auth", qstring_from_str(auth)); @@ -274,7 +270,6 @@ static SpiceCoreInterface core_interface = { .channel_event = channel_event, }; -#ifdef SPICE_INTERFACE_MIGRATION typedef struct SpiceMigration { SpiceMigrateInstance sin; struct { @@ -284,6 +279,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 +287,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,7 +300,12 @@ static void migrate_connect_complete_cb(SpiceMigrateInstance *sin) } sm->connect_complete.cb = NULL; } -#endif + +static void migrate_end_complete_cb(SpiceMigrateInstance *sin) +{ + monitor_protocol_event(QEVENT_SPICE_MIGRATE_COMPLETED, NULL); + spice_migration_completed = true; +} /* config string parsing */ @@ -344,7 +345,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", @@ -383,17 +385,13 @@ static SpiceChannelList *qmp_query_spice_channels(void) chan = g_malloc0(sizeof(*chan)); chan->value = g_malloc0(sizeof(*chan->value)); -#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT if (item->info->flags & SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT) { paddr = (struct sockaddr *)&item->info->paddr_ext; plen = item->info->plen_ext; } else { -#endif paddr = &item->info->paddr; plen = item->info->plen; -#ifdef SPICE_CHANNEL_EVENT_FLAG_ADDR_EXT } -#endif getnameinfo(paddr, plen, host, sizeof(host), port, sizeof(port), @@ -435,6 +433,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); @@ -462,13 +461,10 @@ SpiceInfo *qmp_query_spice(Error **errp) info->tls_port = tls_port; } -#if SPICE_SERVER_VERSION >= 0x000a03 /* 0.10.3 */ info->mouse_mode = spice_server_is_server_mouse(spice_server) ? SPICE_QUERY_MOUSE_MODE_SERVER : SPICE_QUERY_MOUSE_MODE_CLIENT; -#else - info->mouse_mode = SPICE_QUERY_MOUSE_MODE_UNKNOWN; -#endif + /* for compatibility with the original command */ info->has_channels = true; info->channels = qmp_query_spice_channels(); @@ -481,17 +477,11 @@ static void migration_state_notifier(Notifier *notifier, void *data) MigrationState *s = data; if (migration_is_active(s)) { -#ifdef SPICE_INTERFACE_MIGRATION spice_server_migrate_start(spice_server); -#endif } else if (migration_has_finished(s)) { -#ifndef SPICE_INTERFACE_MIGRATION - spice_server_migrate_switch(spice_server); -#else spice_server_migrate_end(spice_server, true); } else if (migration_has_failed(s)) { spice_server_migrate_end(spice_server, false); -#endif } } @@ -500,16 +490,11 @@ int qemu_spice_migrate_info(const char *hostname, int port, int tls_port, MonitorCompletion *cb, void *opaque) { int ret; -#ifdef SPICE_INTERFACE_MIGRATION + spice_migrate.connect_complete.cb = cb; spice_migrate.connect_complete.opaque = opaque; ret = spice_server_migrate_connect(spice_server, hostname, port, tls_port, subject); -#else - ret = spice_server_migrate_info(spice_server, hostname, - port, tls_port, subject); - cb(opaque, NULL); -#endif return ret; } @@ -545,6 +530,18 @@ 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 (running) { + qemu_spice_display_start(); + spice_server_vm_start(spice_server); + } else { + spice_server_vm_stop(spice_server); + qemu_spice_display_stop(); + } +} + void qemu_spice_init(void) { QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head); @@ -558,6 +555,7 @@ void qemu_spice_init(void) int port, tls_port, len, addr_flags; spice_image_compression_t compression; spice_wan_compression_t wan_compr; + bool seamless_migration; qemu_thread_get_self(&me); @@ -612,7 +610,7 @@ void qemu_spice_init(void) } x509_key_password = qemu_opt_get(opts, "x509-key-password"); - x509_dh_file = qemu_opt_get(opts, "x509-dh-file"); + x509_dh_file = qemu_opt_get(opts, "x509-dh-key-file"); tls_ciphers = qemu_opt_get(opts, "tls-ciphers"); } @@ -642,16 +640,11 @@ void qemu_spice_init(void) spice_server_set_ticket(spice_server, password, 0, 0, 0); } if (qemu_opt_get_bool(opts, "sasl", 0)) { -#if SPICE_SERVER_VERSION >= 0x000900 /* 0.9.0 */ if (spice_server_set_sasl_appname(spice_server, "qemu") == -1 || spice_server_set_sasl(spice_server, 1) == -1) { error_report("spice: failed to enable sasl"); exit(1); } -#else - error_report("spice: sasl is not available (spice >= 0.9 required)"); - exit(1); -#endif } if (qemu_opt_get_bool(opts, "disable-ticketing", 0)) { auth = "none"; @@ -696,11 +689,11 @@ void qemu_spice_init(void) qemu_opt_foreach(opts, add_channel, &tls_port, 0); -#if SPICE_SERVER_VERSION >= 0x000a02 /* 0.10.2 */ spice_server_set_name(spice_server, qemu_name); spice_server_set_uuid(spice_server, qemu_uuid); -#endif + seamless_migration = qemu_opt_get_bool(opts, "seamless-migration", 0); + spice_server_set_seamless_migration(spice_server, seamless_migration); if (0 != spice_server_init(spice_server, &core_interface)) { error_report("failed to initialize spice server"); exit(1); @@ -709,18 +702,22 @@ void qemu_spice_init(void) migration_state.notify = migration_state_notifier; add_migration_state_change_notifier(&migration_state); -#ifdef SPICE_INTERFACE_MIGRATION spice_migrate.sin.base.sif = &migrate_interface.base; spice_migrate.connect_complete.cb = NULL; qemu_spice_add_interface(&spice_migrate.sin.base); -#endif qemu_spice_input_init(); qemu_spice_audio_init(); + qemu_add_vm_change_state_handler(vm_change_state_handler, NULL); + g_free(x509_key_file); g_free(x509_cert_file); g_free(x509_cacert_file); + +#if SPICE_SERVER_VERSION >= 0x000c02 + qemu_spice_register_ports(); +#endif } int qemu_spice_add_interface(SpiceBaseInstance *sin) @@ -739,7 +736,9 @@ int qemu_spice_add_interface(SpiceBaseInstance *sin) */ spice_server = spice_server_new(); spice_server_init(spice_server, &core_interface); + qemu_add_vm_change_state_handler(vm_change_state_handler, NULL); } + return spice_server_add_interface(spice_server, sin); } @@ -778,15 +777,11 @@ int qemu_spice_set_pw_expire(time_t expires) int qemu_spice_display_add_client(int csock, int skipauth, int tls) { -#if SPICE_SERVER_VERSION >= 0x000a01 if (tls) { return spice_server_add_ssl_client(spice_server, csock, skipauth); } else { return spice_server_add_client(spice_server, csock, skipauth); } -#else - return -1; -#endif } static void spice_register_config(void) |