160fe637bSDr. David Alan Gilbert /* 260fe637bSDr. David Alan Gilbert * QEMU System Emulator 360fe637bSDr. David Alan Gilbert * 460fe637bSDr. David Alan Gilbert * Copyright (c) 2003-2008 Fabrice Bellard 560fe637bSDr. David Alan Gilbert * 660fe637bSDr. David Alan Gilbert * Permission is hereby granted, free of charge, to any person obtaining a copy 760fe637bSDr. David Alan Gilbert * of this software and associated documentation files (the "Software"), to deal 860fe637bSDr. David Alan Gilbert * in the Software without restriction, including without limitation the rights 960fe637bSDr. David Alan Gilbert * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 1060fe637bSDr. David Alan Gilbert * copies of the Software, and to permit persons to whom the Software is 1160fe637bSDr. David Alan Gilbert * furnished to do so, subject to the following conditions: 1260fe637bSDr. David Alan Gilbert * 1360fe637bSDr. David Alan Gilbert * The above copyright notice and this permission notice shall be included in 1460fe637bSDr. David Alan Gilbert * all copies or substantial portions of the Software. 1560fe637bSDr. David Alan Gilbert * 1660fe637bSDr. David Alan Gilbert * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1760fe637bSDr. David Alan Gilbert * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1860fe637bSDr. David Alan Gilbert * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1960fe637bSDr. David Alan Gilbert * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 2060fe637bSDr. David Alan Gilbert * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2160fe637bSDr. David Alan Gilbert * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2260fe637bSDr. David Alan Gilbert * THE SOFTWARE. 2360fe637bSDr. David Alan Gilbert */ 241393a485SPeter Maydell #include "qemu/osdep.h" 2544f0eadcSLiang Li #include <zlib.h> 26b85ea5faSPeter Maydell #include "qemu/madvise.h" 27d49b6836SMarkus Armbruster #include "qemu/error-report.h" 2860fe637bSDr. David Alan Gilbert #include "qemu/iov.h" 296666c96aSJuan Quintela #include "migration.h" 3008a0aee1SJuan Quintela #include "qemu-file.h" 3160fe637bSDr. David Alan Gilbert #include "trace.h" 323d661c8aSYury Kotov #include "qapi/error.h" 3360fe637bSDr. David Alan Gilbert 34a24939f2SDaniel P. Berrange #define IO_BUF_SIZE 32768 35f9919116SEric Blake #define MAX_IOV_SIZE MIN_CONST(IOV_MAX, 64) 36a24939f2SDaniel P. Berrange 37a24939f2SDaniel P. Berrange struct QEMUFile { 38a24939f2SDaniel P. Berrange const QEMUFileOps *ops; 39a24939f2SDaniel P. Berrange const QEMUFileHooks *hooks; 40a24939f2SDaniel P. Berrange void *opaque; 41a24939f2SDaniel P. Berrange 42c7fc8d32SDaniel P. Berrangé /* 43c7fc8d32SDaniel P. Berrangé * Maximum amount of data in bytes to transfer during one 44c7fc8d32SDaniel P. Berrangé * rate limiting time window 45c7fc8d32SDaniel P. Berrangé */ 46c7fc8d32SDaniel P. Berrangé int64_t rate_limit_max; 47c7fc8d32SDaniel P. Berrangé /* 48c7fc8d32SDaniel P. Berrangé * Total amount of data in bytes queued for transfer 49c7fc8d32SDaniel P. Berrangé * during this rate limiting time window 50c7fc8d32SDaniel P. Berrangé */ 51c7fc8d32SDaniel P. Berrangé int64_t rate_limit_used; 52a24939f2SDaniel P. Berrange 53154d87b4SDaniel P. Berrangé /* The sum of bytes transferred on the wire */ 54154d87b4SDaniel P. Berrangé int64_t total_transferred; 55154d87b4SDaniel P. Berrangé 56a24939f2SDaniel P. Berrange int buf_index; 57a24939f2SDaniel P. Berrange int buf_size; /* 0 when writing */ 58a24939f2SDaniel P. Berrange uint8_t buf[IO_BUF_SIZE]; 59a24939f2SDaniel P. Berrange 6053f09a10SPavel Butsykin DECLARE_BITMAP(may_free, MAX_IOV_SIZE); 61a24939f2SDaniel P. Berrange struct iovec iov[MAX_IOV_SIZE]; 62a24939f2SDaniel P. Berrange unsigned int iovcnt; 63a24939f2SDaniel P. Berrange 64a24939f2SDaniel P. Berrange int last_error; 653d661c8aSYury Kotov Error *last_error_obj; 66a555b809SJuan Quintela /* has the file has been shutdown */ 67a555b809SJuan Quintela bool shutdown; 68c6ad5be7SPeter Xu /* Whether opaque points to a QIOChannel */ 69c6ad5be7SPeter Xu bool has_ioc; 70a24939f2SDaniel P. Berrange }; 71a24939f2SDaniel P. Berrange 72e1a8c9b6SDr. David Alan Gilbert /* 73e1a8c9b6SDr. David Alan Gilbert * Stop a file from being read/written - not all backing files can do this 74e1a8c9b6SDr. David Alan Gilbert * typically only sockets can. 75e1a8c9b6SDr. David Alan Gilbert */ 76e1a8c9b6SDr. David Alan Gilbert int qemu_file_shutdown(QEMUFile *f) 77e1a8c9b6SDr. David Alan Gilbert { 78a555b809SJuan Quintela int ret; 79a555b809SJuan Quintela 80a555b809SJuan Quintela f->shutdown = true; 81e1a8c9b6SDr. David Alan Gilbert if (!f->ops->shut_down) { 82e1a8c9b6SDr. David Alan Gilbert return -ENOSYS; 83e1a8c9b6SDr. David Alan Gilbert } 84a555b809SJuan Quintela ret = f->ops->shut_down(f->opaque, true, true, NULL); 85a555b809SJuan Quintela 86a555b809SJuan Quintela if (!f->last_error) { 87a555b809SJuan Quintela qemu_file_set_error(f, -EIO); 88a555b809SJuan Quintela } 89a555b809SJuan Quintela return ret; 90e1a8c9b6SDr. David Alan Gilbert } 91e1a8c9b6SDr. David Alan Gilbert 92adc468e9SDr. David Alan Gilbert /* 93adc468e9SDr. David Alan Gilbert * Result: QEMUFile* for a 'return path' for comms in the opposite direction 94adc468e9SDr. David Alan Gilbert * NULL if not available 95adc468e9SDr. David Alan Gilbert */ 96adc468e9SDr. David Alan Gilbert QEMUFile *qemu_file_get_return_path(QEMUFile *f) 97adc468e9SDr. David Alan Gilbert { 98adc468e9SDr. David Alan Gilbert if (!f->ops->get_return_path) { 99adc468e9SDr. David Alan Gilbert return NULL; 100adc468e9SDr. David Alan Gilbert } 101adc468e9SDr. David Alan Gilbert return f->ops->get_return_path(f->opaque); 102adc468e9SDr. David Alan Gilbert } 103adc468e9SDr. David Alan Gilbert 10460fe637bSDr. David Alan Gilbert bool qemu_file_mode_is_not_valid(const char *mode) 10560fe637bSDr. David Alan Gilbert { 10660fe637bSDr. David Alan Gilbert if (mode == NULL || 10760fe637bSDr. David Alan Gilbert (mode[0] != 'r' && mode[0] != 'w') || 10860fe637bSDr. David Alan Gilbert mode[1] != 'b' || mode[2] != 0) { 10960fe637bSDr. David Alan Gilbert fprintf(stderr, "qemu_fopen: Argument validity check failed\n"); 11060fe637bSDr. David Alan Gilbert return true; 11160fe637bSDr. David Alan Gilbert } 11260fe637bSDr. David Alan Gilbert 11360fe637bSDr. David Alan Gilbert return false; 11460fe637bSDr. David Alan Gilbert } 11560fe637bSDr. David Alan Gilbert 116c6ad5be7SPeter Xu QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops, bool has_ioc) 11760fe637bSDr. David Alan Gilbert { 11860fe637bSDr. David Alan Gilbert QEMUFile *f; 11960fe637bSDr. David Alan Gilbert 12097f3ad35SMarkus Armbruster f = g_new0(QEMUFile, 1); 12160fe637bSDr. David Alan Gilbert 12260fe637bSDr. David Alan Gilbert f->opaque = opaque; 12360fe637bSDr. David Alan Gilbert f->ops = ops; 124c6ad5be7SPeter Xu f->has_ioc = has_ioc; 12560fe637bSDr. David Alan Gilbert return f; 12660fe637bSDr. David Alan Gilbert } 12760fe637bSDr. David Alan Gilbert 1280436e09fSDaniel P. Berrange 1290436e09fSDaniel P. Berrange void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks) 1300436e09fSDaniel P. Berrange { 1310436e09fSDaniel P. Berrange f->hooks = hooks; 1320436e09fSDaniel P. Berrange } 1330436e09fSDaniel P. Berrange 13460fe637bSDr. David Alan Gilbert /* 1353d661c8aSYury Kotov * Get last error for stream f with optional Error* 1363d661c8aSYury Kotov * 1373d661c8aSYury Kotov * Return negative error value if there has been an error on previous 1383d661c8aSYury Kotov * operations, return 0 if no error happened. 1393d661c8aSYury Kotov * Optional, it returns Error* in errp, but it may be NULL even if return value 1403d661c8aSYury Kotov * is not 0. 1413d661c8aSYury Kotov * 1423d661c8aSYury Kotov */ 1433d661c8aSYury Kotov int qemu_file_get_error_obj(QEMUFile *f, Error **errp) 1443d661c8aSYury Kotov { 1453d661c8aSYury Kotov if (errp) { 1463d661c8aSYury Kotov *errp = f->last_error_obj ? error_copy(f->last_error_obj) : NULL; 1473d661c8aSYury Kotov } 1483d661c8aSYury Kotov return f->last_error; 1493d661c8aSYury Kotov } 1503d661c8aSYury Kotov 1513d661c8aSYury Kotov /* 1523d661c8aSYury Kotov * Set the last error for stream f with optional Error* 1533d661c8aSYury Kotov */ 1543d661c8aSYury Kotov void qemu_file_set_error_obj(QEMUFile *f, int ret, Error *err) 1553d661c8aSYury Kotov { 1563d661c8aSYury Kotov if (f->last_error == 0 && ret) { 1573d661c8aSYury Kotov f->last_error = ret; 1583d661c8aSYury Kotov error_propagate(&f->last_error_obj, err); 1593d661c8aSYury Kotov } else if (err) { 1603d661c8aSYury Kotov error_report_err(err); 1613d661c8aSYury Kotov } 1623d661c8aSYury Kotov } 1633d661c8aSYury Kotov 1643d661c8aSYury Kotov /* 16560fe637bSDr. David Alan Gilbert * Get last error for stream f 16660fe637bSDr. David Alan Gilbert * 16760fe637bSDr. David Alan Gilbert * Return negative error value if there has been an error on previous 16860fe637bSDr. David Alan Gilbert * operations, return 0 if no error happened. 16960fe637bSDr. David Alan Gilbert * 17060fe637bSDr. David Alan Gilbert */ 17160fe637bSDr. David Alan Gilbert int qemu_file_get_error(QEMUFile *f) 17260fe637bSDr. David Alan Gilbert { 1733d661c8aSYury Kotov return qemu_file_get_error_obj(f, NULL); 17460fe637bSDr. David Alan Gilbert } 17560fe637bSDr. David Alan Gilbert 1763d661c8aSYury Kotov /* 1773d661c8aSYury Kotov * Set the last error for stream f 1783d661c8aSYury Kotov */ 17960fe637bSDr. David Alan Gilbert void qemu_file_set_error(QEMUFile *f, int ret) 18060fe637bSDr. David Alan Gilbert { 1813d661c8aSYury Kotov qemu_file_set_error_obj(f, ret, NULL); 18260fe637bSDr. David Alan Gilbert } 18360fe637bSDr. David Alan Gilbert 18460fe637bSDr. David Alan Gilbert bool qemu_file_is_writable(QEMUFile *f) 18560fe637bSDr. David Alan Gilbert { 18611808bb0SDaniel P. Berrange return f->ops->writev_buffer; 18760fe637bSDr. David Alan Gilbert } 18860fe637bSDr. David Alan Gilbert 18953f09a10SPavel Butsykin static void qemu_iovec_release_ram(QEMUFile *f) 19053f09a10SPavel Butsykin { 19153f09a10SPavel Butsykin struct iovec iov; 19253f09a10SPavel Butsykin unsigned long idx; 19353f09a10SPavel Butsykin 19453f09a10SPavel Butsykin /* Find and release all the contiguous memory ranges marked as may_free. */ 19553f09a10SPavel Butsykin idx = find_next_bit(f->may_free, f->iovcnt, 0); 19653f09a10SPavel Butsykin if (idx >= f->iovcnt) { 19753f09a10SPavel Butsykin return; 19853f09a10SPavel Butsykin } 19953f09a10SPavel Butsykin iov = f->iov[idx]; 20053f09a10SPavel Butsykin 20153f09a10SPavel Butsykin /* The madvise() in the loop is called for iov within a continuous range and 20253f09a10SPavel Butsykin * then reinitialize the iov. And in the end, madvise() is called for the 20353f09a10SPavel Butsykin * last iov. 20453f09a10SPavel Butsykin */ 20553f09a10SPavel Butsykin while ((idx = find_next_bit(f->may_free, f->iovcnt, idx + 1)) < f->iovcnt) { 20653f09a10SPavel Butsykin /* check for adjacent buffer and coalesce them */ 20753f09a10SPavel Butsykin if (iov.iov_base + iov.iov_len == f->iov[idx].iov_base) { 20853f09a10SPavel Butsykin iov.iov_len += f->iov[idx].iov_len; 20953f09a10SPavel Butsykin continue; 21053f09a10SPavel Butsykin } 21153f09a10SPavel Butsykin if (qemu_madvise(iov.iov_base, iov.iov_len, QEMU_MADV_DONTNEED) < 0) { 21253f09a10SPavel Butsykin error_report("migrate: madvise DONTNEED failed %p %zd: %s", 21353f09a10SPavel Butsykin iov.iov_base, iov.iov_len, strerror(errno)); 21453f09a10SPavel Butsykin } 21553f09a10SPavel Butsykin iov = f->iov[idx]; 21653f09a10SPavel Butsykin } 21753f09a10SPavel Butsykin if (qemu_madvise(iov.iov_base, iov.iov_len, QEMU_MADV_DONTNEED) < 0) { 21853f09a10SPavel Butsykin error_report("migrate: madvise DONTNEED failed %p %zd: %s", 21953f09a10SPavel Butsykin iov.iov_base, iov.iov_len, strerror(errno)); 22053f09a10SPavel Butsykin } 22153f09a10SPavel Butsykin memset(f->may_free, 0, sizeof(f->may_free)); 22253f09a10SPavel Butsykin } 22353f09a10SPavel Butsykin 22460fe637bSDr. David Alan Gilbert /** 22560fe637bSDr. David Alan Gilbert * Flushes QEMUFile buffer 22660fe637bSDr. David Alan Gilbert * 2273b348706SDr. David Alan Gilbert * This will flush all pending data. If data was only partially flushed, it 2283b348706SDr. David Alan Gilbert * will set an error state. 22960fe637bSDr. David Alan Gilbert */ 23060fe637bSDr. David Alan Gilbert void qemu_fflush(QEMUFile *f) 23160fe637bSDr. David Alan Gilbert { 23260fe637bSDr. David Alan Gilbert ssize_t ret = 0; 233baf51e77SDaniel P. Berrange ssize_t expect = 0; 2343d661c8aSYury Kotov Error *local_error = NULL; 23560fe637bSDr. David Alan Gilbert 23660fe637bSDr. David Alan Gilbert if (!qemu_file_is_writable(f)) { 23760fe637bSDr. David Alan Gilbert return; 23860fe637bSDr. David Alan Gilbert } 23960fe637bSDr. David Alan Gilbert 240a555b809SJuan Quintela if (f->shutdown) { 241a555b809SJuan Quintela return; 242a555b809SJuan Quintela } 24360fe637bSDr. David Alan Gilbert if (f->iovcnt > 0) { 244baf51e77SDaniel P. Berrange expect = iov_size(f->iov, f->iovcnt); 245154d87b4SDaniel P. Berrangé ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, 246154d87b4SDaniel P. Berrangé f->total_transferred, &local_error); 24753f09a10SPavel Butsykin 24853f09a10SPavel Butsykin qemu_iovec_release_ram(f); 24960fe637bSDr. David Alan Gilbert } 250baf51e77SDaniel P. Berrange 25160fe637bSDr. David Alan Gilbert if (ret >= 0) { 252154d87b4SDaniel P. Berrangé f->total_transferred += ret; 25360fe637bSDr. David Alan Gilbert } 254baf51e77SDaniel P. Berrange /* We expect the QEMUFile write impl to send the full 255baf51e77SDaniel P. Berrange * data set we requested, so sanity check that. 256baf51e77SDaniel P. Berrange */ 257baf51e77SDaniel P. Berrange if (ret != expect) { 2583d661c8aSYury Kotov qemu_file_set_error_obj(f, ret < 0 ? ret : -EIO, local_error); 259baf51e77SDaniel P. Berrange } 26060fe637bSDr. David Alan Gilbert f->buf_index = 0; 26160fe637bSDr. David Alan Gilbert f->iovcnt = 0; 26260fe637bSDr. David Alan Gilbert } 26360fe637bSDr. David Alan Gilbert 26460fe637bSDr. David Alan Gilbert void ram_control_before_iterate(QEMUFile *f, uint64_t flags) 26560fe637bSDr. David Alan Gilbert { 26660fe637bSDr. David Alan Gilbert int ret = 0; 26760fe637bSDr. David Alan Gilbert 2680436e09fSDaniel P. Berrange if (f->hooks && f->hooks->before_ram_iterate) { 269365c0463SDaniel P. Berrangé ret = f->hooks->before_ram_iterate(f, flags, NULL); 27060fe637bSDr. David Alan Gilbert if (ret < 0) { 27160fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 27260fe637bSDr. David Alan Gilbert } 27360fe637bSDr. David Alan Gilbert } 27460fe637bSDr. David Alan Gilbert } 27560fe637bSDr. David Alan Gilbert 27660fe637bSDr. David Alan Gilbert void ram_control_after_iterate(QEMUFile *f, uint64_t flags) 27760fe637bSDr. David Alan Gilbert { 27860fe637bSDr. David Alan Gilbert int ret = 0; 27960fe637bSDr. David Alan Gilbert 2800436e09fSDaniel P. Berrange if (f->hooks && f->hooks->after_ram_iterate) { 281365c0463SDaniel P. Berrangé ret = f->hooks->after_ram_iterate(f, flags, NULL); 28260fe637bSDr. David Alan Gilbert if (ret < 0) { 28360fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 28460fe637bSDr. David Alan Gilbert } 28560fe637bSDr. David Alan Gilbert } 28660fe637bSDr. David Alan Gilbert } 28760fe637bSDr. David Alan Gilbert 288632e3a5cSDr. David Alan Gilbert void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data) 28960fe637bSDr. David Alan Gilbert { 29060fe637bSDr. David Alan Gilbert int ret = -EINVAL; 29160fe637bSDr. David Alan Gilbert 2920436e09fSDaniel P. Berrange if (f->hooks && f->hooks->hook_ram_load) { 293365c0463SDaniel P. Berrangé ret = f->hooks->hook_ram_load(f, flags, data); 29460fe637bSDr. David Alan Gilbert if (ret < 0) { 29560fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 29660fe637bSDr. David Alan Gilbert } 29760fe637bSDr. David Alan Gilbert } else { 298632e3a5cSDr. David Alan Gilbert /* 299632e3a5cSDr. David Alan Gilbert * Hook is a hook specifically requested by the source sending a flag 300632e3a5cSDr. David Alan Gilbert * that expects there to be a hook on the destination. 301632e3a5cSDr. David Alan Gilbert */ 302632e3a5cSDr. David Alan Gilbert if (flags == RAM_CONTROL_HOOK) { 30360fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 30460fe637bSDr. David Alan Gilbert } 30560fe637bSDr. David Alan Gilbert } 306632e3a5cSDr. David Alan Gilbert } 30760fe637bSDr. David Alan Gilbert 30860fe637bSDr. David Alan Gilbert size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset, 3096e1dea46SJuan Quintela ram_addr_t offset, size_t size, 3106e1dea46SJuan Quintela uint64_t *bytes_sent) 31160fe637bSDr. David Alan Gilbert { 3120436e09fSDaniel P. Berrange if (f->hooks && f->hooks->save_page) { 313365c0463SDaniel P. Berrangé int ret = f->hooks->save_page(f, block_offset, 31460fe637bSDr. David Alan Gilbert offset, size, bytes_sent); 315ccb7e1b5SLidong Chen if (ret != RAM_SAVE_CONTROL_NOT_SUPP) { 316c7fc8d32SDaniel P. Berrangé f->rate_limit_used += size; 317ccb7e1b5SLidong Chen } 318ccb7e1b5SLidong Chen 319ccb7e1b5SLidong Chen if (ret != RAM_SAVE_CONTROL_DELAYED && 320ccb7e1b5SLidong Chen ret != RAM_SAVE_CONTROL_NOT_SUPP) { 32160fe637bSDr. David Alan Gilbert if (bytes_sent && *bytes_sent > 0) { 3221a93bd2fSDaniel P. Berrangé qemu_file_credit_transfer(f, *bytes_sent); 32360fe637bSDr. David Alan Gilbert } else if (ret < 0) { 32460fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 32560fe637bSDr. David Alan Gilbert } 32660fe637bSDr. David Alan Gilbert } 32760fe637bSDr. David Alan Gilbert 32860fe637bSDr. David Alan Gilbert return ret; 32960fe637bSDr. David Alan Gilbert } 33060fe637bSDr. David Alan Gilbert 33160fe637bSDr. David Alan Gilbert return RAM_SAVE_CONTROL_NOT_SUPP; 33260fe637bSDr. David Alan Gilbert } 33360fe637bSDr. David Alan Gilbert 33460fe637bSDr. David Alan Gilbert /* 33560fe637bSDr. David Alan Gilbert * Attempt to fill the buffer from the underlying file 33660fe637bSDr. David Alan Gilbert * Returns the number of bytes read, or negative value for an error. 33760fe637bSDr. David Alan Gilbert * 33860fe637bSDr. David Alan Gilbert * Note that it can return a partially full buffer even in a not error/not EOF 33960fe637bSDr. David Alan Gilbert * case if the underlying file descriptor gives a short read, and that can 34060fe637bSDr. David Alan Gilbert * happen even on a blocking fd. 34160fe637bSDr. David Alan Gilbert */ 34260fe637bSDr. David Alan Gilbert static ssize_t qemu_fill_buffer(QEMUFile *f) 34360fe637bSDr. David Alan Gilbert { 34460fe637bSDr. David Alan Gilbert int len; 34560fe637bSDr. David Alan Gilbert int pending; 3463d661c8aSYury Kotov Error *local_error = NULL; 34760fe637bSDr. David Alan Gilbert 34860fe637bSDr. David Alan Gilbert assert(!qemu_file_is_writable(f)); 34960fe637bSDr. David Alan Gilbert 35060fe637bSDr. David Alan Gilbert pending = f->buf_size - f->buf_index; 35160fe637bSDr. David Alan Gilbert if (pending > 0) { 35260fe637bSDr. David Alan Gilbert memmove(f->buf, f->buf + f->buf_index, pending); 35360fe637bSDr. David Alan Gilbert } 35460fe637bSDr. David Alan Gilbert f->buf_index = 0; 35560fe637bSDr. David Alan Gilbert f->buf_size = pending; 35660fe637bSDr. David Alan Gilbert 357a555b809SJuan Quintela if (f->shutdown) { 358a555b809SJuan Quintela return 0; 359a555b809SJuan Quintela } 360a555b809SJuan Quintela 361154d87b4SDaniel P. Berrangé len = f->ops->get_buffer(f->opaque, f->buf + pending, f->total_transferred, 3623d661c8aSYury Kotov IO_BUF_SIZE - pending, &local_error); 36360fe637bSDr. David Alan Gilbert if (len > 0) { 36460fe637bSDr. David Alan Gilbert f->buf_size += len; 365154d87b4SDaniel P. Berrangé f->total_transferred += len; 36660fe637bSDr. David Alan Gilbert } else if (len == 0) { 3673d661c8aSYury Kotov qemu_file_set_error_obj(f, -EIO, local_error); 36860fe637bSDr. David Alan Gilbert } else if (len != -EAGAIN) { 3693d661c8aSYury Kotov qemu_file_set_error_obj(f, len, local_error); 3703d661c8aSYury Kotov } else { 3713d661c8aSYury Kotov error_free(local_error); 37260fe637bSDr. David Alan Gilbert } 37360fe637bSDr. David Alan Gilbert 37460fe637bSDr. David Alan Gilbert return len; 37560fe637bSDr. David Alan Gilbert } 37660fe637bSDr. David Alan Gilbert 3771a93bd2fSDaniel P. Berrangé void qemu_file_credit_transfer(QEMUFile *f, size_t size) 37860fe637bSDr. David Alan Gilbert { 379154d87b4SDaniel P. Berrangé f->total_transferred += size; 38060fe637bSDr. David Alan Gilbert } 38160fe637bSDr. David Alan Gilbert 38260fe637bSDr. David Alan Gilbert /** Closes the file 38360fe637bSDr. David Alan Gilbert * 38460fe637bSDr. David Alan Gilbert * Returns negative error value if any error happened on previous operations or 38560fe637bSDr. David Alan Gilbert * while closing the file. Returns 0 or positive number on success. 38660fe637bSDr. David Alan Gilbert * 38760fe637bSDr. David Alan Gilbert * The meaning of return value on success depends on the specific backend 38860fe637bSDr. David Alan Gilbert * being used. 38960fe637bSDr. David Alan Gilbert */ 39060fe637bSDr. David Alan Gilbert int qemu_fclose(QEMUFile *f) 39160fe637bSDr. David Alan Gilbert { 39260fe637bSDr. David Alan Gilbert int ret; 39360fe637bSDr. David Alan Gilbert qemu_fflush(f); 39460fe637bSDr. David Alan Gilbert ret = qemu_file_get_error(f); 39560fe637bSDr. David Alan Gilbert 39660fe637bSDr. David Alan Gilbert if (f->ops->close) { 3973d661c8aSYury Kotov int ret2 = f->ops->close(f->opaque, NULL); 39860fe637bSDr. David Alan Gilbert if (ret >= 0) { 39960fe637bSDr. David Alan Gilbert ret = ret2; 40060fe637bSDr. David Alan Gilbert } 40160fe637bSDr. David Alan Gilbert } 40260fe637bSDr. David Alan Gilbert /* If any error was spotted before closing, we should report it 40360fe637bSDr. David Alan Gilbert * instead of the close() return value. 40460fe637bSDr. David Alan Gilbert */ 40560fe637bSDr. David Alan Gilbert if (f->last_error) { 40660fe637bSDr. David Alan Gilbert ret = f->last_error; 40760fe637bSDr. David Alan Gilbert } 4083d661c8aSYury Kotov error_free(f->last_error_obj); 40960fe637bSDr. David Alan Gilbert g_free(f); 41060fe637bSDr. David Alan Gilbert trace_qemu_file_fclose(); 41160fe637bSDr. David Alan Gilbert return ret; 41260fe637bSDr. David Alan Gilbert } 41360fe637bSDr. David Alan Gilbert 4141bf57fb3SWei Yang /* 4151bf57fb3SWei Yang * Add buf to iovec. Do flush if iovec is full. 4161bf57fb3SWei Yang * 4171bf57fb3SWei Yang * Return values: 4181bf57fb3SWei Yang * 1 iovec is full and flushed 4191bf57fb3SWei Yang * 0 iovec is not flushed 4201bf57fb3SWei Yang * 4211bf57fb3SWei Yang */ 4221bf57fb3SWei Yang static int add_to_iovec(QEMUFile *f, const uint8_t *buf, size_t size, 42353f09a10SPavel Butsykin bool may_free) 42460fe637bSDr. David Alan Gilbert { 42560fe637bSDr. David Alan Gilbert /* check for adjacent buffer and coalesce them */ 42660fe637bSDr. David Alan Gilbert if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base + 42753f09a10SPavel Butsykin f->iov[f->iovcnt - 1].iov_len && 42853f09a10SPavel Butsykin may_free == test_bit(f->iovcnt - 1, f->may_free)) 42953f09a10SPavel Butsykin { 43060fe637bSDr. David Alan Gilbert f->iov[f->iovcnt - 1].iov_len += size; 43160fe637bSDr. David Alan Gilbert } else { 432c00d434aSFeng Lin if (f->iovcnt >= MAX_IOV_SIZE) { 433c00d434aSFeng Lin /* Should only happen if a previous fflush failed */ 434c00d434aSFeng Lin assert(f->shutdown || !qemu_file_is_writable(f)); 435c00d434aSFeng Lin return 1; 436c00d434aSFeng Lin } 43753f09a10SPavel Butsykin if (may_free) { 43853f09a10SPavel Butsykin set_bit(f->iovcnt, f->may_free); 43953f09a10SPavel Butsykin } 44060fe637bSDr. David Alan Gilbert f->iov[f->iovcnt].iov_base = (uint8_t *)buf; 44160fe637bSDr. David Alan Gilbert f->iov[f->iovcnt++].iov_len = size; 44260fe637bSDr. David Alan Gilbert } 44360fe637bSDr. David Alan Gilbert 44460fe637bSDr. David Alan Gilbert if (f->iovcnt >= MAX_IOV_SIZE) { 44560fe637bSDr. David Alan Gilbert qemu_fflush(f); 4461bf57fb3SWei Yang return 1; 4471bf57fb3SWei Yang } 4481bf57fb3SWei Yang 4491bf57fb3SWei Yang return 0; 4501bf57fb3SWei Yang } 4511bf57fb3SWei Yang 4521bf57fb3SWei Yang static void add_buf_to_iovec(QEMUFile *f, size_t len) 4531bf57fb3SWei Yang { 4541bf57fb3SWei Yang if (!add_to_iovec(f, f->buf + f->buf_index, len, false)) { 4551bf57fb3SWei Yang f->buf_index += len; 4561bf57fb3SWei Yang if (f->buf_index == IO_BUF_SIZE) { 4571bf57fb3SWei Yang qemu_fflush(f); 4581bf57fb3SWei Yang } 45960fe637bSDr. David Alan Gilbert } 46060fe637bSDr. David Alan Gilbert } 46160fe637bSDr. David Alan Gilbert 46253f09a10SPavel Butsykin void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size, 46353f09a10SPavel Butsykin bool may_free) 46460fe637bSDr. David Alan Gilbert { 46560fe637bSDr. David Alan Gilbert if (f->last_error) { 46660fe637bSDr. David Alan Gilbert return; 46760fe637bSDr. David Alan Gilbert } 46860fe637bSDr. David Alan Gilbert 469c7fc8d32SDaniel P. Berrangé f->rate_limit_used += size; 47053f09a10SPavel Butsykin add_to_iovec(f, buf, size, may_free); 47160fe637bSDr. David Alan Gilbert } 47260fe637bSDr. David Alan Gilbert 47356f3835fSDr. David Alan Gilbert void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size) 47460fe637bSDr. David Alan Gilbert { 47556f3835fSDr. David Alan Gilbert size_t l; 47660fe637bSDr. David Alan Gilbert 47760fe637bSDr. David Alan Gilbert if (f->last_error) { 47860fe637bSDr. David Alan Gilbert return; 47960fe637bSDr. David Alan Gilbert } 48060fe637bSDr. David Alan Gilbert 48160fe637bSDr. David Alan Gilbert while (size > 0) { 48260fe637bSDr. David Alan Gilbert l = IO_BUF_SIZE - f->buf_index; 48360fe637bSDr. David Alan Gilbert if (l > size) { 48460fe637bSDr. David Alan Gilbert l = size; 48560fe637bSDr. David Alan Gilbert } 48660fe637bSDr. David Alan Gilbert memcpy(f->buf + f->buf_index, buf, l); 487c7fc8d32SDaniel P. Berrangé f->rate_limit_used += l; 4881bf57fb3SWei Yang add_buf_to_iovec(f, l); 48960fe637bSDr. David Alan Gilbert if (qemu_file_get_error(f)) { 49060fe637bSDr. David Alan Gilbert break; 49160fe637bSDr. David Alan Gilbert } 49260fe637bSDr. David Alan Gilbert buf += l; 49360fe637bSDr. David Alan Gilbert size -= l; 49460fe637bSDr. David Alan Gilbert } 49560fe637bSDr. David Alan Gilbert } 49660fe637bSDr. David Alan Gilbert 49760fe637bSDr. David Alan Gilbert void qemu_put_byte(QEMUFile *f, int v) 49860fe637bSDr. David Alan Gilbert { 49960fe637bSDr. David Alan Gilbert if (f->last_error) { 50060fe637bSDr. David Alan Gilbert return; 50160fe637bSDr. David Alan Gilbert } 50260fe637bSDr. David Alan Gilbert 50360fe637bSDr. David Alan Gilbert f->buf[f->buf_index] = v; 504c7fc8d32SDaniel P. Berrangé f->rate_limit_used++; 5051bf57fb3SWei Yang add_buf_to_iovec(f, 1); 50660fe637bSDr. David Alan Gilbert } 50760fe637bSDr. David Alan Gilbert 50860fe637bSDr. David Alan Gilbert void qemu_file_skip(QEMUFile *f, int size) 50960fe637bSDr. David Alan Gilbert { 51060fe637bSDr. David Alan Gilbert if (f->buf_index + size <= f->buf_size) { 51160fe637bSDr. David Alan Gilbert f->buf_index += size; 51260fe637bSDr. David Alan Gilbert } 51360fe637bSDr. David Alan Gilbert } 51460fe637bSDr. David Alan Gilbert 51560fe637bSDr. David Alan Gilbert /* 5167c1e52baSDr. David Alan Gilbert * Read 'size' bytes from file (at 'offset') without moving the 5177c1e52baSDr. David Alan Gilbert * pointer and set 'buf' to point to that data. 51860fe637bSDr. David Alan Gilbert * 51960fe637bSDr. David Alan Gilbert * It will return size bytes unless there was an error, in which case it will 52060fe637bSDr. David Alan Gilbert * return as many as it managed to read (assuming blocking fd's which 52160fe637bSDr. David Alan Gilbert * all current QEMUFile are) 52260fe637bSDr. David Alan Gilbert */ 52356f3835fSDr. David Alan Gilbert size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset) 52460fe637bSDr. David Alan Gilbert { 52556f3835fSDr. David Alan Gilbert ssize_t pending; 52656f3835fSDr. David Alan Gilbert size_t index; 52760fe637bSDr. David Alan Gilbert 52860fe637bSDr. David Alan Gilbert assert(!qemu_file_is_writable(f)); 52960fe637bSDr. David Alan Gilbert assert(offset < IO_BUF_SIZE); 53060fe637bSDr. David Alan Gilbert assert(size <= IO_BUF_SIZE - offset); 53160fe637bSDr. David Alan Gilbert 53260fe637bSDr. David Alan Gilbert /* The 1st byte to read from */ 53360fe637bSDr. David Alan Gilbert index = f->buf_index + offset; 53460fe637bSDr. David Alan Gilbert /* The number of available bytes starting at index */ 53560fe637bSDr. David Alan Gilbert pending = f->buf_size - index; 53660fe637bSDr. David Alan Gilbert 53760fe637bSDr. David Alan Gilbert /* 53860fe637bSDr. David Alan Gilbert * qemu_fill_buffer might return just a few bytes, even when there isn't 53960fe637bSDr. David Alan Gilbert * an error, so loop collecting them until we get enough. 54060fe637bSDr. David Alan Gilbert */ 54160fe637bSDr. David Alan Gilbert while (pending < size) { 54260fe637bSDr. David Alan Gilbert int received = qemu_fill_buffer(f); 54360fe637bSDr. David Alan Gilbert 54460fe637bSDr. David Alan Gilbert if (received <= 0) { 54560fe637bSDr. David Alan Gilbert break; 54660fe637bSDr. David Alan Gilbert } 54760fe637bSDr. David Alan Gilbert 54860fe637bSDr. David Alan Gilbert index = f->buf_index + offset; 54960fe637bSDr. David Alan Gilbert pending = f->buf_size - index; 55060fe637bSDr. David Alan Gilbert } 55160fe637bSDr. David Alan Gilbert 55260fe637bSDr. David Alan Gilbert if (pending <= 0) { 55360fe637bSDr. David Alan Gilbert return 0; 55460fe637bSDr. David Alan Gilbert } 55560fe637bSDr. David Alan Gilbert if (size > pending) { 55660fe637bSDr. David Alan Gilbert size = pending; 55760fe637bSDr. David Alan Gilbert } 55860fe637bSDr. David Alan Gilbert 5597c1e52baSDr. David Alan Gilbert *buf = f->buf + index; 56060fe637bSDr. David Alan Gilbert return size; 56160fe637bSDr. David Alan Gilbert } 56260fe637bSDr. David Alan Gilbert 56360fe637bSDr. David Alan Gilbert /* 56460fe637bSDr. David Alan Gilbert * Read 'size' bytes of data from the file into buf. 56560fe637bSDr. David Alan Gilbert * 'size' can be larger than the internal buffer. 56660fe637bSDr. David Alan Gilbert * 56760fe637bSDr. David Alan Gilbert * It will return size bytes unless there was an error, in which case it will 56860fe637bSDr. David Alan Gilbert * return as many as it managed to read (assuming blocking fd's which 56960fe637bSDr. David Alan Gilbert * all current QEMUFile are) 57060fe637bSDr. David Alan Gilbert */ 57156f3835fSDr. David Alan Gilbert size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size) 57260fe637bSDr. David Alan Gilbert { 57356f3835fSDr. David Alan Gilbert size_t pending = size; 57456f3835fSDr. David Alan Gilbert size_t done = 0; 57560fe637bSDr. David Alan Gilbert 57660fe637bSDr. David Alan Gilbert while (pending > 0) { 57756f3835fSDr. David Alan Gilbert size_t res; 5787c1e52baSDr. David Alan Gilbert uint8_t *src; 57960fe637bSDr. David Alan Gilbert 5807c1e52baSDr. David Alan Gilbert res = qemu_peek_buffer(f, &src, MIN(pending, IO_BUF_SIZE), 0); 58160fe637bSDr. David Alan Gilbert if (res == 0) { 58260fe637bSDr. David Alan Gilbert return done; 58360fe637bSDr. David Alan Gilbert } 5847c1e52baSDr. David Alan Gilbert memcpy(buf, src, res); 58560fe637bSDr. David Alan Gilbert qemu_file_skip(f, res); 58660fe637bSDr. David Alan Gilbert buf += res; 58760fe637bSDr. David Alan Gilbert pending -= res; 58860fe637bSDr. David Alan Gilbert done += res; 58960fe637bSDr. David Alan Gilbert } 59060fe637bSDr. David Alan Gilbert return done; 59160fe637bSDr. David Alan Gilbert } 59260fe637bSDr. David Alan Gilbert 59360fe637bSDr. David Alan Gilbert /* 5949504fb51SDr. David Alan Gilbert * Read 'size' bytes of data from the file. 5959504fb51SDr. David Alan Gilbert * 'size' can be larger than the internal buffer. 5969504fb51SDr. David Alan Gilbert * 5979504fb51SDr. David Alan Gilbert * The data: 5989504fb51SDr. David Alan Gilbert * may be held on an internal buffer (in which case *buf is updated 5999504fb51SDr. David Alan Gilbert * to point to it) that is valid until the next qemu_file operation. 6009504fb51SDr. David Alan Gilbert * OR 6019504fb51SDr. David Alan Gilbert * will be copied to the *buf that was passed in. 6029504fb51SDr. David Alan Gilbert * 6039504fb51SDr. David Alan Gilbert * The code tries to avoid the copy if possible. 6049504fb51SDr. David Alan Gilbert * 6059504fb51SDr. David Alan Gilbert * It will return size bytes unless there was an error, in which case it will 6069504fb51SDr. David Alan Gilbert * return as many as it managed to read (assuming blocking fd's which 6079504fb51SDr. David Alan Gilbert * all current QEMUFile are) 6089504fb51SDr. David Alan Gilbert * 6099504fb51SDr. David Alan Gilbert * Note: Since **buf may get changed, the caller should take care to 6109504fb51SDr. David Alan Gilbert * keep a pointer to the original buffer if it needs to deallocate it. 6119504fb51SDr. David Alan Gilbert */ 6129504fb51SDr. David Alan Gilbert size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size) 6139504fb51SDr. David Alan Gilbert { 6149504fb51SDr. David Alan Gilbert if (size < IO_BUF_SIZE) { 6159504fb51SDr. David Alan Gilbert size_t res; 6161dfafcbdSWainer dos Santos Moschetta uint8_t *src = NULL; 6179504fb51SDr. David Alan Gilbert 6189504fb51SDr. David Alan Gilbert res = qemu_peek_buffer(f, &src, size, 0); 6199504fb51SDr. David Alan Gilbert 6209504fb51SDr. David Alan Gilbert if (res == size) { 6219504fb51SDr. David Alan Gilbert qemu_file_skip(f, res); 6229504fb51SDr. David Alan Gilbert *buf = src; 6239504fb51SDr. David Alan Gilbert return res; 6249504fb51SDr. David Alan Gilbert } 6259504fb51SDr. David Alan Gilbert } 6269504fb51SDr. David Alan Gilbert 6279504fb51SDr. David Alan Gilbert return qemu_get_buffer(f, *buf, size); 6289504fb51SDr. David Alan Gilbert } 6299504fb51SDr. David Alan Gilbert 6309504fb51SDr. David Alan Gilbert /* 63160fe637bSDr. David Alan Gilbert * Peeks a single byte from the buffer; this isn't guaranteed to work if 63260fe637bSDr. David Alan Gilbert * offset leaves a gap after the previous read/peeked data. 63360fe637bSDr. David Alan Gilbert */ 63460fe637bSDr. David Alan Gilbert int qemu_peek_byte(QEMUFile *f, int offset) 63560fe637bSDr. David Alan Gilbert { 63660fe637bSDr. David Alan Gilbert int index = f->buf_index + offset; 63760fe637bSDr. David Alan Gilbert 63860fe637bSDr. David Alan Gilbert assert(!qemu_file_is_writable(f)); 63960fe637bSDr. David Alan Gilbert assert(offset < IO_BUF_SIZE); 64060fe637bSDr. David Alan Gilbert 64160fe637bSDr. David Alan Gilbert if (index >= f->buf_size) { 64260fe637bSDr. David Alan Gilbert qemu_fill_buffer(f); 64360fe637bSDr. David Alan Gilbert index = f->buf_index + offset; 64460fe637bSDr. David Alan Gilbert if (index >= f->buf_size) { 64560fe637bSDr. David Alan Gilbert return 0; 64660fe637bSDr. David Alan Gilbert } 64760fe637bSDr. David Alan Gilbert } 64860fe637bSDr. David Alan Gilbert return f->buf[index]; 64960fe637bSDr. David Alan Gilbert } 65060fe637bSDr. David Alan Gilbert 65160fe637bSDr. David Alan Gilbert int qemu_get_byte(QEMUFile *f) 65260fe637bSDr. David Alan Gilbert { 65360fe637bSDr. David Alan Gilbert int result; 65460fe637bSDr. David Alan Gilbert 65560fe637bSDr. David Alan Gilbert result = qemu_peek_byte(f, 0); 65660fe637bSDr. David Alan Gilbert qemu_file_skip(f, 1); 65760fe637bSDr. David Alan Gilbert return result; 65860fe637bSDr. David Alan Gilbert } 65960fe637bSDr. David Alan Gilbert 660fbfa6404SDaniel P. Berrangé int64_t qemu_file_total_transferred_fast(QEMUFile *f) 66197221400SAlexander Graf { 662154d87b4SDaniel P. Berrangé int64_t ret = f->total_transferred; 66397221400SAlexander Graf int i; 66497221400SAlexander Graf 66597221400SAlexander Graf for (i = 0; i < f->iovcnt; i++) { 66697221400SAlexander Graf ret += f->iov[i].iov_len; 66797221400SAlexander Graf } 66897221400SAlexander Graf 66997221400SAlexander Graf return ret; 67097221400SAlexander Graf } 67197221400SAlexander Graf 672fbfa6404SDaniel P. Berrangé int64_t qemu_file_total_transferred(QEMUFile *f) 67360fe637bSDr. David Alan Gilbert { 67460fe637bSDr. David Alan Gilbert qemu_fflush(f); 675154d87b4SDaniel P. Berrangé return f->total_transferred; 67660fe637bSDr. David Alan Gilbert } 67760fe637bSDr. David Alan Gilbert 67860fe637bSDr. David Alan Gilbert int qemu_file_rate_limit(QEMUFile *f) 67960fe637bSDr. David Alan Gilbert { 680a555b809SJuan Quintela if (f->shutdown) { 681a555b809SJuan Quintela return 1; 682a555b809SJuan Quintela } 68360fe637bSDr. David Alan Gilbert if (qemu_file_get_error(f)) { 68460fe637bSDr. David Alan Gilbert return 1; 68560fe637bSDr. David Alan Gilbert } 686c7fc8d32SDaniel P. Berrangé if (f->rate_limit_max > 0 && f->rate_limit_used > f->rate_limit_max) { 68760fe637bSDr. David Alan Gilbert return 1; 68860fe637bSDr. David Alan Gilbert } 68960fe637bSDr. David Alan Gilbert return 0; 69060fe637bSDr. David Alan Gilbert } 69160fe637bSDr. David Alan Gilbert 69260fe637bSDr. David Alan Gilbert int64_t qemu_file_get_rate_limit(QEMUFile *f) 69360fe637bSDr. David Alan Gilbert { 694c7fc8d32SDaniel P. Berrangé return f->rate_limit_max; 69560fe637bSDr. David Alan Gilbert } 69660fe637bSDr. David Alan Gilbert 69760fe637bSDr. David Alan Gilbert void qemu_file_set_rate_limit(QEMUFile *f, int64_t limit) 69860fe637bSDr. David Alan Gilbert { 699c7fc8d32SDaniel P. Berrangé f->rate_limit_max = limit; 70060fe637bSDr. David Alan Gilbert } 70160fe637bSDr. David Alan Gilbert 70260fe637bSDr. David Alan Gilbert void qemu_file_reset_rate_limit(QEMUFile *f) 70360fe637bSDr. David Alan Gilbert { 704c7fc8d32SDaniel P. Berrangé f->rate_limit_used = 0; 70560fe637bSDr. David Alan Gilbert } 70660fe637bSDr. David Alan Gilbert 707bc698c36SDaniel P. Berrangé void qemu_file_acct_rate_limit(QEMUFile *f, int64_t len) 7085d7d2558SIvan Ren { 709c7fc8d32SDaniel P. Berrangé f->rate_limit_used += len; 7105d7d2558SIvan Ren } 7115d7d2558SIvan Ren 71260fe637bSDr. David Alan Gilbert void qemu_put_be16(QEMUFile *f, unsigned int v) 71360fe637bSDr. David Alan Gilbert { 71460fe637bSDr. David Alan Gilbert qemu_put_byte(f, v >> 8); 71560fe637bSDr. David Alan Gilbert qemu_put_byte(f, v); 71660fe637bSDr. David Alan Gilbert } 71760fe637bSDr. David Alan Gilbert 71860fe637bSDr. David Alan Gilbert void qemu_put_be32(QEMUFile *f, unsigned int v) 71960fe637bSDr. David Alan Gilbert { 72060fe637bSDr. David Alan Gilbert qemu_put_byte(f, v >> 24); 72160fe637bSDr. David Alan Gilbert qemu_put_byte(f, v >> 16); 72260fe637bSDr. David Alan Gilbert qemu_put_byte(f, v >> 8); 72360fe637bSDr. David Alan Gilbert qemu_put_byte(f, v); 72460fe637bSDr. David Alan Gilbert } 72560fe637bSDr. David Alan Gilbert 72660fe637bSDr. David Alan Gilbert void qemu_put_be64(QEMUFile *f, uint64_t v) 72760fe637bSDr. David Alan Gilbert { 72860fe637bSDr. David Alan Gilbert qemu_put_be32(f, v >> 32); 72960fe637bSDr. David Alan Gilbert qemu_put_be32(f, v); 73060fe637bSDr. David Alan Gilbert } 73160fe637bSDr. David Alan Gilbert 73260fe637bSDr. David Alan Gilbert unsigned int qemu_get_be16(QEMUFile *f) 73360fe637bSDr. David Alan Gilbert { 73460fe637bSDr. David Alan Gilbert unsigned int v; 73560fe637bSDr. David Alan Gilbert v = qemu_get_byte(f) << 8; 73660fe637bSDr. David Alan Gilbert v |= qemu_get_byte(f); 73760fe637bSDr. David Alan Gilbert return v; 73860fe637bSDr. David Alan Gilbert } 73960fe637bSDr. David Alan Gilbert 74060fe637bSDr. David Alan Gilbert unsigned int qemu_get_be32(QEMUFile *f) 74160fe637bSDr. David Alan Gilbert { 74260fe637bSDr. David Alan Gilbert unsigned int v; 74390d6a673SPeter Maydell v = (unsigned int)qemu_get_byte(f) << 24; 74460fe637bSDr. David Alan Gilbert v |= qemu_get_byte(f) << 16; 74560fe637bSDr. David Alan Gilbert v |= qemu_get_byte(f) << 8; 74660fe637bSDr. David Alan Gilbert v |= qemu_get_byte(f); 74760fe637bSDr. David Alan Gilbert return v; 74860fe637bSDr. David Alan Gilbert } 74960fe637bSDr. David Alan Gilbert 75060fe637bSDr. David Alan Gilbert uint64_t qemu_get_be64(QEMUFile *f) 75160fe637bSDr. David Alan Gilbert { 75260fe637bSDr. David Alan Gilbert uint64_t v; 75360fe637bSDr. David Alan Gilbert v = (uint64_t)qemu_get_be32(f) << 32; 75460fe637bSDr. David Alan Gilbert v |= qemu_get_be32(f); 75560fe637bSDr. David Alan Gilbert return v; 75660fe637bSDr. David Alan Gilbert } 75744f0eadcSLiang Li 758dcaf446eSXiao Guangrong /* return the size after compression, or negative value on error */ 759dcaf446eSXiao Guangrong static int qemu_compress_data(z_stream *stream, uint8_t *dest, size_t dest_len, 760dcaf446eSXiao Guangrong const uint8_t *source, size_t source_len) 761dcaf446eSXiao Guangrong { 762dcaf446eSXiao Guangrong int err; 763dcaf446eSXiao Guangrong 764dcaf446eSXiao Guangrong err = deflateReset(stream); 765dcaf446eSXiao Guangrong if (err != Z_OK) { 766dcaf446eSXiao Guangrong return -1; 767dcaf446eSXiao Guangrong } 768dcaf446eSXiao Guangrong 769dcaf446eSXiao Guangrong stream->avail_in = source_len; 770dcaf446eSXiao Guangrong stream->next_in = (uint8_t *)source; 771dcaf446eSXiao Guangrong stream->avail_out = dest_len; 772dcaf446eSXiao Guangrong stream->next_out = dest; 773dcaf446eSXiao Guangrong 774dcaf446eSXiao Guangrong err = deflate(stream, Z_FINISH); 775dcaf446eSXiao Guangrong if (err != Z_STREAM_END) { 776dcaf446eSXiao Guangrong return -1; 777dcaf446eSXiao Guangrong } 778dcaf446eSXiao Guangrong 779dcaf446eSXiao Guangrong return stream->next_out - dest; 780dcaf446eSXiao Guangrong } 781dcaf446eSXiao Guangrong 782dcaf446eSXiao Guangrong /* Compress size bytes of data start at p and store the compressed 783dcaf446eSXiao Guangrong * data to the buffer of f. 784b3be2896SLiang Li * 78542d24611SWei Yang * Since the file is dummy file with empty_ops, return -1 if f has no space to 78642d24611SWei Yang * save the compressed data. 78744f0eadcSLiang Li */ 788dcaf446eSXiao Guangrong ssize_t qemu_put_compression_data(QEMUFile *f, z_stream *stream, 789dcaf446eSXiao Guangrong const uint8_t *p, size_t size) 79044f0eadcSLiang Li { 79144f0eadcSLiang Li ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t); 79244f0eadcSLiang Li 79344f0eadcSLiang Li if (blen < compressBound(size)) { 794b3be2896SLiang Li return -1; 795b3be2896SLiang Li } 796dcaf446eSXiao Guangrong 797dcaf446eSXiao Guangrong blen = qemu_compress_data(stream, f->buf + f->buf_index + sizeof(int32_t), 798dcaf446eSXiao Guangrong blen, p, size); 799dcaf446eSXiao Guangrong if (blen < 0) { 80034ab9e97SXiao Guangrong return -1; 80144f0eadcSLiang Li } 80234ab9e97SXiao Guangrong 80344f0eadcSLiang Li qemu_put_be32(f, blen); 8041bf57fb3SWei Yang add_buf_to_iovec(f, blen); 80544f0eadcSLiang Li return blen + sizeof(int32_t); 80644f0eadcSLiang Li } 80744f0eadcSLiang Li 80844f0eadcSLiang Li /* Put the data in the buffer of f_src to the buffer of f_des, and 80944f0eadcSLiang Li * then reset the buf_index of f_src to 0. 81044f0eadcSLiang Li */ 81144f0eadcSLiang Li 81244f0eadcSLiang Li int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src) 81344f0eadcSLiang Li { 81444f0eadcSLiang Li int len = 0; 81544f0eadcSLiang Li 81644f0eadcSLiang Li if (f_src->buf_index > 0) { 81744f0eadcSLiang Li len = f_src->buf_index; 81844f0eadcSLiang Li qemu_put_buffer(f_des, f_src->buf, f_src->buf_index); 81944f0eadcSLiang Li f_src->buf_index = 0; 820787d134fSLiang Li f_src->iovcnt = 0; 82144f0eadcSLiang Li } 82244f0eadcSLiang Li return len; 82344f0eadcSLiang Li } 824b3af1bc9SDr. David Alan Gilbert 825b3af1bc9SDr. David Alan Gilbert /* 826b3af1bc9SDr. David Alan Gilbert * Get a string whose length is determined by a single preceding byte 827b3af1bc9SDr. David Alan Gilbert * A preallocated 256 byte buffer must be passed in. 828b3af1bc9SDr. David Alan Gilbert * Returns: len on success and a 0 terminated string in the buffer 829b3af1bc9SDr. David Alan Gilbert * else 0 830b3af1bc9SDr. David Alan Gilbert * (Note a 0 length string will return 0 either way) 831b3af1bc9SDr. David Alan Gilbert */ 832b3af1bc9SDr. David Alan Gilbert size_t qemu_get_counted_string(QEMUFile *f, char buf[256]) 833b3af1bc9SDr. David Alan Gilbert { 834b3af1bc9SDr. David Alan Gilbert size_t len = qemu_get_byte(f); 835b3af1bc9SDr. David Alan Gilbert size_t res = qemu_get_buffer(f, (uint8_t *)buf, len); 836b3af1bc9SDr. David Alan Gilbert 837b3af1bc9SDr. David Alan Gilbert buf[res] = 0; 838b3af1bc9SDr. David Alan Gilbert 839b3af1bc9SDr. David Alan Gilbert return res == len ? res : 0; 840b3af1bc9SDr. David Alan Gilbert } 841a800cd5cSDr. David Alan Gilbert 842a800cd5cSDr. David Alan Gilbert /* 843f0d64cb7SVladimir Sementsov-Ogievskiy * Put a string with one preceding byte containing its length. The length of 844f0d64cb7SVladimir Sementsov-Ogievskiy * the string should be less than 256. 845f0d64cb7SVladimir Sementsov-Ogievskiy */ 846f0d64cb7SVladimir Sementsov-Ogievskiy void qemu_put_counted_string(QEMUFile *f, const char *str) 847f0d64cb7SVladimir Sementsov-Ogievskiy { 848f0d64cb7SVladimir Sementsov-Ogievskiy size_t len = strlen(str); 849f0d64cb7SVladimir Sementsov-Ogievskiy 850f0d64cb7SVladimir Sementsov-Ogievskiy assert(len < 256); 851f0d64cb7SVladimir Sementsov-Ogievskiy qemu_put_byte(f, len); 852f0d64cb7SVladimir Sementsov-Ogievskiy qemu_put_buffer(f, (const uint8_t *)str, len); 853f0d64cb7SVladimir Sementsov-Ogievskiy } 854f0d64cb7SVladimir Sementsov-Ogievskiy 855f0d64cb7SVladimir Sementsov-Ogievskiy /* 856a800cd5cSDr. David Alan Gilbert * Set the blocking state of the QEMUFile. 857a800cd5cSDr. David Alan Gilbert * Note: On some transports the OS only keeps a single blocking state for 858a800cd5cSDr. David Alan Gilbert * both directions, and thus changing the blocking on the main 859a800cd5cSDr. David Alan Gilbert * QEMUFile can also affect the return path. 860a800cd5cSDr. David Alan Gilbert */ 861a800cd5cSDr. David Alan Gilbert void qemu_file_set_blocking(QEMUFile *f, bool block) 862a800cd5cSDr. David Alan Gilbert { 86306ad5135SDaniel P. Berrange if (f->ops->set_blocking) { 8643d661c8aSYury Kotov f->ops->set_blocking(f->opaque, block, NULL); 865a800cd5cSDr. David Alan Gilbert } 86606ad5135SDaniel P. Berrange } 867c6ad5be7SPeter Xu 868c6ad5be7SPeter Xu /* 869c6ad5be7SPeter Xu * Return the ioc object if it's a migration channel. Note: it can return NULL 870c6ad5be7SPeter Xu * for callers passing in a non-migration qemufile. E.g. see qemu_fopen_bdrv() 871c6ad5be7SPeter Xu * and its usage in e.g. load_snapshot(). So we need to check against NULL 872c6ad5be7SPeter Xu * before using it. If without the check, migration_incoming_state_destroy() 873c6ad5be7SPeter Xu * could fail for load_snapshot(). 874c6ad5be7SPeter Xu */ 875c6ad5be7SPeter Xu QIOChannel *qemu_file_get_ioc(QEMUFile *file) 876c6ad5be7SPeter Xu { 877c6ad5be7SPeter Xu return file->has_ioc ? QIO_CHANNEL(file->opaque) : NULL; 878c6ad5be7SPeter Xu } 879