Commit d0dff238 authored by Peter Maydell's avatar Peter Maydell
Browse files

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: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 3c457da1 ef8d6488
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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,
            if (vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev,
                                               dev->instance_id_alias,
                                           dev->alias_required_for_version);
                                               dev->alias_required_for_version,
                                               &local_err) < 0) {
                goto post_realize_fail;
            }
        }

        QLIST_FOREACH(bus, &dev->child_bus, sibling) {
+1 −1
Original line number Diff line number Diff line
@@ -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)
+0 −1
Original line number Diff line number Diff line
@@ -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);

/*
+5 −2
Original line number Diff line number Diff line
@@ -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,
+42 −21
Original line number Diff line number Diff line
@@ -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;
}

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);
    static bool once;
    static MigrationIncomingState mis_current;

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