migration/next for 20170206
-----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJYmKCmAAoJEPSH7xhYctcju4EP/3R5+ezqOIRS+ybURKC0W0+h VkpEMu1Vrmu+Y5m4rBpiPbr2vxuR0r4SvTGHpkhzNlbVI8H24mDN6snkf0r0M/HJ ERU9pH46kJV8MWmbfsSY6JQqIlZiqww/2oDQ5ILI/m8oRaqF2hKkJtAA7JZJEasA gpA4r6yng0V5eKJ05MQVNzavY0uNxWKkQ7+6cXPcoFWiyZXvnuL0EDlxAdTzW9qH oMzqnnywBg6xj8/qz/g7ZjfiXfZnNshrPqS0LztxPJJaCVD+XK7JWs0yDyxJLqz5 qhy/3an6d5bo0A5aG8qM8Q4PSHfY+Mahre2I3kfBH8vUiLlQ4c8N+v6HHLSi2LMi EK0Sy8jBALDjg9Tr4Jl9oG46YKgdct13rUxMb+Gvr5GIkhALB/sTAS/x7QXHck2z ecDYC+LKXXY8vqgPri+aaF6OLngeVWP7bszF79xXNB6jo+lTwU0Xbhh0M1c552ZV TaOwy+z/G0My4dUAq0zGx43ZJqSrwY0RrR1Hp6YCNQoL3Gj5RjJL6CBJ7MIq8AYV G2L2J/u6AGLjuLf4zYre12rKsmK+IBOyYK2osfcPpx0/i3gi5POl/ep5pVD0z9e6 Ry7sDOwlkN5CwlDdaWDQEg8jrhZlGe424jqe4ScwlubjylBm/UhLjnyPUK38o+jk hAjvVFCrbuA9jrlJMgNZ =R5kr -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20170206' into staging migration/next for 20170206 # gpg: Signature made Mon 06 Feb 2017 16:13:26 GMT # gpg: using RSA key 0xF487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" # gpg: aka "Juan Quintela <quintela@trasno.org>" # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * remotes/juanquintela/tags/migration/20170206: postcopy: Recover block devices on early failure Postcopy: Reset state to avoid cleanup assert vmstate registration: check return values migration: Check for ID length vmstate_register_with_alias_id: Take an Error ** migration: create Migration Incoming State at init time Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
d0dff238a8
@ -933,9 +933,12 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
|
||||
}
|
||||
|
||||
if (qdev_get_vmsd(dev)) {
|
||||
vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
|
||||
dev->instance_id_alias,
|
||||
dev->alias_required_for_version);
|
||||
if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
|
||||
dev->instance_id_alias,
|
||||
dev->alias_required_for_version,
|
||||
&local_err) < 0) {
|
||||
goto post_realize_fail;
|
||||
}
|
||||
}
|
||||
|
||||
QLIST_FOREACH(bus, &dev->child_bus, sibling) {
|
||||
|
@ -329,7 +329,7 @@ static void apic_common_realize(DeviceState *dev, Error **errp)
|
||||
instance_id = -1;
|
||||
}
|
||||
vmstate_register_with_alias_id(NULL, instance_id, &vmstate_apic_common,
|
||||
s, -1, 0);
|
||||
s, -1, 0, NULL);
|
||||
}
|
||||
|
||||
static void apic_common_unrealize(DeviceState *dev, Error **errp)
|
||||
|
@ -122,7 +122,6 @@ struct MigrationIncomingState {
|
||||
};
|
||||
|
||||
MigrationIncomingState *migration_incoming_get_current(void);
|
||||
MigrationIncomingState *migration_incoming_state_new(QEMUFile *f);
|
||||
void migration_incoming_state_destroy(void);
|
||||
|
||||
/*
|
||||
|
@ -985,17 +985,20 @@ void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
|
||||
bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque);
|
||||
|
||||
/* Returns: 0 on success, -1 on failure */
|
||||
int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
|
||||
const VMStateDescription *vmsd,
|
||||
void *base, int alias_id,
|
||||
int required_for_version);
|
||||
int required_for_version,
|
||||
Error **errp);
|
||||
|
||||
/* Returns: 0 on success, -1 on failure */
|
||||
static inline int vmstate_register(DeviceState *dev, int instance_id,
|
||||
const VMStateDescription *vmsd,
|
||||
void *opaque)
|
||||
{
|
||||
return vmstate_register_with_alias_id(dev, instance_id, vmsd,
|
||||
opaque, -1, 0);
|
||||
opaque, -1, 0, NULL);
|
||||
}
|
||||
|
||||
void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
|
||||
|
@ -111,32 +111,28 @@ MigrationState *migrate_get_current(void)
|
||||
return ¤t_migration;
|
||||
}
|
||||
|
||||
/* For incoming */
|
||||
static MigrationIncomingState *mis_current;
|
||||
|
||||
MigrationIncomingState *migration_incoming_get_current(void)
|
||||
{
|
||||
return mis_current;
|
||||
}
|
||||
static bool once;
|
||||
static MigrationIncomingState mis_current;
|
||||
|
||||
MigrationIncomingState *migration_incoming_state_new(QEMUFile* f)
|
||||
{
|
||||
mis_current = g_new0(MigrationIncomingState, 1);
|
||||
mis_current->from_src_file = f;
|
||||
mis_current->state = MIGRATION_STATUS_NONE;
|
||||
QLIST_INIT(&mis_current->loadvm_handlers);
|
||||
qemu_mutex_init(&mis_current->rp_mutex);
|
||||
qemu_event_init(&mis_current->main_thread_load_event, false);
|
||||
|
||||
return mis_current;
|
||||
if (!once) {
|
||||
mis_current.state = MIGRATION_STATUS_NONE;
|
||||
memset(&mis_current, 0, sizeof(MigrationIncomingState));
|
||||
QLIST_INIT(&mis_current.loadvm_handlers);
|
||||
qemu_mutex_init(&mis_current.rp_mutex);
|
||||
qemu_event_init(&mis_current.main_thread_load_event, false);
|
||||
once = true;
|
||||
}
|
||||
return &mis_current;
|
||||
}
|
||||
|
||||
void migration_incoming_state_destroy(void)
|
||||
{
|
||||
qemu_event_destroy(&mis_current->main_thread_load_event);
|
||||
loadvm_free_handlers(mis_current);
|
||||
g_free(mis_current);
|
||||
mis_current = NULL;
|
||||
struct MigrationIncomingState *mis = migration_incoming_get_current();
|
||||
|
||||
qemu_event_destroy(&mis->main_thread_load_event);
|
||||
loadvm_free_handlers(mis);
|
||||
}
|
||||
|
||||
|
||||
@ -382,11 +378,11 @@ static void process_incoming_migration_bh(void *opaque)
|
||||
static void process_incoming_migration_co(void *opaque)
|
||||
{
|
||||
QEMUFile *f = opaque;
|
||||
MigrationIncomingState *mis;
|
||||
MigrationIncomingState *mis = migration_incoming_get_current();
|
||||
PostcopyState ps;
|
||||
int ret;
|
||||
|
||||
mis = migration_incoming_state_new(f);
|
||||
mis->from_src_file = f;
|
||||
postcopy_state_set(POSTCOPY_INCOMING_NONE);
|
||||
migrate_set_state(&mis->state, MIGRATION_STATUS_NONE,
|
||||
MIGRATION_STATUS_ACTIVE);
|
||||
@ -1605,6 +1601,7 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
|
||||
QIOChannelBuffer *bioc;
|
||||
QEMUFile *fb;
|
||||
int64_t time_at_stop = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
|
||||
bool restart_block = false;
|
||||
migrate_set_state(&ms->state, MIGRATION_STATUS_ACTIVE,
|
||||
MIGRATION_STATUS_POSTCOPY_ACTIVE);
|
||||
|
||||
@ -1624,6 +1621,7 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
restart_block = true;
|
||||
|
||||
/*
|
||||
* Cause any non-postcopiable, but iterative devices to
|
||||
@ -1680,6 +1678,18 @@ static int postcopy_start(MigrationState *ms, bool *old_vm_running)
|
||||
|
||||
/* <><> end of stuff going into the package */
|
||||
|
||||
/* Last point of recovery; as soon as we send the package the destination
|
||||
* can open devices and potentially start running.
|
||||
* Lets just check again we've not got any errors.
|
||||
*/
|
||||
ret = qemu_file_get_error(ms->to_dst_file);
|
||||
if (ret) {
|
||||
error_report("postcopy_start: Migration stream errored (pre package)");
|
||||
goto fail_closefb;
|
||||
}
|
||||
|
||||
restart_block = false;
|
||||
|
||||
/* Now send that blob */
|
||||
if (qemu_savevm_send_packaged(ms->to_dst_file, bioc->data, bioc->usage)) {
|
||||
goto fail_closefb;
|
||||
@ -1717,6 +1727,17 @@ fail_closefb:
|
||||
fail:
|
||||
migrate_set_state(&ms->state, MIGRATION_STATUS_POSTCOPY_ACTIVE,
|
||||
MIGRATION_STATUS_FAILED);
|
||||
if (restart_block) {
|
||||
/* A failure happened early enough that we know the destination hasn't
|
||||
* accessed block devices, so we're safe to recover.
|
||||
*/
|
||||
Error *local_err = NULL;
|
||||
|
||||
bdrv_invalidate_cache_all(&local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
}
|
||||
}
|
||||
qemu_mutex_unlock_iothread();
|
||||
return -1;
|
||||
}
|
||||
|
@ -590,8 +590,14 @@ int register_savevm_live(DeviceState *dev,
|
||||
if (dev) {
|
||||
char *id = qdev_get_dev_path(dev);
|
||||
if (id) {
|
||||
pstrcpy(se->idstr, sizeof(se->idstr), id);
|
||||
pstrcat(se->idstr, sizeof(se->idstr), "/");
|
||||
if (snprintf(se->idstr, sizeof(se->idstr), "%s/", id) >=
|
||||
sizeof(se->idstr)) {
|
||||
error_report("Path too long for VMState (%s)", id);
|
||||
g_free(id);
|
||||
g_free(se);
|
||||
|
||||
return -1;
|
||||
}
|
||||
g_free(id);
|
||||
|
||||
se->compat = g_new0(CompatEntry, 1);
|
||||
@ -656,7 +662,8 @@ void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque)
|
||||
int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
|
||||
const VMStateDescription *vmsd,
|
||||
void *opaque, int alias_id,
|
||||
int required_for_version)
|
||||
int required_for_version,
|
||||
Error **errp)
|
||||
{
|
||||
SaveStateEntry *se;
|
||||
|
||||
@ -673,9 +680,14 @@ int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
|
||||
if (dev) {
|
||||
char *id = qdev_get_dev_path(dev);
|
||||
if (id) {
|
||||
pstrcpy(se->idstr, sizeof(se->idstr), id);
|
||||
pstrcat(se->idstr, sizeof(se->idstr), "/");
|
||||
g_free(id);
|
||||
if (snprintf(se->idstr, sizeof(se->idstr), "%s/", id) >=
|
||||
sizeof(se->idstr)) {
|
||||
error_setg(errp, "Path too long for VMState (%s)", id);
|
||||
g_free(id);
|
||||
g_free(se);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
se->compat = g_new0(CompatEntry, 1);
|
||||
pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name);
|
||||
@ -1343,6 +1355,7 @@ static int loadvm_postcopy_handle_advise(MigrationIncomingState *mis)
|
||||
}
|
||||
|
||||
if (!postcopy_ram_supported_by_host()) {
|
||||
postcopy_state_set(POSTCOPY_INCOMING_NONE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2199,7 +2212,6 @@ void qmp_xen_load_devices_state(const char *filename, Error **errp)
|
||||
qio_channel_set_name(QIO_CHANNEL(ioc), "migration-xen-load-state");
|
||||
f = qemu_fopen_channel_input(QIO_CHANNEL(ioc));
|
||||
|
||||
migration_incoming_state_new(f);
|
||||
ret = qemu_loadvm_state(f);
|
||||
qemu_fclose(f);
|
||||
if (ret < 0) {
|
||||
@ -2215,6 +2227,7 @@ int load_vmstate(const char *name)
|
||||
QEMUFile *f;
|
||||
int ret;
|
||||
AioContext *aio_context;
|
||||
MigrationIncomingState *mis = migration_incoming_get_current();
|
||||
|
||||
if (!bdrv_all_can_snapshot(&bs)) {
|
||||
error_report("Device '%s' is writable but does not support snapshots.",
|
||||
@ -2265,7 +2278,7 @@ int load_vmstate(const char *name)
|
||||
}
|
||||
|
||||
qemu_system_reset(VMRESET_SILENT);
|
||||
migration_incoming_state_new(f);
|
||||
mis->from_src_file = f;
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
ret = qemu_loadvm_state(f);
|
||||
|
@ -8,7 +8,8 @@ int vmstate_register_with_alias_id(DeviceState *dev,
|
||||
int instance_id,
|
||||
const VMStateDescription *vmsd,
|
||||
void *base, int alias_id,
|
||||
int required_for_version)
|
||||
int required_for_version,
|
||||
Error **errp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user