diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-03-19 08:51:06 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-03-19 08:51:06 -0500 |
commit | 5c20f4e54a311620861c659dec29d0ee402e8b93 (patch) | |
tree | 4e35db5155d8539650df69e629cc1a009ae54579 | |
parent | 46a5801d0cb5f5ed01a4d31c0e7cc581237ed5ce (diff) | |
parent | e1c37d0e94048502f9874e6356ce7136d4b05bdb (diff) |
Merge remote-tracking branch 'qmp/queue/qmp' into staging
* qmp/queue/qmp:
qapi: Convert migrate
Purge migration of (almost) everything to do with monitors
Error: Introduce error_copy()
QError: Introduce new errors for the migration command
-rw-r--r-- | arch_init.c | 2 | ||||
-rw-r--r-- | block-migration.c | 58 | ||||
-rw-r--r-- | error.c | 13 | ||||
-rw-r--r-- | error.h | 5 | ||||
-rw-r--r-- | hmp-commands.hx | 3 | ||||
-rw-r--r-- | hmp.c | 74 | ||||
-rw-r--r-- | hmp.h | 1 | ||||
-rw-r--r-- | migration-fd.c | 2 | ||||
-rw-r--r-- | migration.c | 74 | ||||
-rw-r--r-- | migration.h | 5 | ||||
-rw-r--r-- | qapi-schema.json | 21 | ||||
-rw-r--r-- | qerror.c | 8 | ||||
-rw-r--r-- | qerror.h | 6 | ||||
-rw-r--r-- | qmp-commands.hx | 9 | ||||
-rw-r--r-- | savevm.c | 42 | ||||
-rw-r--r-- | sysemu.h | 11 | ||||
-rw-r--r-- | vmstate.h | 3 |
17 files changed, 205 insertions, 132 deletions
diff --git a/arch_init.c b/arch_init.c index a95ef495fe..595badf50f 100644 --- a/arch_init.c +++ b/arch_init.c @@ -260,7 +260,7 @@ static void sort_ram_list(void) g_free(blocks); } -int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) +int ram_save_live(QEMUFile *f, int stage, void *opaque) { ram_addr_t addr; uint64_t bytes_transferred_last; diff --git a/block-migration.c b/block-migration.c index 4467468506..fd2ffff0d5 100644 --- a/block-migration.c +++ b/block-migration.c @@ -18,7 +18,6 @@ #include "hw/hw.h" #include "qemu-queue.h" #include "qemu-timer.h" -#include "monitor.h" #include "block-migration.h" #include "migration.h" #include "blockdev.h" @@ -204,8 +203,7 @@ static void blk_mig_read_cb(void *opaque, int ret) assert(block_mig_state.submitted >= 0); } -static int mig_save_device_bulk(Monitor *mon, QEMUFile *f, - BlkMigDevState *bmds) +static int mig_save_device_bulk(QEMUFile *f, BlkMigDevState *bmds) { int64_t total_sectors = bmds->total_sectors; int64_t cur_sector = bmds->cur_sector; @@ -272,7 +270,6 @@ static void set_dirty_tracking(int enable) static void init_blk_migration_it(void *opaque, BlockDriverState *bs) { - Monitor *mon = opaque; BlkMigDevState *bmds; int64_t sectors; @@ -295,19 +292,17 @@ static void init_blk_migration_it(void *opaque, BlockDriverState *bs) block_mig_state.total_sector_sum += sectors; if (bmds->shared_base) { - monitor_printf(mon, "Start migration for %s with shared base " - "image\n", - bs->device_name); + DPRINTF("Start migration for %s with shared base image\n", + bs->device_name); } else { - monitor_printf(mon, "Start full migration for %s\n", - bs->device_name); + DPRINTF("Start full migration for %s\n", bs->device_name); } QSIMPLEQ_INSERT_TAIL(&block_mig_state.bmds_list, bmds, entry); } } -static void init_blk_migration(Monitor *mon, QEMUFile *f) +static void init_blk_migration(QEMUFile *f) { block_mig_state.submitted = 0; block_mig_state.read_done = 0; @@ -318,10 +313,10 @@ static void init_blk_migration(Monitor *mon, QEMUFile *f) block_mig_state.total_time = 0; block_mig_state.reads = 0; - bdrv_iterate(init_blk_migration_it, mon); + bdrv_iterate(init_blk_migration_it, NULL); } -static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f) +static int blk_mig_save_bulked_block(QEMUFile *f) { int64_t completed_sector_sum = 0; BlkMigDevState *bmds; @@ -330,7 +325,7 @@ static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f) QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { if (bmds->bulk_completed == 0) { - if (mig_save_device_bulk(mon, f, bmds) == 1) { + if (mig_save_device_bulk(f, bmds) == 1) { /* completed bulk section for this device */ bmds->bulk_completed = 1; } @@ -352,8 +347,7 @@ static int blk_mig_save_bulked_block(Monitor *mon, QEMUFile *f) block_mig_state.prev_progress = progress; qemu_put_be64(f, (progress << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS); - monitor_printf(mon, "Completed %d %%\r", progress); - monitor_flush(mon); + DPRINTF("Completed %d %%\r", progress); } return ret; @@ -368,8 +362,8 @@ static void blk_mig_reset_dirty_cursor(void) } } -static int mig_save_device_dirty(Monitor *mon, QEMUFile *f, - BlkMigDevState *bmds, int is_async) +static int mig_save_device_dirty(QEMUFile *f, BlkMigDevState *bmds, + int is_async) { BlkMigBlock *blk; int64_t total_sectors = bmds->total_sectors; @@ -428,20 +422,20 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f, return (bmds->cur_dirty >= bmds->total_sectors); error: - monitor_printf(mon, "Error reading sector %" PRId64 "\n", sector); + DPRINTF("Error reading sector %" PRId64 "\n", sector); qemu_file_set_error(f, ret); g_free(blk->buf); g_free(blk); return 0; } -static int blk_mig_save_dirty_block(Monitor *mon, QEMUFile *f, int is_async) +static int blk_mig_save_dirty_block(QEMUFile *f, int is_async) { BlkMigDevState *bmds; int ret = 0; QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) { - if (mig_save_device_dirty(mon, f, bmds, is_async) == 0) { + if (mig_save_device_dirty(f, bmds, is_async) == 0) { ret = 1; break; } @@ -520,7 +514,7 @@ static int is_stage2_completed(void) return 0; } -static void blk_mig_cleanup(Monitor *mon) +static void blk_mig_cleanup(void) { BlkMigDevState *bmds; BlkMigBlock *blk; @@ -540,11 +534,9 @@ static void blk_mig_cleanup(Monitor *mon) g_free(blk->buf); g_free(blk); } - - monitor_printf(mon, "\n"); } -static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) +static int block_save_live(QEMUFile *f, int stage, void *opaque) { int ret; @@ -552,7 +544,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) stage, block_mig_state.submitted, block_mig_state.transferred); if (stage < 0) { - blk_mig_cleanup(mon); + blk_mig_cleanup(); return 0; } @@ -563,7 +555,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) } if (stage == 1) { - init_blk_migration(mon, f); + init_blk_migration(f); /* start track dirty blocks */ set_dirty_tracking(1); @@ -573,7 +565,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) ret = qemu_file_get_error(f); if (ret) { - blk_mig_cleanup(mon); + blk_mig_cleanup(); return ret; } @@ -586,12 +578,12 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) qemu_file_get_rate_limit(f)) { if (block_mig_state.bulk_completed == 0) { /* first finish the bulk phase */ - if (blk_mig_save_bulked_block(mon, f) == 0) { + if (blk_mig_save_bulked_block(f) == 0) { /* finished saving bulk on all devices */ block_mig_state.bulk_completed = 1; } } else { - if (blk_mig_save_dirty_block(mon, f, 1) == 0) { + if (blk_mig_save_dirty_block(f, 1) == 0) { /* no more dirty blocks */ break; } @@ -602,7 +594,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) ret = qemu_file_get_error(f); if (ret) { - blk_mig_cleanup(mon); + blk_mig_cleanup(); return ret; } } @@ -612,8 +604,8 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) all async read completed */ assert(block_mig_state.submitted == 0); - while (blk_mig_save_dirty_block(mon, f, 0) != 0); - blk_mig_cleanup(mon); + while (blk_mig_save_dirty_block(f, 0) != 0); + blk_mig_cleanup(); /* report completion */ qemu_put_be64(f, (100 << BDRV_SECTOR_BITS) | BLK_MIG_FLAG_PROGRESS); @@ -623,7 +615,7 @@ static int block_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque) return ret; } - monitor_printf(mon, "Block migration completed\n"); + DPRINTF("Block migration completed\n"); } qemu_put_be64(f, BLK_MIG_FLAG_EOS); @@ -43,6 +43,19 @@ void error_set(Error **errp, const char *fmt, ...) *errp = err; } +Error *error_copy(const Error *err) +{ + Error *err_new; + + err_new = g_malloc0(sizeof(*err)); + err_new->msg = g_strdup(err->msg); + err_new->fmt = err->fmt; + err_new->obj = err->obj; + QINCREF(err_new->obj); + + return err_new; +} + bool error_is_set(Error **errp) { return (errp && *errp); @@ -35,6 +35,11 @@ void error_set(Error **err, const char *fmt, ...) GCC_FMT_ATTR(2, 3); bool error_is_set(Error **err); /** + * Returns an exact copy of the error passed as an argument. + */ +Error *error_copy(const Error *err); + +/** * Get a human readable representation of an error object. */ const char *error_get_pretty(Error *err); diff --git a/hmp-commands.hx b/hmp-commands.hx index 6980214a1a..bd35a3eb08 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -806,8 +806,7 @@ ETEXI " full copy of disk\n\t\t\t -i for migration without " "shared storage with incremental copy of disk " "(base image shared between src and destination)", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_migrate, + .mhandler.cmd = hmp_migrate, }, @@ -14,6 +14,7 @@ */ #include "hmp.h" +#include "qemu-timer.h" #include "qmp-commands.h" static void hmp_handle_error(Monitor *mon, Error **errp) @@ -860,3 +861,76 @@ void hmp_block_job_cancel(Monitor *mon, const QDict *qdict) hmp_handle_error(mon, &error); } + +typedef struct MigrationStatus +{ + QEMUTimer *timer; + Monitor *mon; + bool is_block_migration; +} MigrationStatus; + +static void hmp_migrate_status_cb(void *opaque) +{ + MigrationStatus *status = opaque; + MigrationInfo *info; + + info = qmp_query_migrate(NULL); + if (!info->has_status || strcmp(info->status, "active") == 0) { + if (info->has_disk) { + int progress; + + if (info->disk->remaining) { + progress = info->disk->transferred * 100 / info->disk->total; + } else { + progress = 100; + } + + monitor_printf(status->mon, "Completed %d %%\r", progress); + monitor_flush(status->mon); + } + + qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock) + 1000); + } else { + if (status->is_block_migration) { + monitor_printf(status->mon, "\n"); + } + monitor_resume(status->mon); + qemu_del_timer(status->timer); + g_free(status); + } + + qapi_free_MigrationInfo(info); +} + +void hmp_migrate(Monitor *mon, const QDict *qdict) +{ + int detach = qdict_get_try_bool(qdict, "detach", 0); + int blk = qdict_get_try_bool(qdict, "blk", 0); + int inc = qdict_get_try_bool(qdict, "inc", 0); + const char *uri = qdict_get_str(qdict, "uri"); + Error *err = NULL; + + qmp_migrate(uri, !!blk, blk, !!inc, inc, false, false, &err); + if (err) { + monitor_printf(mon, "migrate: %s\n", error_get_pretty(err)); + error_free(err); + return; + } + + if (!detach) { + MigrationStatus *status; + + if (monitor_suspend(mon) < 0) { + monitor_printf(mon, "terminal does not allow synchronous " + "migration, continuing detached\n"); + return; + } + + status = g_malloc0(sizeof(*status)); + status->mon = mon; + status->is_block_migration = blk || inc; + status->timer = qemu_new_timer_ms(rt_clock, hmp_migrate_status_cb, + status); + qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock)); + } +} @@ -59,5 +59,6 @@ void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict); void hmp_block_stream(Monitor *mon, const QDict *qdict); void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict); void hmp_block_job_cancel(Monitor *mon, const QDict *qdict); +void hmp_migrate(Monitor *mon, const QDict *qdict); #endif diff --git a/migration-fd.c b/migration-fd.c index 5a068c632a..50138edb34 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -75,7 +75,7 @@ static int fd_close(MigrationState *s) int fd_start_outgoing_migration(MigrationState *s, const char *fdname) { - s->fd = monitor_get_fd(s->mon, fdname); + s->fd = monitor_get_fd(cur_mon, fdname); if (s->fd == -1) { DPRINTF("fd_migration: invalid file descriptor identifier\n"); goto err_after_get_fd; diff --git a/migration.c b/migration.c index 00fa1e3f72..8c119ba8ff 100644 --- a/migration.c +++ b/migration.c @@ -158,16 +158,6 @@ MigrationInfo *qmp_query_migrate(Error **errp) /* shared migration helpers */ -static void migrate_fd_monitor_suspend(MigrationState *s, Monitor *mon) -{ - if (monitor_suspend(mon) == 0) { - DPRINTF("suspending monitor\n"); - } else { - monitor_printf(mon, "terminal does not allow synchronous " - "migration, continuing detached\n"); - } -} - static int migrate_fd_cleanup(MigrationState *s) { int ret = 0; @@ -178,10 +168,6 @@ static int migrate_fd_cleanup(MigrationState *s) DPRINTF("closing file\n"); ret = qemu_fclose(s->file); s->file = NULL; - } else { - if (s->mon) { - monitor_resume(s->mon); - } } if (s->fd != -1) { @@ -258,7 +244,7 @@ static void migrate_fd_put_ready(void *opaque) } DPRINTF("iterate\n"); - ret = qemu_savevm_state_iterate(s->mon, s->file); + ret = qemu_savevm_state_iterate(s->file); if (ret < 0) { migrate_fd_error(s); } else if (ret == 1) { @@ -267,7 +253,7 @@ static void migrate_fd_put_ready(void *opaque) DPRINTF("done iterating\n"); vm_stop_force_state(RUN_STATE_FINISH_MIGRATE); - if (qemu_savevm_state_complete(s->mon, s->file) < 0) { + if (qemu_savevm_state_complete(s->file) < 0) { migrate_fd_error(s); } else { migrate_fd_completed(s); @@ -289,7 +275,7 @@ static void migrate_fd_cancel(MigrationState *s) s->state = MIG_STATE_CANCELLED; notifier_list_notify(&migration_state_notifiers, s); - qemu_savevm_state_cancel(s->mon, s->file); + qemu_savevm_state_cancel(s->file); migrate_fd_cleanup(s); } @@ -321,9 +307,6 @@ static int migrate_fd_close(void *opaque) { MigrationState *s = opaque; - if (s->mon) { - monitor_resume(s->mon); - } qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); return s->close(s); } @@ -367,7 +350,7 @@ void migrate_fd_connect(MigrationState *s) migrate_fd_close); DPRINTF("beginning savevm\n"); - ret = qemu_savevm_state_begin(s->mon, s->file, s->blk, s->shared); + ret = qemu_savevm_state_begin(s->file, s->blk, s->shared); if (ret < 0) { DPRINTF("failed, %d\n", ret); migrate_fd_error(s); @@ -376,7 +359,7 @@ void migrate_fd_connect(MigrationState *s) migrate_fd_put_ready(s); } -static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc) +static MigrationState *migrate_init(int blk, int inc) { MigrationState *s = migrate_get_current(); int64_t bandwidth_limit = s->bandwidth_limit; @@ -386,18 +369,9 @@ static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc) s->blk = blk; s->shared = inc; - /* s->mon is used for two things: - - pass fd in fd migration - - suspend/resume monitor for not detached migration - */ - s->mon = mon; s->bandwidth_limit = bandwidth_limit; s->state = MIG_STATE_SETUP; - if (!detach) { - migrate_fd_monitor_suspend(s, mon); - } - return s; } @@ -413,32 +387,29 @@ void migrate_del_blocker(Error *reason) migration_blockers = g_slist_remove(migration_blockers, reason); } -int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) +void qmp_migrate(const char *uri, bool has_blk, bool blk, + bool has_inc, bool inc, bool has_detach, bool detach, + Error **errp) { MigrationState *s = migrate_get_current(); const char *p; - int detach = qdict_get_try_bool(qdict, "detach", 0); - int blk = qdict_get_try_bool(qdict, "blk", 0); - int inc = qdict_get_try_bool(qdict, "inc", 0); - const char *uri = qdict_get_str(qdict, "uri"); int ret; if (s->state == MIG_STATE_ACTIVE) { - monitor_printf(mon, "migration already in progress\n"); - return -1; + error_set(errp, QERR_MIGRATION_ACTIVE); + return; } - if (qemu_savevm_state_blocked(mon)) { - return -1; + if (qemu_savevm_state_blocked(errp)) { + return; } if (migration_blockers) { - Error *err = migration_blockers->data; - qerror_report_err(err); - return -1; + *errp = error_copy(migration_blockers->data); + return; } - s = migrate_init(mon, detach, blk, inc); + s = migrate_init(blk, inc); if (strstart(uri, "tcp:", &p)) { ret = tcp_start_outgoing_migration(s, p); @@ -451,21 +422,18 @@ int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) ret = fd_start_outgoing_migration(s, p); #endif } else { - monitor_printf(mon, "unknown migration protocol: %s\n", uri); - ret = -EINVAL; + error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol"); + return; } if (ret < 0) { - monitor_printf(mon, "migration failed: %s\n", strerror(-ret)); - return ret; - } - - if (detach) { - s->mon = NULL; + DPRINTF("migration failed: %s\n", strerror(-ret)); + /* FIXME: we should return meaningful errors */ + error_set(errp, QERR_UNDEFINED_ERROR); + return; } notifier_list_notify(&migration_state_notifiers, s); - return 0; } void qmp_migrate_cancel(Error **errp) diff --git a/migration.h b/migration.h index 372b066b48..691b367389 100644 --- a/migration.h +++ b/migration.h @@ -26,7 +26,6 @@ struct MigrationState int64_t bandwidth_limit; QEMUFile *file; int fd; - Monitor *mon; int state; int (*get_error)(MigrationState *s); int (*close)(MigrationState *s); @@ -40,8 +39,6 @@ void process_incoming_migration(QEMUFile *f); int qemu_start_incoming_migration(const char *uri); -int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data); - uint64_t migrate_max_downtime(void); void do_info_migrate_print(Monitor *mon, const QObject *data); @@ -78,7 +75,7 @@ uint64_t ram_bytes_remaining(void); uint64_t ram_bytes_transferred(void); uint64_t ram_bytes_total(void); -int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque); +int ram_save_live(QEMUFile *f, int stage, void *opaque); int ram_load(QEMUFile *f, void *opaque, int version_id); /** diff --git a/qapi-schema.json b/qapi-schema.json index 04fa84fbde..3a962c1b40 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1663,3 +1663,24 @@ { 'command': 'qom-list-types', 'data': { '*implements': 'str', '*abstract': 'bool' }, 'returns': [ 'ObjectTypeInfo' ] } + +## +# @migrate +# +# Migrates the current running guest to another Virtual Machine. +# +# @uri: the Uniform Resource Identifier of the destination VM +# +# @blk: #optional do block migration (full disk copy) +# +# @inc: #optional incremental disk copy migration +# +# @detach: this argument exists only for compatibility reasons and +# is ignored by QEMU +# +# Returns: nothing on success +# +# Since: 0.14.0 +## +{ 'command': 'migrate', + 'data': {'uri': 'str', '*blk': 'bool', '*inc': 'bool', '*detach': 'bool' } } @@ -193,6 +193,14 @@ static const QErrorStringTable qerror_table[] = { .desc = "Using KVM without %(capability), %(feature) unavailable", }, { + .error_fmt = QERR_MIGRATION_ACTIVE, + .desc = "There's a migration process in progress", + }, + { + .error_fmt = QERR_MIGRATION_NOT_SUPPORTED, + .desc = "State blocked by non-migratable device '%(device)'", + }, + { .error_fmt = QERR_MIGRATION_EXPECTED, .desc = "An incoming migration is expected before this command can be executed", }, @@ -166,6 +166,12 @@ QError *qobject_to_qerror(const QObject *obj); #define QERR_KVM_MISSING_CAP \ "{ 'class': 'KVMMissingCap', 'data': { 'capability': %s, 'feature': %s } }" +#define QERR_MIGRATION_ACTIVE \ + "{ 'class': 'MigrationActive', 'data': {} }" + +#define QERR_MIGRATION_NOT_SUPPORTED \ + "{ 'class': 'MigrationNotSupported', 'data': {'device': %s} }" + #define QERR_MIGRATION_EXPECTED \ "{ 'class': 'MigrationExpected', 'data': {} }" diff --git a/qmp-commands.hx b/qmp-commands.hx index dfe8a5b40b..8b820382bc 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -446,14 +446,7 @@ EQMP { .name = "migrate", .args_type = "detach:-d,blk:-b,inc:-i,uri:s", - .params = "[-d] [-b] [-i] uri", - .help = "migrate to URI (using -d to not wait for completion)" - "\n\t\t\t -b for migration without shared storage with" - " full copy of disk\n\t\t\t -i for migration without " - "shared storage with incremental copy of disk " - "(base image shared between src and destination)", - .user_print = monitor_user_noop, - .mhandler.cmd_new = do_migrate, + .mhandler.cmd_new = qmp_marshal_input_migrate, }, SQMP @@ -1540,22 +1540,20 @@ static void vmstate_save(QEMUFile *f, SaveStateEntry *se) #define QEMU_VM_SECTION_FULL 0x04 #define QEMU_VM_SUBSECTION 0x05 -bool qemu_savevm_state_blocked(Monitor *mon) +bool qemu_savevm_state_blocked(Error **errp) { SaveStateEntry *se; QTAILQ_FOREACH(se, &savevm_handlers, entry) { if (se->no_migrate) { - monitor_printf(mon, "state blocked by non-migratable device '%s'\n", - se->idstr); + error_set(errp, QERR_MIGRATION_NOT_SUPPORTED, se->idstr); return true; } } return false; } -int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, - int shared) +int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared) { SaveStateEntry *se; int ret; @@ -1588,15 +1586,15 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, qemu_put_be32(f, se->instance_id); qemu_put_be32(f, se->version_id); - ret = se->save_live_state(mon, f, QEMU_VM_SECTION_START, se->opaque); + ret = se->save_live_state(f, QEMU_VM_SECTION_START, se->opaque); if (ret < 0) { - qemu_savevm_state_cancel(mon, f); + qemu_savevm_state_cancel(f); return ret; } } ret = qemu_file_get_error(f); if (ret != 0) { - qemu_savevm_state_cancel(mon, f); + qemu_savevm_state_cancel(f); } return ret; @@ -1609,7 +1607,7 @@ int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, * 0 : We haven't finished, caller have to go again * 1 : We have finished, we can go to complete phase */ -int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) +int qemu_savevm_state_iterate(QEMUFile *f) { SaveStateEntry *se; int ret = 1; @@ -1622,7 +1620,7 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) qemu_put_byte(f, QEMU_VM_SECTION_PART); qemu_put_be32(f, se->section_id); - ret = se->save_live_state(mon, f, QEMU_VM_SECTION_PART, se->opaque); + ret = se->save_live_state(f, QEMU_VM_SECTION_PART, se->opaque); if (ret <= 0) { /* Do not proceed to the next vmstate before this one reported completion of the current stage. This serializes the migration @@ -1636,12 +1634,12 @@ int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f) } ret = qemu_file_get_error(f); if (ret != 0) { - qemu_savevm_state_cancel(mon, f); + qemu_savevm_state_cancel(f); } return ret; } -int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) +int qemu_savevm_state_complete(QEMUFile *f) { SaveStateEntry *se; int ret; @@ -1656,7 +1654,7 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) qemu_put_byte(f, QEMU_VM_SECTION_END); qemu_put_be32(f, se->section_id); - ret = se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque); + ret = se->save_live_state(f, QEMU_VM_SECTION_END, se->opaque); if (ret < 0) { return ret; } @@ -1688,37 +1686,37 @@ int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f) return qemu_file_get_error(f); } -void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f) +void qemu_savevm_state_cancel(QEMUFile *f) { SaveStateEntry *se; QTAILQ_FOREACH(se, &savevm_handlers, entry) { if (se->save_live_state) { - se->save_live_state(mon, f, -1, se->opaque); + se->save_live_state(f, -1, se->opaque); } } } -static int qemu_savevm_state(Monitor *mon, QEMUFile *f) +static int qemu_savevm_state(QEMUFile *f) { int ret; - if (qemu_savevm_state_blocked(mon)) { + if (qemu_savevm_state_blocked(NULL)) { ret = -EINVAL; goto out; } - ret = qemu_savevm_state_begin(mon, f, 0, 0); + ret = qemu_savevm_state_begin(f, 0, 0); if (ret < 0) goto out; do { - ret = qemu_savevm_state_iterate(mon, f); + ret = qemu_savevm_state_iterate(f); if (ret < 0) goto out; } while (ret == 0); - ret = qemu_savevm_state_complete(mon, f); + ret = qemu_savevm_state_complete(f); out: if (ret == 0) { @@ -1837,7 +1835,7 @@ int qemu_loadvm_state(QEMUFile *f) unsigned int v; int ret; - if (qemu_savevm_state_blocked(default_mon)) { + if (qemu_savevm_state_blocked(NULL)) { return -EINVAL; } @@ -2081,7 +2079,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) monitor_printf(mon, "Could not open VM state file\n"); goto the_end; } - ret = qemu_savevm_state(mon, f); + ret = qemu_savevm_state(f); vm_state_size = qemu_ftell(f); qemu_fclose(f); if (ret < 0) { @@ -76,12 +76,11 @@ void do_info_snapshots(Monitor *mon); void qemu_announce_self(void); -bool qemu_savevm_state_blocked(Monitor *mon); -int qemu_savevm_state_begin(Monitor *mon, QEMUFile *f, int blk_enable, - int shared); -int qemu_savevm_state_iterate(Monitor *mon, QEMUFile *f); -int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f); -void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f); +bool qemu_savevm_state_blocked(Error **errp); +int qemu_savevm_state_begin(QEMUFile *f, int blk_enable, int shared); +int qemu_savevm_state_iterate(QEMUFile *f); +int qemu_savevm_state_complete(QEMUFile *f); +void qemu_savevm_state_cancel(QEMUFile *f); int qemu_loadvm_state(QEMUFile *f); /* SLIRP */ @@ -28,8 +28,7 @@ typedef void SaveSetParamsHandler(int blk_enable, int shared, void * opaque); typedef void SaveStateHandler(QEMUFile *f, void *opaque); -typedef int SaveLiveStateHandler(Monitor *mon, QEMUFile *f, int stage, - void *opaque); +typedef int SaveLiveStateHandler(QEMUFile *f, int stage, void *opaque); typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id); int register_savevm(DeviceState *dev, |