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 */ 2444f0eadcSLiang Li #include <zlib.h> 2560fe637bSDr. David Alan Gilbert #include "qemu-common.h" 26d49b6836SMarkus Armbruster #include "qemu/error-report.h" 2760fe637bSDr. David Alan Gilbert #include "qemu/iov.h" 2860fe637bSDr. David Alan Gilbert #include "qemu/sockets.h" 2960fe637bSDr. David Alan Gilbert #include "block/coroutine.h" 3060fe637bSDr. David Alan Gilbert #include "migration/migration.h" 3160fe637bSDr. David Alan Gilbert #include "migration/qemu-file.h" 324f9d0900SDr. David Alan Gilbert #include "migration/qemu-file-internal.h" 3360fe637bSDr. David Alan Gilbert #include "trace.h" 3460fe637bSDr. David Alan Gilbert 35e1a8c9b6SDr. David Alan Gilbert /* 36e1a8c9b6SDr. David Alan Gilbert * Stop a file from being read/written - not all backing files can do this 37e1a8c9b6SDr. David Alan Gilbert * typically only sockets can. 38e1a8c9b6SDr. David Alan Gilbert */ 39e1a8c9b6SDr. David Alan Gilbert int qemu_file_shutdown(QEMUFile *f) 40e1a8c9b6SDr. David Alan Gilbert { 41e1a8c9b6SDr. David Alan Gilbert if (!f->ops->shut_down) { 42e1a8c9b6SDr. David Alan Gilbert return -ENOSYS; 43e1a8c9b6SDr. David Alan Gilbert } 44e1a8c9b6SDr. David Alan Gilbert return f->ops->shut_down(f->opaque, true, true); 45e1a8c9b6SDr. David Alan Gilbert } 46e1a8c9b6SDr. David Alan Gilbert 4760fe637bSDr. David Alan Gilbert bool qemu_file_mode_is_not_valid(const char *mode) 4860fe637bSDr. David Alan Gilbert { 4960fe637bSDr. David Alan Gilbert if (mode == NULL || 5060fe637bSDr. David Alan Gilbert (mode[0] != 'r' && mode[0] != 'w') || 5160fe637bSDr. David Alan Gilbert mode[1] != 'b' || mode[2] != 0) { 5260fe637bSDr. David Alan Gilbert fprintf(stderr, "qemu_fopen: Argument validity check failed\n"); 5360fe637bSDr. David Alan Gilbert return true; 5460fe637bSDr. David Alan Gilbert } 5560fe637bSDr. David Alan Gilbert 5660fe637bSDr. David Alan Gilbert return false; 5760fe637bSDr. David Alan Gilbert } 5860fe637bSDr. David Alan Gilbert 5960fe637bSDr. David Alan Gilbert QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops) 6060fe637bSDr. David Alan Gilbert { 6160fe637bSDr. David Alan Gilbert QEMUFile *f; 6260fe637bSDr. David Alan Gilbert 6360fe637bSDr. David Alan Gilbert f = g_malloc0(sizeof(QEMUFile)); 6460fe637bSDr. David Alan Gilbert 6560fe637bSDr. David Alan Gilbert f->opaque = opaque; 6660fe637bSDr. David Alan Gilbert f->ops = ops; 6760fe637bSDr. David Alan Gilbert return f; 6860fe637bSDr. David Alan Gilbert } 6960fe637bSDr. David Alan Gilbert 7060fe637bSDr. David Alan Gilbert /* 7160fe637bSDr. David Alan Gilbert * Get last error for stream f 7260fe637bSDr. David Alan Gilbert * 7360fe637bSDr. David Alan Gilbert * Return negative error value if there has been an error on previous 7460fe637bSDr. David Alan Gilbert * operations, return 0 if no error happened. 7560fe637bSDr. David Alan Gilbert * 7660fe637bSDr. David Alan Gilbert */ 7760fe637bSDr. David Alan Gilbert int qemu_file_get_error(QEMUFile *f) 7860fe637bSDr. David Alan Gilbert { 7960fe637bSDr. David Alan Gilbert return f->last_error; 8060fe637bSDr. David Alan Gilbert } 8160fe637bSDr. David Alan Gilbert 8260fe637bSDr. David Alan Gilbert void qemu_file_set_error(QEMUFile *f, int ret) 8360fe637bSDr. David Alan Gilbert { 8460fe637bSDr. David Alan Gilbert if (f->last_error == 0) { 8560fe637bSDr. David Alan Gilbert f->last_error = ret; 8660fe637bSDr. David Alan Gilbert } 8760fe637bSDr. David Alan Gilbert } 8860fe637bSDr. David Alan Gilbert 8960fe637bSDr. David Alan Gilbert bool qemu_file_is_writable(QEMUFile *f) 9060fe637bSDr. David Alan Gilbert { 9160fe637bSDr. David Alan Gilbert return f->ops->writev_buffer || f->ops->put_buffer; 9260fe637bSDr. David Alan Gilbert } 9360fe637bSDr. David Alan Gilbert 9460fe637bSDr. David Alan Gilbert /** 9560fe637bSDr. David Alan Gilbert * Flushes QEMUFile buffer 9660fe637bSDr. David Alan Gilbert * 9760fe637bSDr. David Alan Gilbert * If there is writev_buffer QEMUFileOps it uses it otherwise uses 9860fe637bSDr. David Alan Gilbert * put_buffer ops. 9960fe637bSDr. David Alan Gilbert */ 10060fe637bSDr. David Alan Gilbert void qemu_fflush(QEMUFile *f) 10160fe637bSDr. David Alan Gilbert { 10260fe637bSDr. David Alan Gilbert ssize_t ret = 0; 10360fe637bSDr. David Alan Gilbert 10460fe637bSDr. David Alan Gilbert if (!qemu_file_is_writable(f)) { 10560fe637bSDr. David Alan Gilbert return; 10660fe637bSDr. David Alan Gilbert } 10760fe637bSDr. David Alan Gilbert 10860fe637bSDr. David Alan Gilbert if (f->ops->writev_buffer) { 10960fe637bSDr. David Alan Gilbert if (f->iovcnt > 0) { 11060fe637bSDr. David Alan Gilbert ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos); 11160fe637bSDr. David Alan Gilbert } 11260fe637bSDr. David Alan Gilbert } else { 11360fe637bSDr. David Alan Gilbert if (f->buf_index > 0) { 11460fe637bSDr. David Alan Gilbert ret = f->ops->put_buffer(f->opaque, f->buf, f->pos, f->buf_index); 11560fe637bSDr. David Alan Gilbert } 11660fe637bSDr. David Alan Gilbert } 11760fe637bSDr. David Alan Gilbert if (ret >= 0) { 11860fe637bSDr. David Alan Gilbert f->pos += ret; 11960fe637bSDr. David Alan Gilbert } 12060fe637bSDr. David Alan Gilbert f->buf_index = 0; 12160fe637bSDr. David Alan Gilbert f->iovcnt = 0; 12260fe637bSDr. David Alan Gilbert if (ret < 0) { 12360fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 12460fe637bSDr. David Alan Gilbert } 12560fe637bSDr. David Alan Gilbert } 12660fe637bSDr. David Alan Gilbert 12760fe637bSDr. David Alan Gilbert void ram_control_before_iterate(QEMUFile *f, uint64_t flags) 12860fe637bSDr. David Alan Gilbert { 12960fe637bSDr. David Alan Gilbert int ret = 0; 13060fe637bSDr. David Alan Gilbert 13160fe637bSDr. David Alan Gilbert if (f->ops->before_ram_iterate) { 132*632e3a5cSDr. David Alan Gilbert ret = f->ops->before_ram_iterate(f, f->opaque, flags, NULL); 13360fe637bSDr. David Alan Gilbert if (ret < 0) { 13460fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 13560fe637bSDr. David Alan Gilbert } 13660fe637bSDr. David Alan Gilbert } 13760fe637bSDr. David Alan Gilbert } 13860fe637bSDr. David Alan Gilbert 13960fe637bSDr. David Alan Gilbert void ram_control_after_iterate(QEMUFile *f, uint64_t flags) 14060fe637bSDr. David Alan Gilbert { 14160fe637bSDr. David Alan Gilbert int ret = 0; 14260fe637bSDr. David Alan Gilbert 14360fe637bSDr. David Alan Gilbert if (f->ops->after_ram_iterate) { 144*632e3a5cSDr. David Alan Gilbert ret = f->ops->after_ram_iterate(f, f->opaque, flags, NULL); 14560fe637bSDr. David Alan Gilbert if (ret < 0) { 14660fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 14760fe637bSDr. David Alan Gilbert } 14860fe637bSDr. David Alan Gilbert } 14960fe637bSDr. David Alan Gilbert } 15060fe637bSDr. David Alan Gilbert 151*632e3a5cSDr. David Alan Gilbert void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data) 15260fe637bSDr. David Alan Gilbert { 15360fe637bSDr. David Alan Gilbert int ret = -EINVAL; 15460fe637bSDr. David Alan Gilbert 15560fe637bSDr. David Alan Gilbert if (f->ops->hook_ram_load) { 156*632e3a5cSDr. David Alan Gilbert ret = f->ops->hook_ram_load(f, f->opaque, flags, data); 15760fe637bSDr. David Alan Gilbert if (ret < 0) { 15860fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 15960fe637bSDr. David Alan Gilbert } 16060fe637bSDr. David Alan Gilbert } else { 161*632e3a5cSDr. David Alan Gilbert /* 162*632e3a5cSDr. David Alan Gilbert * Hook is a hook specifically requested by the source sending a flag 163*632e3a5cSDr. David Alan Gilbert * that expects there to be a hook on the destination. 164*632e3a5cSDr. David Alan Gilbert */ 165*632e3a5cSDr. David Alan Gilbert if (flags == RAM_CONTROL_HOOK) { 16660fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 16760fe637bSDr. David Alan Gilbert } 16860fe637bSDr. David Alan Gilbert } 169*632e3a5cSDr. David Alan Gilbert } 17060fe637bSDr. David Alan Gilbert 17160fe637bSDr. David Alan Gilbert size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset, 1726e1dea46SJuan Quintela ram_addr_t offset, size_t size, 1736e1dea46SJuan Quintela uint64_t *bytes_sent) 17460fe637bSDr. David Alan Gilbert { 17560fe637bSDr. David Alan Gilbert if (f->ops->save_page) { 17660fe637bSDr. David Alan Gilbert int ret = f->ops->save_page(f, f->opaque, block_offset, 17760fe637bSDr. David Alan Gilbert offset, size, bytes_sent); 17860fe637bSDr. David Alan Gilbert 17960fe637bSDr. David Alan Gilbert if (ret != RAM_SAVE_CONTROL_DELAYED) { 18060fe637bSDr. David Alan Gilbert if (bytes_sent && *bytes_sent > 0) { 18160fe637bSDr. David Alan Gilbert qemu_update_position(f, *bytes_sent); 18260fe637bSDr. David Alan Gilbert } else if (ret < 0) { 18360fe637bSDr. David Alan Gilbert qemu_file_set_error(f, ret); 18460fe637bSDr. David Alan Gilbert } 18560fe637bSDr. David Alan Gilbert } 18660fe637bSDr. David Alan Gilbert 18760fe637bSDr. David Alan Gilbert return ret; 18860fe637bSDr. David Alan Gilbert } 18960fe637bSDr. David Alan Gilbert 19060fe637bSDr. David Alan Gilbert return RAM_SAVE_CONTROL_NOT_SUPP; 19160fe637bSDr. David Alan Gilbert } 19260fe637bSDr. David Alan Gilbert 19360fe637bSDr. David Alan Gilbert /* 19460fe637bSDr. David Alan Gilbert * Attempt to fill the buffer from the underlying file 19560fe637bSDr. David Alan Gilbert * Returns the number of bytes read, or negative value for an error. 19660fe637bSDr. David Alan Gilbert * 19760fe637bSDr. David Alan Gilbert * Note that it can return a partially full buffer even in a not error/not EOF 19860fe637bSDr. David Alan Gilbert * case if the underlying file descriptor gives a short read, and that can 19960fe637bSDr. David Alan Gilbert * happen even on a blocking fd. 20060fe637bSDr. David Alan Gilbert */ 20160fe637bSDr. David Alan Gilbert static ssize_t qemu_fill_buffer(QEMUFile *f) 20260fe637bSDr. David Alan Gilbert { 20360fe637bSDr. David Alan Gilbert int len; 20460fe637bSDr. David Alan Gilbert int pending; 20560fe637bSDr. David Alan Gilbert 20660fe637bSDr. David Alan Gilbert assert(!qemu_file_is_writable(f)); 20760fe637bSDr. David Alan Gilbert 20860fe637bSDr. David Alan Gilbert pending = f->buf_size - f->buf_index; 20960fe637bSDr. David Alan Gilbert if (pending > 0) { 21060fe637bSDr. David Alan Gilbert memmove(f->buf, f->buf + f->buf_index, pending); 21160fe637bSDr. David Alan Gilbert } 21260fe637bSDr. David Alan Gilbert f->buf_index = 0; 21360fe637bSDr. David Alan Gilbert f->buf_size = pending; 21460fe637bSDr. David Alan Gilbert 21560fe637bSDr. David Alan Gilbert len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos, 21660fe637bSDr. David Alan Gilbert IO_BUF_SIZE - pending); 21760fe637bSDr. David Alan Gilbert if (len > 0) { 21860fe637bSDr. David Alan Gilbert f->buf_size += len; 21960fe637bSDr. David Alan Gilbert f->pos += len; 22060fe637bSDr. David Alan Gilbert } else if (len == 0) { 22160fe637bSDr. David Alan Gilbert qemu_file_set_error(f, -EIO); 22260fe637bSDr. David Alan Gilbert } else if (len != -EAGAIN) { 22360fe637bSDr. David Alan Gilbert qemu_file_set_error(f, len); 22460fe637bSDr. David Alan Gilbert } 22560fe637bSDr. David Alan Gilbert 22660fe637bSDr. David Alan Gilbert return len; 22760fe637bSDr. David Alan Gilbert } 22860fe637bSDr. David Alan Gilbert 22960fe637bSDr. David Alan Gilbert int qemu_get_fd(QEMUFile *f) 23060fe637bSDr. David Alan Gilbert { 23160fe637bSDr. David Alan Gilbert if (f->ops->get_fd) { 23260fe637bSDr. David Alan Gilbert return f->ops->get_fd(f->opaque); 23360fe637bSDr. David Alan Gilbert } 23460fe637bSDr. David Alan Gilbert return -1; 23560fe637bSDr. David Alan Gilbert } 23660fe637bSDr. David Alan Gilbert 23760fe637bSDr. David Alan Gilbert void qemu_update_position(QEMUFile *f, size_t size) 23860fe637bSDr. David Alan Gilbert { 23960fe637bSDr. David Alan Gilbert f->pos += size; 24060fe637bSDr. David Alan Gilbert } 24160fe637bSDr. David Alan Gilbert 24260fe637bSDr. David Alan Gilbert /** Closes the file 24360fe637bSDr. David Alan Gilbert * 24460fe637bSDr. David Alan Gilbert * Returns negative error value if any error happened on previous operations or 24560fe637bSDr. David Alan Gilbert * while closing the file. Returns 0 or positive number on success. 24660fe637bSDr. David Alan Gilbert * 24760fe637bSDr. David Alan Gilbert * The meaning of return value on success depends on the specific backend 24860fe637bSDr. David Alan Gilbert * being used. 24960fe637bSDr. David Alan Gilbert */ 25060fe637bSDr. David Alan Gilbert int qemu_fclose(QEMUFile *f) 25160fe637bSDr. David Alan Gilbert { 25260fe637bSDr. David Alan Gilbert int ret; 25360fe637bSDr. David Alan Gilbert qemu_fflush(f); 25460fe637bSDr. David Alan Gilbert ret = qemu_file_get_error(f); 25560fe637bSDr. David Alan Gilbert 25660fe637bSDr. David Alan Gilbert if (f->ops->close) { 25760fe637bSDr. David Alan Gilbert int ret2 = f->ops->close(f->opaque); 25860fe637bSDr. David Alan Gilbert if (ret >= 0) { 25960fe637bSDr. David Alan Gilbert ret = ret2; 26060fe637bSDr. David Alan Gilbert } 26160fe637bSDr. David Alan Gilbert } 26260fe637bSDr. David Alan Gilbert /* If any error was spotted before closing, we should report it 26360fe637bSDr. David Alan Gilbert * instead of the close() return value. 26460fe637bSDr. David Alan Gilbert */ 26560fe637bSDr. David Alan Gilbert if (f->last_error) { 26660fe637bSDr. David Alan Gilbert ret = f->last_error; 26760fe637bSDr. David Alan Gilbert } 26860fe637bSDr. David Alan Gilbert g_free(f); 26960fe637bSDr. David Alan Gilbert trace_qemu_file_fclose(); 27060fe637bSDr. David Alan Gilbert return ret; 27160fe637bSDr. David Alan Gilbert } 27260fe637bSDr. David Alan Gilbert 27360fe637bSDr. David Alan Gilbert static void add_to_iovec(QEMUFile *f, const uint8_t *buf, int size) 27460fe637bSDr. David Alan Gilbert { 27560fe637bSDr. David Alan Gilbert /* check for adjacent buffer and coalesce them */ 27660fe637bSDr. David Alan Gilbert if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base + 27760fe637bSDr. David Alan Gilbert f->iov[f->iovcnt - 1].iov_len) { 27860fe637bSDr. David Alan Gilbert f->iov[f->iovcnt - 1].iov_len += size; 27960fe637bSDr. David Alan Gilbert } else { 28060fe637bSDr. David Alan Gilbert f->iov[f->iovcnt].iov_base = (uint8_t *)buf; 28160fe637bSDr. David Alan Gilbert f->iov[f->iovcnt++].iov_len = size; 28260fe637bSDr. David Alan Gilbert } 28360fe637bSDr. David Alan Gilbert 28460fe637bSDr. David Alan Gilbert if (f->iovcnt >= MAX_IOV_SIZE) { 28560fe637bSDr. David Alan Gilbert qemu_fflush(f); 28660fe637bSDr. David Alan Gilbert } 28760fe637bSDr. David Alan Gilbert } 28860fe637bSDr. David Alan Gilbert 28960fe637bSDr. David Alan Gilbert void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size) 29060fe637bSDr. David Alan Gilbert { 29160fe637bSDr. David Alan Gilbert if (!f->ops->writev_buffer) { 29260fe637bSDr. David Alan Gilbert qemu_put_buffer(f, buf, size); 29360fe637bSDr. David Alan Gilbert return; 29460fe637bSDr. David Alan Gilbert } 29560fe637bSDr. David Alan Gilbert 29660fe637bSDr. David Alan Gilbert if (f->last_error) { 29760fe637bSDr. David Alan Gilbert return; 29860fe637bSDr. David Alan Gilbert } 29960fe637bSDr. David Alan Gilbert 30060fe637bSDr. David Alan Gilbert f->bytes_xfer += size; 30160fe637bSDr. David Alan Gilbert add_to_iovec(f, buf, size); 30260fe637bSDr. David Alan Gilbert } 30360fe637bSDr. David Alan Gilbert 30460fe637bSDr. David Alan Gilbert void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) 30560fe637bSDr. David Alan Gilbert { 30660fe637bSDr. David Alan Gilbert int l; 30760fe637bSDr. David Alan Gilbert 30860fe637bSDr. David Alan Gilbert if (f->last_error) { 30960fe637bSDr. David Alan Gilbert return; 31060fe637bSDr. David Alan Gilbert } 31160fe637bSDr. David Alan Gilbert 31260fe637bSDr. David Alan Gilbert while (size > 0) { 31360fe637bSDr. David Alan Gilbert l = IO_BUF_SIZE - f->buf_index; 31460fe637bSDr. David Alan Gilbert if (l > size) { 31560fe637bSDr. David Alan Gilbert l = size; 31660fe637bSDr. David Alan Gilbert } 31760fe637bSDr. David Alan Gilbert memcpy(f->buf + f->buf_index, buf, l); 31860fe637bSDr. David Alan Gilbert f->bytes_xfer += l; 31960fe637bSDr. David Alan Gilbert if (f->ops->writev_buffer) { 32060fe637bSDr. David Alan Gilbert add_to_iovec(f, f->buf + f->buf_index, l); 32160fe637bSDr. David Alan Gilbert } 32260fe637bSDr. David Alan Gilbert f->buf_index += l; 32360fe637bSDr. David Alan Gilbert if (f->buf_index == IO_BUF_SIZE) { 32460fe637bSDr. David Alan Gilbert qemu_fflush(f); 32560fe637bSDr. David Alan Gilbert } 32660fe637bSDr. David Alan Gilbert if (qemu_file_get_error(f)) { 32760fe637bSDr. David Alan Gilbert break; 32860fe637bSDr. David Alan Gilbert } 32960fe637bSDr. David Alan Gilbert buf += l; 33060fe637bSDr. David Alan Gilbert size -= l; 33160fe637bSDr. David Alan Gilbert } 33260fe637bSDr. David Alan Gilbert } 33360fe637bSDr. David Alan Gilbert 33460fe637bSDr. David Alan Gilbert void qemu_put_byte(QEMUFile *f, int v) 33560fe637bSDr. David Alan Gilbert { 33660fe637bSDr. David Alan Gilbert if (f->last_error) { 33760fe637bSDr. David Alan Gilbert return; 33860fe637bSDr. David Alan Gilbert } 33960fe637bSDr. David Alan Gilbert 34060fe637bSDr. David Alan Gilbert f->buf[f->buf_index] = v; 34160fe637bSDr. David Alan Gilbert f->bytes_xfer++; 34260fe637bSDr. David Alan Gilbert if (f->ops->writev_buffer) { 34360fe637bSDr. David Alan Gilbert add_to_iovec(f, f->buf + f->buf_index, 1); 34460fe637bSDr. David Alan Gilbert } 34560fe637bSDr. David Alan Gilbert f->buf_index++; 34660fe637bSDr. David Alan Gilbert if (f->buf_index == IO_BUF_SIZE) { 34760fe637bSDr. David Alan Gilbert qemu_fflush(f); 34860fe637bSDr. David Alan Gilbert } 34960fe637bSDr. David Alan Gilbert } 35060fe637bSDr. David Alan Gilbert 35160fe637bSDr. David Alan Gilbert void qemu_file_skip(QEMUFile *f, int size) 35260fe637bSDr. David Alan Gilbert { 35360fe637bSDr. David Alan Gilbert if (f->buf_index + size <= f->buf_size) { 35460fe637bSDr. David Alan Gilbert f->buf_index += size; 35560fe637bSDr. David Alan Gilbert } 35660fe637bSDr. David Alan Gilbert } 35760fe637bSDr. David Alan Gilbert 35860fe637bSDr. David Alan Gilbert /* 3597c1e52baSDr. David Alan Gilbert * Read 'size' bytes from file (at 'offset') without moving the 3607c1e52baSDr. David Alan Gilbert * pointer and set 'buf' to point to that data. 36160fe637bSDr. David Alan Gilbert * 36260fe637bSDr. David Alan Gilbert * It will return size bytes unless there was an error, in which case it will 36360fe637bSDr. David Alan Gilbert * return as many as it managed to read (assuming blocking fd's which 36460fe637bSDr. David Alan Gilbert * all current QEMUFile are) 36560fe637bSDr. David Alan Gilbert */ 3667c1e52baSDr. David Alan Gilbert int qemu_peek_buffer(QEMUFile *f, uint8_t **buf, int size, size_t offset) 36760fe637bSDr. David Alan Gilbert { 36860fe637bSDr. David Alan Gilbert int pending; 36960fe637bSDr. David Alan Gilbert int index; 37060fe637bSDr. David Alan Gilbert 37160fe637bSDr. David Alan Gilbert assert(!qemu_file_is_writable(f)); 37260fe637bSDr. David Alan Gilbert assert(offset < IO_BUF_SIZE); 37360fe637bSDr. David Alan Gilbert assert(size <= IO_BUF_SIZE - offset); 37460fe637bSDr. David Alan Gilbert 37560fe637bSDr. David Alan Gilbert /* The 1st byte to read from */ 37660fe637bSDr. David Alan Gilbert index = f->buf_index + offset; 37760fe637bSDr. David Alan Gilbert /* The number of available bytes starting at index */ 37860fe637bSDr. David Alan Gilbert pending = f->buf_size - index; 37960fe637bSDr. David Alan Gilbert 38060fe637bSDr. David Alan Gilbert /* 38160fe637bSDr. David Alan Gilbert * qemu_fill_buffer might return just a few bytes, even when there isn't 38260fe637bSDr. David Alan Gilbert * an error, so loop collecting them until we get enough. 38360fe637bSDr. David Alan Gilbert */ 38460fe637bSDr. David Alan Gilbert while (pending < size) { 38560fe637bSDr. David Alan Gilbert int received = qemu_fill_buffer(f); 38660fe637bSDr. David Alan Gilbert 38760fe637bSDr. David Alan Gilbert if (received <= 0) { 38860fe637bSDr. David Alan Gilbert break; 38960fe637bSDr. David Alan Gilbert } 39060fe637bSDr. David Alan Gilbert 39160fe637bSDr. David Alan Gilbert index = f->buf_index + offset; 39260fe637bSDr. David Alan Gilbert pending = f->buf_size - index; 39360fe637bSDr. David Alan Gilbert } 39460fe637bSDr. David Alan Gilbert 39560fe637bSDr. David Alan Gilbert if (pending <= 0) { 39660fe637bSDr. David Alan Gilbert return 0; 39760fe637bSDr. David Alan Gilbert } 39860fe637bSDr. David Alan Gilbert if (size > pending) { 39960fe637bSDr. David Alan Gilbert size = pending; 40060fe637bSDr. David Alan Gilbert } 40160fe637bSDr. David Alan Gilbert 4027c1e52baSDr. David Alan Gilbert *buf = f->buf + index; 40360fe637bSDr. David Alan Gilbert return size; 40460fe637bSDr. David Alan Gilbert } 40560fe637bSDr. David Alan Gilbert 40660fe637bSDr. David Alan Gilbert /* 40760fe637bSDr. David Alan Gilbert * Read 'size' bytes of data from the file into buf. 40860fe637bSDr. David Alan Gilbert * 'size' can be larger than the internal buffer. 40960fe637bSDr. David Alan Gilbert * 41060fe637bSDr. David Alan Gilbert * It will return size bytes unless there was an error, in which case it will 41160fe637bSDr. David Alan Gilbert * return as many as it managed to read (assuming blocking fd's which 41260fe637bSDr. David Alan Gilbert * all current QEMUFile are) 41360fe637bSDr. David Alan Gilbert */ 41460fe637bSDr. David Alan Gilbert int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size) 41560fe637bSDr. David Alan Gilbert { 41660fe637bSDr. David Alan Gilbert int pending = size; 41760fe637bSDr. David Alan Gilbert int done = 0; 41860fe637bSDr. David Alan Gilbert 41960fe637bSDr. David Alan Gilbert while (pending > 0) { 42060fe637bSDr. David Alan Gilbert int res; 4217c1e52baSDr. David Alan Gilbert uint8_t *src; 42260fe637bSDr. David Alan Gilbert 4237c1e52baSDr. David Alan Gilbert res = qemu_peek_buffer(f, &src, MIN(pending, IO_BUF_SIZE), 0); 42460fe637bSDr. David Alan Gilbert if (res == 0) { 42560fe637bSDr. David Alan Gilbert return done; 42660fe637bSDr. David Alan Gilbert } 4277c1e52baSDr. David Alan Gilbert memcpy(buf, src, res); 42860fe637bSDr. David Alan Gilbert qemu_file_skip(f, res); 42960fe637bSDr. David Alan Gilbert buf += res; 43060fe637bSDr. David Alan Gilbert pending -= res; 43160fe637bSDr. David Alan Gilbert done += res; 43260fe637bSDr. David Alan Gilbert } 43360fe637bSDr. David Alan Gilbert return done; 43460fe637bSDr. David Alan Gilbert } 43560fe637bSDr. David Alan Gilbert 43660fe637bSDr. David Alan Gilbert /* 43760fe637bSDr. David Alan Gilbert * Peeks a single byte from the buffer; this isn't guaranteed to work if 43860fe637bSDr. David Alan Gilbert * offset leaves a gap after the previous read/peeked data. 43960fe637bSDr. David Alan Gilbert */ 44060fe637bSDr. David Alan Gilbert int qemu_peek_byte(QEMUFile *f, int offset) 44160fe637bSDr. David Alan Gilbert { 44260fe637bSDr. David Alan Gilbert int index = f->buf_index + offset; 44360fe637bSDr. David Alan Gilbert 44460fe637bSDr. David Alan Gilbert assert(!qemu_file_is_writable(f)); 44560fe637bSDr. David Alan Gilbert assert(offset < IO_BUF_SIZE); 44660fe637bSDr. David Alan Gilbert 44760fe637bSDr. David Alan Gilbert if (index >= f->buf_size) { 44860fe637bSDr. David Alan Gilbert qemu_fill_buffer(f); 44960fe637bSDr. David Alan Gilbert index = f->buf_index + offset; 45060fe637bSDr. David Alan Gilbert if (index >= f->buf_size) { 45160fe637bSDr. David Alan Gilbert return 0; 45260fe637bSDr. David Alan Gilbert } 45360fe637bSDr. David Alan Gilbert } 45460fe637bSDr. David Alan Gilbert return f->buf[index]; 45560fe637bSDr. David Alan Gilbert } 45660fe637bSDr. David Alan Gilbert 45760fe637bSDr. David Alan Gilbert int qemu_get_byte(QEMUFile *f) 45860fe637bSDr. David Alan Gilbert { 45960fe637bSDr. David Alan Gilbert int result; 46060fe637bSDr. David Alan Gilbert 46160fe637bSDr. David Alan Gilbert result = qemu_peek_byte(f, 0); 46260fe637bSDr. David Alan Gilbert qemu_file_skip(f, 1); 46360fe637bSDr. David Alan Gilbert return result; 46460fe637bSDr. David Alan Gilbert } 46560fe637bSDr. David Alan Gilbert 46697221400SAlexander Graf int64_t qemu_ftell_fast(QEMUFile *f) 46797221400SAlexander Graf { 46897221400SAlexander Graf int64_t ret = f->pos; 46997221400SAlexander Graf int i; 47097221400SAlexander Graf 47197221400SAlexander Graf if (f->ops->writev_buffer) { 47297221400SAlexander Graf for (i = 0; i < f->iovcnt; i++) { 47397221400SAlexander Graf ret += f->iov[i].iov_len; 47497221400SAlexander Graf } 47597221400SAlexander Graf } else { 47697221400SAlexander Graf ret += f->buf_index; 47797221400SAlexander Graf } 47897221400SAlexander Graf 47997221400SAlexander Graf return ret; 48097221400SAlexander Graf } 48197221400SAlexander Graf 48260fe637bSDr. David Alan Gilbert int64_t qemu_ftell(QEMUFile *f) 48360fe637bSDr. David Alan Gilbert { 48460fe637bSDr. David Alan Gilbert qemu_fflush(f); 48560fe637bSDr. David Alan Gilbert return f->pos; 48660fe637bSDr. David Alan Gilbert } 48760fe637bSDr. David Alan Gilbert 48860fe637bSDr. David Alan Gilbert int qemu_file_rate_limit(QEMUFile *f) 48960fe637bSDr. David Alan Gilbert { 49060fe637bSDr. David Alan Gilbert if (qemu_file_get_error(f)) { 49160fe637bSDr. David Alan Gilbert return 1; 49260fe637bSDr. David Alan Gilbert } 49360fe637bSDr. David Alan Gilbert if (f->xfer_limit > 0 && f->bytes_xfer > f->xfer_limit) { 49460fe637bSDr. David Alan Gilbert return 1; 49560fe637bSDr. David Alan Gilbert } 49660fe637bSDr. David Alan Gilbert return 0; 49760fe637bSDr. David Alan Gilbert } 49860fe637bSDr. David Alan Gilbert 49960fe637bSDr. David Alan Gilbert int64_t qemu_file_get_rate_limit(QEMUFile *f) 50060fe637bSDr. David Alan Gilbert { 50160fe637bSDr. David Alan Gilbert return f->xfer_limit; 50260fe637bSDr. David Alan Gilbert } 50360fe637bSDr. David Alan Gilbert 50460fe637bSDr. David Alan Gilbert void qemu_file_set_rate_limit(QEMUFile *f, int64_t limit) 50560fe637bSDr. David Alan Gilbert { 50660fe637bSDr. David Alan Gilbert f->xfer_limit = limit; 50760fe637bSDr. David Alan Gilbert } 50860fe637bSDr. David Alan Gilbert 50960fe637bSDr. David Alan Gilbert void qemu_file_reset_rate_limit(QEMUFile *f) 51060fe637bSDr. David Alan Gilbert { 51160fe637bSDr. David Alan Gilbert f->bytes_xfer = 0; 51260fe637bSDr. David Alan Gilbert } 51360fe637bSDr. David Alan Gilbert 51460fe637bSDr. David Alan Gilbert void qemu_put_be16(QEMUFile *f, unsigned int v) 51560fe637bSDr. David Alan Gilbert { 51660fe637bSDr. David Alan Gilbert qemu_put_byte(f, v >> 8); 51760fe637bSDr. David Alan Gilbert qemu_put_byte(f, v); 51860fe637bSDr. David Alan Gilbert } 51960fe637bSDr. David Alan Gilbert 52060fe637bSDr. David Alan Gilbert void qemu_put_be32(QEMUFile *f, unsigned int v) 52160fe637bSDr. David Alan Gilbert { 52260fe637bSDr. David Alan Gilbert qemu_put_byte(f, v >> 24); 52360fe637bSDr. David Alan Gilbert qemu_put_byte(f, v >> 16); 52460fe637bSDr. David Alan Gilbert qemu_put_byte(f, v >> 8); 52560fe637bSDr. David Alan Gilbert qemu_put_byte(f, v); 52660fe637bSDr. David Alan Gilbert } 52760fe637bSDr. David Alan Gilbert 52860fe637bSDr. David Alan Gilbert void qemu_put_be64(QEMUFile *f, uint64_t v) 52960fe637bSDr. David Alan Gilbert { 53060fe637bSDr. David Alan Gilbert qemu_put_be32(f, v >> 32); 53160fe637bSDr. David Alan Gilbert qemu_put_be32(f, v); 53260fe637bSDr. David Alan Gilbert } 53360fe637bSDr. David Alan Gilbert 53460fe637bSDr. David Alan Gilbert unsigned int qemu_get_be16(QEMUFile *f) 53560fe637bSDr. David Alan Gilbert { 53660fe637bSDr. David Alan Gilbert unsigned int v; 53760fe637bSDr. David Alan Gilbert v = qemu_get_byte(f) << 8; 53860fe637bSDr. David Alan Gilbert v |= qemu_get_byte(f); 53960fe637bSDr. David Alan Gilbert return v; 54060fe637bSDr. David Alan Gilbert } 54160fe637bSDr. David Alan Gilbert 54260fe637bSDr. David Alan Gilbert unsigned int qemu_get_be32(QEMUFile *f) 54360fe637bSDr. David Alan Gilbert { 54460fe637bSDr. David Alan Gilbert unsigned int v; 54590d6a673SPeter Maydell v = (unsigned int)qemu_get_byte(f) << 24; 54660fe637bSDr. David Alan Gilbert v |= qemu_get_byte(f) << 16; 54760fe637bSDr. David Alan Gilbert v |= qemu_get_byte(f) << 8; 54860fe637bSDr. David Alan Gilbert v |= qemu_get_byte(f); 54960fe637bSDr. David Alan Gilbert return v; 55060fe637bSDr. David Alan Gilbert } 55160fe637bSDr. David Alan Gilbert 55260fe637bSDr. David Alan Gilbert uint64_t qemu_get_be64(QEMUFile *f) 55360fe637bSDr. David Alan Gilbert { 55460fe637bSDr. David Alan Gilbert uint64_t v; 55560fe637bSDr. David Alan Gilbert v = (uint64_t)qemu_get_be32(f) << 32; 55660fe637bSDr. David Alan Gilbert v |= qemu_get_be32(f); 55760fe637bSDr. David Alan Gilbert return v; 55860fe637bSDr. David Alan Gilbert } 55944f0eadcSLiang Li 56044f0eadcSLiang Li /* compress size bytes of data start at p with specific compression 56144f0eadcSLiang Li * level and store the compressed data to the buffer of f. 56244f0eadcSLiang Li */ 56344f0eadcSLiang Li 56444f0eadcSLiang Li ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size, 56544f0eadcSLiang Li int level) 56644f0eadcSLiang Li { 56744f0eadcSLiang Li ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t); 56844f0eadcSLiang Li 56944f0eadcSLiang Li if (blen < compressBound(size)) { 57044f0eadcSLiang Li return 0; 57144f0eadcSLiang Li } 57244f0eadcSLiang Li if (compress2(f->buf + f->buf_index + sizeof(int32_t), (uLongf *)&blen, 57344f0eadcSLiang Li (Bytef *)p, size, level) != Z_OK) { 57444f0eadcSLiang Li error_report("Compress Failed!"); 57544f0eadcSLiang Li return 0; 57644f0eadcSLiang Li } 57744f0eadcSLiang Li qemu_put_be32(f, blen); 57844f0eadcSLiang Li f->buf_index += blen; 57944f0eadcSLiang Li return blen + sizeof(int32_t); 58044f0eadcSLiang Li } 58144f0eadcSLiang Li 58244f0eadcSLiang Li /* Put the data in the buffer of f_src to the buffer of f_des, and 58344f0eadcSLiang Li * then reset the buf_index of f_src to 0. 58444f0eadcSLiang Li */ 58544f0eadcSLiang Li 58644f0eadcSLiang Li int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src) 58744f0eadcSLiang Li { 58844f0eadcSLiang Li int len = 0; 58944f0eadcSLiang Li 59044f0eadcSLiang Li if (f_src->buf_index > 0) { 59144f0eadcSLiang Li len = f_src->buf_index; 59244f0eadcSLiang Li qemu_put_buffer(f_des, f_src->buf, f_src->buf_index); 59344f0eadcSLiang Li f_src->buf_index = 0; 59444f0eadcSLiang Li } 59544f0eadcSLiang Li return len; 59644f0eadcSLiang Li } 597b3af1bc9SDr. David Alan Gilbert 598b3af1bc9SDr. David Alan Gilbert /* 599b3af1bc9SDr. David Alan Gilbert * Get a string whose length is determined by a single preceding byte 600b3af1bc9SDr. David Alan Gilbert * A preallocated 256 byte buffer must be passed in. 601b3af1bc9SDr. David Alan Gilbert * Returns: len on success and a 0 terminated string in the buffer 602b3af1bc9SDr. David Alan Gilbert * else 0 603b3af1bc9SDr. David Alan Gilbert * (Note a 0 length string will return 0 either way) 604b3af1bc9SDr. David Alan Gilbert */ 605b3af1bc9SDr. David Alan Gilbert size_t qemu_get_counted_string(QEMUFile *f, char buf[256]) 606b3af1bc9SDr. David Alan Gilbert { 607b3af1bc9SDr. David Alan Gilbert size_t len = qemu_get_byte(f); 608b3af1bc9SDr. David Alan Gilbert size_t res = qemu_get_buffer(f, (uint8_t *)buf, len); 609b3af1bc9SDr. David Alan Gilbert 610b3af1bc9SDr. David Alan Gilbert buf[res] = 0; 611b3af1bc9SDr. David Alan Gilbert 612b3af1bc9SDr. David Alan Gilbert return res == len ? res : 0; 613b3af1bc9SDr. David Alan Gilbert } 614