]> Git Repo - qemu.git/blob - qemu-file.c
qemu-file: Use qemu_file_is_writable() on stdio_fclose()
[qemu.git] / qemu-file.c
1 /*
2  * QEMU System Emulator
3  *
4  * Copyright (c) 2003-2008 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "qemu-common.h"
25 #include "qemu/iov.h"
26 #include "qemu/sockets.h"
27 #include "block/coroutine.h"
28 #include "migration/migration.h"
29 #include "migration/qemu-file.h"
30 #include "trace.h"
31
32 #define IO_BUF_SIZE 32768
33 #define MAX_IOV_SIZE MIN(IOV_MAX, 64)
34
35 struct QEMUFile {
36     const QEMUFileOps *ops;
37     void *opaque;
38
39     int64_t bytes_xfer;
40     int64_t xfer_limit;
41
42     int64_t pos; /* start of buffer when writing, end of buffer
43                     when reading */
44     int buf_index;
45     int buf_size; /* 0 when writing */
46     uint8_t buf[IO_BUF_SIZE];
47
48     struct iovec iov[MAX_IOV_SIZE];
49     unsigned int iovcnt;
50
51     int last_error;
52 };
53
54 typedef struct QEMUFileStdio {
55     FILE *stdio_file;
56     QEMUFile *file;
57 } QEMUFileStdio;
58
59 typedef struct QEMUFileSocket {
60     int fd;
61     QEMUFile *file;
62 } QEMUFileSocket;
63
64 static ssize_t socket_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
65                                     int64_t pos)
66 {
67     QEMUFileSocket *s = opaque;
68     ssize_t len;
69     ssize_t size = iov_size(iov, iovcnt);
70
71     len = iov_send(s->fd, iov, iovcnt, 0, size);
72     if (len < size) {
73         len = -socket_error();
74     }
75     return len;
76 }
77
78 static int socket_get_fd(void *opaque)
79 {
80     QEMUFileSocket *s = opaque;
81
82     return s->fd;
83 }
84
85 static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
86 {
87     QEMUFileSocket *s = opaque;
88     ssize_t len;
89
90     for (;;) {
91         len = qemu_recv(s->fd, buf, size, 0);
92         if (len != -1) {
93             break;
94         }
95         if (socket_error() == EAGAIN) {
96             yield_until_fd_readable(s->fd);
97         } else if (socket_error() != EINTR) {
98             break;
99         }
100     }
101
102     if (len == -1) {
103         len = -socket_error();
104     }
105     return len;
106 }
107
108 static int socket_close(void *opaque)
109 {
110     QEMUFileSocket *s = opaque;
111     closesocket(s->fd);
112     g_free(s);
113     return 0;
114 }
115
116 static int stdio_get_fd(void *opaque)
117 {
118     QEMUFileStdio *s = opaque;
119
120     return fileno(s->stdio_file);
121 }
122
123 static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,
124                             int size)
125 {
126     QEMUFileStdio *s = opaque;
127     int res;
128
129     res = fwrite(buf, 1, size, s->stdio_file);
130
131     if (res != size) {
132         return -errno;
133     }
134     return res;
135 }
136
137 static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
138 {
139     QEMUFileStdio *s = opaque;
140     FILE *fp = s->stdio_file;
141     int bytes;
142
143     for (;;) {
144         clearerr(fp);
145         bytes = fread(buf, 1, size, fp);
146         if (bytes != 0 || !ferror(fp)) {
147             break;
148         }
149         if (errno == EAGAIN) {
150             yield_until_fd_readable(fileno(fp));
151         } else if (errno != EINTR) {
152             break;
153         }
154     }
155     return bytes;
156 }
157
158 static int stdio_pclose(void *opaque)
159 {
160     QEMUFileStdio *s = opaque;
161     int ret;
162     ret = pclose(s->stdio_file);
163     if (ret == -1) {
164         ret = -errno;
165     } else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {
166         /* close succeeded, but non-zero exit code: */
167         ret = -EIO; /* fake errno value */
168     }
169     g_free(s);
170     return ret;
171 }
172
173 static int stdio_fclose(void *opaque)
174 {
175     QEMUFileStdio *s = opaque;
176     int ret = 0;
177
178     if (qemu_file_is_writable(s->file)) {
179         int fd = fileno(s->stdio_file);
180         struct stat st;
181
182         ret = fstat(fd, &st);
183         if (ret == 0 && S_ISREG(st.st_mode)) {
184             /*
185              * If the file handle is a regular file make sure the
186              * data is flushed to disk before signaling success.
187              */
188             ret = fsync(fd);
189             if (ret != 0) {
190                 ret = -errno;
191                 return ret;
192             }
193         }
194     }
195     if (fclose(s->stdio_file) == EOF) {
196         ret = -errno;
197     }
198     g_free(s);
199     return ret;
200 }
201
202 static const QEMUFileOps stdio_pipe_read_ops = {
203     .get_fd =     stdio_get_fd,
204     .get_buffer = stdio_get_buffer,
205     .close =      stdio_pclose
206 };
207
208 static const QEMUFileOps stdio_pipe_write_ops = {
209     .get_fd =     stdio_get_fd,
210     .put_buffer = stdio_put_buffer,
211     .close =      stdio_pclose
212 };
213
214 QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
215 {
216     FILE *stdio_file;
217     QEMUFileStdio *s;
218
219     if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != 0) {
220         fprintf(stderr, "qemu_popen: Argument validity check failed\n");
221         return NULL;
222     }
223
224     stdio_file = popen(command, mode);
225     if (stdio_file == NULL) {
226         return NULL;
227     }
228
229     s = g_malloc0(sizeof(QEMUFileStdio));
230
231     s->stdio_file = stdio_file;
232
233     if (mode[0] == 'r') {
234         s->file = qemu_fopen_ops(s, &stdio_pipe_read_ops);
235     } else {
236         s->file = qemu_fopen_ops(s, &stdio_pipe_write_ops);
237     }
238     return s->file;
239 }
240
241 static const QEMUFileOps stdio_file_read_ops = {
242     .get_fd =     stdio_get_fd,
243     .get_buffer = stdio_get_buffer,
244     .close =      stdio_fclose
245 };
246
247 static const QEMUFileOps stdio_file_write_ops = {
248     .get_fd =     stdio_get_fd,
249     .put_buffer = stdio_put_buffer,
250     .close =      stdio_fclose
251 };
252
253 static ssize_t unix_writev_buffer(void *opaque, struct iovec *iov, int iovcnt,
254                                   int64_t pos)
255 {
256     QEMUFileSocket *s = opaque;
257     ssize_t len, offset;
258     ssize_t size = iov_size(iov, iovcnt);
259     ssize_t total = 0;
260
261     assert(iovcnt > 0);
262     offset = 0;
263     while (size > 0) {
264         /* Find the next start position; skip all full-sized vector elements  */
265         while (offset >= iov[0].iov_len) {
266             offset -= iov[0].iov_len;
267             iov++, iovcnt--;
268         }
269
270         /* skip `offset' bytes from the (now) first element, undo it on exit */
271         assert(iovcnt > 0);
272         iov[0].iov_base += offset;
273         iov[0].iov_len -= offset;
274
275         do {
276             len = writev(s->fd, iov, iovcnt);
277         } while (len == -1 && errno == EINTR);
278         if (len == -1) {
279             return -errno;
280         }
281
282         /* Undo the changes above */
283         iov[0].iov_base -= offset;
284         iov[0].iov_len += offset;
285
286         /* Prepare for the next iteration */
287         offset += len;
288         total += len;
289         size -= len;
290     }
291
292     return total;
293 }
294
295 static int unix_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
296 {
297     QEMUFileSocket *s = opaque;
298     ssize_t len;
299
300     for (;;) {
301         len = read(s->fd, buf, size);
302         if (len != -1) {
303             break;
304         }
305         if (errno == EAGAIN) {
306             yield_until_fd_readable(s->fd);
307         } else if (errno != EINTR) {
308             break;
309         }
310     }
311
312     if (len == -1) {
313         len = -errno;
314     }
315     return len;
316 }
317
318 static int unix_close(void *opaque)
319 {
320     QEMUFileSocket *s = opaque;
321     close(s->fd);
322     g_free(s);
323     return 0;
324 }
325
326 static const QEMUFileOps unix_read_ops = {
327     .get_fd =     socket_get_fd,
328     .get_buffer = unix_get_buffer,
329     .close =      unix_close
330 };
331
332 static const QEMUFileOps unix_write_ops = {
333     .get_fd =     socket_get_fd,
334     .writev_buffer = unix_writev_buffer,
335     .close =      unix_close
336 };
337
338 QEMUFile *qemu_fdopen(int fd, const char *mode)
339 {
340     QEMUFileSocket *s;
341
342     if (mode == NULL ||
343         (mode[0] != 'r' && mode[0] != 'w') ||
344         mode[1] != 'b' || mode[2] != 0) {
345         fprintf(stderr, "qemu_fdopen: Argument validity check failed\n");
346         return NULL;
347     }
348
349     s = g_malloc0(sizeof(QEMUFileSocket));
350     s->fd = fd;
351
352     if (mode[0] == 'r') {
353         s->file = qemu_fopen_ops(s, &unix_read_ops);
354     } else {
355         s->file = qemu_fopen_ops(s, &unix_write_ops);
356     }
357     return s->file;
358 }
359
360 static const QEMUFileOps socket_read_ops = {
361     .get_fd =     socket_get_fd,
362     .get_buffer = socket_get_buffer,
363     .close =      socket_close
364 };
365
366 static const QEMUFileOps socket_write_ops = {
367     .get_fd =     socket_get_fd,
368     .writev_buffer = socket_writev_buffer,
369     .close =      socket_close
370 };
371
372 bool qemu_file_mode_is_not_valid(const char *mode)
373 {
374     if (mode == NULL ||
375         (mode[0] != 'r' && mode[0] != 'w') ||
376         mode[1] != 'b' || mode[2] != 0) {
377         fprintf(stderr, "qemu_fopen: Argument validity check failed\n");
378         return true;
379     }
380
381     return false;
382 }
383
384 QEMUFile *qemu_fopen_socket(int fd, const char *mode)
385 {
386     QEMUFileSocket *s;
387
388     if (qemu_file_mode_is_not_valid(mode)) {
389         return NULL;
390     }
391
392     s = g_malloc0(sizeof(QEMUFileSocket));
393     s->fd = fd;
394     if (mode[0] == 'w') {
395         qemu_set_block(s->fd);
396         s->file = qemu_fopen_ops(s, &socket_write_ops);
397     } else {
398         s->file = qemu_fopen_ops(s, &socket_read_ops);
399     }
400     return s->file;
401 }
402
403 QEMUFile *qemu_fopen(const char *filename, const char *mode)
404 {
405     QEMUFileStdio *s;
406
407     if (qemu_file_mode_is_not_valid(mode)) {
408         return NULL;
409     }
410
411     s = g_malloc0(sizeof(QEMUFileStdio));
412
413     s->stdio_file = fopen(filename, mode);
414     if (!s->stdio_file) {
415         goto fail;
416     }
417
418     if (mode[0] == 'w') {
419         s->file = qemu_fopen_ops(s, &stdio_file_write_ops);
420     } else {
421         s->file = qemu_fopen_ops(s, &stdio_file_read_ops);
422     }
423     return s->file;
424 fail:
425     g_free(s);
426     return NULL;
427 }
428
429 QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)
430 {
431     QEMUFile *f;
432
433     f = g_malloc0(sizeof(QEMUFile));
434
435     f->opaque = opaque;
436     f->ops = ops;
437     return f;
438 }
439
440 /*
441  * Get last error for stream f
442  *
443  * Return negative error value if there has been an error on previous
444  * operations, return 0 if no error happened.
445  *
446  */
447 int qemu_file_get_error(QEMUFile *f)
448 {
449     return f->last_error;
450 }
451
452 void qemu_file_set_error(QEMUFile *f, int ret)
453 {
454     if (f->last_error == 0) {
455         f->last_error = ret;
456     }
457 }
458
459 bool qemu_file_is_writable(QEMUFile *f)
460 {
461     return f->ops->writev_buffer || f->ops->put_buffer;
462 }
463
464 /**
465  * Flushes QEMUFile buffer
466  *
467  * If there is writev_buffer QEMUFileOps it uses it otherwise uses
468  * put_buffer ops.
469  */
470 void qemu_fflush(QEMUFile *f)
471 {
472     ssize_t ret = 0;
473
474     if (!qemu_file_is_writable(f)) {
475         return;
476     }
477
478     if (f->ops->writev_buffer) {
479         if (f->iovcnt > 0) {
480             ret = f->ops->writev_buffer(f->opaque, f->iov, f->iovcnt, f->pos);
481         }
482     } else {
483         if (f->buf_index > 0) {
484             ret = f->ops->put_buffer(f->opaque, f->buf, f->pos, f->buf_index);
485         }
486     }
487     if (ret >= 0) {
488         f->pos += ret;
489     }
490     f->buf_index = 0;
491     f->iovcnt = 0;
492     if (ret < 0) {
493         qemu_file_set_error(f, ret);
494     }
495 }
496
497 void ram_control_before_iterate(QEMUFile *f, uint64_t flags)
498 {
499     int ret = 0;
500
501     if (f->ops->before_ram_iterate) {
502         ret = f->ops->before_ram_iterate(f, f->opaque, flags);
503         if (ret < 0) {
504             qemu_file_set_error(f, ret);
505         }
506     }
507 }
508
509 void ram_control_after_iterate(QEMUFile *f, uint64_t flags)
510 {
511     int ret = 0;
512
513     if (f->ops->after_ram_iterate) {
514         ret = f->ops->after_ram_iterate(f, f->opaque, flags);
515         if (ret < 0) {
516             qemu_file_set_error(f, ret);
517         }
518     }
519 }
520
521 void ram_control_load_hook(QEMUFile *f, uint64_t flags)
522 {
523     int ret = -EINVAL;
524
525     if (f->ops->hook_ram_load) {
526         ret = f->ops->hook_ram_load(f, f->opaque, flags);
527         if (ret < 0) {
528             qemu_file_set_error(f, ret);
529         }
530     } else {
531         qemu_file_set_error(f, ret);
532     }
533 }
534
535 size_t ram_control_save_page(QEMUFile *f, ram_addr_t block_offset,
536                          ram_addr_t offset, size_t size, int *bytes_sent)
537 {
538     if (f->ops->save_page) {
539         int ret = f->ops->save_page(f, f->opaque, block_offset,
540                                     offset, size, bytes_sent);
541
542         if (ret != RAM_SAVE_CONTROL_DELAYED) {
543             if (bytes_sent && *bytes_sent > 0) {
544                 qemu_update_position(f, *bytes_sent);
545             } else if (ret < 0) {
546                 qemu_file_set_error(f, ret);
547             }
548         }
549
550         return ret;
551     }
552
553     return RAM_SAVE_CONTROL_NOT_SUPP;
554 }
555
556 /*
557  * Attempt to fill the buffer from the underlying file
558  * Returns the number of bytes read, or negative value for an error.
559  *
560  * Note that it can return a partially full buffer even in a not error/not EOF
561  * case if the underlying file descriptor gives a short read, and that can
562  * happen even on a blocking fd.
563  */
564 static ssize_t qemu_fill_buffer(QEMUFile *f)
565 {
566     int len;
567     int pending;
568
569     assert(!qemu_file_is_writable(f));
570
571     pending = f->buf_size - f->buf_index;
572     if (pending > 0) {
573         memmove(f->buf, f->buf + f->buf_index, pending);
574     }
575     f->buf_index = 0;
576     f->buf_size = pending;
577
578     len = f->ops->get_buffer(f->opaque, f->buf + pending, f->pos,
579                         IO_BUF_SIZE - pending);
580     if (len > 0) {
581         f->buf_size += len;
582         f->pos += len;
583     } else if (len == 0) {
584         qemu_file_set_error(f, -EIO);
585     } else if (len != -EAGAIN) {
586         qemu_file_set_error(f, len);
587     }
588
589     return len;
590 }
591
592 int qemu_get_fd(QEMUFile *f)
593 {
594     if (f->ops->get_fd) {
595         return f->ops->get_fd(f->opaque);
596     }
597     return -1;
598 }
599
600 void qemu_update_position(QEMUFile *f, size_t size)
601 {
602     f->pos += size;
603 }
604
605 /** Closes the file
606  *
607  * Returns negative error value if any error happened on previous operations or
608  * while closing the file. Returns 0 or positive number on success.
609  *
610  * The meaning of return value on success depends on the specific backend
611  * being used.
612  */
613 int qemu_fclose(QEMUFile *f)
614 {
615     int ret;
616     qemu_fflush(f);
617     ret = qemu_file_get_error(f);
618
619     if (f->ops->close) {
620         int ret2 = f->ops->close(f->opaque);
621         if (ret >= 0) {
622             ret = ret2;
623         }
624     }
625     /* If any error was spotted before closing, we should report it
626      * instead of the close() return value.
627      */
628     if (f->last_error) {
629         ret = f->last_error;
630     }
631     g_free(f);
632     trace_qemu_file_fclose();
633     return ret;
634 }
635
636 static void add_to_iovec(QEMUFile *f, const uint8_t *buf, int size)
637 {
638     /* check for adjacent buffer and coalesce them */
639     if (f->iovcnt > 0 && buf == f->iov[f->iovcnt - 1].iov_base +
640         f->iov[f->iovcnt - 1].iov_len) {
641         f->iov[f->iovcnt - 1].iov_len += size;
642     } else {
643         f->iov[f->iovcnt].iov_base = (uint8_t *)buf;
644         f->iov[f->iovcnt++].iov_len = size;
645     }
646
647     if (f->iovcnt >= MAX_IOV_SIZE) {
648         qemu_fflush(f);
649     }
650 }
651
652 void qemu_put_buffer_async(QEMUFile *f, const uint8_t *buf, int size)
653 {
654     if (!f->ops->writev_buffer) {
655         qemu_put_buffer(f, buf, size);
656         return;
657     }
658
659     if (f->last_error) {
660         return;
661     }
662
663     f->bytes_xfer += size;
664     add_to_iovec(f, buf, size);
665 }
666
667 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size)
668 {
669     int l;
670
671     if (f->last_error) {
672         return;
673     }
674
675     while (size > 0) {
676         l = IO_BUF_SIZE - f->buf_index;
677         if (l > size) {
678             l = size;
679         }
680         memcpy(f->buf + f->buf_index, buf, l);
681         f->bytes_xfer += l;
682         if (f->ops->writev_buffer) {
683             add_to_iovec(f, f->buf + f->buf_index, l);
684         }
685         f->buf_index += l;
686         if (f->buf_index == IO_BUF_SIZE) {
687             qemu_fflush(f);
688         }
689         if (qemu_file_get_error(f)) {
690             break;
691         }
692         buf += l;
693         size -= l;
694     }
695 }
696
697 void qemu_put_byte(QEMUFile *f, int v)
698 {
699     if (f->last_error) {
700         return;
701     }
702
703     f->buf[f->buf_index] = v;
704     f->bytes_xfer++;
705     if (f->ops->writev_buffer) {
706         add_to_iovec(f, f->buf + f->buf_index, 1);
707     }
708     f->buf_index++;
709     if (f->buf_index == IO_BUF_SIZE) {
710         qemu_fflush(f);
711     }
712 }
713
714 void qemu_file_skip(QEMUFile *f, int size)
715 {
716     if (f->buf_index + size <= f->buf_size) {
717         f->buf_index += size;
718     }
719 }
720
721 /*
722  * Read 'size' bytes from file (at 'offset') into buf without moving the
723  * pointer.
724  *
725  * It will return size bytes unless there was an error, in which case it will
726  * return as many as it managed to read (assuming blocking fd's which
727  * all current QEMUFile are)
728  */
729 int qemu_peek_buffer(QEMUFile *f, uint8_t *buf, int size, size_t offset)
730 {
731     int pending;
732     int index;
733
734     assert(!qemu_file_is_writable(f));
735     assert(offset < IO_BUF_SIZE);
736     assert(size <= IO_BUF_SIZE - offset);
737
738     /* The 1st byte to read from */
739     index = f->buf_index + offset;
740     /* The number of available bytes starting at index */
741     pending = f->buf_size - index;
742
743     /*
744      * qemu_fill_buffer might return just a few bytes, even when there isn't
745      * an error, so loop collecting them until we get enough.
746      */
747     while (pending < size) {
748         int received = qemu_fill_buffer(f);
749
750         if (received <= 0) {
751             break;
752         }
753
754         index = f->buf_index + offset;
755         pending = f->buf_size - index;
756     }
757
758     if (pending <= 0) {
759         return 0;
760     }
761     if (size > pending) {
762         size = pending;
763     }
764
765     memcpy(buf, f->buf + index, size);
766     return size;
767 }
768
769 /*
770  * Read 'size' bytes of data from the file into buf.
771  * 'size' can be larger than the internal buffer.
772  *
773  * It will return size bytes unless there was an error, in which case it will
774  * return as many as it managed to read (assuming blocking fd's which
775  * all current QEMUFile are)
776  */
777 int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size)
778 {
779     int pending = size;
780     int done = 0;
781
782     while (pending > 0) {
783         int res;
784
785         res = qemu_peek_buffer(f, buf, MIN(pending, IO_BUF_SIZE), 0);
786         if (res == 0) {
787             return done;
788         }
789         qemu_file_skip(f, res);
790         buf += res;
791         pending -= res;
792         done += res;
793     }
794     return done;
795 }
796
797 /*
798  * Peeks a single byte from the buffer; this isn't guaranteed to work if
799  * offset leaves a gap after the previous read/peeked data.
800  */
801 int qemu_peek_byte(QEMUFile *f, int offset)
802 {
803     int index = f->buf_index + offset;
804
805     assert(!qemu_file_is_writable(f));
806     assert(offset < IO_BUF_SIZE);
807
808     if (index >= f->buf_size) {
809         qemu_fill_buffer(f);
810         index = f->buf_index + offset;
811         if (index >= f->buf_size) {
812             return 0;
813         }
814     }
815     return f->buf[index];
816 }
817
818 int qemu_get_byte(QEMUFile *f)
819 {
820     int result;
821
822     result = qemu_peek_byte(f, 0);
823     qemu_file_skip(f, 1);
824     return result;
825 }
826
827 int64_t qemu_ftell(QEMUFile *f)
828 {
829     qemu_fflush(f);
830     return f->pos;
831 }
832
833 int qemu_file_rate_limit(QEMUFile *f)
834 {
835     if (qemu_file_get_error(f)) {
836         return 1;
837     }
838     if (f->xfer_limit > 0 && f->bytes_xfer > f->xfer_limit) {
839         return 1;
840     }
841     return 0;
842 }
843
844 int64_t qemu_file_get_rate_limit(QEMUFile *f)
845 {
846     return f->xfer_limit;
847 }
848
849 void qemu_file_set_rate_limit(QEMUFile *f, int64_t limit)
850 {
851     f->xfer_limit = limit;
852 }
853
854 void qemu_file_reset_rate_limit(QEMUFile *f)
855 {
856     f->bytes_xfer = 0;
857 }
858
859 void qemu_put_be16(QEMUFile *f, unsigned int v)
860 {
861     qemu_put_byte(f, v >> 8);
862     qemu_put_byte(f, v);
863 }
864
865 void qemu_put_be32(QEMUFile *f, unsigned int v)
866 {
867     qemu_put_byte(f, v >> 24);
868     qemu_put_byte(f, v >> 16);
869     qemu_put_byte(f, v >> 8);
870     qemu_put_byte(f, v);
871 }
872
873 void qemu_put_be64(QEMUFile *f, uint64_t v)
874 {
875     qemu_put_be32(f, v >> 32);
876     qemu_put_be32(f, v);
877 }
878
879 unsigned int qemu_get_be16(QEMUFile *f)
880 {
881     unsigned int v;
882     v = qemu_get_byte(f) << 8;
883     v |= qemu_get_byte(f);
884     return v;
885 }
886
887 unsigned int qemu_get_be32(QEMUFile *f)
888 {
889     unsigned int v;
890     v = qemu_get_byte(f) << 24;
891     v |= qemu_get_byte(f) << 16;
892     v |= qemu_get_byte(f) << 8;
893     v |= qemu_get_byte(f);
894     return v;
895 }
896
897 uint64_t qemu_get_be64(QEMUFile *f)
898 {
899     uint64_t v;
900     v = (uint64_t)qemu_get_be32(f) << 32;
901     v |= qemu_get_be32(f);
902     return v;
903 }
904
905 #define QSB_CHUNK_SIZE      (1 << 10)
906 #define QSB_MAX_CHUNK_SIZE  (16 * QSB_CHUNK_SIZE)
907
908 /**
909  * Create a QEMUSizedBuffer
910  * This type of buffer uses scatter-gather lists internally and
911  * can grow to any size. Any data array in the scatter-gather list
912  * can hold different amount of bytes.
913  *
914  * @buffer: Optional buffer to copy into the QSB
915  * @len: size of initial buffer; if @buffer is given, buffer must
916  *       hold at least len bytes
917  *
918  * Returns a pointer to a QEMUSizedBuffer or NULL on allocation failure
919  */
920 QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len)
921 {
922     QEMUSizedBuffer *qsb;
923     size_t alloc_len, num_chunks, i, to_copy;
924     size_t chunk_size = (len > QSB_MAX_CHUNK_SIZE)
925                         ? QSB_MAX_CHUNK_SIZE
926                         : QSB_CHUNK_SIZE;
927
928     num_chunks = DIV_ROUND_UP(len ? len : QSB_CHUNK_SIZE, chunk_size);
929     alloc_len = num_chunks * chunk_size;
930
931     qsb = g_try_new0(QEMUSizedBuffer, 1);
932     if (!qsb) {
933         return NULL;
934     }
935
936     qsb->iov = g_try_new0(struct iovec, num_chunks);
937     if (!qsb->iov) {
938         g_free(qsb);
939         return NULL;
940     }
941
942     qsb->n_iov = num_chunks;
943
944     for (i = 0; i < num_chunks; i++) {
945         qsb->iov[i].iov_base = g_try_malloc0(chunk_size);
946         if (!qsb->iov[i].iov_base) {
947             /* qsb_free is safe since g_free can cope with NULL */
948             qsb_free(qsb);
949             return NULL;
950         }
951
952         qsb->iov[i].iov_len = chunk_size;
953         if (buffer) {
954             to_copy = (len - qsb->used) > chunk_size
955                       ? chunk_size : (len - qsb->used);
956             memcpy(qsb->iov[i].iov_base, &buffer[qsb->used], to_copy);
957             qsb->used += to_copy;
958         }
959     }
960
961     qsb->size = alloc_len;
962
963     return qsb;
964 }
965
966 /**
967  * Free the QEMUSizedBuffer
968  *
969  * @qsb: The QEMUSizedBuffer to free
970  */
971 void qsb_free(QEMUSizedBuffer *qsb)
972 {
973     size_t i;
974
975     if (!qsb) {
976         return;
977     }
978
979     for (i = 0; i < qsb->n_iov; i++) {
980         g_free(qsb->iov[i].iov_base);
981     }
982     g_free(qsb->iov);
983     g_free(qsb);
984 }
985
986 /**
987  * Get the number of used bytes in the QEMUSizedBuffer
988  *
989  * @qsb: A QEMUSizedBuffer
990  *
991  * Returns the number of bytes currently used in this buffer
992  */
993 size_t qsb_get_length(const QEMUSizedBuffer *qsb)
994 {
995     return qsb->used;
996 }
997
998 /**
999  * Set the length of the buffer; the primary usage of this
1000  * function is to truncate the number of used bytes in the buffer.
1001  * The size will not be extended beyond the current number of
1002  * allocated bytes in the QEMUSizedBuffer.
1003  *
1004  * @qsb: A QEMUSizedBuffer
1005  * @new_len: The new length of bytes in the buffer
1006  *
1007  * Returns the number of bytes the buffer was truncated or extended
1008  * to.
1009  */
1010 size_t qsb_set_length(QEMUSizedBuffer *qsb, size_t new_len)
1011 {
1012     if (new_len <= qsb->size) {
1013         qsb->used = new_len;
1014     } else {
1015         qsb->used = qsb->size;
1016     }
1017     return qsb->used;
1018 }
1019
1020 /**
1021  * Get the iovec that holds the data for a given position @pos.
1022  *
1023  * @qsb: A QEMUSizedBuffer
1024  * @pos: The index of a byte in the buffer
1025  * @d_off: Pointer to an offset that this function will indicate
1026  *         at what position within the returned iovec the byte
1027  *         is to be found
1028  *
1029  * Returns the index of the iovec that holds the byte at the given
1030  * index @pos in the byte stream; a negative number if the iovec
1031  * for the given position @pos does not exist.
1032  */
1033 static ssize_t qsb_get_iovec(const QEMUSizedBuffer *qsb,
1034                              off_t pos, off_t *d_off)
1035 {
1036     ssize_t i;
1037     off_t curr = 0;
1038
1039     if (pos > qsb->used) {
1040         return -1;
1041     }
1042
1043     for (i = 0; i < qsb->n_iov; i++) {
1044         if (curr + qsb->iov[i].iov_len > pos) {
1045             *d_off = pos - curr;
1046             return i;
1047         }
1048         curr += qsb->iov[i].iov_len;
1049     }
1050     return -1;
1051 }
1052
1053 /*
1054  * Convert the QEMUSizedBuffer into a flat buffer.
1055  *
1056  * Note: If at all possible, try to avoid this function since it
1057  *       may unnecessarily copy memory around.
1058  *
1059  * @qsb: pointer to QEMUSizedBuffer
1060  * @start: offset to start at
1061  * @count: number of bytes to copy
1062  * @buf: a pointer to a buffer to write into (at least @count bytes)
1063  *
1064  * Returns the number of bytes copied into the output buffer
1065  */
1066 ssize_t qsb_get_buffer(const QEMUSizedBuffer *qsb, off_t start,
1067                        size_t count, uint8_t *buffer)
1068 {
1069     const struct iovec *iov;
1070     size_t to_copy, all_copy;
1071     ssize_t index;
1072     off_t s_off;
1073     off_t d_off = 0;
1074     char *s;
1075
1076     if (start > qsb->used) {
1077         return 0;
1078     }
1079
1080     all_copy = qsb->used - start;
1081     if (all_copy > count) {
1082         all_copy = count;
1083     } else {
1084         count = all_copy;
1085     }
1086
1087     index = qsb_get_iovec(qsb, start, &s_off);
1088     if (index < 0) {
1089         return 0;
1090     }
1091
1092     while (all_copy > 0) {
1093         iov = &qsb->iov[index];
1094
1095         s = iov->iov_base;
1096
1097         to_copy = iov->iov_len - s_off;
1098         if (to_copy > all_copy) {
1099             to_copy = all_copy;
1100         }
1101         memcpy(&buffer[d_off], &s[s_off], to_copy);
1102
1103         d_off += to_copy;
1104         all_copy -= to_copy;
1105
1106         s_off = 0;
1107         index++;
1108     }
1109
1110     return count;
1111 }
1112
1113 /**
1114  * Grow the QEMUSizedBuffer to the given size and allocate
1115  * memory for it.
1116  *
1117  * @qsb: A QEMUSizedBuffer
1118  * @new_size: The new size of the buffer
1119  *
1120  * Return:
1121  *    a negative error code in case of memory allocation failure
1122  * or
1123  *    the new size of the buffer. The returned size may be greater or equal
1124  *    to @new_size.
1125  */
1126 static ssize_t qsb_grow(QEMUSizedBuffer *qsb, size_t new_size)
1127 {
1128     size_t needed_chunks, i;
1129
1130     if (qsb->size < new_size) {
1131         struct iovec *new_iov;
1132         size_t size_diff = new_size - qsb->size;
1133         size_t chunk_size = (size_diff > QSB_MAX_CHUNK_SIZE)
1134                              ? QSB_MAX_CHUNK_SIZE : QSB_CHUNK_SIZE;
1135
1136         needed_chunks = DIV_ROUND_UP(size_diff, chunk_size);
1137
1138         new_iov = g_try_new(struct iovec, qsb->n_iov + needed_chunks);
1139         if (new_iov == NULL) {
1140             return -ENOMEM;
1141         }
1142
1143         /* Allocate new chunks as needed into new_iov */
1144         for (i = qsb->n_iov; i < qsb->n_iov + needed_chunks; i++) {
1145             new_iov[i].iov_base = g_try_malloc0(chunk_size);
1146             new_iov[i].iov_len = chunk_size;
1147             if (!new_iov[i].iov_base) {
1148                 size_t j;
1149
1150                 /* Free previously allocated new chunks */
1151                 for (j = qsb->n_iov; j < i; j++) {
1152                     g_free(new_iov[j].iov_base);
1153                 }
1154                 g_free(new_iov);
1155
1156                 return -ENOMEM;
1157             }
1158         }
1159
1160         /*
1161          * Now we can't get any allocation errors, copy over to new iov
1162          * and switch.
1163          */
1164         for (i = 0; i < qsb->n_iov; i++) {
1165             new_iov[i] = qsb->iov[i];
1166         }
1167
1168         qsb->n_iov += needed_chunks;
1169         g_free(qsb->iov);
1170         qsb->iov = new_iov;
1171         qsb->size += (needed_chunks * chunk_size);
1172     }
1173
1174     return qsb->size;
1175 }
1176
1177 /**
1178  * Write into the QEMUSizedBuffer at a given position and a given
1179  * number of bytes. This function will automatically grow the
1180  * QEMUSizedBuffer.
1181  *
1182  * @qsb: A QEMUSizedBuffer
1183  * @source: A byte array to copy data from
1184  * @pos: The position within the @qsb to write data to
1185  * @size: The number of bytes to copy into the @qsb
1186  *
1187  * Returns @size or a negative error code in case of memory allocation failure,
1188  *           or with an invalid 'pos'
1189  */
1190 ssize_t qsb_write_at(QEMUSizedBuffer *qsb, const uint8_t *source,
1191                      off_t pos, size_t count)
1192 {
1193     ssize_t rc = qsb_grow(qsb, pos + count);
1194     size_t to_copy;
1195     size_t all_copy = count;
1196     const struct iovec *iov;
1197     ssize_t index;
1198     char *dest;
1199     off_t d_off, s_off = 0;
1200
1201     if (rc < 0) {
1202         return rc;
1203     }
1204
1205     if (pos + count > qsb->used) {
1206         qsb->used = pos + count;
1207     }
1208
1209     index = qsb_get_iovec(qsb, pos, &d_off);
1210     if (index < 0) {
1211         return -EINVAL;
1212     }
1213
1214     while (all_copy > 0) {
1215         iov = &qsb->iov[index];
1216
1217         dest = iov->iov_base;
1218
1219         to_copy = iov->iov_len - d_off;
1220         if (to_copy > all_copy) {
1221             to_copy = all_copy;
1222         }
1223
1224         memcpy(&dest[d_off], &source[s_off], to_copy);
1225
1226         s_off += to_copy;
1227         all_copy -= to_copy;
1228
1229         d_off = 0;
1230         index++;
1231     }
1232
1233     return count;
1234 }
1235
1236 /**
1237  * Create a deep copy of the given QEMUSizedBuffer.
1238  *
1239  * @qsb: A QEMUSizedBuffer
1240  *
1241  * Returns a clone of @qsb or NULL on allocation failure
1242  */
1243 QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *qsb)
1244 {
1245     QEMUSizedBuffer *out = qsb_create(NULL, qsb_get_length(qsb));
1246     size_t i;
1247     ssize_t res;
1248     off_t pos = 0;
1249
1250     if (!out) {
1251         return NULL;
1252     }
1253
1254     for (i = 0; i < qsb->n_iov; i++) {
1255         res =  qsb_write_at(out, qsb->iov[i].iov_base,
1256                             pos, qsb->iov[i].iov_len);
1257         if (res < 0) {
1258             qsb_free(out);
1259             return NULL;
1260         }
1261         pos += res;
1262     }
1263
1264     return out;
1265 }
1266
1267 typedef struct QEMUBuffer {
1268     QEMUSizedBuffer *qsb;
1269     QEMUFile *file;
1270 } QEMUBuffer;
1271
1272 static int buf_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int size)
1273 {
1274     QEMUBuffer *s = opaque;
1275     ssize_t len = qsb_get_length(s->qsb) - pos;
1276
1277     if (len <= 0) {
1278         return 0;
1279     }
1280
1281     if (len > size) {
1282         len = size;
1283     }
1284     return qsb_get_buffer(s->qsb, pos, len, buf);
1285 }
1286
1287 static int buf_put_buffer(void *opaque, const uint8_t *buf,
1288                           int64_t pos, int size)
1289 {
1290     QEMUBuffer *s = opaque;
1291
1292     return qsb_write_at(s->qsb, buf, pos, size);
1293 }
1294
1295 static int buf_close(void *opaque)
1296 {
1297     QEMUBuffer *s = opaque;
1298
1299     qsb_free(s->qsb);
1300
1301     g_free(s);
1302
1303     return 0;
1304 }
1305
1306 const QEMUSizedBuffer *qemu_buf_get(QEMUFile *f)
1307 {
1308     QEMUBuffer *p;
1309
1310     qemu_fflush(f);
1311
1312     p = f->opaque;
1313
1314     return p->qsb;
1315 }
1316
1317 static const QEMUFileOps buf_read_ops = {
1318     .get_buffer = buf_get_buffer,
1319     .close =      buf_close,
1320 };
1321
1322 static const QEMUFileOps buf_write_ops = {
1323     .put_buffer = buf_put_buffer,
1324     .close =      buf_close,
1325 };
1326
1327 QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input)
1328 {
1329     QEMUBuffer *s;
1330
1331     if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') ||
1332         mode[1] != '\0') {
1333         error_report("qemu_bufopen: Argument validity check failed");
1334         return NULL;
1335     }
1336
1337     s = g_malloc0(sizeof(QEMUBuffer));
1338     if (mode[0] == 'r') {
1339         s->qsb = input;
1340     }
1341
1342     if (s->qsb == NULL) {
1343         s->qsb = qsb_create(NULL, 0);
1344     }
1345     if (!s->qsb) {
1346         g_free(s);
1347         error_report("qemu_bufopen: qsb_create failed");
1348         return NULL;
1349     }
1350
1351
1352     if (mode[0] == 'r') {
1353         s->file = qemu_fopen_ops(s, &buf_read_ops);
1354     } else {
1355         s->file = qemu_fopen_ops(s, &buf_write_ops);
1356     }
1357     return s->file;
1358 }
This page took 0.095994 seconds and 4 git commands to generate.