* [Qemu-devel] [PATCH] migration: adding migration to/from a file
@ 2009-01-19 0:18 Uri Lublin
2009-01-19 0:55 ` Paul Brook
2009-01-19 15:11 ` Anthony Liguori
0 siblings, 2 replies; 11+ messages in thread
From: Uri Lublin @ 2009-01-19 0:18 UTC (permalink / raw)
To: qemu-devel; +Cc: Uri Lublin
Migration to file, reuses migration-to-fd.
Migration from file, uses qemu-fopen directly.
The saved state-file should be used only once and removed (or used
with -snapshot, or a the disk-image should be copied), as the
disk image is not saved, only the VM state.
Also there is not point of doing a _live_ migration to file (except
for debugging migration code), so I recommend to stop the VM before
migrating its state to a file.
An advantage migration-to-file over savevm/loadvm is that for the latter
a qcow2 is a requirement, while the former works for any image-format.
Signed-off-by: Uri Lublin <uril@redhat.com>
---
Makefile | 2 +-
migration-file.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
migration.c | 4 ++
migration.h | 5 ++
4 files changed, 137 insertions(+), 1 deletions(-)
create mode 100644 migration-file.c
diff --git a/Makefile b/Makefile
index 8cbdcda..7e0e6f2 100644
--- a/Makefile
+++ b/Makefile
@@ -81,7 +81,7 @@ OBJS+=usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
OBJS+=usb-serial.o usb-net.o
OBJS+=sd.o ssi-sd.o
OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
-OBJS+=buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
+OBJS+=buffered_file.o migration.o migration-tcp.o migration-file.o net.o qemu-sockets.o
OBJS+=qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o
ifdef CONFIG_BRLAPI
diff --git a/migration-file.c b/migration-file.c
new file mode 100644
index 0000000..5cde3e2
--- /dev/null
+++ b/migration-file.c
@@ -0,0 +1,127 @@
+/*
+ * QEMU live migration
+ *
+ * Copyright IBM, Corp. 2008
+ * Red Hat, Inc. 2008
+ *
+ * Authors:
+ * Anthony Liguori <aliguori@us.ibm.com>
+ * Uri Lublin <uril@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <unistd.h>
+#include "qemu-common.h"
+#include "migration.h"
+#include "sysemu.h"
+#include "console.h"
+#include "block.h"
+
+//#define DEBUG_MIGRATION_FILE
+
+#ifdef DEBUG_MIGRATION_FILE
+#define dprintf(fmt, ...) \
+ do { printf("migration-file: " fmt, ## __VA_ARGS__); } while (0)
+#else
+#define dprintf(fmt, ...) \
+ do { } while (0)
+#endif
+
+static int file_close(FdMigrationState *s)
+{
+ close(s->fd);
+}
+
+static int file_errno(FdMigrationState *s)
+{
+ return errno;
+}
+
+static int file_write(FdMigrationState *s, const void * buf, size_t size)
+{
+ return write(s->fd, buf, size);
+}
+
+MigrationState *file_start_outgoing_migration(const char *filename,
+ int64_t bandwidth_limit,
+ int async)
+{
+ FdMigrationState *s;
+ int fd;
+
+ s = qemu_mallocz(sizeof(*s));
+ if (s == NULL) {
+ perror("file_migration: qemu_mallocz failed");
+ term_printf("file_migration: qemu_mallocz failed");
+ goto err1;
+ }
+
+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd < 0) {
+ perror("file_migration: failed to open filename");
+ term_printf("file_migration: failed to open filename %s\n", filename);
+ goto err2;
+ }
+
+ s->fd = fd;
+ s->close = file_close;
+ s->get_error = file_errno;
+ s->write = file_write;
+ s->mig_state.cancel = migrate_fd_cancel;
+ s->mig_state.get_status = migrate_fd_get_status;
+ s->mig_state.release = migrate_fd_release;
+
+ s->state = MIG_STATE_ACTIVE;
+ s->detach = !async;
+ s->bandwidth_limit = bandwidth_limit;
+
+ if (s->detach == 1) {
+ dprintf("detaching from monitor\n");
+ monitor_suspend();
+ s->detach = 2;
+ }
+
+ migrate_fd_connect(s);
+ return &s->mig_state;
+
+err1:
+ close(fd);
+ unlink(filename);
+err2:
+ qemu_free(s);
+
+ return NULL;
+}
+
+int file_start_incoming_migration(const char *filename)
+{
+ int ret;
+ QEMUFile *f;
+
+ dprintf("Starting incoming file migration from '%s'\n", filename);
+ f = qemu_fopen(filename, "rb");
+ if(f == NULL) {
+ perror("failed to open file");
+ term_printf("failed to open file %s\n", filename);
+ return -errno;
+ }
+
+ vm_stop(0); /* just in case */
+ ret = qemu_loadvm_state(f);
+ if (ret < 0) {
+ fprintf(stderr, "in_file_mig: load of migration failed\n");
+ goto err;
+ }
+ qemu_announce_self();
+ dprintf("successfully loaded vm state\n");
+ vm_start();
+ qemu_fclose(f);
+ return 0;
+
+err:
+ qemu_fclose(f);
+ return -errno;
+}
diff --git a/migration.c b/migration.c
index 0ef777a..0dde557 100644
--- a/migration.c
+++ b/migration.c
@@ -44,6 +44,8 @@ void qemu_start_incoming_migration(const char *uri)
else if (strstart(uri, "exec:", &p))
exec_start_incoming_migration(p);
#endif
+ else if (strstart(uri, "file:", &p))
+ file_start_incoming_migration(p);
else
fprintf(stderr, "unknown migration protocol: %s\n", uri);
}
@@ -59,6 +61,8 @@ void do_migrate(int detach, const char *uri)
else if (strstart(uri, "exec:", &p))
s = exec_start_outgoing_migration(p, max_throttle, detach);
#endif
+ else if (strstart(uri, "file:", &p))
+ s = file_start_outgoing_migration(p, (1<<31), detach);
else
term_printf("unknown migration protocol: %s\n", uri);
diff --git a/migration.h b/migration.h
index d9771ad..30d4ab4 100644
--- a/migration.h
+++ b/migration.h
@@ -67,6 +67,11 @@ MigrationState *tcp_start_outgoing_migration(const char *host_port,
int64_t bandwidth_limit,
int detach);
+MigrationState *file_start_outgoing_migration(const char *filename,
+ int64_t bandwidth_limit,
+ int detach);
+int file_start_incoming_migration(const char *filename);
+
void migrate_fd_error(FdMigrationState *s);
void migrate_fd_cleanup(FdMigrationState *s);
--
1.6.0.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-19 0:18 [Qemu-devel] [PATCH] migration: adding migration to/from a file Uri Lublin
@ 2009-01-19 0:55 ` Paul Brook
2009-01-20 11:05 ` Uri Lublin
2009-01-19 15:11 ` Anthony Liguori
1 sibling, 1 reply; 11+ messages in thread
From: Paul Brook @ 2009-01-19 0:55 UTC (permalink / raw)
To: qemu-devel; +Cc: Uri Lublin
On Monday 19 January 2009, Uri Lublin wrote:
> Migration to file, reuses migration-to-fd.
> Migration from file, uses qemu-fopen directly.
>
> The saved state-file should be used only once and removed (or used
> with -snapshot, or a the disk-image should be copied), as the
> disk image is not saved, only the VM state.
>
> Also there is not point of doing a _live_ migration to file (except
> for debugging migration code), so I recommend to stop the VM before
> migrating its state to a file.
>
> An advantage migration-to-file over savevm/loadvm is that for the latter
> a qcow2 is a requirement, while the former works for any image-format.
Wouldn't it be better to just implement savevm to file?
Paul
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-19 0:55 ` Paul Brook
@ 2009-01-20 11:05 ` Uri Lublin
2009-01-20 14:06 ` Ian Jackson
0 siblings, 1 reply; 11+ messages in thread
From: Uri Lublin @ 2009-01-20 11:05 UTC (permalink / raw)
To: Paul Brook; +Cc: qemu-devel
Paul Brook wrote:
> On Monday 19 January 2009, Uri Lublin wrote:
>> Migration to file, reuses migration-to-fd.
>> Migration from file, uses qemu-fopen directly.
>>
>> The saved state-file should be used only once and removed (or used
>> with -snapshot, or a the disk-image should be copied), as the
>> disk image is not saved, only the VM state.
>>
>> Also there is not point of doing a _live_ migration to file (except
>> for debugging migration code), so I recommend to stop the VM before
>> migrating its state to a file.
>>
>> An advantage migration-to-file over savevm/loadvm is that for the latter
>> a qcow2 is a requirement, while the former works for any image-format.
>
> Wouldn't it be better to just implement savevm to file?
>
> Paul
It sure is simpler.
The possible advantage of migration-to-file (over savevm-to-file) is that in the
future we may want to implement vm-snapshoting (live save to file + snapshot
disk-image).
I've implemented a savevm_file, and will send it in a separate email.
Thanks,
Uri.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-20 11:05 ` Uri Lublin
@ 2009-01-20 14:06 ` Ian Jackson
0 siblings, 0 replies; 11+ messages in thread
From: Ian Jackson @ 2009-01-20 14:06 UTC (permalink / raw)
To: qemu-devel; +Cc: Paul Brook
Uri Lublin writes ("Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file"):
> Paul Brook wrote:
> > Wouldn't it be better to just implement savevm to file?
>
> It sure is simpler.
In the Xen tree we already have an alternatively implementation of
savevm which does not depend on or interact with the cow snapshots.
See below.
This is a bit of a mess and it would be nice to have some
functionality in upstream that did the same thing. NB that since we
want to retain compatibility with previous savefiles the exact syntax
of the data saved to the file is important.
FYI in the Xen case we don't need the live migration support that qemu
upstream and kvm have, because the RAM live migration is handled by
the Xen toolstack, and the remaining qemu saved state is small enough
to do all in one go. But that doesn't mean that it's a bad idea.
Ian.
void do_savevm(const char *name)
{
QEMUFile *f;
int saved_vm_running, ret;
f = qemu_fopen(name, "wb");
/* ??? Should this occur after vm_stop? */
qemu_aio_flush();
saved_vm_running = vm_running;
vm_stop(0);
if (!f) {
fprintf(logfile, "Failed to open savevm file '%s'\n", name);
goto the_end;
}
ret = qemu_savevm_state(f);
qemu_fclose(f);
if (ret < 0)
fprintf(logfile, "Error %d while writing VM to savevm file '%s'\n",
ret, name);
the_end:
if (saved_vm_running)
vm_start();
return;
}
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-19 0:18 [Qemu-devel] [PATCH] migration: adding migration to/from a file Uri Lublin
2009-01-19 0:55 ` Paul Brook
@ 2009-01-19 15:11 ` Anthony Liguori
2009-01-20 11:15 ` Daniel P. Berrange
2009-01-20 11:32 ` Uri Lublin
1 sibling, 2 replies; 11+ messages in thread
From: Anthony Liguori @ 2009-01-19 15:11 UTC (permalink / raw)
To: qemu-devel; +Cc: Uri Lublin
Uri Lublin wrote:
> Migration to file, reuses migration-to-fd.
> Migration from file, uses qemu-fopen directly.
>
> The saved state-file should be used only once and removed (or used
> with -snapshot, or a the disk-image should be copied), as the
> disk image is not saved, only the VM state.
>
> Also there is not point of doing a _live_ migration to file (except
> for debugging migration code), so I recommend to stop the VM before
> migrating its state to a file.
>
> An advantage migration-to-file over savevm/loadvm is that for the latter
> a qcow2 is a requirement, while the former works for any image-format.
>
> Signed-off-by: Uri Lublin <uril@redhat.com>
> ---
> Makefile | 2 +-
> migration-file.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> migration.c | 4 ++
> migration.h | 5 ++
> 4 files changed, 137 insertions(+), 1 deletions(-)
> create mode 100644 migration-file.c
>
> diff --git a/Makefile b/Makefile
> index 8cbdcda..7e0e6f2 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -81,7 +81,7 @@ OBJS+=usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o usb-msd.o usb-wacom.o
> OBJS+=usb-serial.o usb-net.o
> OBJS+=sd.o ssi-sd.o
> OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o usb-bt.o
> -OBJS+=buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
> +OBJS+=buffered_file.o migration.o migration-tcp.o migration-file.o net.o qemu-sockets.o
> OBJS+=qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o
>
> ifdef CONFIG_BRLAPI
> diff --git a/migration-file.c b/migration-file.c
> new file mode 100644
> index 0000000..5cde3e2
> --- /dev/null
> +++ b/migration-file.c
> @@ -0,0 +1,127 @@
> +/*
> + * QEMU live migration
> + *
> + * Copyright IBM, Corp. 2008
> + * Red Hat, Inc. 2008
> + *
> + * Authors:
> + * Anthony Liguori <aliguori@us.ibm.com>
> + * Uri Lublin <uril@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2. See
> + * the COPYING file in the top-level directory.
> + *
> + */
> +
> +#include <unistd.h>
> +#include "qemu-common.h"
> +#include "migration.h"
> +#include "sysemu.h"
> +#include "console.h"
> +#include "block.h"
> +
> +//#define DEBUG_MIGRATION_FILE
> +
> +#ifdef DEBUG_MIGRATION_FILE
> +#define dprintf(fmt, ...) \
> + do { printf("migration-file: " fmt, ## __VA_ARGS__); } while (0)
> +#else
> +#define dprintf(fmt, ...) \
> + do { } while (0)
> +#endif
> +
> +static int file_close(FdMigrationState *s)
> +{
> + close(s->fd);
> +}
> +
> +static int file_errno(FdMigrationState *s)
> +{
> + return errno;
> +}
> +
> +static int file_write(FdMigrationState *s, const void * buf, size_t size)
> +{
> + return write(s->fd, buf, size);
> +}
> +
> +MigrationState *file_start_outgoing_migration(const char *filename,
> + int64_t bandwidth_limit,
> + int async)
> +{
> + FdMigrationState *s;
> + int fd;
> +
> + s = qemu_mallocz(sizeof(*s));
> + if (s == NULL) {
> + perror("file_migration: qemu_mallocz failed");
> + term_printf("file_migration: qemu_mallocz failed");
> + goto err1;
> + }
> +
> + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
> + if (fd < 0) {
> + perror("file_migration: failed to open filename");
> + term_printf("file_migration: failed to open filename %s\n", filename);
> + goto err2;
> + }
>
The migration code assumes that the file descriptor used is
non-blocking. In general, open() on a file system cannot produce a
non-blocking file descriptor.
You could either use the posix-aio code to implement migration to a file
or you could introduce a fork()'d process that wrote to a file from
stdin. Although this is basically just exec dd of=.
It shouldn't be too hard to use posix-aio though. You just have to be
clever about implementing the s->write op.
Regards,
Anthony Liguori
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-19 15:11 ` Anthony Liguori
@ 2009-01-20 11:15 ` Daniel P. Berrange
2009-01-20 12:15 ` Uri Lublin
2009-01-20 16:24 ` Anthony Liguori
2009-01-20 11:32 ` Uri Lublin
1 sibling, 2 replies; 11+ messages in thread
From: Daniel P. Berrange @ 2009-01-20 11:15 UTC (permalink / raw)
To: qemu-devel; +Cc: Uri Lublin
On Mon, Jan 19, 2009 at 09:11:28AM -0600, Anthony Liguori wrote:
> Uri Lublin wrote:
> >Migration to file, reuses migration-to-fd.
> >Migration from file, uses qemu-fopen directly.
> >
> >The saved state-file should be used only once and removed (or used
> >with -snapshot, or a the disk-image should be copied), as the
> >disk image is not saved, only the VM state.
> >
> >Also there is not point of doing a _live_ migration to file (except
> >for debugging migration code), so I recommend to stop the VM before
> >migrating its state to a file.
> >
> >An advantage migration-to-file over savevm/loadvm is that for the latter
> >a qcow2 is a requirement, while the former works for any image-format.
> >
> >Signed-off-by: Uri Lublin <uril@redhat.com>
> >---
> > Makefile | 2 +-
> > migration-file.c | 127
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > migration.c | 4 ++
> > migration.h | 5 ++
> > 4 files changed, 137 insertions(+), 1 deletions(-)
> > create mode 100644 migration-file.c
> >
> >diff --git a/Makefile b/Makefile
> >index 8cbdcda..7e0e6f2 100644
> >--- a/Makefile
> >+++ b/Makefile
> >@@ -81,7 +81,7 @@ OBJS+=usb.o usb-hub.o usb-$(HOST_USB).o usb-hid.o
> >usb-msd.o usb-wacom.o
> > OBJS+=usb-serial.o usb-net.o
> > OBJS+=sd.o ssi-sd.o
> > OBJS+=bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-hci.o bt-hid.o
> > usb-bt.o
> >-OBJS+=buffered_file.o migration.o migration-tcp.o net.o qemu-sockets.o
> >+OBJS+=buffered_file.o migration.o migration-tcp.o migration-file.o net.o
> >qemu-sockets.o
> > OBJS+=qemu-char.o aio.o net-checksum.o savevm.o cache-utils.o
> >
> > ifdef CONFIG_BRLAPI
> >diff --git a/migration-file.c b/migration-file.c
> >new file mode 100644
> >index 0000000..5cde3e2
> >--- /dev/null
> >+++ b/migration-file.c
> >@@ -0,0 +1,127 @@
> >+/*
> >+ * QEMU live migration
> >+ *
> >+ * Copyright IBM, Corp. 2008
> >+ * Red Hat, Inc. 2008
> >+ *
> >+ * Authors:
> >+ * Anthony Liguori <aliguori@us.ibm.com>
> >+ * Uri Lublin <uril@redhat.com>
> >+ *
> >+ * This work is licensed under the terms of the GNU GPL, version 2. See
> >+ * the COPYING file in the top-level directory.
> >+ *
> >+ */
> >+
> >+#include <unistd.h>
> >+#include "qemu-common.h"
> >+#include "migration.h"
> >+#include "sysemu.h"
> >+#include "console.h"
> >+#include "block.h"
> >+
> >+//#define DEBUG_MIGRATION_FILE
> >+
> >+#ifdef DEBUG_MIGRATION_FILE
> >+#define dprintf(fmt, ...) \
> >+ do { printf("migration-file: " fmt, ## __VA_ARGS__); } while (0)
> >+#else
> >+#define dprintf(fmt, ...) \
> >+ do { } while (0)
> >+#endif
> >+
> >+static int file_close(FdMigrationState *s)
> >+{
> >+ close(s->fd);
> >+}
> >+
> >+static int file_errno(FdMigrationState *s)
> >+{
> >+ return errno;
> >+}
> >+
> >+static int file_write(FdMigrationState *s, const void * buf, size_t size)
> >+{
> >+ return write(s->fd, buf, size);
> >+}
> >+
> >+MigrationState *file_start_outgoing_migration(const char *filename,
> >+ int64_t bandwidth_limit,
> >+ int async)
> >+{
> >+ FdMigrationState *s;
> >+ int fd;
> >+
> >+ s = qemu_mallocz(sizeof(*s));
> >+ if (s == NULL) {
> >+ perror("file_migration: qemu_mallocz failed");
> >+ term_printf("file_migration: qemu_mallocz failed");
> >+ goto err1;
> >+ }
> >+
> >+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
> >+ if (fd < 0) {
> >+ perror("file_migration: failed to open filename");
> >+ term_printf("file_migration: failed to open filename %s\n",
> >filename);
> >+ goto err2;
> >+ }
> >
>
> The migration code assumes that the file descriptor used is
> non-blocking. In general, open() on a file system cannot produce a
> non-blocking file descriptor.
Does it matter if it blocks though ? Migrating to a file is not
"live" migration anyway, so if we happen to block the rest of the
QEMU event loop during course of writing to the file it doesn't seem
too serious. Or is there some scenario which badly breaks with blocking
writes even for non-live usage ?
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-20 11:15 ` Daniel P. Berrange
@ 2009-01-20 12:15 ` Uri Lublin
2009-01-20 16:24 ` Anthony Liguori
1 sibling, 0 replies; 11+ messages in thread
From: Uri Lublin @ 2009-01-20 12:15 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel
Daniel P. Berrange wrote:
> On Mon, Jan 19, 2009 at 09:11:28AM -0600, Anthony Liguori wrote:
>> Uri Lublin wrote:
>>> Migration to file, reuses migration-to-fd.
>>> Migration from file, uses qemu-fopen directly.
>>>
>>> The saved state-file should be used only once and removed (or used
>>> with -snapshot, or a the disk-image should be copied), as the
>>> disk image is not saved, only the VM state.
>>>
>>> Also there is not point of doing a _live_ migration to file (except
>>> for debugging migration code), so I recommend to stop the VM before
>>> migrating its state to a file.
>>>
>>> An advantage migration-to-file over savevm/loadvm is that for the latter
>>> a qcow2 is a requirement, while the former works for any image-format.
>>>
>>> Signed-off-by: Uri Lublin <uril@redhat.com>
>>> ---
>>>
>> The migration code assumes that the file descriptor used is
>> non-blocking. In general, open() on a file system cannot produce a
>> non-blocking file descriptor.
>
> Does it matter if it blocks though ? Migrating to a file is not
> "live" migration anyway, so if we happen to block the rest of the
> QEMU event loop during course of writing to the file it doesn't seem
> too serious. Or is there some scenario which badly breaks with blocking
> writes even for non-live usage ?
>
I first thought it's not that important too.
But it may be less than optimal, especially if qemu does not respond to monitor
commands, which may affect management applications.
What does libvirt do when qemu does not respond to a monitor command ?
Uri.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-20 11:15 ` Daniel P. Berrange
2009-01-20 12:15 ` Uri Lublin
@ 2009-01-20 16:24 ` Anthony Liguori
1 sibling, 0 replies; 11+ messages in thread
From: Anthony Liguori @ 2009-01-20 16:24 UTC (permalink / raw)
To: Daniel P. Berrange, qemu-devel; +Cc: Uri Lublin
Daniel P. Berrange wrote:
> Does it matter if it blocks though ? Migrating to a file is not
> "live" migration anyway,
Yes. The general reason is that blocking in QEMU is evil because it's
single threaded. If you block on IO in QEMU, then everything comes
grinding to a halt. The VM may not be running, but you still want the
GUI to be responsive, the monitor, and VNC to be responsive. This is
particularly import in the context of asynchronous monitor
notifications. savevm may be a long operation and there may be pending
notifications that would get significantly delayed.
If you issue a "stop" before doing live migration, the result is
equivalent to "savevm" from a binary perspective but the monitor will
remain responsive during the whole operation. I'd like to eliminate the
blocking version of savevm entirely but we're currently prevent from
doing this because of the savevm to a disk. The issue is that you
cannot write to the qcow2 snapshot space while other IO operations can
happen. stop'ing the guest would prevent this (obviously) but it would
be nice to support this in a truly live form.
I think we need to adjust the qcow2 snapshot format to support chaining
of snapshot segments. That would allow a truly live save to qcow2.
Regards,
Anthony Liguori
> so if we happen to block the rest of the
> QEMU event loop during course of writing to the file it doesn't seem
> too serious. Or is there some scenario which badly breaks with blocking
> writes even for non-live usage ?
>
> Daniel
>
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-19 15:11 ` Anthony Liguori
2009-01-20 11:15 ` Daniel P. Berrange
@ 2009-01-20 11:32 ` Uri Lublin
2009-01-20 11:53 ` Daniel P. Berrange
1 sibling, 1 reply; 11+ messages in thread
From: Uri Lublin @ 2009-01-20 11:32 UTC (permalink / raw)
To: Anthony Liguori; +Cc: qemu-devel
Anthony Liguori wrote:
> Uri Lublin wrote:
>> Migration to file, reuses migration-to-fd.
>> Migration from file, uses qemu-fopen directly.
>>
>> The saved state-file should be used only once and removed (or used
>> with -snapshot, or a the disk-image should be copied), as the
>> disk image is not saved, only the VM state.
>>
>> Also there is not point of doing a _live_ migration to file (except
>> for debugging migration code), so I recommend to stop the VM before
>> migrating its state to a file.
>>
>> An advantage migration-to-file over savevm/loadvm is that for the latter
>> a qcow2 is a requirement, while the former works for any image-format.
>>
>> Signed-off-by: Uri Lublin <uril@redhat.com>
>> ---
>> +
>> +MigrationState *file_start_outgoing_migration(const char *filename,
>> + int64_t bandwidth_limit,
>> + int async)
>> +{
>> + FdMigrationState *s;
>> + int fd;
>> +
>> + s = qemu_mallocz(sizeof(*s));
>> + if (s == NULL) {
>> + perror("file_migration: qemu_mallocz failed");
>> + term_printf("file_migration: qemu_mallocz failed");
>> + goto err1;
>> + }
>> +
>> + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
>> + if (fd < 0) {
>> + perror("file_migration: failed to open filename");
>> + term_printf("file_migration: failed to open filename %s\n",
>> filename);
>> + goto err2;
>> + }
>>
>
> The migration code assumes that the file descriptor used is
> non-blocking. In general, open() on a file system cannot produce a
> non-blocking file descriptor.
I can call fcntl with F_SETFL and O_NONBLOCK.
>
> You could either use the posix-aio code to implement migration to a file
> or you could introduce a fork()'d process that wrote to a file from
> stdin. Although this is basically just exec dd of=.
We started with "exec dd..." for saving state in a file. It's obviously not the
best solution, as it needs to fork/exec/pipe instead of just open a file.
Thanks,
Uri.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-20 11:32 ` Uri Lublin
@ 2009-01-20 11:53 ` Daniel P. Berrange
2009-01-20 16:26 ` Anthony Liguori
0 siblings, 1 reply; 11+ messages in thread
From: Daniel P. Berrange @ 2009-01-20 11:53 UTC (permalink / raw)
To: qemu-devel
On Tue, Jan 20, 2009 at 01:32:24PM +0200, Uri Lublin wrote:
> Anthony Liguori wrote:
> >Uri Lublin wrote:
> >>Migration to file, reuses migration-to-fd.
> >>Migration from file, uses qemu-fopen directly.
> >>
> >>The saved state-file should be used only once and removed (or used
> >>with -snapshot, or a the disk-image should be copied), as the
> >>disk image is not saved, only the VM state.
> >>
> >>Also there is not point of doing a _live_ migration to file (except
> >>for debugging migration code), so I recommend to stop the VM before
> >>migrating its state to a file.
> >>
> >>An advantage migration-to-file over savevm/loadvm is that for the latter
> >>a qcow2 is a requirement, while the former works for any image-format.
> >>
> >>Signed-off-by: Uri Lublin <uril@redhat.com>
> >>---
>
> >>+
> >>+MigrationState *file_start_outgoing_migration(const char *filename,
> >>+ int64_t bandwidth_limit,
> >>+ int async)
> >>+{
> >>+ FdMigrationState *s;
> >>+ int fd;
> >>+
> >>+ s = qemu_mallocz(sizeof(*s));
> >>+ if (s == NULL) {
> >>+ perror("file_migration: qemu_mallocz failed");
> >>+ term_printf("file_migration: qemu_mallocz failed");
> >>+ goto err1;
> >>+ }
> >>+
> >>+ fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600);
> >>+ if (fd < 0) {
> >>+ perror("file_migration: failed to open filename");
> >>+ term_printf("file_migration: failed to open filename %s\n",
> >>filename);
> >>+ goto err2;
> >>+ }
> >>
> >
> >The migration code assumes that the file descriptor used is
> >non-blocking. In general, open() on a file system cannot produce a
> >non-blocking file descriptor.
>
> I can call fcntl with F_SETFL and O_NONBLOCK.
IIRC that doesn't have any effect on plain files - they'll still potentially
block on write.
Daniel
--
|: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [Qemu-devel] [PATCH] migration: adding migration to/from a file
2009-01-20 11:53 ` Daniel P. Berrange
@ 2009-01-20 16:26 ` Anthony Liguori
0 siblings, 0 replies; 11+ messages in thread
From: Anthony Liguori @ 2009-01-20 16:26 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: qemu-devel
Daniel P. Berrange wrote:
> On Tue, Jan 20, 2009 at 01:32:24PM +0200, Uri Lublin wrote:
>
>>
>> I can call fcntl with F_SETFL and O_NONBLOCK.
>>
>
> IIRC that doesn't have any effect on plain files - they'll still potentially
> block on write.
>
Yes, it doesn't. I learned this the hard way with the old migration
code. When I implemented file: migration, I noticed it never worked
properly (properly being live) unless I used a rate limit. Since we
defaulted a rate limit, it seemed to work, but the true test is whether
it works in the absence of rate limiting.
Regards,
Anthony Liguori
> Daniel
>
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2009-01-20 16:26 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-01-19 0:18 [Qemu-devel] [PATCH] migration: adding migration to/from a file Uri Lublin
2009-01-19 0:55 ` Paul Brook
2009-01-20 11:05 ` Uri Lublin
2009-01-20 14:06 ` Ian Jackson
2009-01-19 15:11 ` Anthony Liguori
2009-01-20 11:15 ` Daniel P. Berrange
2009-01-20 12:15 ` Uri Lublin
2009-01-20 16:24 ` Anthony Liguori
2009-01-20 11:32 ` Uri Lublin
2009-01-20 11:53 ` Daniel P. Berrange
2009-01-20 16:26 ` Anthony Liguori
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).