mirror of
https://github.com/qemu/qemu.git
synced 2025-08-08 08:05:17 +00:00
Merge remote-tracking branch 'spice/spice.v45' into staging
This commit is contained in:
commit
eca968d0d4
@ -824,7 +824,8 @@ ETEXI
|
|||||||
.params = "protocol hostname port tls-port cert-subject",
|
.params = "protocol hostname port tls-port cert-subject",
|
||||||
.help = "send migration info to spice/vnc client",
|
.help = "send migration info to spice/vnc client",
|
||||||
.user_print = monitor_user_noop,
|
.user_print = monitor_user_noop,
|
||||||
.mhandler.cmd_new = client_migrate_info,
|
.mhandler.cmd_async = client_migrate_info,
|
||||||
|
.flags = MONITOR_CMD_ASYNC,
|
||||||
},
|
},
|
||||||
|
|
||||||
STEXI
|
STEXI
|
||||||
|
66
hw/qxl.c
66
hw/qxl.c
@ -18,8 +18,6 @@
|
|||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu-timer.h"
|
#include "qemu-timer.h"
|
||||||
#include "qemu-queue.h"
|
#include "qemu-queue.h"
|
||||||
@ -238,6 +236,9 @@ void qxl_spice_reset_image_cache(PCIQXLDevice *qxl)
|
|||||||
void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
|
void qxl_spice_reset_cursor(PCIQXLDevice *qxl)
|
||||||
{
|
{
|
||||||
qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
|
qxl->ssd.worker->reset_cursor(qxl->ssd.worker);
|
||||||
|
qemu_mutex_lock(&qxl->track_lock);
|
||||||
|
qxl->guest_cursor = 0;
|
||||||
|
qemu_mutex_unlock(&qxl->track_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -330,6 +331,7 @@ static void init_qxl_ram(PCIQXLDevice *d)
|
|||||||
d->ram->magic = cpu_to_le32(QXL_RAM_MAGIC);
|
d->ram->magic = cpu_to_le32(QXL_RAM_MAGIC);
|
||||||
d->ram->int_pending = cpu_to_le32(0);
|
d->ram->int_pending = cpu_to_le32(0);
|
||||||
d->ram->int_mask = cpu_to_le32(0);
|
d->ram->int_mask = cpu_to_le32(0);
|
||||||
|
d->ram->update_surface = 0;
|
||||||
SPICE_RING_INIT(&d->ram->cmd_ring);
|
SPICE_RING_INIT(&d->ram->cmd_ring);
|
||||||
SPICE_RING_INIT(&d->ram->cursor_ring);
|
SPICE_RING_INIT(&d->ram->cursor_ring);
|
||||||
SPICE_RING_INIT(&d->ram->release_ring);
|
SPICE_RING_INIT(&d->ram->release_ring);
|
||||||
@ -402,7 +404,9 @@ static void qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
|
|||||||
{
|
{
|
||||||
QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
|
QXLCursorCmd *cmd = qxl_phys2virt(qxl, ext->cmd.data, ext->group_id);
|
||||||
if (cmd->type == QXL_CURSOR_SET) {
|
if (cmd->type == QXL_CURSOR_SET) {
|
||||||
|
qemu_mutex_lock(&qxl->track_lock);
|
||||||
qxl->guest_cursor = ext->cmd.data;
|
qxl->guest_cursor = ext->cmd.data;
|
||||||
|
qemu_mutex_unlock(&qxl->track_lock);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1067,6 +1071,7 @@ static int qxl_destroy_primary(PCIQXLDevice *d, qxl_async_io async)
|
|||||||
|
|
||||||
d->mode = QXL_MODE_UNDEFINED;
|
d->mode = QXL_MODE_UNDEFINED;
|
||||||
qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
|
qemu_spice_destroy_primary_surface(&d->ssd, 0, async);
|
||||||
|
qxl_spice_reset_cursor(d);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1212,10 +1217,6 @@ async_common:
|
|||||||
qxl_update_irq(d);
|
qxl_update_irq(d);
|
||||||
break;
|
break;
|
||||||
case QXL_IO_NOTIFY_OOM:
|
case QXL_IO_NOTIFY_OOM:
|
||||||
if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
pthread_yield();
|
|
||||||
if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {
|
if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1372,7 +1373,7 @@ static void qxl_send_events(PCIQXLDevice *d, uint32_t events)
|
|||||||
if ((old_pending & le_events) == le_events) {
|
if ((old_pending & le_events) == le_events) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pthread_self() == d->main) {
|
if (qemu_thread_is_self(&d->main)) {
|
||||||
qxl_update_irq(d);
|
qxl_update_irq(d);
|
||||||
} else {
|
} else {
|
||||||
if (write(d->pipe[1], d, 1) != 1) {
|
if (write(d->pipe[1], d, 1) != 1) {
|
||||||
@ -1391,7 +1392,7 @@ static void init_pipe_signaling(PCIQXLDevice *d)
|
|||||||
fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
|
fcntl(d->pipe[1], F_SETFL, O_NONBLOCK);
|
||||||
fcntl(d->pipe[0], F_SETOWN, getpid());
|
fcntl(d->pipe[0], F_SETOWN, getpid());
|
||||||
|
|
||||||
d->main = pthread_self();
|
qemu_thread_get_self(&d->main);
|
||||||
qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
|
qemu_set_fd_handler(d->pipe[0], pipe_read, NULL, d);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1710,10 +1711,12 @@ static int qxl_post_load(void *opaque, int version)
|
|||||||
cmds[out].group_id = MEMSLOT_GROUP_GUEST;
|
cmds[out].group_id = MEMSLOT_GROUP_GUEST;
|
||||||
out++;
|
out++;
|
||||||
}
|
}
|
||||||
cmds[out].cmd.data = d->guest_cursor;
|
if (d->guest_cursor) {
|
||||||
cmds[out].cmd.type = QXL_CMD_CURSOR;
|
cmds[out].cmd.data = d->guest_cursor;
|
||||||
cmds[out].group_id = MEMSLOT_GROUP_GUEST;
|
cmds[out].cmd.type = QXL_CMD_CURSOR;
|
||||||
out++;
|
cmds[out].group_id = MEMSLOT_GROUP_GUEST;
|
||||||
|
out++;
|
||||||
|
}
|
||||||
qxl_spice_loadvm_commands(d, cmds, out);
|
qxl_spice_loadvm_commands(d, cmds, out);
|
||||||
g_free(cmds);
|
g_free(cmds);
|
||||||
|
|
||||||
@ -1787,6 +1790,19 @@ static VMStateDescription qxl_vmstate = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static Property qxl_properties[] = {
|
||||||
|
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
|
||||||
|
64 * 1024 * 1024),
|
||||||
|
DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size,
|
||||||
|
64 * 1024 * 1024),
|
||||||
|
DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
|
||||||
|
QXL_DEFAULT_REVISION),
|
||||||
|
DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
|
||||||
|
DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
|
||||||
|
DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
static PCIDeviceInfo qxl_info_primary = {
|
static PCIDeviceInfo qxl_info_primary = {
|
||||||
.qdev.name = "qxl-vga",
|
.qdev.name = "qxl-vga",
|
||||||
.qdev.desc = "Spice QXL GPU (primary, vga compatible)",
|
.qdev.desc = "Spice QXL GPU (primary, vga compatible)",
|
||||||
@ -1799,18 +1815,7 @@ static PCIDeviceInfo qxl_info_primary = {
|
|||||||
.vendor_id = REDHAT_PCI_VENDOR_ID,
|
.vendor_id = REDHAT_PCI_VENDOR_ID,
|
||||||
.device_id = QXL_DEVICE_ID_STABLE,
|
.device_id = QXL_DEVICE_ID_STABLE,
|
||||||
.class_id = PCI_CLASS_DISPLAY_VGA,
|
.class_id = PCI_CLASS_DISPLAY_VGA,
|
||||||
.qdev.props = (Property[]) {
|
.qdev.props = qxl_properties,
|
||||||
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
|
|
||||||
64 * 1024 * 1024),
|
|
||||||
DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size,
|
|
||||||
64 * 1024 * 1024),
|
|
||||||
DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
|
|
||||||
QXL_DEFAULT_REVISION),
|
|
||||||
DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
|
|
||||||
DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
|
|
||||||
DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static PCIDeviceInfo qxl_info_secondary = {
|
static PCIDeviceInfo qxl_info_secondary = {
|
||||||
@ -1823,18 +1828,7 @@ static PCIDeviceInfo qxl_info_secondary = {
|
|||||||
.vendor_id = REDHAT_PCI_VENDOR_ID,
|
.vendor_id = REDHAT_PCI_VENDOR_ID,
|
||||||
.device_id = QXL_DEVICE_ID_STABLE,
|
.device_id = QXL_DEVICE_ID_STABLE,
|
||||||
.class_id = PCI_CLASS_DISPLAY_OTHER,
|
.class_id = PCI_CLASS_DISPLAY_OTHER,
|
||||||
.qdev.props = (Property[]) {
|
.qdev.props = qxl_properties,
|
||||||
DEFINE_PROP_UINT32("ram_size", PCIQXLDevice, vga.vram_size,
|
|
||||||
64 * 1024 * 1024),
|
|
||||||
DEFINE_PROP_UINT32("vram_size", PCIQXLDevice, vram_size,
|
|
||||||
64 * 1024 * 1024),
|
|
||||||
DEFINE_PROP_UINT32("revision", PCIQXLDevice, revision,
|
|
||||||
QXL_DEFAULT_REVISION),
|
|
||||||
DEFINE_PROP_UINT32("debug", PCIQXLDevice, debug, 0),
|
|
||||||
DEFINE_PROP_UINT32("guestdebug", PCIQXLDevice, guestdebug, 0),
|
|
||||||
DEFINE_PROP_UINT32("cmdlog", PCIQXLDevice, cmdlog, 0),
|
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void qxl_register(void)
|
static void qxl_register(void)
|
||||||
|
3
hw/qxl.h
3
hw/qxl.h
@ -4,6 +4,7 @@
|
|||||||
#include "hw.h"
|
#include "hw.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
#include "vga_int.h"
|
#include "vga_int.h"
|
||||||
|
#include "qemu-thread.h"
|
||||||
|
|
||||||
#include "ui/qemu-spice.h"
|
#include "ui/qemu-spice.h"
|
||||||
#include "ui/spice-display.h"
|
#include "ui/spice-display.h"
|
||||||
@ -63,7 +64,7 @@ typedef struct PCIQXLDevice {
|
|||||||
QemuMutex track_lock;
|
QemuMutex track_lock;
|
||||||
|
|
||||||
/* thread signaling */
|
/* thread signaling */
|
||||||
pthread_t main;
|
QemuThread main;
|
||||||
int pipe[2];
|
int pipe[2];
|
||||||
|
|
||||||
/* ram pci bar */
|
/* ram pci bar */
|
||||||
|
11
migration.c
11
migration.c
@ -372,11 +372,22 @@ void remove_migration_state_change_notifier(Notifier *notify)
|
|||||||
notifier_list_remove(&migration_state_notifiers, notify);
|
notifier_list_remove(&migration_state_notifiers, notify);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool migration_is_active(MigrationState *s)
|
||||||
|
{
|
||||||
|
return s->state == MIG_STATE_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
bool migration_has_finished(MigrationState *s)
|
bool migration_has_finished(MigrationState *s)
|
||||||
{
|
{
|
||||||
return s->state == MIG_STATE_COMPLETED;
|
return s->state == MIG_STATE_COMPLETED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool migration_has_failed(MigrationState *s)
|
||||||
|
{
|
||||||
|
return (s->state == MIG_STATE_CANCELLED ||
|
||||||
|
s->state == MIG_STATE_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
void migrate_fd_connect(MigrationState *s)
|
void migrate_fd_connect(MigrationState *s)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -76,7 +76,9 @@ void migrate_fd_connect(MigrationState *s);
|
|||||||
|
|
||||||
void add_migration_state_change_notifier(Notifier *notify);
|
void add_migration_state_change_notifier(Notifier *notify);
|
||||||
void remove_migration_state_change_notifier(Notifier *notify);
|
void remove_migration_state_change_notifier(Notifier *notify);
|
||||||
|
bool migration_is_active(MigrationState *);
|
||||||
bool migration_has_finished(MigrationState *);
|
bool migration_has_finished(MigrationState *);
|
||||||
|
bool migration_has_failed(MigrationState *);
|
||||||
|
|
||||||
uint64_t ram_bytes_remaining(void);
|
uint64_t ram_bytes_remaining(void);
|
||||||
uint64_t ram_bytes_transferred(void);
|
uint64_t ram_bytes_transferred(void);
|
||||||
|
@ -1153,7 +1153,8 @@ static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_d
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int client_migrate_info(Monitor *mon, const QDict *qdict, QObject **ret_data)
|
static int client_migrate_info(Monitor *mon, const QDict *qdict,
|
||||||
|
MonitorCompletion cb, void *opaque)
|
||||||
{
|
{
|
||||||
const char *protocol = qdict_get_str(qdict, "protocol");
|
const char *protocol = qdict_get_str(qdict, "protocol");
|
||||||
const char *hostname = qdict_get_str(qdict, "hostname");
|
const char *hostname = qdict_get_str(qdict, "hostname");
|
||||||
@ -1168,7 +1169,8 @@ static int client_migrate_info(Monitor *mon, const QDict *qdict, QObject **ret_d
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qemu_spice_migrate_info(hostname, port, tls_port, subject);
|
ret = qemu_spice_migrate_info(hostname, port, tls_port, subject,
|
||||||
|
cb, opaque);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
qerror_report(QERR_UNDEFINED_ERROR);
|
qerror_report(QERR_UNDEFINED_ERROR);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -569,7 +569,8 @@ EQMP
|
|||||||
.params = "protocol hostname port tls-port cert-subject",
|
.params = "protocol hostname port tls-port cert-subject",
|
||||||
.help = "send migration info to spice/vnc client",
|
.help = "send migration info to spice/vnc client",
|
||||||
.user_print = monitor_user_noop,
|
.user_print = monitor_user_noop,
|
||||||
.mhandler.cmd_new = client_migrate_info,
|
.mhandler.cmd_async = client_migrate_info,
|
||||||
|
.flags = MONITOR_CMD_ASYNC,
|
||||||
},
|
},
|
||||||
|
|
||||||
SQMP
|
SQMP
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "qemu-option.h"
|
#include "qemu-option.h"
|
||||||
#include "qemu-config.h"
|
#include "qemu-config.h"
|
||||||
#include "qemu-char.h"
|
#include "qemu-char.h"
|
||||||
|
#include "monitor.h"
|
||||||
|
|
||||||
extern int using_spice;
|
extern int using_spice;
|
||||||
|
|
||||||
@ -37,7 +38,8 @@ int qemu_spice_set_passwd(const char *passwd,
|
|||||||
bool fail_if_connected, bool disconnect_if_connected);
|
bool fail_if_connected, bool disconnect_if_connected);
|
||||||
int qemu_spice_set_pw_expire(time_t expires);
|
int qemu_spice_set_pw_expire(time_t expires);
|
||||||
int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
|
int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
|
||||||
const char *subject);
|
const char *subject,
|
||||||
|
MonitorCompletion cb, void *opaque);
|
||||||
|
|
||||||
void do_info_spice_print(Monitor *mon, const QObject *data);
|
void do_info_spice_print(Monitor *mon, const QObject *data);
|
||||||
void do_info_spice(Monitor *mon, QObject **ret_data);
|
void do_info_spice(Monitor *mon, QObject **ret_data);
|
||||||
@ -45,6 +47,7 @@ void do_info_spice(Monitor *mon, QObject **ret_data);
|
|||||||
int qemu_chr_open_spice(QemuOpts *opts, CharDriverState **_chr);
|
int qemu_chr_open_spice(QemuOpts *opts, CharDriverState **_chr);
|
||||||
|
|
||||||
#else /* CONFIG_SPICE */
|
#else /* CONFIG_SPICE */
|
||||||
|
#include "monitor.h"
|
||||||
|
|
||||||
#define using_spice 0
|
#define using_spice 0
|
||||||
static inline int qemu_spice_set_passwd(const char *passwd,
|
static inline int qemu_spice_set_passwd(const char *passwd,
|
||||||
@ -57,8 +60,13 @@ static inline int qemu_spice_set_pw_expire(time_t expires)
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
static inline int qemu_spice_migrate_info(const char *h, int p, int t, const char *s)
|
static inline int qemu_spice_migrate_info(const char *h, int p, int t,
|
||||||
{ return -1; }
|
const char *s,
|
||||||
|
MonitorCompletion cb, void *opaque)
|
||||||
|
{
|
||||||
|
cb(opaque, NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_SPICE */
|
#endif /* CONFIG_SPICE */
|
||||||
|
|
||||||
|
@ -19,10 +19,10 @@
|
|||||||
#include <spice-experimental.h>
|
#include <spice-experimental.h>
|
||||||
|
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
#include "qemu-common.h"
|
||||||
#include "qemu-spice.h"
|
#include "qemu-spice.h"
|
||||||
|
#include "qemu-thread.h"
|
||||||
#include "qemu-timer.h"
|
#include "qemu-timer.h"
|
||||||
#include "qemu-queue.h"
|
#include "qemu-queue.h"
|
||||||
#include "qemu-x509.h"
|
#include "qemu-x509.h"
|
||||||
@ -45,7 +45,7 @@ static char *auth_passwd;
|
|||||||
static time_t auth_expires = TIME_MAX;
|
static time_t auth_expires = TIME_MAX;
|
||||||
int using_spice = 0;
|
int using_spice = 0;
|
||||||
|
|
||||||
static pthread_t me;
|
static QemuThread me;
|
||||||
|
|
||||||
struct SpiceTimer {
|
struct SpiceTimer {
|
||||||
QEMUTimer *timer;
|
QEMUTimer *timer;
|
||||||
@ -133,7 +133,7 @@ static SpiceWatch *watch_add(int fd, int event_mask, SpiceWatchFunc func, void *
|
|||||||
|
|
||||||
static void watch_remove(SpiceWatch *watch)
|
static void watch_remove(SpiceWatch *watch)
|
||||||
{
|
{
|
||||||
watch_update_mask(watch, 0);
|
qemu_set_fd_handler(watch->fd, NULL, NULL, NULL);
|
||||||
QTAILQ_REMOVE(&watches, watch, next);
|
QTAILQ_REMOVE(&watches, watch, next);
|
||||||
g_free(watch);
|
g_free(watch);
|
||||||
}
|
}
|
||||||
@ -229,7 +229,7 @@ static void channel_event(int event, SpiceChannelEventInfo *info)
|
|||||||
* thread and grab the iothread lock if so before calling qemu
|
* thread and grab the iothread lock if so before calling qemu
|
||||||
* functions.
|
* functions.
|
||||||
*/
|
*/
|
||||||
bool need_lock = !pthread_equal(me, pthread_self());
|
bool need_lock = !qemu_thread_is_self(&me);
|
||||||
if (need_lock) {
|
if (need_lock) {
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
}
|
}
|
||||||
@ -288,6 +288,38 @@ static SpiceCoreInterface core_interface = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef SPICE_INTERFACE_MIGRATION
|
||||||
|
typedef struct SpiceMigration {
|
||||||
|
SpiceMigrateInstance sin;
|
||||||
|
struct {
|
||||||
|
MonitorCompletion *cb;
|
||||||
|
void *opaque;
|
||||||
|
} connect_complete;
|
||||||
|
} SpiceMigration;
|
||||||
|
|
||||||
|
static void migrate_connect_complete_cb(SpiceMigrateInstance *sin);
|
||||||
|
|
||||||
|
static const SpiceMigrateInterface migrate_interface = {
|
||||||
|
.base.type = SPICE_INTERFACE_MIGRATION,
|
||||||
|
.base.description = "migration",
|
||||||
|
.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,
|
||||||
|
};
|
||||||
|
|
||||||
|
static SpiceMigration spice_migrate;
|
||||||
|
|
||||||
|
static void migrate_connect_complete_cb(SpiceMigrateInstance *sin)
|
||||||
|
{
|
||||||
|
SpiceMigration *sm = container_of(sin, SpiceMigration, sin);
|
||||||
|
if (sm->connect_complete.cb) {
|
||||||
|
sm->connect_complete.cb(sm->connect_complete.opaque, NULL);
|
||||||
|
}
|
||||||
|
sm->connect_complete.cb = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* config string parsing */
|
/* config string parsing */
|
||||||
|
|
||||||
static int name2enum(const char *string, const char *table[], int entries)
|
static int name2enum(const char *string, const char *table[], int entries)
|
||||||
@ -413,7 +445,7 @@ void do_info_spice(Monitor *mon, QObject **ret_data)
|
|||||||
int port, tls_port;
|
int port, tls_port;
|
||||||
char version_string[20]; /* 12 = |255.255.255\0| is the max */
|
char version_string[20]; /* 12 = |255.255.255\0| is the max */
|
||||||
|
|
||||||
if (!spice_server) {
|
if (!spice_server || !opts) {
|
||||||
*ret_data = qobject_from_jsonf("{ 'enabled': false }");
|
*ret_data = qobject_from_jsonf("{ 'enabled': false }");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -449,18 +481,39 @@ static void migration_state_notifier(Notifier *notifier, void *data)
|
|||||||
{
|
{
|
||||||
MigrationState *s = data;
|
MigrationState *s = data;
|
||||||
|
|
||||||
if (migration_has_finished(s)) {
|
if (migration_is_active(s)) {
|
||||||
|
#ifdef SPICE_INTERFACE_MIGRATION
|
||||||
|
spice_server_migrate_start(spice_server);
|
||||||
|
#endif
|
||||||
|
} else if (migration_has_finished(s)) {
|
||||||
#if SPICE_SERVER_VERSION >= 0x000701 /* 0.7.1 */
|
#if SPICE_SERVER_VERSION >= 0x000701 /* 0.7.1 */
|
||||||
|
#ifndef SPICE_INTERFACE_MIGRATION
|
||||||
spice_server_migrate_switch(spice_server);
|
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
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
|
int qemu_spice_migrate_info(const char *hostname, int port, int tls_port,
|
||||||
const char *subject)
|
const char *subject,
|
||||||
|
MonitorCompletion *cb, void *opaque)
|
||||||
{
|
{
|
||||||
return spice_server_migrate_info(spice_server, hostname,
|
int ret;
|
||||||
port, tls_port, subject);
|
#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;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_channel(const char *name, const char *value, void *opaque)
|
static int add_channel(const char *name, const char *value, void *opaque)
|
||||||
@ -503,7 +556,7 @@ void qemu_spice_init(void)
|
|||||||
spice_image_compression_t compression;
|
spice_image_compression_t compression;
|
||||||
spice_wan_compression_t wan_compr;
|
spice_wan_compression_t wan_compr;
|
||||||
|
|
||||||
me = pthread_self();
|
qemu_thread_get_self(&me);
|
||||||
|
|
||||||
if (!opts) {
|
if (!opts) {
|
||||||
return;
|
return;
|
||||||
@ -650,6 +703,11 @@ void qemu_spice_init(void)
|
|||||||
|
|
||||||
migration_state.notify = migration_state_notifier;
|
migration_state.notify = migration_state_notifier;
|
||||||
add_migration_state_change_notifier(&migration_state);
|
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_input_init();
|
||||||
qemu_spice_audio_init();
|
qemu_spice_audio_init();
|
||||||
|
Loading…
Reference in New Issue
Block a user