From 9504fb510c87c3dd6fe2e9a25e84c1426672f226 Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 5 Nov 2015 18:10:35 +0000 Subject: Add qemu_get_buffer_in_place to avoid copies some of the time qemu_get_buffer always copies the data it reads to a users buffer, however in many cases the file buffer inside qemu_file could be given back to the caller, avoiding the copy. This isn't always possible depending on the size and alignment of the data. Thus 'qemu_get_buffer_in_place' either copies the data to a supplied buffer or updates a pointer to the internal buffer if convenient. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- migration/qemu-file.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'migration/qemu-file.c') diff --git a/migration/qemu-file.c b/migration/qemu-file.c index df49023ed8..e41a677fe3 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -433,6 +433,43 @@ size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size) return done; } +/* + * Read 'size' bytes of data from the file. + * 'size' can be larger than the internal buffer. + * + * The data: + * may be held on an internal buffer (in which case *buf is updated + * to point to it) that is valid until the next qemu_file operation. + * OR + * will be copied to the *buf that was passed in. + * + * The code tries to avoid the copy if possible. + * + * It will return size bytes unless there was an error, in which case it will + * return as many as it managed to read (assuming blocking fd's which + * all current QEMUFile are) + * + * Note: Since **buf may get changed, the caller should take care to + * keep a pointer to the original buffer if it needs to deallocate it. + */ +size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size) +{ + if (size < IO_BUF_SIZE) { + size_t res; + uint8_t *src; + + res = qemu_peek_buffer(f, &src, size, 0); + + if (res == size) { + qemu_file_skip(f, res); + *buf = src; + return res; + } + } + + return qemu_get_buffer(f, *buf, size); +} + /* * Peeks a single byte from the buffer; this isn't guaranteed to work if * offset leaves a gap after the previous read/peeked data. -- cgit v1.2.3 From a800cd5c38ba4ac20fe9ca68a6dee408f2d5b11f Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 5 Nov 2015 18:10:36 +0000 Subject: Add wrapper for setting blocking status on a QEMUFile Add a wrapper to change the blocking status on a QEMUFile rather than having to use qemu_set_block(qemu_get_fd(f)); it seems best to avoid exposing the fd since not all QEMUFile's really have one. With this wrapper we could move the implementation down to be different on different transports. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Amit Shah Reviewed-by: Juan Quintela Signed-off-by: Juan Quintela --- migration/qemu-file.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'migration/qemu-file.c') diff --git a/migration/qemu-file.c b/migration/qemu-file.c index e41a677fe3..9ec22678a8 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -648,3 +648,18 @@ size_t qemu_get_counted_string(QEMUFile *f, char buf[256]) return res == len ? res : 0; } + +/* + * Set the blocking state of the QEMUFile. + * Note: On some transports the OS only keeps a single blocking state for + * both directions, and thus changing the blocking on the main + * QEMUFile can also affect the return path. + */ +void qemu_file_set_blocking(QEMUFile *f, bool block) +{ + if (block) { + qemu_set_block(qemu_get_fd(f)); + } else { + qemu_set_nonblock(qemu_get_fd(f)); + } +} -- cgit v1.2.3 From adc468e9b9ad866cd95b1e567291f9dcc1f49f1c Mon Sep 17 00:00:00 2001 From: "Dr. David Alan Gilbert" Date: Thu, 5 Nov 2015 18:10:43 +0000 Subject: Return path: Open a return path on QEMUFile for sockets Postcopy needs a method to send messages from the destination back to the source, this is the 'return path'. Wire it up for 'socket' QEMUFile's. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Juan Quintela Reviewed-by: Amit Shah Signed-off-by: Juan Quintela --- migration/qemu-file.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'migration/qemu-file.c') diff --git a/migration/qemu-file.c b/migration/qemu-file.c index 9ec22678a8..0bbd2574a8 100644 --- a/migration/qemu-file.c +++ b/migration/qemu-file.c @@ -44,6 +44,18 @@ int qemu_file_shutdown(QEMUFile *f) return f->ops->shut_down(f->opaque, true, true); } +/* + * Result: QEMUFile* for a 'return path' for comms in the opposite direction + * NULL if not available + */ +QEMUFile *qemu_file_get_return_path(QEMUFile *f) +{ + if (!f->ops->get_return_path) { + return NULL; + } + return f->ops->get_return_path(f->opaque); +} + bool qemu_file_mode_is_not_valid(const char *mode) { if (mode == NULL || -- cgit v1.2.3