diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2015-01-16 10:16:14 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2015-01-16 10:16:14 +0000 |
commit | e68cba36360a2ab5bf0576b66df4d0eb0d822f8d (patch) | |
tree | 933ecff5cc8e380fe38693dc0cca2d7b8e479dfc /migration | |
parent | df58887b20fab8fe8a6dcca4db30cd4e4077d53a (diff) | |
parent | ea987c2c21d4326bb58ee28f6888fdcf8fbda067 (diff) | |
download | qemu-e68cba36360a2ab5bf0576b66df4d0eb0d822f8d.zip qemu-e68cba36360a2ab5bf0576b66df4d0eb0d822f8d.tar.gz qemu-e68cba36360a2ab5bf0576b66df4d0eb0d822f8d.tar.bz2 |
Merge remote-tracking branch 'remotes/amit-migration/tags/mig-2.3-1' into staging
A set of patches collected over the holidays. Mix of optimizations and
fixes.
# gpg: Signature made Fri 16 Jan 2015 07:42:00 GMT using RSA key ID 854083B6
# gpg: Good signature from "Amit Shah <amit@amitshah.net>"
# gpg: aka "Amit Shah <amit@kernel.org>"
# gpg: aka "Amit Shah <amitshah@gmx.net>"
* remotes/amit-migration/tags/mig-2.3-1:
vmstate: type-check sub-arrays
migration_cancel: shutdown migration socket
Handle bi-directional communication for fd migration
socket shutdown
Tests: QEMUSizedBuffer/QEMUBuffer
QEMUSizedBuffer: only free qsb that qemu_bufopen allocated
xbzrle: rebuild the cache_is_cached function
xbzrle: optimize XBZRLE to decrease the cache misses
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'migration')
-rw-r--r-- | migration/fd.c | 24 | ||||
-rw-r--r-- | migration/migration.c | 12 | ||||
-rw-r--r-- | migration/qemu-file-buf.c | 10 | ||||
-rw-r--r-- | migration/qemu-file-unix.c | 23 | ||||
-rw-r--r-- | migration/qemu-file.c | 12 |
5 files changed, 71 insertions, 10 deletions
diff --git a/migration/fd.c b/migration/fd.c index d2e523a..129da99 100644 --- a/migration/fd.c +++ b/migration/fd.c @@ -31,13 +31,29 @@ do { } while (0) #endif +static bool fd_is_socket(int fd) +{ + struct stat stat; + int ret = fstat(fd, &stat); + if (ret == -1) { + /* When in doubt say no */ + return false; + } + return S_ISSOCK(stat.st_mode); +} + void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp) { int fd = monitor_get_fd(cur_mon, fdname, errp); if (fd == -1) { return; } - s->file = qemu_fdopen(fd, "wb"); + + if (fd_is_socket(fd)) { + s->file = qemu_fopen_socket(fd, "wb"); + } else { + s->file = qemu_fdopen(fd, "wb"); + } migrate_fd_connect(s); } @@ -58,7 +74,11 @@ void fd_start_incoming_migration(const char *infd, Error **errp) DPRINTF("Attempting to start an incoming migration via fd\n"); fd = strtol(infd, NULL, 0); - f = qemu_fdopen(fd, "rb"); + if (fd_is_socket(fd)) { + f = qemu_fopen_socket(fd, "rb"); + } else { + f = qemu_fdopen(fd, "rb"); + } if(f == NULL) { error_setg_errno(errp, errno, "failed to open the source descriptor"); return; diff --git a/migration/migration.c b/migration/migration.c index c49a05a..b3adbc6 100644 --- a/migration/migration.c +++ b/migration/migration.c @@ -330,6 +330,7 @@ void migrate_fd_error(MigrationState *s) static void migrate_fd_cancel(MigrationState *s) { int old_state ; + QEMUFile *f = migrate_get_current()->file; trace_migrate_fd_cancel(); do { @@ -339,6 +340,17 @@ static void migrate_fd_cancel(MigrationState *s) } migrate_set_state(s, old_state, MIG_STATE_CANCELLING); } while (s->state != MIG_STATE_CANCELLING); + + /* + * If we're unlucky the migration code might be stuck somewhere in a + * send/write while the network has failed and is waiting to timeout; + * if we've got shutdown(2) available then we can force it to quit. + * The outgoing qemu file gets closed in migrate_fd_cleanup that is + * called in a bh, so there is no race against this cancel. + */ + if (s->state == MIG_STATE_CANCELLING && f) { + qemu_file_shutdown(f); + } } void add_migration_state_change_notifier(Notifier *notify) diff --git a/migration/qemu-file-buf.c b/migration/qemu-file-buf.c index d33dd44..e97e0bd 100644 --- a/migration/qemu-file-buf.c +++ b/migration/qemu-file-buf.c @@ -395,6 +395,7 @@ QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *qsb) typedef struct QEMUBuffer { QEMUSizedBuffer *qsb; QEMUFile *file; + bool qsb_allocated; } QEMUBuffer; static int buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size) @@ -424,7 +425,9 @@ static int buf_close(void *opaque) { QEMUBuffer *s = opaque; - qsb_free(s->qsb); + if (s->qsb_allocated) { + qsb_free(s->qsb); + } g_free(s); @@ -463,12 +466,11 @@ QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input) } s = g_malloc0(sizeof(QEMUBuffer)); - if (mode[0] == 'r') { - s->qsb = input; - } + s->qsb = input; if (s->qsb == NULL) { s->qsb = qsb_create(NULL, 0); + s->qsb_allocated = true; } if (!s->qsb) { g_free(s); diff --git a/migration/qemu-file-unix.c b/migration/qemu-file-unix.c index 9682396..bfbc086 100644 --- a/migration/qemu-file-unix.c +++ b/migration/qemu-file-unix.c @@ -26,6 +26,7 @@ #include "qemu/sockets.h" #include "block/coroutine.h" #include "migration/qemu-file.h" +#include "migration/qemu-file-internal.h" typedef struct QEMUFileSocket { int fd; @@ -84,6 +85,17 @@ static int socket_close(void *opaque) return 0; } +static int socket_shutdown(void *opaque, bool rd, bool wr) +{ + QEMUFileSocket *s = opaque; + + if (shutdown(s->fd, rd ? (wr ? SHUT_RDWR : SHUT_RD) : SHUT_WR)) { + return -errno; + } else { + return 0; + } +} + static ssize_t unix_writev_buffer(void *opaque, struct iovec *iov, int iovcnt, int64_t pos) { @@ -192,15 +204,18 @@ QEMUFile *qemu_fdopen(int fd, const char *mode) } static const QEMUFileOps socket_read_ops = { - .get_fd = socket_get_fd, + .get_fd = socket_get_fd, .get_buffer = socket_get_buffer, - .close = socket_close + .close = socket_close, + .shut_down = socket_shutdown + }; static const QEMUFileOps socket_write_ops = { - .get_fd = socket_get_fd, + .get_fd = socket_get_fd, .writev_buffer = socket_writev_buffer, - .close = socket_close + .close = socket_close, + .shut_down = socket_shutdown }; QEMUFile *qemu_fopen_socket(int fd, const char *mode) diff --git a/migration/qemu-file.c b/migration/qemu-file.c index a7f2a34..edc2830 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -30,6 +30,18 @@ #include "migration/qemu-file-internal.h" #include "trace.h" +/* + * Stop a file from being read/written - not all backing files can do this + * typically only sockets can. + */ +int qemu_file_shutdown(QEMUFile *f) +{ + if (!f->ops->shut_down) { + return -ENOSYS; + } + return f->ops->shut_down(f->opaque, true, true); +} + bool qemu_file_mode_is_not_valid(const char *mode) { if (mode == NULL || |