add file: migration support
PATCH 1/1 add file: migration support
This patch adds support for migration to and from file: targets, moves common helpers between exec: and file: use cases from migration-exec.c to migration.c, and adds a qemu_fdopen() helper parallel to qemu_fopen().
.gitignore +1 -1
@@ -30,4 +30,4 @@ qemu-nbd.8 *.tp *.vr *.d - +*.o
Makefile +2 -2
@@ -78,8 +78,8 @@ OBJS+=usb.o usb-hub.o usb-linux.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+=qemu-char.o aio.o net-checksum.o savevm.o +OBJS+=buffered_file.o migration.o migration-file.o migration-tcp.o net.o +OBJS+=qemu-sockets.o qemu-char.o aio.o net-checksum.o savevm.o ifdef CONFIG_BRLAPI OBJS+= baum.o
hw/hw.h +1 -0
@@ -35,6 +35,7 @@ QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer, QEMUFileRateLimit *rate_limit);QEMUFile *qemu_fopen (const char *filename,const char *mode);QEMUFile *qemu_fopen_socket (int fd); +QEMUFile *qemu_fdopen (int fd,const char *mode);QEMUFile *qemu_popen (FILE *popen_file,const char *mode);QEMUFile *qemu_popen_cmd (const char *command,const char *mode);void qemu_fflush (QEMUFile *f);
migration-exec.c +2 -12
@@ -32,16 +32,6 @@ do { } while (0)#endif -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); -} -static int exec_close (FdMigrationState *s) {dprintf ("exec_close\n" );
@@ -86,8 +76,8 @@ MigrationState *exec_start_outgoing_migration(const char *command, s->opaque =qemu_popen (f,"w" ); s->close = exec_close; - s->get_error = file_errno; - s->write = file_write; + s->get_error = migrate_file_errno; + s->write = migrate_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;
migration-file.c new file +119 -0
119 lines not on this page · raw message
migration.c +19 -0
@@ -40,6 +40,8 @@ void qemu_start_incoming_migration(const char *uri)if (strstart (uri,"tcp:" , &p))tcp_start_incoming_migration (p); +else if (strstart (uri,"file:" , &p)) +file_start_incoming_migration (p);#if !defined(WIN32 ) else if (strstart(uri, "exec:", &p)) exec_start_incoming_migration(p);
@@ -55,6 +57,8 @@ void do_migrate(int detach, const char *uri)if (strstart (uri,"tcp:" , &p)) s =tcp_start_outgoing_migration (p, max_throttle, detach); +else if (strstart (uri,"file:" , &p)) + s =file_start_outgoing_migration (p, max_throttle, detach);#if !defined(WIN32 ) else if (strstart(uri, "exec:", &p)) s =exec_start_outgoing_migration (p, max_throttle, detach);
@@ -279,3 +283,18 @@ int migrate_fd_close(void *opaque)FdMigrationState *s = opaque;return s->close (s); } + +int migrate_file_errno (FdMigrationState *s) +{ +return errno; +} + +int migrate_file_write (FdMigrationState *s,const void * buf,size_t size) +{ +return write (s->fd, buf, size); +} + +int migrate_file_close (FdMigrationState *s) +{ +return close (s->fd); +}
migration.h +12 -0
@@ -61,6 +61,12 @@ MigrationState *exec_start_outgoing_migration(const char *host_port,int64_t bandwidth_limit, int detach); +int file_start_incoming_migration (const char *filename); + +MigrationState *file_start_outgoing_migration (const char *filename, +int64_t bandwidth_limit, +int async); +int tcp_start_incoming_migration (const char *host_port); MigrationState *tcp_start_outgoing_migration(const char *host_port,
@@ -89,6 +95,12 @@ void migrate_fd_wait_for_unfreeze(void *opaque);int migrate_fd_close (void *opaque); +int migrate_file_errno (FdMigrationState *s); + +int migrate_file_write (FdMigrationState *s,const void * buf,size_t size); + +int migrate_file_close (FdMigrationState *s); +static inline FdMigrationState *migrate_to_fms (MigrationState *mig_state) {return container_of (mig_state, FdMigrationState, mig_state);
savevm.c +24 -1
@@ -226,7 +226,6 @@ QEMUFile *qemu_popen(FILE *popen_file, const char *mode) }else { s->file =qemu_fopen_ops (s, popen_put_buffer,NULL , popen_close,NULL ); } -fprintf (stderr,"qemu_popen: returning result of qemu_fopen_ops\n" );return s->file; }
@@ -283,6 +282,30 @@ static int file_close(void *opaque)return 0 ; } +QEMUFile *qemu_fdopen (int fd,const char *mode) +{ +QEMUFileStdio *s; + + s =qemu_mallocz (sizeof (QEMUFileStdio)); +if (!s) +return NULL ; + + s->outfile =fdopen (fd, mode); +if (!s->outfile) + goto fail; + +if (!strcmp (mode,"wb" )) +return qemu_fopen_ops (s, file_put_buffer,NULL , file_close,NULL ); +else if (!strcmp (mode,"rb" )) +return qemu_fopen_ops (s,NULL , file_get_buffer, file_close,NULL ); + +fail: +if (s->outfile) +fclose (s->outfile); +qemu_free (s); +return NULL ; +} +QEMUFile *qemu_fopen (const char *filename,const char *mode) {QEMUFileStdio *s;
Oops -- didn't mean to include my local .gitignore changes in that.
Quoted 9 lines · Charles Duffy
This patch adds support for migration to and from file: targets, moves common helpers between exec: and file: use cases from
migration-exec.ctomigration.c, and adds aqemu_fdopen()helper parallel toqemu_fopen().Signed-off-by Charles Duffy <[email protected]>.gitignore +0
-0
.gitignore qemu-nbd.8 · line 33
Quoted 5 lines
.gitignore +1
-1@@ -30,4 +30,4 @@ qemu-nbd.8 *.tp *.vr *.d - +*.o
Please keep this sort of stuff separate from a general patch.
.gitignore
Quoted 11 lines
.gitignore +10
-0+ s->fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (s->fd == -1) { + perror("Unable to open migration target"); + goto err_after_alloc; + } + + if (fcntl(s->fd, F_SETFD, O_NONBLOCK) == -1) { + dprintf("Unable to set nonblocking mode on file descriptor\n"); + goto err_after_open; + }
Did you mean F_SETFL?
At any rate, this doesn't do what you think it does. O_NONBLOCK still blocks with a file. To implement a proper file: migration protocol, you have to use something like posix-aio to write to the file asychronously.
You can observe the problem here by setting the migration data limit to something very, very high (like 10GB). That will cause the VM to become unresponsive until all the data is on disk which is certainly not live migration.
Regards,
Anthony Liguori