Usage: (qemu) migrate file:/path/to/vm_statefile Signed-off-by: Benoit Canet <ben...@irqsave.net> --- migration-fd.c | 4 ++-- migration.c | 20 +++++++++++++++++++- migration.h | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/migration-fd.c b/migration-fd.c index 50138ed..d39e44a 100644 --- a/migration-fd.c +++ b/migration-fd.c @@ -73,9 +73,9 @@ static int fd_close(MigrationState *s) return 0; } -int fd_start_outgoing_migration(MigrationState *s, const char *fdname) +int fd_start_outgoing_migration(MigrationState *s, const char *fdname, int fd) { - s->fd = monitor_get_fd(cur_mon, fdname); + s->fd = fd ? 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 1edeec5..679847d 100644 --- a/migration.c +++ b/migration.c @@ -239,9 +239,14 @@ void qmp_migrate_set_capabilities(MigrationCapabilityStatusList *params, static int migrate_fd_cleanup(MigrationState *s) { int ret = 0; + struct stat st; qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); + if (!fstat(s->fd, &st) && S_ISREG(st.st_mode)) { + fsync(s->fd); + } + if (s->file) { DPRINTF("closing file\n"); ret = qemu_fclose(s->file); @@ -475,6 +480,17 @@ void migrate_del_blocker(Error *reason) migration_blockers = g_slist_remove(migration_blockers, reason); } +static int file_start_outgoing_migration(MigrationState *s, + const char *filename) +{ + int fd; + fd = open(filename, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR); + if (fd < 0) { + return -errno; + } + return fd_start_outgoing_migration(s, NULL, fd); +} + void qmp_migrate(const char *uri, bool has_blk, bool blk, bool has_inc, bool inc, bool has_detach, bool detach, Error **errp) @@ -511,7 +527,9 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk, } else if (strstart(uri, "unix:", &p)) { ret = unix_start_outgoing_migration(s, p); } else if (strstart(uri, "fd:", &p)) { - ret = fd_start_outgoing_migration(s, p); + ret = fd_start_outgoing_migration(s, p, 0); + } else if (strstart(uri, "file:", &p)) { + ret = file_start_outgoing_migration(s, p); #endif } else { error_set(errp, QERR_INVALID_PARAMETER_VALUE, "uri", "a valid migration protocol"); diff --git a/migration.h b/migration.h index a9852fc..d431284 100644 --- a/migration.h +++ b/migration.h @@ -69,7 +69,7 @@ int unix_start_outgoing_migration(MigrationState *s, const char *path); int fd_start_incoming_migration(const char *path); -int fd_start_outgoing_migration(MigrationState *s, const char *fdname); +int fd_start_outgoing_migration(MigrationState *s, const char *fdname, int fd); void migrate_fd_error(MigrationState *s); -- 1.7.9.5