From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 3/3] add live dumping capability
Date: Thu, 9 Jul 2009 13:47:39 +0200 [thread overview]
Message-ID: <1247140059-5034-4-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1247140059-5034-1-git-send-email-pbonzini@redhat.com>
With the previous cleanups in place, it is easy to trigger
restart when the state machine goes from the COMPLETING to the
COMPLETED state. Besides this, the patch is just simple
scaffolding for the monitor command and to migrate to a file
rather than a pipe (which is a bit simpler because we do not
need non-blocking I/O).
The patch reuses most of the code in migration-exec.c. The
functions there were half named exec_* and the other half
named file_*. I consistently adopted file_* for what can be used
for dumping, and exec_* when the function is different in the
two cases.
---
Cancelling a dump will leave a half-created file. I
can fix this in a v2 or in a follow-up. Right now,
I would like to make sure that the idea is sound and
agree on the name of the new monitor command (if
anything).
migration-exec.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
migration.c | 26 +++++++++++++++++++++++++-
migration.h | 7 +++++++
qemu-monitor.hx | 8 ++++++++
4 files changed, 83 insertions(+), 6 deletions(-)
diff --git a/migration-exec.c b/migration-exec.c
index cfa1304..95642dc 100644
--- a/migration-exec.c
+++ b/migration-exec.c
@@ -36,14 +36,20 @@ static int file_errno(FdMigrationState *s)
return errno;
}
-static int file_write(FdMigrationState *s, const void * buf, size_t size)
+static int exec_write(FdMigrationState *s, const void * buf, size_t size)
{
return write(s->fd, buf, size);
}
-static int exec_close(FdMigrationState *s)
+static int file_write(FdMigrationState *s, const void * buf, size_t size)
+{
+ qemu_put_buffer(s->opaque, buf, size);
+ return size;
+}
+
+static int file_close(FdMigrationState *s)
{
- dprintf("exec_close\n");
+ dprintf("file_close\n");
if (s->opaque) {
qemu_fclose(s->opaque);
s->opaque = NULL;
@@ -80,9 +86,9 @@ MigrationState *exec_start_outgoing_migration(const char *command,
s->opaque = qemu_popen(f, "w");
- s->close = exec_close;
+ s->close = file_close;
s->get_error = file_errno;
- s->write = file_write;
+ s->write = exec_write;
s->bandwidth_limit = bandwidth_limit;
@@ -138,3 +144,35 @@ int exec_start_incoming_migration(const char *command)
return 0;
}
+
+MigrationState *start_live_dump(const char *file,
+ int64_t bandwidth_limit,
+ int detach)
+{
+ FdMigrationState *s;
+ FILE *f;
+
+ s = qemu_mallocz(sizeof(*s));
+
+ s->opaque = qemu_fopen(file, "wb");
+ if (!s->opaque)
+ goto err_after_alloc;
+
+ s->close = file_close;
+ s->get_error = file_errno;
+ s->write = file_write;
+ s->bandwidth_limit = bandwidth_limit;
+
+ migrate_fd_init(s);
+ s->mig_state.restart_after = 1;
+ if (!detach)
+ migrate_monitor_suspend(&s->mig_state);
+
+ migrate_fd_connect(s);
+ return &s->mig_state;
+
+ pclose(f);
+err_after_alloc:
+ qemu_free(s);
+ return NULL;
+}
diff --git a/migration.c b/migration.c
index 96585dd..beed034 100644
--- a/migration.c
+++ b/migration.c
@@ -72,6 +72,29 @@ void do_migrate(Monitor *mon, int detach, const char *uri)
}
}
+void do_dump(Monitor *mon, int detach, const char *file)
+{
+ MigrationState *s;
+
+ if (current_migration) {
+ if (current_migration->state == MIG_STATE_ACTIVE) {
+ monitor_printf(mon, "migration in progress, cannot dump\n");
+ return;
+ }
+ }
+
+ s = start_live_dump(file, max_throttle, detach);
+
+ if (s == NULL)
+ monitor_printf(mon, "dump failed\n");
+ else {
+ if (current_migration)
+ current_migration->release(current_migration);
+
+ current_migration = s;
+ }
+}
+
void do_migrate_cancel(Monitor *mon)
{
MigrationState *s = current_migration;
@@ -302,7 +325,8 @@ void migrate_set_state(MigrationState *s, int state)
if (s->mon_resume)
monitor_resume(s->mon_resume);
- if (s->save_vm_running && state != MIG_STATE_COMPLETED)
+ if (s->save_vm_running &&
+ (state != MIG_STATE_COMPLETED || s->restart_after))
vm_start();
break;
}
diff --git a/migration.h b/migration.h
index c44bd75..17dea30 100644
--- a/migration.h
+++ b/migration.h
@@ -28,6 +28,7 @@ struct MigrationState
{
Monitor *mon_resume;
int state;
+ int restart_after;
int save_vm_running;
/* FIXME: add more accessors to print migration info */
@@ -52,6 +53,8 @@ struct FdMigrationState
void qemu_start_incoming_migration(const char *uri);
+void do_dump(Monitor *mon, int detach, const char *file);
+
void do_migrate(Monitor *mon, int detach, const char *uri);
void do_migrate_cancel(Monitor *mon);
@@ -64,6 +67,10 @@ void do_migrate_set_downtime(Monitor *mon, const char *value);
void do_info_migrate(Monitor *mon);
+MigrationState *start_live_dump(const char *file,
+ int64_t bandwidth_limit,
+ int detach);
+
int exec_start_incoming_migration(const char *host_port);
MigrationState *exec_start_outgoing_migration(const char *host_port,
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index dc10b75..86ec3a9 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -463,6 +463,14 @@ STEXI
Inject an NMI on the given CPU (x86 only).
ETEXI
+ { "dump", "-dF", do_dump,
+ "[-d] file", "dump the VM state to FILE (using -d to not wait for completion)" },
+STEXI
+@item dump [-d] @var{file}
+Dump the state of the running VM to @var{file} (using -d to not wait for
+completion). Commands that act on migration can be used for dumps too.
+ETEXI
+
{ "migrate", "-ds", do_migrate,
"[-d] uri", "migrate to URI (using -d to not wait for completion)" },
STEXI
--
1.5.5.6
next prev parent reply other threads:[~2009-07-09 11:47 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-09 11:47 [Qemu-devel] [PATCH 0/3] add "core dump"-like capability Paolo Bonzini
2009-07-09 11:47 ` [Qemu-devel] [PATCH 1/3] move state and mon_resume to struct MigrationState Paolo Bonzini
2009-07-09 11:47 ` [Qemu-devel] [PATCH 2/3] move vm stop/start to migrate_set_state Paolo Bonzini
2009-07-09 13:45 ` Anthony Liguori
2009-07-09 13:48 ` Paolo Bonzini
2009-07-09 13:53 ` Anthony Liguori
2009-07-09 13:58 ` Paolo Bonzini
2009-07-09 14:41 ` Anthony Liguori
2009-07-10 23:14 ` Jamie Lokier
2009-07-11 0:04 ` malc
2009-07-11 0:42 ` Jamie Lokier
2009-07-11 0:55 ` Anthony Liguori
2009-07-11 0:58 ` Anthony Liguori
2009-07-11 1:42 ` Jamie Lokier
2009-07-12 3:31 ` Anthony Liguori
2009-07-12 14:22 ` Avi Kivity
2009-07-12 19:10 ` Anthony Liguori
2009-07-12 19:30 ` Avi Kivity
2009-07-13 5:31 ` Gleb Natapov
2009-07-13 8:05 ` Gleb Natapov
2009-07-13 14:52 ` Anthony Liguori
2009-07-14 8:48 ` Dor Laor
2009-07-14 14:41 ` Paolo Bonzini
2009-07-09 11:47 ` Paolo Bonzini [this message]
2009-07-09 13:49 ` [Qemu-devel] [PATCH 3/3] add live dumping capability Anthony Liguori
2009-07-09 14:06 ` Paolo Bonzini
2009-07-09 14:43 ` Anthony Liguori
2009-07-10 8:32 ` Paolo Bonzini
2009-07-10 12:51 ` Anthony Liguori
2009-07-09 13:42 ` [Qemu-devel] [PATCH 0/3] add "core dump"-like capability Anthony Liguori
2009-07-09 13:46 ` Paolo Bonzini
2009-07-09 13:51 ` Anthony Liguori
2009-07-09 14:46 ` Gerd Hoffmann
2009-07-09 16:20 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1247140059-5034-4-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).