xref: /qemu/migration/qemu-file.c (revision 0436e09f)
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>
2660fe637bSDr. David Alan Gilbert #include "qemu-common.h"
27d49b6836SMarkus Armbruster #include "qemu/error-report.h"
2860fe637bSDr. David Alan Gilbert #include "qemu/iov.h"
2960fe637bSDr. David Alan Gilbert #include "qemu/sockets.h"
3010817bf0SDaniel P. Berrange #include "qemu/coroutine.h"
3160fe637bSDr. David Alan Gilbert #include "migration/migration.h"
3260fe637bSDr. David Alan Gilbert #include "migration/qemu-file.h"
334f9d0900SDr. David Alan Gilbert #include "migration/qemu-file-internal.h"
3460fe637bSDr. David Alan Gilbert #include "trace.h"
3560fe637bSDr. David Alan Gilbert 
36e1a8c9b6SDr. David Alan Gilbert /*
37e1a8c9b6SDr. David Alan Gilbert  * Stop a file from being read/written - not all backing files can do this
38e1a8c9b6SDr. David Alan Gilbert  * typically only sockets can.
39e1a8c9b6SDr. David Alan Gilbert  */
40e1a8c9b6SDr. David Alan Gilbert int qemu_file_shutdown(QEMUFile *f)
41e1a8c9b6SDr. David Alan Gilbert {
42e1a8c9b6SDr. David Alan Gilbert     if (!f->ops->shut_down) {
43e1a8c9b6SDr. David Alan Gilbert         return -ENOSYS;
44e1a8c9b6SDr. David Alan Gilbert     }
45e1a8c9b6SDr. David Alan Gilbert     return f->ops->shut_down(f->opaque, true, true);
46e1a8c9b6SDr. David Alan Gilbert }
47e1a8c9b6SDr. David Alan Gilbert 
48adc468e9SDr. David Alan Gilbert /*
49adc468e9SDr. David Alan Gilbert  * Result: QEMUFile* for a 'return path' for comms in the opposite direction
50adc468e9SDr. David Alan Gilbert  *         NULL if not available
51adc468e9SDr. David Alan Gilbert  */
52adc468e9SDr. David Alan Gilbert QEMUFile *qemu_file_get_return_path(QEMUFile *f)
53adc468e9SDr. David Alan Gilbert {
54adc468e9SDr. David Alan Gilbert     if (!f->ops->get_return_path) {
55adc468e9SDr. David Alan Gilbert         return NULL;
56adc468e9SDr. David Alan Gilbert     }
57adc468e9SDr. David Alan Gilbert     return f->ops->get_return_path(f->opaque);
58adc468e9SDr. David Alan Gilbert }
59adc468e9SDr. David Alan Gilbert 
6060fe637bSDr. David Alan Gilbert bool qemu_file_mode_is_not_valid(const char *mode)
6160fe637bSDr. David Alan Gilbert {
6260fe637bSDr. David Alan Gilbert     if (mode == NULL ||
6360fe637bSDr. David Alan Gilbert         (mode[0] != 'r' && mode[0] != 'w') ||
6460fe637bSDr. David Alan Gilbert         mode[1] != 'b' || mode[2] != 0) {
6560fe637bSDr. David Alan Gilbert         fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
6660fe637bSDr. David Alan Gilbert         return true;
6760fe637bSDr. David Alan Gilbert     }
6860fe637bSDr. David Alan Gilbert 
6960fe637bSDr. David Alan Gilbert     return false;
7060fe637bSDr. David Alan Gilbert }
7160fe637bSDr. David Alan Gilbert 
7260fe637bSDr. David Alan Gilbert QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)
7360fe637bSDr. David Alan Gilbert {
7460fe637bSDr. David Alan Gilbert     QEMUFile *f;
7560fe637bSDr. David Alan Gilbert 
7697f3ad35SMarkus Armbruster     f = g_new0(QEMUFile, 1);
7760fe637bSDr. David Alan Gilbert 
7860fe637bSDr. David Alan Gilbert     f->opaque = opaque;
7960fe637bSDr. David Alan Gilbert     f->ops = ops;
8060fe637bSDr. David Alan Gilbert     return f;
8160fe637bSDr. David Alan Gilbert }
8260fe637bSDr. David Alan Gilbert 
83*0436e09fSDaniel P. Berrange 
84*0436e09fSDaniel P. Berrange void qemu_file_set_hooks(QEMUFile *f, const QEMUFileHooks *hooks)
85*0436e09fSDaniel P. Berrange {
86*0436e09fSDaniel P. Berrange     f->hooks = hooks;
87*0436e09fSDaniel P. Berrange }
88*0436e09fSDaniel P. Berrange 
8960fe637bSDr. David Alan Gilbert /*
9060fe637bSDr. David Alan Gilbert  * Get last error for stream f
9160fe637bSDr. David Alan Gilbert  *
9260fe637bSDr. David Alan Gilbert  * Return negative error value if there has been an error on previous
9360fe637bSDr. David Alan Gilbert  * operations, return 0 if no error happened.
9460fe637bSDr. David Alan Gilbert  *
9560fe637bSDr. David Alan Gilbert  */
9660fe637bSDr. David Alan Gilbert int qemu_file_get_error(QEMUFile *f)
9760fe637bSDr. David Alan Gilbert {
9860fe637bSDr. David Alan Gilbert     return f->last_error;
9960fe637bSDr. David Alan Gilbert }
10060fe637bSDr. David Alan Gilbert 
10160fe637bSDr. David Alan Gilbert void qemu_file_set_error(QEMUFile *f, int ret)
10260fe637bSDr. David Alan Gilbert {
10360fe637bSDr. David Alan Gilbert     if (f->last_error == 0) {
10460fe637bSDr. David Alan Gilbert         f->last_error = ret;
10560fe637bSDr. David Alan Gilbert     }
10660fe637bSDr. David Alan Gilbert }
10760fe637bSDr. David Alan Gilbert 
10860fe637bSDr. David Alan Gilbert bool qemu_file_is_writable(QEMUFile *f)
10960fe637bSDr. David Alan Gilbert {
11060fe637bSDr. David Alan Gilbert     return f->ops->writev_buffer || f->ops->put_buffer;
11160fe637bSDr. David Alan Gilbert }
11260fe637bSDr. David Alan Gilbert 
11360fe637bSDr. David Alan Gilbert /**
11460fe637bSDr. David Alan Gilbert  * Flushes QEMUFile buffer
11560fe637bSDr. David Alan Gilbert  *
11660fe637bSDr. David Alan Gilbert  * If there is writev_buffer QEMUFileOps it uses it otherwise uses
117baf51e77SDaniel P. Berrange  * put_buffer ops. This will flush all pending data. If data was
118baf51e77SDaniel P. Berrange  * only partially flushed, it will set an error state.
11960fe637bSDr. David Alan Gilbert  */
12060fe637bSDr. David Alan Gilbert void qemu_fflush(QEMUFile *f)
12160fe637bSDr. David Alan Gilbert {
12260fe637bSDr. David Alan Gilbert     ssize_t ret = 0;
123baf51e77SDaniel P. Berrange     ssize_t expect = 0;
12460fe637bSDr. David Alan Gilbert 
12560fe637bSDr. David Alan Gilbert     if (!qemu_file_is_writable(f)) {
12660fe637bSDr. David Alan Gilbert         return;
12760fe637bSDr. David Alan Gilbert     }
12860fe637bSDr. David Alan Gilbert 
12960fe637bSDr. David Alan Gilbert     if (f->ops->writev_buffer) {
13060fe637bSDr. David Alan Gilbert         if (f->iovcnt > 0) {
131baf51e77SDaniel P. Berrange             expect = iov_size(f->iov, f->iovcnt);
13260fe637bSDr. David Alan Gilbert             ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos);
13360fe637bSDr. David Alan Gilbert         }
13460fe637bSDr. David Alan Gilbert     } else {
13560fe637bSDr. David Alan Gilbert         if (f->buf_index > 0) {
136baf51e77SDaniel P. Berrange             expect = f->buf_index;
13760fe637bSDr. David Alan Gilbert             ret = f->ops->put_buffer(f->opaque, f->buf, f->pos, f->buf_index);
13860fe637bSDr. David Alan Gilbert         }
13960fe637bSDr. David Alan Gilbert     }
140baf51e77SDaniel P. Berrange 
14160fe637bSDr. David Alan Gilbert     if (ret >= 0) {
14260fe637bSDr. David Alan Gilbert         f->pos += ret;
14360fe637bSDr. David Alan Gilbert     }
144baf51e77SDaniel P. Berrange     /* We expect the QEMUFile write impl to send the full
145baf51e77SDaniel P. Berrange      * data set we requested, so sanity check that.
146baf51e77SDaniel P. Berrange      */
147baf51e77SDaniel P. Berrange     if (ret != expect) {
148baf51e77SDaniel P. Berrange         qemu_file_set_error(f, ret < 0 ? ret : -EIO);
149baf51e77SDaniel P. Berrange     }
15060fe637bSDr. David Alan Gilbert     f->buf_index = 0;
15160fe637bSDr. David Alan Gilbert     f->iovcnt = 0;
15260fe637bSDr. David Alan Gilbert }
15360fe637bSDr. David Alan Gilbert 
15460fe637bSDr. David Alan Gilbert void ram_control_before_iterate(QEMUFile *f, uint64_t flags)
15560fe637bSDr. David Alan Gilbert {
15660fe637bSDr. David Alan Gilbert     int ret = 0;
15760fe637bSDr. David Alan Gilbert 
158*0436e09fSDaniel P. Berrange     if (f->hooks && f->hooks->before_ram_iterate) {
159*0436e09fSDaniel P. Berrange         ret = f->hooks->before_ram_iterate(f, f->opaque, flags, NULL);
16060fe637bSDr. David Alan Gilbert         if (ret < 0) {
16160fe637bSDr. David Alan Gilbert             qemu_file_set_error(f, ret);
16260fe637bSDr. David Alan Gilbert         }
16360fe637bSDr. David Alan Gilbert     }
16460fe637bSDr. David Alan Gilbert }
16560fe637bSDr. David Alan Gilbert 
16660fe637bSDr. David Alan Gilbert void ram_control_after_iterate(QEMUFile *f, uint64_t flags)
16760fe637bSDr. David Alan Gilbert {
16860fe637bSDr. David Alan Gilbert     int ret = 0;
16960fe637bSDr. David Alan Gilbert 
170*0436e09fSDaniel P. Berrange     if (f->hooks && f->hooks->after_ram_iterate) {
171*0436e09fSDaniel P. Berrange         ret = f->hooks->after_ram_iterate(f, f->opaque, flags, NULL);
17260fe637bSDr. David Alan Gilbert         if (ret < 0) {
17360fe637bSDr. David Alan Gilbert             qemu_file_set_error(f, ret);
17460fe637bSDr. David Alan Gilbert         }
17560fe637bSDr. David Alan Gilbert     }
17660fe637bSDr. David Alan Gilbert }
17760fe637bSDr. David Alan Gilbert 
178632e3a5cSDr. David Alan Gilbert void ram_control_load_hook(QEMUFile *f, uint64_t flags, void *data)
17960fe637bSDr. David Alan Gilbert {
18060fe637bSDr. David Alan Gilbert     int ret = -EINVAL;
18160fe637bSDr. David Alan Gilbert 
182*0436e09fSDaniel P. Berrange     if (f->hooks && f->hooks->hook_ram_load) {
183*0436e09fSDaniel P. Berrange         ret = f->hooks->hook_ram_load(f, f->opaque, flags, data);
18460fe637bSDr. David Alan Gilbert         if (ret < 0) {
18560fe637bSDr. David Alan Gilbert             qemu_file_set_error(f, ret);
18660fe637bSDr. David Alan Gilbert         }
18760fe637bSDr. David Alan Gilbert     } else {
188632e3a5cSDr. David Alan Gilbert         /*
189632e3a5cSDr. David Alan Gilbert          * Hook is a hook specifically requested by the source sending a flag
190632e3a5cSDr. David Alan Gilbert          * that expects there to be a hook on the destination.
191632e3a5cSDr. David Alan Gilbert          */
192632e3a5cSDr. David Alan Gilbert         if (flags == RAM_CONTROL_HOOK) {
19360fe637bSDr. David Alan Gilbert             qemu_file_set_error(f, ret);
19460fe637bSDr. David Alan Gilbert         }
19560fe637bSDr. David Alan Gilbert     }
196632e3a5cSDr. David Alan Gilbert }
19760fe637bSDr. David Alan Gilbert 
19860fe637bSDr. David Alan Gilbert size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
1996e1dea46SJuan Quintela                              ram_addr_t offset, size_t size,
2006e1dea46SJuan Quintela                              uint64_t *bytes_sent)
20160fe637bSDr. David Alan Gilbert {
202*0436e09fSDaniel P. Berrange     if (f->hooks && f->hooks->save_page) {
203*0436e09fSDaniel P. Berrange         int ret = f->hooks->save_page(f, f->opaque, block_offset,
20460fe637bSDr. David Alan Gilbert                                       offset, size, bytes_sent);
20560fe637bSDr. David Alan Gilbert 
20660fe637bSDr. David Alan Gilbert         if (ret != RAM_SAVE_CONTROL_DELAYED) {
20760fe637bSDr. David Alan Gilbert             if (bytes_sent && *bytes_sent > 0) {
20860fe637bSDr. David Alan Gilbert                 qemu_update_position(f, *bytes_sent);
20960fe637bSDr. David Alan Gilbert             } else if (ret < 0) {
21060fe637bSDr. David Alan Gilbert                 qemu_file_set_error(f, ret);
21160fe637bSDr. David Alan Gilbert             }
21260fe637bSDr. David Alan Gilbert         }
21360fe637bSDr. David Alan Gilbert 
21460fe637bSDr. David Alan Gilbert         return ret;
21560fe637bSDr. David Alan Gilbert     }
21660fe637bSDr. David Alan Gilbert 
21760fe637bSDr. David Alan Gilbert     return RAM_SAVE_CONTROL_NOT_SUPP;
21860fe637bSDr. David Alan Gilbert }
21960fe637bSDr. David Alan Gilbert 
22060fe637bSDr. David Alan Gilbert /*
22160fe637bSDr. David Alan Gilbert  * Attempt to fill the buffer from the underlying file
22260fe637bSDr. David Alan Gilbert  * Returns the number of bytes read, or negative value for an error.
22360fe637bSDr. David Alan Gilbert  *
22460fe637bSDr. David Alan Gilbert  * Note that it can return a partially full buffer even in a not error/not EOF
22560fe637bSDr. David Alan Gilbert  * case if the underlying file descriptor gives a short read, and that can
22660fe637bSDr. David Alan Gilbert  * happen even on a blocking fd.
22760fe637bSDr. David Alan Gilbert  */
22860fe637bSDr. David Alan Gilbert static ssize_t qemu_fill_buffer(QEMUFile *f)
22960fe637bSDr. David Alan Gilbert {
23060fe637bSDr. David Alan Gilbert     int len;
23160fe637bSDr. David Alan Gilbert     int pending;
23260fe637bSDr. David Alan Gilbert 
23360fe637bSDr. David Alan Gilbert     assert(!qemu_file_is_writable(f));
23460fe637bSDr. David Alan Gilbert 
23560fe637bSDr. David Alan Gilbert     pending = f->buf_size - f->buf_index;
23660fe637bSDr. David Alan Gilbert     if (pending > 0) {
23760fe637bSDr. David Alan Gilbert         memmove(f->buf, f->buf + f->buf_index, pending);
23860fe637bSDr. David Alan Gilbert     }
23960fe637bSDr. David Alan Gilbert     f->buf_index = 0;
24060fe637bSDr. David Alan Gilbert     f->buf_size = pending;
24160fe637bSDr. David Alan Gilbert 
24260fe637bSDr. David Alan Gilbert     len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos,
24360fe637bSDr. David Alan Gilbert                         IO_BUF_SIZE - pending);
24460fe637bSDr. David Alan Gilbert     if (len > 0) {
24560fe637bSDr. David Alan Gilbert         f->buf_size += len;
24660fe637bSDr. David Alan Gilbert         f->pos += len;
24760fe637bSDr. David Alan Gilbert     } else if (len == 0) {
24860fe637bSDr. David Alan Gilbert         qemu_file_set_error(f, -EIO);
24960fe637bSDr. David Alan Gilbert     } else if (len != -EAGAIN) {
25060fe637bSDr. David Alan Gilbert         qemu_file_set_error(f, len);
25160fe637bSDr. David Alan Gilbert     }
25260fe637bSDr. David Alan Gilbert 
25360fe637bSDr. David Alan Gilbert     return len;
25460fe637bSDr. David Alan Gilbert }
25560fe637bSDr. David Alan Gilbert 
25660fe637bSDr. David Alan Gilbert int qemu_get_fd(QEMUFile *f)
25760fe637bSDr. David Alan Gilbert {
25860fe637bSDr. David Alan Gilbert     if (f->ops->get_fd) {
25960fe637bSDr. David Alan Gilbert         return f->ops->get_fd(f->opaque);
26060fe637bSDr. David Alan Gilbert     }
26160fe637bSDr. David Alan Gilbert     return -1;
26260fe637bSDr. David Alan Gilbert }
26360fe637bSDr. David Alan Gilbert 
26460fe637bSDr. David Alan Gilbert void qemu_update_position(QEMUFile *f, size_t size)
26560fe637bSDr. David Alan Gilbert {
26660fe637bSDr. David Alan Gilbert     f->pos += size;
26760fe637bSDr. David Alan Gilbert }
26860fe637bSDr. David Alan Gilbert 
26960fe637bSDr. David Alan Gilbert /** Closes the file
27060fe637bSDr. David Alan Gilbert  *
27160fe637bSDr. David Alan Gilbert  * Returns negative error value if any error happened on previous operations or
27260fe637bSDr. David Alan Gilbert  * while closing the file. Returns 0 or positive number on success.
27360fe637bSDr. David Alan Gilbert  *
27460fe637bSDr. David Alan Gilbert  * The meaning of return value on success depends on the specific backend
27560fe637bSDr. David Alan Gilbert  * being used.
27660fe637bSDr. David Alan Gilbert  */
27760fe637bSDr. David Alan Gilbert int qemu_fclose(QEMUFile *f)
27860fe637bSDr. David Alan Gilbert {
27960fe637bSDr. David Alan Gilbert     int ret;
28060fe637bSDr. David Alan Gilbert     qemu_fflush(f);
28160fe637bSDr. David Alan Gilbert     ret = qemu_file_get_error(f);
28260fe637bSDr. David Alan Gilbert 
28360fe637bSDr. David Alan Gilbert     if (f->ops->close) {
28460fe637bSDr. David Alan Gilbert         int ret2 = f->ops->close(f->opaque);
28560fe637bSDr. David Alan Gilbert         if (ret >= 0) {
28660fe637bSDr. David Alan Gilbert             ret = ret2;
28760fe637bSDr. David Alan Gilbert         }
28860fe637bSDr. David Alan Gilbert     }
28960fe637bSDr. David Alan Gilbert     /* If any error was spotted before closing, we should report it
29060fe637bSDr. David Alan Gilbert      * instead of the close() return value.
29160fe637bSDr. David Alan Gilbert      */
29260fe637bSDr. David Alan Gilbert     if (f->last_error) {
29360fe637bSDr. David Alan Gilbert         ret = f->last_error;
29460fe637bSDr. David Alan Gilbert     }
29560fe637bSDr. David Alan Gilbert     g_free(f);
29660fe637bSDr. David Alan Gilbert     trace_qemu_file_fclose();
29760fe637bSDr. David Alan Gilbert     return ret;
29860fe637bSDr. David Alan Gilbert }
29960fe637bSDr. David Alan Gilbert 
30056f3835fSDr. David Alan Gilbert static void add_to_iovec(QEMUFile *f, const uint8_t *buf, size_t size)
30160fe637bSDr. David Alan Gilbert {
30260fe637bSDr. David Alan Gilbert     /* check for adjacent buffer and coalesce them */
30360fe637bSDr. David Alan Gilbert     if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base +
30460fe637bSDr. David Alan Gilbert         f->iov[f->iovcnt - 1].iov_len) {
30560fe637bSDr. David Alan Gilbert         f->iov[f->iovcnt - 1].iov_len += size;
30660fe637bSDr. David Alan Gilbert     } else {
30760fe637bSDr. David Alan Gilbert         f->iov[f->iovcnt].iov_base = (uint8_t *)buf;
30860fe637bSDr. David Alan Gilbert         f->iov[f->iovcnt++].iov_len = size;
30960fe637bSDr. David Alan Gilbert     }
31060fe637bSDr. David Alan Gilbert 
31160fe637bSDr. David Alan Gilbert     if (f->iovcnt >= MAX_IOV_SIZE) {
31260fe637bSDr. David Alan Gilbert         qemu_fflush(f);
31360fe637bSDr. David Alan Gilbert     }
31460fe637bSDr. David Alan Gilbert }
31560fe637bSDr. David Alan Gilbert 
31656f3835fSDr. David Alan Gilbert void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, size_t size)
31760fe637bSDr. David Alan Gilbert {
31860fe637bSDr. David Alan Gilbert     if (!f->ops->writev_buffer) {
31960fe637bSDr. David Alan Gilbert         qemu_put_buffer(f, buf, size);
32060fe637bSDr. David Alan Gilbert         return;
32160fe637bSDr. David Alan Gilbert     }
32260fe637bSDr. David Alan Gilbert 
32360fe637bSDr. David Alan Gilbert     if (f->last_error) {
32460fe637bSDr. David Alan Gilbert         return;
32560fe637bSDr. David Alan Gilbert     }
32660fe637bSDr. David Alan Gilbert 
32760fe637bSDr. David Alan Gilbert     f->bytes_xfer += size;
32860fe637bSDr. David Alan Gilbert     add_to_iovec(f, buf, size);
32960fe637bSDr. David Alan Gilbert }
33060fe637bSDr. David Alan Gilbert 
33156f3835fSDr. David Alan Gilbert void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size)
33260fe637bSDr. David Alan Gilbert {
33356f3835fSDr. David Alan Gilbert     size_t l;
33460fe637bSDr. David Alan Gilbert 
33560fe637bSDr. David Alan Gilbert     if (f->last_error) {
33660fe637bSDr. David Alan Gilbert         return;
33760fe637bSDr. David Alan Gilbert     }
33860fe637bSDr. David Alan Gilbert 
33960fe637bSDr. David Alan Gilbert     while (size > 0) {
34060fe637bSDr. David Alan Gilbert         l = IO_BUF_SIZE - f->buf_index;
34160fe637bSDr. David Alan Gilbert         if (l > size) {
34260fe637bSDr. David Alan Gilbert             l = size;
34360fe637bSDr. David Alan Gilbert         }
34460fe637bSDr. David Alan Gilbert         memcpy(f->buf + f->buf_index, buf, l);
34560fe637bSDr. David Alan Gilbert         f->bytes_xfer += l;
34660fe637bSDr. David Alan Gilbert         if (f->ops->writev_buffer) {
34760fe637bSDr. David Alan Gilbert             add_to_iovec(f, f->buf + f->buf_index, l);
34860fe637bSDr. David Alan Gilbert         }
34960fe637bSDr. David Alan Gilbert         f->buf_index += l;
35060fe637bSDr. David Alan Gilbert         if (f->buf_index == IO_BUF_SIZE) {
35160fe637bSDr. David Alan Gilbert             qemu_fflush(f);
35260fe637bSDr. David Alan Gilbert         }
35360fe637bSDr. David Alan Gilbert         if (qemu_file_get_error(f)) {
35460fe637bSDr. David Alan Gilbert             break;
35560fe637bSDr. David Alan Gilbert         }
35660fe637bSDr. David Alan Gilbert         buf += l;
35760fe637bSDr. David Alan Gilbert         size -= l;
35860fe637bSDr. David Alan Gilbert     }
35960fe637bSDr. David Alan Gilbert }
36060fe637bSDr. David Alan Gilbert 
36160fe637bSDr. David Alan Gilbert void qemu_put_byte(QEMUFile *f, int v)
36260fe637bSDr. David Alan Gilbert {
36360fe637bSDr. David Alan Gilbert     if (f->last_error) {
36460fe637bSDr. David Alan Gilbert         return;
36560fe637bSDr. David Alan Gilbert     }
36660fe637bSDr. David Alan Gilbert 
36760fe637bSDr. David Alan Gilbert     f->buf[f->buf_index] = v;
36860fe637bSDr. David Alan Gilbert     f->bytes_xfer++;
36960fe637bSDr. David Alan Gilbert     if (f->ops->writev_buffer) {
37060fe637bSDr. David Alan Gilbert         add_to_iovec(f, f->buf + f->buf_index, 1);
37160fe637bSDr. David Alan Gilbert     }
37260fe637bSDr. David Alan Gilbert     f->buf_index++;
37360fe637bSDr. David Alan Gilbert     if (f->buf_index == IO_BUF_SIZE) {
37460fe637bSDr. David Alan Gilbert         qemu_fflush(f);
37560fe637bSDr. David Alan Gilbert     }
37660fe637bSDr. David Alan Gilbert }
37760fe637bSDr. David Alan Gilbert 
37860fe637bSDr. David Alan Gilbert void qemu_file_skip(QEMUFile *f, int size)
37960fe637bSDr. David Alan Gilbert {
38060fe637bSDr. David Alan Gilbert     if (f->buf_index + size <= f->buf_size) {
38160fe637bSDr. David Alan Gilbert         f->buf_index += size;
38260fe637bSDr. David Alan Gilbert     }
38360fe637bSDr. David Alan Gilbert }
38460fe637bSDr. David Alan Gilbert 
38560fe637bSDr. David Alan Gilbert /*
3867c1e52baSDr. David Alan Gilbert  * Read 'size' bytes from file (at 'offset') without moving the
3877c1e52baSDr. David Alan Gilbert  * pointer and set 'buf' to point to that data.
38860fe637bSDr. David Alan Gilbert  *
38960fe637bSDr. David Alan Gilbert  * It will return size bytes unless there was an error, in which case it will
39060fe637bSDr. David Alan Gilbert  * return as many as it managed to read (assuming blocking fd's which
39160fe637bSDr. David Alan Gilbert  * all current QEMUFile are)
39260fe637bSDr. David Alan Gilbert  */
39356f3835fSDr. David Alan Gilbert size_t qemu_peek_buffer(QEMUFile *f, uint8_t **buf, size_t size, size_t offset)
39460fe637bSDr. David Alan Gilbert {
39556f3835fSDr. David Alan Gilbert     ssize_t pending;
39656f3835fSDr. David Alan Gilbert     size_t index;
39760fe637bSDr. David Alan Gilbert 
39860fe637bSDr. David Alan Gilbert     assert(!qemu_file_is_writable(f));
39960fe637bSDr. David Alan Gilbert     assert(offset < IO_BUF_SIZE);
40060fe637bSDr. David Alan Gilbert     assert(size <= IO_BUF_SIZE - offset);
40160fe637bSDr. David Alan Gilbert 
40260fe637bSDr. David Alan Gilbert     /* The 1st byte to read from */
40360fe637bSDr. David Alan Gilbert     index = f->buf_index + offset;
40460fe637bSDr. David Alan Gilbert     /* The number of available bytes starting at index */
40560fe637bSDr. David Alan Gilbert     pending = f->buf_size - index;
40660fe637bSDr. David Alan Gilbert 
40760fe637bSDr. David Alan Gilbert     /*
40860fe637bSDr. David Alan Gilbert      * qemu_fill_buffer might return just a few bytes, even when there isn't
40960fe637bSDr. David Alan Gilbert      * an error, so loop collecting them until we get enough.
41060fe637bSDr. David Alan Gilbert      */
41160fe637bSDr. David Alan Gilbert     while (pending < size) {
41260fe637bSDr. David Alan Gilbert         int received = qemu_fill_buffer(f);
41360fe637bSDr. David Alan Gilbert 
41460fe637bSDr. David Alan Gilbert         if (received <= 0) {
41560fe637bSDr. David Alan Gilbert             break;
41660fe637bSDr. David Alan Gilbert         }
41760fe637bSDr. David Alan Gilbert 
41860fe637bSDr. David Alan Gilbert         index = f->buf_index + offset;
41960fe637bSDr. David Alan Gilbert         pending = f->buf_size - index;
42060fe637bSDr. David Alan Gilbert     }
42160fe637bSDr. David Alan Gilbert 
42260fe637bSDr. David Alan Gilbert     if (pending <= 0) {
42360fe637bSDr. David Alan Gilbert         return 0;
42460fe637bSDr. David Alan Gilbert     }
42560fe637bSDr. David Alan Gilbert     if (size > pending) {
42660fe637bSDr. David Alan Gilbert         size = pending;
42760fe637bSDr. David Alan Gilbert     }
42860fe637bSDr. David Alan Gilbert 
4297c1e52baSDr. David Alan Gilbert     *buf = f->buf + index;
43060fe637bSDr. David Alan Gilbert     return size;
43160fe637bSDr. David Alan Gilbert }
43260fe637bSDr. David Alan Gilbert 
43360fe637bSDr. David Alan Gilbert /*
43460fe637bSDr. David Alan Gilbert  * Read 'size' bytes of data from the file into buf.
43560fe637bSDr. David Alan Gilbert  * 'size' can be larger than the internal buffer.
43660fe637bSDr. David Alan Gilbert  *
43760fe637bSDr. David Alan Gilbert  * It will return size bytes unless there was an error, in which case it will
43860fe637bSDr. David Alan Gilbert  * return as many as it managed to read (assuming blocking fd's which
43960fe637bSDr. David Alan Gilbert  * all current QEMUFile are)
44060fe637bSDr. David Alan Gilbert  */
44156f3835fSDr. David Alan Gilbert size_t qemu_get_buffer(QEMUFile *f, uint8_t *buf, size_t size)
44260fe637bSDr. David Alan Gilbert {
44356f3835fSDr. David Alan Gilbert     size_t pending = size;
44456f3835fSDr. David Alan Gilbert     size_t done = 0;
44560fe637bSDr. David Alan Gilbert 
44660fe637bSDr. David Alan Gilbert     while (pending > 0) {
44756f3835fSDr. David Alan Gilbert         size_t res;
4487c1e52baSDr. David Alan Gilbert         uint8_t *src;
44960fe637bSDr. David Alan Gilbert 
4507c1e52baSDr. David Alan Gilbert         res = qemu_peek_buffer(f, &src, MIN(pending, IO_BUF_SIZE), 0);
45160fe637bSDr. David Alan Gilbert         if (res == 0) {
45260fe637bSDr. David Alan Gilbert             return done;
45360fe637bSDr. David Alan Gilbert         }
4547c1e52baSDr. David Alan Gilbert         memcpy(buf, src, res);
45560fe637bSDr. David Alan Gilbert         qemu_file_skip(f, res);
45660fe637bSDr. David Alan Gilbert         buf += res;
45760fe637bSDr. David Alan Gilbert         pending -= res;
45860fe637bSDr. David Alan Gilbert         done += res;
45960fe637bSDr. David Alan Gilbert     }
46060fe637bSDr. David Alan Gilbert     return done;
46160fe637bSDr. David Alan Gilbert }
46260fe637bSDr. David Alan Gilbert 
46360fe637bSDr. David Alan Gilbert /*
4649504fb51SDr. David Alan Gilbert  * Read 'size' bytes of data from the file.
4659504fb51SDr. David Alan Gilbert  * 'size' can be larger than the internal buffer.
4669504fb51SDr. David Alan Gilbert  *
4679504fb51SDr. David Alan Gilbert  * The data:
4689504fb51SDr. David Alan Gilbert  *   may be held on an internal buffer (in which case *buf is updated
4699504fb51SDr. David Alan Gilbert  *     to point to it) that is valid until the next qemu_file operation.
4709504fb51SDr. David Alan Gilbert  * OR
4719504fb51SDr. David Alan Gilbert  *   will be copied to the *buf that was passed in.
4729504fb51SDr. David Alan Gilbert  *
4739504fb51SDr. David Alan Gilbert  * The code tries to avoid the copy if possible.
4749504fb51SDr. David Alan Gilbert  *
4759504fb51SDr. David Alan Gilbert  * It will return size bytes unless there was an error, in which case it will
4769504fb51SDr. David Alan Gilbert  * return as many as it managed to read (assuming blocking fd's which
4779504fb51SDr. David Alan Gilbert  * all current QEMUFile are)
4789504fb51SDr. David Alan Gilbert  *
4799504fb51SDr. David Alan Gilbert  * Note: Since **buf may get changed, the caller should take care to
4809504fb51SDr. David Alan Gilbert  *       keep a pointer to the original buffer if it needs to deallocate it.
4819504fb51SDr. David Alan Gilbert  */
4829504fb51SDr. David Alan Gilbert size_t qemu_get_buffer_in_place(QEMUFile *f, uint8_t **buf, size_t size)
4839504fb51SDr. David Alan Gilbert {
4849504fb51SDr. David Alan Gilbert     if (size < IO_BUF_SIZE) {
4859504fb51SDr. David Alan Gilbert         size_t res;
4869504fb51SDr. David Alan Gilbert         uint8_t *src;
4879504fb51SDr. David Alan Gilbert 
4889504fb51SDr. David Alan Gilbert         res = qemu_peek_buffer(f, &src, size, 0);
4899504fb51SDr. David Alan Gilbert 
4909504fb51SDr. David Alan Gilbert         if (res == size) {
4919504fb51SDr. David Alan Gilbert             qemu_file_skip(f, res);
4929504fb51SDr. David Alan Gilbert             *buf = src;
4939504fb51SDr. David Alan Gilbert             return res;
4949504fb51SDr. David Alan Gilbert         }
4959504fb51SDr. David Alan Gilbert     }
4969504fb51SDr. David Alan Gilbert 
4979504fb51SDr. David Alan Gilbert     return qemu_get_buffer(f, *buf, size);
4989504fb51SDr. David Alan Gilbert }
4999504fb51SDr. David Alan Gilbert 
5009504fb51SDr. David Alan Gilbert /*
50160fe637bSDr. David Alan Gilbert  * Peeks a single byte from the buffer; this isn't guaranteed to work if
50260fe637bSDr. David Alan Gilbert  * offset leaves a gap after the previous read/peeked data.
50360fe637bSDr. David Alan Gilbert  */
50460fe637bSDr. David Alan Gilbert int qemu_peek_byte(QEMUFile *f, int offset)
50560fe637bSDr. David Alan Gilbert {
50660fe637bSDr. David Alan Gilbert     int index = f->buf_index + offset;
50760fe637bSDr. David Alan Gilbert 
50860fe637bSDr. David Alan Gilbert     assert(!qemu_file_is_writable(f));
50960fe637bSDr. David Alan Gilbert     assert(offset < IO_BUF_SIZE);
51060fe637bSDr. David Alan Gilbert 
51160fe637bSDr. David Alan Gilbert     if (index >= f->buf_size) {
51260fe637bSDr. David Alan Gilbert         qemu_fill_buffer(f);
51360fe637bSDr. David Alan Gilbert         index = f->buf_index + offset;
51460fe637bSDr. David Alan Gilbert         if (index >= f->buf_size) {
51560fe637bSDr. David Alan Gilbert             return 0;
51660fe637bSDr. David Alan Gilbert         }
51760fe637bSDr. David Alan Gilbert     }
51860fe637bSDr. David Alan Gilbert     return f->buf[index];
51960fe637bSDr. David Alan Gilbert }
52060fe637bSDr. David Alan Gilbert 
52160fe637bSDr. David Alan Gilbert int qemu_get_byte(QEMUFile *f)
52260fe637bSDr. David Alan Gilbert {
52360fe637bSDr. David Alan Gilbert     int result;
52460fe637bSDr. David Alan Gilbert 
52560fe637bSDr. David Alan Gilbert     result = qemu_peek_byte(f, 0);
52660fe637bSDr. David Alan Gilbert     qemu_file_skip(f, 1);
52760fe637bSDr. David Alan Gilbert     return result;
52860fe637bSDr. David Alan Gilbert }
52960fe637bSDr. David Alan Gilbert 
53097221400SAlexander Graf int64_t qemu_ftell_fast(QEMUFile *f)
53197221400SAlexander Graf {
53297221400SAlexander Graf     int64_t ret = f->pos;
53397221400SAlexander Graf     int i;
53497221400SAlexander Graf 
53597221400SAlexander Graf     if (f->ops->writev_buffer) {
53697221400SAlexander Graf         for (i = 0; i < f->iovcnt; i++) {
53797221400SAlexander Graf             ret += f->iov[i].iov_len;
53897221400SAlexander Graf         }
53997221400SAlexander Graf     } else {
54097221400SAlexander Graf         ret += f->buf_index;
54197221400SAlexander Graf     }
54297221400SAlexander Graf 
54397221400SAlexander Graf     return ret;
54497221400SAlexander Graf }
54597221400SAlexander Graf 
54660fe637bSDr. David Alan Gilbert int64_t qemu_ftell(QEMUFile *f)
54760fe637bSDr. David Alan Gilbert {
54860fe637bSDr. David Alan Gilbert     qemu_fflush(f);
54960fe637bSDr. David Alan Gilbert     return f->pos;
55060fe637bSDr. David Alan Gilbert }
55160fe637bSDr. David Alan Gilbert 
55260fe637bSDr. David Alan Gilbert int qemu_file_rate_limit(QEMUFile *f)
55360fe637bSDr. David Alan Gilbert {
55460fe637bSDr. David Alan Gilbert     if (qemu_file_get_error(f)) {
55560fe637bSDr. David Alan Gilbert         return 1;
55660fe637bSDr. David Alan Gilbert     }
55760fe637bSDr. David Alan Gilbert     if (f->xfer_limit > 0 && f->bytes_xfer > f->xfer_limit) {
55860fe637bSDr. David Alan Gilbert         return 1;
55960fe637bSDr. David Alan Gilbert     }
56060fe637bSDr. David Alan Gilbert     return 0;
56160fe637bSDr. David Alan Gilbert }
56260fe637bSDr. David Alan Gilbert 
56360fe637bSDr. David Alan Gilbert int64_t qemu_file_get_rate_limit(QEMUFile *f)
56460fe637bSDr. David Alan Gilbert {
56560fe637bSDr. David Alan Gilbert     return f->xfer_limit;
56660fe637bSDr. David Alan Gilbert }
56760fe637bSDr. David Alan Gilbert 
56860fe637bSDr. David Alan Gilbert void qemu_file_set_rate_limit(QEMUFile *f, int64_t limit)
56960fe637bSDr. David Alan Gilbert {
57060fe637bSDr. David Alan Gilbert     f->xfer_limit = limit;
57160fe637bSDr. David Alan Gilbert }
57260fe637bSDr. David Alan Gilbert 
57360fe637bSDr. David Alan Gilbert void qemu_file_reset_rate_limit(QEMUFile *f)
57460fe637bSDr. David Alan Gilbert {
57560fe637bSDr. David Alan Gilbert     f->bytes_xfer = 0;
57660fe637bSDr. David Alan Gilbert }
57760fe637bSDr. David Alan Gilbert 
57860fe637bSDr. David Alan Gilbert void qemu_put_be16(QEMUFile *f, unsigned int v)
57960fe637bSDr. David Alan Gilbert {
58060fe637bSDr. David Alan Gilbert     qemu_put_byte(f, v >> 8);
58160fe637bSDr. David Alan Gilbert     qemu_put_byte(f, v);
58260fe637bSDr. David Alan Gilbert }
58360fe637bSDr. David Alan Gilbert 
58460fe637bSDr. David Alan Gilbert void qemu_put_be32(QEMUFile *f, unsigned int v)
58560fe637bSDr. David Alan Gilbert {
58660fe637bSDr. David Alan Gilbert     qemu_put_byte(f, v >> 24);
58760fe637bSDr. David Alan Gilbert     qemu_put_byte(f, v >> 16);
58860fe637bSDr. David Alan Gilbert     qemu_put_byte(f, v >> 8);
58960fe637bSDr. David Alan Gilbert     qemu_put_byte(f, v);
59060fe637bSDr. David Alan Gilbert }
59160fe637bSDr. David Alan Gilbert 
59260fe637bSDr. David Alan Gilbert void qemu_put_be64(QEMUFile *f, uint64_t v)
59360fe637bSDr. David Alan Gilbert {
59460fe637bSDr. David Alan Gilbert     qemu_put_be32(f, v >> 32);
59560fe637bSDr. David Alan Gilbert     qemu_put_be32(f, v);
59660fe637bSDr. David Alan Gilbert }
59760fe637bSDr. David Alan Gilbert 
59860fe637bSDr. David Alan Gilbert unsigned int qemu_get_be16(QEMUFile *f)
59960fe637bSDr. David Alan Gilbert {
60060fe637bSDr. David Alan Gilbert     unsigned int v;
60160fe637bSDr. David Alan Gilbert     v = qemu_get_byte(f) << 8;
60260fe637bSDr. David Alan Gilbert     v |= qemu_get_byte(f);
60360fe637bSDr. David Alan Gilbert     return v;
60460fe637bSDr. David Alan Gilbert }
60560fe637bSDr. David Alan Gilbert 
60660fe637bSDr. David Alan Gilbert unsigned int qemu_get_be32(QEMUFile *f)
60760fe637bSDr. David Alan Gilbert {
60860fe637bSDr. David Alan Gilbert     unsigned int v;
60990d6a673SPeter Maydell     v = (unsigned int)qemu_get_byte(f) << 24;
61060fe637bSDr. David Alan Gilbert     v |= qemu_get_byte(f) << 16;
61160fe637bSDr. David Alan Gilbert     v |= qemu_get_byte(f) << 8;
61260fe637bSDr. David Alan Gilbert     v |= qemu_get_byte(f);
61360fe637bSDr. David Alan Gilbert     return v;
61460fe637bSDr. David Alan Gilbert }
61560fe637bSDr. David Alan Gilbert 
61660fe637bSDr. David Alan Gilbert uint64_t qemu_get_be64(QEMUFile *f)
61760fe637bSDr. David Alan Gilbert {
61860fe637bSDr. David Alan Gilbert     uint64_t v;
61960fe637bSDr. David Alan Gilbert     v = (uint64_t)qemu_get_be32(f) << 32;
62060fe637bSDr. David Alan Gilbert     v |= qemu_get_be32(f);
62160fe637bSDr. David Alan Gilbert     return v;
62260fe637bSDr. David Alan Gilbert }
62344f0eadcSLiang Li 
62444f0eadcSLiang Li /* compress size bytes of data start at p with specific compression
62544f0eadcSLiang Li  * level and store the compressed data to the buffer of f.
62644f0eadcSLiang Li  */
62744f0eadcSLiang Li 
62844f0eadcSLiang Li ssize_t qemu_put_compression_data(QEMUFile *f, const uint8_t *p, size_t size,
62944f0eadcSLiang Li                                   int level)
63044f0eadcSLiang Li {
63144f0eadcSLiang Li     ssize_t blen = IO_BUF_SIZE - f->buf_index - sizeof(int32_t);
63244f0eadcSLiang Li 
63344f0eadcSLiang Li     if (blen < compressBound(size)) {
63444f0eadcSLiang Li         return 0;
63544f0eadcSLiang Li     }
63644f0eadcSLiang Li     if (compress2(f->buf + f->buf_index + sizeof(int32_t), (uLongf *)&blen,
63744f0eadcSLiang Li                   (Bytef *)p, size, level) != Z_OK) {
63844f0eadcSLiang Li         error_report("Compress Failed!");
63944f0eadcSLiang Li         return 0;
64044f0eadcSLiang Li     }
64144f0eadcSLiang Li     qemu_put_be32(f, blen);
64244f0eadcSLiang Li     f->buf_index += blen;
64344f0eadcSLiang Li     return blen + sizeof(int32_t);
64444f0eadcSLiang Li }
64544f0eadcSLiang Li 
64644f0eadcSLiang Li /* Put the data in the buffer of f_src to the buffer of f_des, and
64744f0eadcSLiang Li  * then reset the buf_index of f_src to 0.
64844f0eadcSLiang Li  */
64944f0eadcSLiang Li 
65044f0eadcSLiang Li int qemu_put_qemu_file(QEMUFile *f_des, QEMUFile *f_src)
65144f0eadcSLiang Li {
65244f0eadcSLiang Li     int len = 0;
65344f0eadcSLiang Li 
65444f0eadcSLiang Li     if (f_src->buf_index > 0) {
65544f0eadcSLiang Li         len = f_src->buf_index;
65644f0eadcSLiang Li         qemu_put_buffer(f_des, f_src->buf, f_src->buf_index);
65744f0eadcSLiang Li         f_src->buf_index = 0;
65844f0eadcSLiang Li     }
65944f0eadcSLiang Li     return len;
66044f0eadcSLiang Li }
661b3af1bc9SDr. David Alan Gilbert 
662b3af1bc9SDr. David Alan Gilbert /*
663b3af1bc9SDr. David Alan Gilbert  * Get a string whose length is determined by a single preceding byte
664b3af1bc9SDr. David Alan Gilbert  * A preallocated 256 byte buffer must be passed in.
665b3af1bc9SDr. David Alan Gilbert  * Returns: len on success and a 0 terminated string in the buffer
666b3af1bc9SDr. David Alan Gilbert  *          else 0
667b3af1bc9SDr. David Alan Gilbert  *          (Note a 0 length string will return 0 either way)
668b3af1bc9SDr. David Alan Gilbert  */
669b3af1bc9SDr. David Alan Gilbert size_t qemu_get_counted_string(QEMUFile *f, char buf[256])
670b3af1bc9SDr. David Alan Gilbert {
671b3af1bc9SDr. David Alan Gilbert     size_t len = qemu_get_byte(f);
672b3af1bc9SDr. David Alan Gilbert     size_t res = qemu_get_buffer(f, (uint8_t *)buf, len);
673b3af1bc9SDr. David Alan Gilbert 
674b3af1bc9SDr. David Alan Gilbert     buf[res] = 0;
675b3af1bc9SDr. David Alan Gilbert 
676b3af1bc9SDr. David Alan Gilbert     return res == len ? res : 0;
677b3af1bc9SDr. David Alan Gilbert }
678a800cd5cSDr. David Alan Gilbert 
679a800cd5cSDr. David Alan Gilbert /*
680a800cd5cSDr. David Alan Gilbert  * Set the blocking state of the QEMUFile.
681a800cd5cSDr. David Alan Gilbert  * Note: On some transports the OS only keeps a single blocking state for
682a800cd5cSDr. David Alan Gilbert  *       both directions, and thus changing the blocking on the main
683a800cd5cSDr. David Alan Gilbert  *       QEMUFile can also affect the return path.
684a800cd5cSDr. David Alan Gilbert  */
685a800cd5cSDr. David Alan Gilbert void qemu_file_set_blocking(QEMUFile *f, bool block)
686a800cd5cSDr. David Alan Gilbert {
687a800cd5cSDr. David Alan Gilbert     if (block) {
688a800cd5cSDr. David Alan Gilbert         qemu_set_block(qemu_get_fd(f));
689a800cd5cSDr. David Alan Gilbert     } else {
690a800cd5cSDr. David Alan Gilbert         qemu_set_nonblock(qemu_get_fd(f));
691a800cd5cSDr. David Alan Gilbert     }
692a800cd5cSDr. David Alan Gilbert }
693