aboutsummaryrefslogtreecommitdiff
path: root/migration
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2016-04-27 11:04:54 +0100
committerAmit Shah <amit.shah@redhat.com>2016-05-26 11:31:14 +0530
commitbaf51e7739a4d176284d2e38e1755afeafcd2ee0 (patch)
treee9ee8de74540a573b60d6a3e16b6c8d85217201b /migration
parenta8ec4437cd52b2258c77d6b4195c927139c4ced5 (diff)
downloadqemu-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')
-rw-r--r--migration/qemu-file.c16
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)