diff options
author | Daniel P. Berrange <berrange@redhat.com> | 2016-04-27 11:04:54 +0100 |
---|---|---|
committer | Amit Shah <amit.shah@redhat.com> | 2016-05-26 11:31:14 +0530 |
commit | baf51e7739a4d176284d2e38e1755afeafcd2ee0 (patch) | |
tree | e9ee8de74540a573b60d6a3e16b6c8d85217201b /migration/qemu-file.c | |
parent | a8ec4437cd52b2258c77d6b4195c927139c4ced5 (diff) | |
download | qemu-baf51e7739a4d176284d2e38e1755afeafcd2ee0.zip qemu-baf51e7739a4d176284d2e38e1755afeafcd2ee0.tar.gz qemu-baf51e7739a4d176284d2e38e1755afeafcd2ee0.tar.bz2 |
migration: ensure qemu_fflush() always writes full data amount
The QEMUFile writev_buffer / put_buffer functions are expected
to write out the full set of requested data, blocking until
complete. The qemu_fflush() caller does not expect to deal with
partial writes. Clarify the function comments and add a sanity
check to the code to catch mistaken implementations.
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Juan Quintela <quintela@redhat.com>
Message-Id: <1461751518-12128-5-git-send-email-berrange@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
Diffstat (limited to 'migration/qemu-file.c')
-rw-r--r-- | migration/qemu-file.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/migration/qemu-file.c b/migration/qemu-file.c index 6f4a129..656db4a 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -108,11 +108,13 @@ bool qemu_file_is_writable(QEMUFile *f) * Flushes QEMUFile buffer * * If there is writev_buffer QEMUFileOps it uses it otherwise uses - * put_buffer ops. + * put_buffer ops. This will flush all pending data. If data was + * only partially flushed, it will set an error state. */ void qemu_fflush(QEMUFile *f) { ssize_t ret = 0; + ssize_t expect = 0; if (!qemu_file_is_writable(f)) { return; @@ -120,21 +122,27 @@ void qemu_fflush(QEMUFile *f) if (f->ops->writev_buffer) { if (f->iovcnt > 0) { + expect = iov_size(f->iov, f->iovcnt); ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos); } } else { if (f->buf_index > 0) { + expect = f->buf_index; ret = f->ops->put_buffer(f->opaque, f->buf, f->pos, f->buf_index); } } + if (ret >= 0) { f->pos += ret; } + /* We expect the QEMUFile write impl to send the full + * data set we requested, so sanity check that. + */ + if (ret != expect) { + qemu_file_set_error(f, ret < 0 ? ret : -EIO); + } f->buf_index = 0; f->iovcnt = 0; - if (ret < 0) { - qemu_file_set_error(f, ret); - } } void ram_control_before_iterate(QEMUFile *f, uint64_t flags) |