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

Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20150317' into staging



migration/next for 20150317

# gpg: Signature made Tue Mar 17 14:21:14 2015 GMT using RSA key ID 5872D723
# gpg: Can't check signature: public key not found

* remotes/juanquintela/tags/migration/20150317:
  migration: Expose 'cancelling' status to user
  migration: Convert 'status' of MigrationInfo to use an enum type
  hmp: Rename 'MigrationStatus' to 'HMPMigrationStatus'
  migration: Rename abbreviated macro MIG_STATE_* to MIGRATION_STATUS_*
  migration: Remove unused functions
  arch_init: Count the total number of pages by using helper function
  migrate_incoming: Cleanup/clarify error messages
  Warn against the use of the string as uri parameter to migrate-incoming
  migrate_incoming: use hmp_handle_error
  migration: Fix remaining 32 bit compiler errors
  migration: Fix some 32 bit compiler errors
  migration/rdma: clean up qemu_rdma_dest_init a bit
  migration: Avoid qerror_report_err() outside QMP command handlers

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents ac738ead cde63fbe
Loading
Loading
Loading
Loading
+1 −7
Original line number Diff line number Diff line
@@ -895,13 +895,7 @@ static int ram_save_setup(QEMUFile *f, void *opaque)
     * Count the total number of pages used by ram blocks not including any
     * gaps due to alignment or unplugs.
     */
    migration_dirty_pages = 0;
    QLIST_FOREACH_RCU(block, &ram_list.blocks, next) {
        uint64_t block_pages;

        block_pages = block->used_length >> TARGET_PAGE_BITS;
        migration_dirty_pages += block_pages;
    }
    migration_dirty_pages = ram_bytes_total() >> TARGET_PAGE_BITS;

    memory_global_dirty_log_start();
    migration_bitmap_sync();
+9 −12
Original line number Diff line number Diff line
@@ -162,7 +162,8 @@ void hmp_info_migrate(Monitor *mon, const QDict *qdict)
    }

    if (info->has_status) {
        monitor_printf(mon, "Migration status: %s\n", info->status);
        monitor_printf(mon, "Migration status: %s\n",
                       MigrationStatus_lookup[info->status]);
        monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
                       info->total_time);
        if (info->has_expected_downtime) {
@@ -1123,11 +1124,7 @@ void hmp_migrate_incoming(Monitor *mon, const QDict *qdict)

    qmp_migrate_incoming(uri, &err);

    if (err) {
        monitor_printf(mon, "%s\n", error_get_pretty(err));
        error_free(err);
        return;
    }
    hmp_handle_error(mon, &err);
}

void hmp_migrate_set_downtime(Monitor *mon, const QDict *qdict)
@@ -1345,21 +1342,21 @@ void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
    hmp_handle_error(mon, &error);
}

typedef struct MigrationStatus
typedef struct HMPMigrationStatus
{
    QEMUTimer *timer;
    Monitor *mon;
    bool is_block_migration;
} MigrationStatus;
} HMPMigrationStatus;

static void hmp_migrate_status_cb(void *opaque)
{
    MigrationStatus *status = opaque;
    HMPMigrationStatus *status = opaque;
    MigrationInfo *info;

    info = qmp_query_migrate(NULL);
    if (!info->has_status || strcmp(info->status, "active") == 0 ||
        strcmp(info->status, "setup") == 0) {
    if (!info->has_status || info->status == MIGRATION_STATUS_ACTIVE ||
        info->status == MIGRATION_STATUS_SETUP) {
        if (info->has_disk) {
            int progress;

@@ -1402,7 +1399,7 @@ void hmp_migrate(Monitor *mon, const QDict *qdict)
    }

    if (!detach) {
        MigrationStatus *status;
        HMPMigrationStatus *status;

        if (monitor_suspend(mon) < 0) {
            monitor_printf(mon, "terminal does not allow synchronous "
+0 −1
Original line number Diff line number Diff line
@@ -139,7 +139,6 @@ void migrate_add_blocker(Error *reason);
 */
void migrate_del_blocker(Error *reason);

bool migrate_rdma_pin_all(void);
bool migrate_zero_blocks(void);

bool migrate_auto_converge(void);
+0 −1
Original line number Diff line number Diff line
@@ -133,7 +133,6 @@ bool qemu_file_mode_is_not_valid(const char *mode);
bool qemu_file_is_writable(QEMUFile *f);

QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len);
QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *);
void qsb_free(QEMUSizedBuffer *);
size_t qsb_set_length(QEMUSizedBuffer *qsb, size_t length);
size_t qsb_get_length(const QEMUSizedBuffer *qsb);
+51 −64
Original line number Diff line number Diff line
@@ -26,16 +26,6 @@
#include "qmp-commands.h"
#include "trace.h"

enum {
    MIG_STATE_ERROR = -1,
    MIG_STATE_NONE,
    MIG_STATE_SETUP,
    MIG_STATE_CANCELLING,
    MIG_STATE_CANCELLED,
    MIG_STATE_ACTIVE,
    MIG_STATE_COMPLETED,
};

#define MAX_THROTTLE  (32 << 20)      /* Migration speed throttling */

/* Amount of time to allocate to each "chunk" of bandwidth-throttled
@@ -58,7 +48,7 @@ static bool deferred_incoming;
MigrationState *migrate_get_current(void)
{
    static MigrationState current_migration = {
        .state = MIG_STATE_NONE,
        .state = MIGRATION_STATUS_NONE,
        .bandwidth_limit = MAX_THROTTLE,
        .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE,
        .mbps = -1,
@@ -123,8 +113,7 @@ static void process_incoming_migration_co(void *opaque)
    /* Make sure all file formats flush their mutable metadata */
    bdrv_invalidate_cache_all(&local_err);
    if (local_err) {
        qerror_report_err(local_err);
        error_free(local_err);
        error_report_err(local_err);
        exit(EXIT_FAILURE);
    }

@@ -201,18 +190,16 @@ MigrationInfo *qmp_query_migrate(Error **errp)
    MigrationState *s = migrate_get_current();

    switch (s->state) {
    case MIG_STATE_NONE:
    case MIGRATION_STATUS_NONE:
        /* no migration has happened ever */
        break;
    case MIG_STATE_SETUP:
    case MIGRATION_STATUS_SETUP:
        info->has_status = true;
        info->status = g_strdup("setup");
        info->has_total_time = false;
        break;
    case MIG_STATE_ACTIVE:
    case MIG_STATE_CANCELLING:
    case MIGRATION_STATUS_ACTIVE:
    case MIGRATION_STATUS_CANCELLING:
        info->has_status = true;
        info->status = g_strdup("active");
        info->has_total_time = true;
        info->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME)
            - s->total_time;
@@ -244,11 +231,10 @@ MigrationInfo *qmp_query_migrate(Error **errp)

        get_xbzrle_cache_stats(info);
        break;
    case MIG_STATE_COMPLETED:
    case MIGRATION_STATUS_COMPLETED:
        get_xbzrle_cache_stats(info);

        info->has_status = true;
        info->status = g_strdup("completed");
        info->has_total_time = true;
        info->total_time = s->total_time;
        info->has_downtime = true;
@@ -268,15 +254,14 @@ MigrationInfo *qmp_query_migrate(Error **errp)
        info->ram->mbps = s->mbps;
        info->ram->dirty_sync_count = s->dirty_sync_count;
        break;
    case MIG_STATE_ERROR:
    case MIGRATION_STATUS_FAILED:
        info->has_status = true;
        info->status = g_strdup("failed");
        break;
    case MIG_STATE_CANCELLED:
    case MIGRATION_STATUS_CANCELLED:
        info->has_status = true;
        info->status = g_strdup("cancelled");
        break;
    }
    info->status = s->state;

    return info;
}
@@ -287,7 +272,8 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params,
    MigrationState *s = migrate_get_current();
    MigrationCapabilityStatusList *cap;

    if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP) {
    if (s->state == MIGRATION_STATUS_ACTIVE ||
        s->state == MIGRATION_STATUS_SETUP) {
        error_set(errp, QERR_MIGRATION_ACTIVE);
        return;
    }
@@ -323,12 +309,13 @@ static void migrate_fd_cleanup(void *opaque)
        s->file = NULL;
    }

    assert(s->state != MIG_STATE_ACTIVE);
    assert(s->state != MIGRATION_STATUS_ACTIVE);

    if (s->state != MIG_STATE_COMPLETED) {
    if (s->state != MIGRATION_STATUS_COMPLETED) {
        qemu_savevm_state_cancel();
        if (s->state == MIG_STATE_CANCELLING) {
            migrate_set_state(s, MIG_STATE_CANCELLING, MIG_STATE_CANCELLED);
        if (s->state == MIGRATION_STATUS_CANCELLING) {
            migrate_set_state(s, MIGRATION_STATUS_CANCELLING,
                              MIGRATION_STATUS_CANCELLED);
        }
    }

@@ -339,8 +326,8 @@ void migrate_fd_error(MigrationState *s)
{
    trace_migrate_fd_error();
    assert(s->file == NULL);
    s->state = MIG_STATE_ERROR;
    trace_migrate_set_state(MIG_STATE_ERROR);
    s->state = MIGRATION_STATUS_FAILED;
    trace_migrate_set_state(MIGRATION_STATUS_FAILED);
    notifier_list_notify(&migration_state_notifiers, s);
}

@@ -352,11 +339,12 @@ static void migrate_fd_cancel(MigrationState *s)

    do {
        old_state = s->state;
        if (old_state != MIG_STATE_SETUP && old_state != MIG_STATE_ACTIVE) {
        if (old_state != MIGRATION_STATUS_SETUP &&
            old_state != MIGRATION_STATUS_ACTIVE) {
            break;
        }
        migrate_set_state(s, old_state, MIG_STATE_CANCELLING);
    } while (s->state != MIG_STATE_CANCELLING);
        migrate_set_state(s, old_state, MIGRATION_STATUS_CANCELLING);
    } while (s->state != MIGRATION_STATUS_CANCELLING);

    /*
     * If we're unlucky the migration code might be stuck somewhere in a
@@ -365,7 +353,7 @@ static void migrate_fd_cancel(MigrationState *s)
     * The outgoing qemu file gets closed in migrate_fd_cleanup that is
     * called in a bh, so there is no race against this cancel.
     */
    if (s->state == MIG_STATE_CANCELLING && f) {
    if (s->state == MIGRATION_STATUS_CANCELLING && f) {
        qemu_file_shutdown(f);
    }
}
@@ -382,18 +370,18 @@ void remove_migration_state_change_notifier(Notifier *notify)

bool migration_in_setup(MigrationState *s)
{
    return s->state == MIG_STATE_SETUP;
    return s->state == MIGRATION_STATUS_SETUP;
}

bool migration_has_finished(MigrationState *s)
{
    return s->state == MIG_STATE_COMPLETED;
    return s->state == MIGRATION_STATUS_COMPLETED;
}

bool migration_has_failed(MigrationState *s)
{
    return (s->state == MIG_STATE_CANCELLED ||
            s->state == MIG_STATE_ERROR);
    return (s->state == MIGRATION_STATUS_CANCELLED ||
            s->state == MIGRATION_STATUS_FAILED);
}

static MigrationState *migrate_init(const MigrationParams *params)
@@ -413,8 +401,8 @@ static MigrationState *migrate_init(const MigrationParams *params)
    s->xbzrle_cache_size = xbzrle_cache_size;

    s->bandwidth_limit = bandwidth_limit;
    s->state = MIG_STATE_SETUP;
    trace_migrate_set_state(MIG_STATE_SETUP);
    s->state = MIGRATION_STATUS_SETUP;
    trace_migrate_set_state(MIGRATION_STATUS_SETUP);

    s->total_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
    return s;
@@ -435,11 +423,15 @@ void migrate_del_blocker(Error *reason)
void qmp_migrate_incoming(const char *uri, Error **errp)
{
    Error *local_err = NULL;
    static bool once = true;

    if (!deferred_incoming) {
        error_setg(errp, "'-incoming defer' is required for migrate_incoming");
        error_setg(errp, "For use with '-incoming defer'");
        return;
    }
    if (!once) {
        error_setg(errp, "The incoming migration has already been started");
    }

    qemu_start_incoming_migration(uri, &local_err);

@@ -448,7 +440,7 @@ void qmp_migrate_incoming(const char *uri, Error **errp)
        return;
    }

    deferred_incoming = false;
    once = false;
}

void qmp_migrate(const char *uri, bool has_blk, bool blk,
@@ -463,8 +455,9 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
    params.blk = has_blk && blk;
    params.shared = has_inc && inc;

    if (s->state == MIG_STATE_ACTIVE || s->state == MIG_STATE_SETUP ||
        s->state == MIG_STATE_CANCELLING) {
    if (s->state == MIGRATION_STATUS_ACTIVE ||
        s->state == MIGRATION_STATUS_SETUP ||
        s->state == MIGRATION_STATUS_CANCELLING) {
        error_set(errp, QERR_MIGRATION_ACTIVE);
        return;
    }
@@ -501,7 +494,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
#endif
    } else {
        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol");
        s->state = MIG_STATE_ERROR;
        s->state = MIGRATION_STATUS_FAILED;
        return;
    }

@@ -576,15 +569,6 @@ void qmp_migrate_set_downtime(double value, Error **errp)
    max_downtime = (uint64_t)value;
}

bool migrate_rdma_pin_all(void)
{
    MigrationState *s;

    s = migrate_get_current();

    return s->enabled_capabilities[MIGRATION_CAPABILITY_RDMA_PIN_ALL];
}

bool migrate_auto_converge(void)
{
    MigrationState *s;
@@ -636,9 +620,9 @@ static void *migration_thread(void *opaque)
    qemu_savevm_state_begin(s->file, &s->params);

    s->setup_time = qemu_clock_get_ms(QEMU_CLOCK_HOST) - setup_start;
    migrate_set_state(s, MIG_STATE_SETUP, MIG_STATE_ACTIVE);
    migrate_set_state(s, MIGRATION_STATUS_SETUP, MIGRATION_STATUS_ACTIVE);

    while (s->state == MIG_STATE_ACTIVE) {
    while (s->state == MIGRATION_STATUS_ACTIVE) {
        int64_t current_time;
        uint64_t pending_size;

@@ -663,19 +647,22 @@ static void *migration_thread(void *opaque)
                qemu_mutex_unlock_iothread();

                if (ret < 0) {
                    migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR);
                    migrate_set_state(s, MIGRATION_STATUS_ACTIVE,
                                      MIGRATION_STATUS_FAILED);
                    break;
                }

                if (!qemu_file_get_error(s->file)) {
                    migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_COMPLETED);
                    migrate_set_state(s, MIGRATION_STATUS_ACTIVE,
                                      MIGRATION_STATUS_COMPLETED);
                    break;
                }
            }
        }

        if (qemu_file_get_error(s->file)) {
            migrate_set_state(s, MIG_STATE_ACTIVE, MIG_STATE_ERROR);
            migrate_set_state(s, MIGRATION_STATUS_ACTIVE,
                              MIGRATION_STATUS_FAILED);
            break;
        }
        current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
@@ -707,7 +694,7 @@ static void *migration_thread(void *opaque)
    }

    qemu_mutex_lock_iothread();
    if (s->state == MIG_STATE_COMPLETED) {
    if (s->state == MIGRATION_STATUS_COMPLETED) {
        int64_t end_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
        uint64_t transferred_bytes = qemu_ftell(s->file);
        s->total_time = end_time - s->total_time;
@@ -730,8 +717,8 @@ static void *migration_thread(void *opaque)

void migrate_fd_connect(MigrationState *s)
{
    s->state = MIG_STATE_SETUP;
    trace_migrate_set_state(MIG_STATE_SETUP);
    s->state = MIGRATION_STATUS_SETUP;
    trace_migrate_set_state(MIGRATION_STATUS_SETUP);

    /* This is a best 1st approximation. ns to ms */
    s->expected_downtime = max_downtime/1000000;
Loading