qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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: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  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-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-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: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: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-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-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).