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>
stable-2.9
Peter Maydell 2017-02-07 15:29:26 +00:00
commit d0dff238a8
7 changed files with 77 additions and 37 deletions

View File

@ -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) {

View File

@ -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)

View File

@ -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);
/*

View File

@ -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,

View File

@ -111,32 +111,28 @@ MigrationState *migrate_get_current(void)
return &current_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;
}

View File

@ -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);

View File

@ -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;
}