From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:57312) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R7MaQ-0005Nu-SA for qemu-devel@nongnu.org; Sat, 24 Sep 2011 03:23:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1R7MaO-0004lB-0l for qemu-devel@nongnu.org; Sat, 24 Sep 2011 03:23:46 -0400 Received: from mail-qy0-f173.google.com ([209.85.216.173]:61663) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1R7MaN-0004l6-RL for qemu-devel@nongnu.org; Sat, 24 Sep 2011 03:23:43 -0400 Received: by qyc1 with SMTP id 1so7257824qyc.4 for ; Sat, 24 Sep 2011 00:23:43 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <1316443309-23843-5-git-send-email-mdroth@linux.vnet.ibm.com> References: <1316443309-23843-1-git-send-email-mdroth@linux.vnet.ibm.com> <1316443309-23843-5-git-send-email-mdroth@linux.vnet.ibm.com> From: Blue Swirl Date: Sat, 24 Sep 2011 07:23:23 +0000 Message-ID: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Qemu-devel] [RFC 4/8] savevm: move QEMUFile interfaces into qemu-file.c List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Michael Roth Cc: aliguori@linux.vnet.ibm.com, qemu-devel@nongnu.org On Mon, Sep 19, 2011 at 2:41 PM, Michael Roth w= rote: > > Signed-off-by: Michael Roth > --- > =C2=A0Makefile.objs | =C2=A0 =C2=A02 +- > =C2=A0hw/hw.h =C2=A0 =C2=A0 =C2=A0 | =C2=A0 =C2=A01 + > =C2=A0qemu-file.c =C2=A0 | =C2=A0521 ++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++ > =C2=A0savevm.c =C2=A0 =C2=A0 =C2=A0| =C2=A0494 --------------------------= ---------------------------- > =C2=A04 files changed, 523 insertions(+), 495 deletions(-) > =C2=A0create mode 100644 qemu-file.c > > diff --git a/Makefile.objs b/Makefile.objs > index 6bc8555..34bf58f 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -119,7 +119,7 @@ common-obj-$(CONFIG_SD) +=3D sd.o > =C2=A0common-obj-y +=3D bt.o bt-host.o bt-vhci.o bt-l2cap.o bt-sdp.o bt-h= ci.o bt-hid.o usb-bt.o > =C2=A0common-obj-y +=3D bt-hci-csr.o > =C2=A0common-obj-y +=3D buffered_file.o migration.o migration-tcp.o > -common-obj-y +=3D qemu-char.o savevm.o #aio.o > +common-obj-y +=3D qemu-char.o savevm.o qemu-file.o #aio.o > =C2=A0common-obj-y +=3D msmouse.o ps2.o > =C2=A0common-obj-y +=3D qdev.o qdev-properties.o > =C2=A0common-obj-y +=3D block-migration.o iohandler.o > diff --git a/hw/hw.h b/hw/hw.h > index a124da9..244bfb9 100644 > --- a/hw/hw.h > +++ b/hw/hw.h > @@ -58,6 +58,7 @@ void qemu_fflush(QEMUFile *f); > =C2=A0int qemu_fclose(QEMUFile *f); > =C2=A0void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size); > =C2=A0void qemu_put_byte(QEMUFile *f, int v); > +int qemu_peek_byte(QEMUFile *f); > > =C2=A0static inline void qemu_put_ubyte(QEMUFile *f, unsigned int v) > =C2=A0{ > diff --git a/qemu-file.c b/qemu-file.c > new file mode 100644 > index 0000000..fb91b91 > --- /dev/null > +++ b/qemu-file.c > @@ -0,0 +1,521 @@ > +/* > + * QEMU System Emulator > + * > + * Copyright (c) 2003-2008 Fabrice Bellard > + * > + * Permission is hereby granted, free of charge, to any person obtaining= a copy > + * of this software and associated documentation files (the "Software"),= to deal > + * in the Software without restriction, including without limitation the= rights > + * to use, copy, modify, merge, publish, distribute, sublicense, and/or = sell > + * copies of the Software, and to permit persons to whom the Software is > + * furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be includ= ed in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRE= SS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILI= TY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHA= LL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR = OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISI= NG FROM, > + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALING= S IN > + * THE SOFTWARE. > + */ > + > +#include "qemu-common.h" > +#include "qemu_socket.h" > +#include "hw/hw.h" > + > +#define IO_BUF_SIZE 32768 > + > +struct QEMUFile { > + =C2=A0 =C2=A0QEMUFilePutBufferFunc *put_buffer; > + =C2=A0 =C2=A0QEMUFileGetBufferFunc *get_buffer; > + =C2=A0 =C2=A0QEMUFileCloseFunc *close; > + =C2=A0 =C2=A0QEMUFileRateLimit *rate_limit; > + =C2=A0 =C2=A0QEMUFileSetRateLimit *set_rate_limit; > + =C2=A0 =C2=A0QEMUFileGetRateLimit *get_rate_limit; > + =C2=A0 =C2=A0void *opaque; > + =C2=A0 =C2=A0int is_write; > + > + =C2=A0 =C2=A0int64_t buf_offset; /* start of buffer when writing, end o= f buffer > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 when reading */ > + =C2=A0 =C2=A0int buf_index; > + =C2=A0 =C2=A0int buf_size; /* 0 when writing */ > + =C2=A0 =C2=A0uint8_t buf[IO_BUF_SIZE]; > + > + =C2=A0 =C2=A0int has_error; > +}; > + > +QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer= , > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileGetBufferFunc *get_buffer, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileCloseFunc *close, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileRateLimit *rate_limit, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileSetRateLimit *set_rate_limit, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileGetRateLimit *get_rate_limit) > +{ > + =C2=A0 =C2=A0QEMUFile *f; > + > + =C2=A0 =C2=A0f =3D g_malloc0(sizeof(QEMUFile)); > + > + =C2=A0 =C2=A0f->opaque =3D opaque; > + =C2=A0 =C2=A0f->put_buffer =3D put_buffer; > + =C2=A0 =C2=A0f->get_buffer =3D get_buffer; > + =C2=A0 =C2=A0f->close =3D close; > + =C2=A0 =C2=A0f->rate_limit =3D rate_limit; > + =C2=A0 =C2=A0f->set_rate_limit =3D set_rate_limit; > + =C2=A0 =C2=A0f->get_rate_limit =3D get_rate_limit; > + =C2=A0 =C2=A0f->is_write =3D 0; > + > + =C2=A0 =C2=A0return f; > +} > + > +int qemu_file_has_error(QEMUFile *f) > +{ > + =C2=A0 =C2=A0return f->has_error; > +} > + > +void qemu_file_set_error(QEMUFile *f) > +{ > + =C2=A0 =C2=A0f->has_error =3D 1; > +} > + > +void qemu_fflush(QEMUFile *f) > +{ > + =C2=A0 =C2=A0if (!f->put_buffer) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return; > + > + =C2=A0 =C2=A0if (f->is_write && f->buf_index > 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0int len; > + > + =C2=A0 =C2=A0 =C2=A0 =C2=A0len =3D f->put_buffer(f->opaque, f->buf, f->= buf_offset, f->buf_index); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (len > 0) Please fix CODING_STYLE issues before moving, so the old style will not persist forever. > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_offset +=3D f->buf_inde= x; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0else > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f->has_error =3D 1; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index =3D 0; > + =C2=A0 =C2=A0} > +} > + > +static void qemu_fill_buffer(QEMUFile *f) > +{ > + =C2=A0 =C2=A0int len; > + > + =C2=A0 =C2=A0if (!f->get_buffer) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return; > + > + =C2=A0 =C2=A0if (f->is_write) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > + > + =C2=A0 =C2=A0len =3D f->get_buffer(f->opaque, f->buf, f->buf_offset, IO= _BUF_SIZE); > + =C2=A0 =C2=A0if (len > 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index =3D 0; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_size =3D len; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_offset +=3D len; > + =C2=A0 =C2=A0} else if (len !=3D -EAGAIN) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->has_error =3D 1; > +} > + > +int qemu_fclose(QEMUFile *f) > +{ > + =C2=A0 =C2=A0int ret =3D 0; > + =C2=A0 =C2=A0qemu_fflush(f); > + =C2=A0 =C2=A0if (f->close) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D f->close(f->opaque); > + =C2=A0 =C2=A0g_free(f); > + =C2=A0 =C2=A0return ret; > +} > + > +void qemu_file_put_notify(QEMUFile *f) > +{ > + =C2=A0 =C2=A0f->put_buffer(f->opaque, NULL, 0, 0); > +} > + > +void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) > +{ > + =C2=A0 =C2=A0int l; > + > + =C2=A0 =C2=A0if (!f->has_error && f->is_write =3D=3D 0 && f->buf_index = > 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"Attempted to wr= ite to buffer while read buffer is not empty\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0while (!f->has_error && size > 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D IO_BUF_SIZE - f->buf_index; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l > size) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D size; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0memcpy(f->buf + f->buf_index, buf, l); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->is_write =3D 1; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index +=3D l; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0buf +=3D l; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0size -=3D l; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (f->buf_index >=3D IO_BUF_SIZE) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fflush(f); > + =C2=A0 =C2=A0} > +} > + > +void qemu_put_byte(QEMUFile *f, int v) > +{ > + =C2=A0 =C2=A0if (!f->has_error && f->is_write =3D=3D 0 && f->buf_index = > 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"Attempted to wr= ite to buffer while read buffer is not empty\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0f->buf[f->buf_index++] =3D v; > + =C2=A0 =C2=A0f->is_write =3D 1; > + =C2=A0 =C2=A0if (f->buf_index >=3D IO_BUF_SIZE) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fflush(f); > +} > + > +int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1) > +{ > + =C2=A0 =C2=A0int size, l; > + > + =C2=A0 =C2=A0if (f->is_write) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > + > + =C2=A0 =C2=A0size =3D size1; > + =C2=A0 =C2=A0while (size > 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D f->buf_size - f->buf_index; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l =3D=3D 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fill_buffer(f); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D f->buf_size - f->buf_ind= ex; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l =3D=3D 0) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0} > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l > size) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D size; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0memcpy(buf, f->buf + f->buf_index, l); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index +=3D l; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0buf +=3D l; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0size -=3D l; > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0return size1 - size; > +} > + > +int qemu_get_byte(QEMUFile *f) > +{ > + =C2=A0 =C2=A0if (f->is_write) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > + > + =C2=A0 =C2=A0if (f->buf_index >=3D f->buf_size) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fill_buffer(f); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (f->buf_index >=3D f->buf_size) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0; > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0return f->buf[f->buf_index++]; > +} > + > +int64_t qemu_ftell(QEMUFile *f) > +{ > + =C2=A0 =C2=A0return f->buf_offset - f->buf_size + f->buf_index; > +} > + > +int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence) > +{ > + =C2=A0 =C2=A0if (whence =3D=3D SEEK_SET) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* nothing to do */ > + =C2=A0 =C2=A0} else if (whence =3D=3D SEEK_CUR) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0pos +=3D qemu_ftell(f); > + =C2=A0 =C2=A0} else { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0/* SEEK_END not supported */ > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1; > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0if (f->put_buffer) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fflush(f); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_offset =3D pos; > + =C2=A0 =C2=A0} else { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_offset =3D pos; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index =3D 0; > + =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_size =3D 0; > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0return pos; > +} > + > +int qemu_peek_byte(QEMUFile *f) > +{ > + =C2=A0 =C2=A0if (f->is_write) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > + > + =C2=A0 =C2=A0if (f->buf_index >=3D f->buf_size) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fill_buffer(f); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0if (f->buf_index >=3D f->buf_size) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0; > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0return f->buf[f->buf_index]; > +} > + > +int qemu_file_rate_limit(QEMUFile *f) > +{ > + =C2=A0 =C2=A0if (f->rate_limit) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return f->rate_limit(f->opaque); > + > + =C2=A0 =C2=A0return 0; > +} > + > +int64_t qemu_file_get_rate_limit(QEMUFile *f) > +{ > + =C2=A0 =C2=A0if (f->get_rate_limit) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return f->get_rate_limit(f->opaque); > + > + =C2=A0 =C2=A0return 0; > +} > + > +int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate) > +{ > + =C2=A0 =C2=A0/* any failed or completed migration keeps its state to al= low probing of > + =C2=A0 =C2=A0 * migration data, but has no associated file anymore */ > + =C2=A0 =C2=A0if (f && f->set_rate_limit) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return f->set_rate_limit(f->opaque, new_rate= ); > + > + =C2=A0 =C2=A0return 0; > +} > + > +void qemu_put_be16(QEMUFile *f, unsigned int v) > +{ > + =C2=A0 =C2=A0qemu_put_byte(f, v >> 8); > + =C2=A0 =C2=A0qemu_put_byte(f, v); > +} > + > +void qemu_put_be32(QEMUFile *f, unsigned int v) > +{ > + =C2=A0 =C2=A0qemu_put_byte(f, v >> 24); > + =C2=A0 =C2=A0qemu_put_byte(f, v >> 16); > + =C2=A0 =C2=A0qemu_put_byte(f, v >> 8); > + =C2=A0 =C2=A0qemu_put_byte(f, v); > +} > + > +void qemu_put_be64(QEMUFile *f, uint64_t v) > +{ > + =C2=A0 =C2=A0qemu_put_be32(f, v >> 32); > + =C2=A0 =C2=A0qemu_put_be32(f, v); > +} > + > +unsigned int qemu_get_be16(QEMUFile *f) > +{ > + =C2=A0 =C2=A0unsigned int v; > + =C2=A0 =C2=A0v =3D qemu_get_byte(f) << 8; > + =C2=A0 =C2=A0v |=3D qemu_get_byte(f); > + =C2=A0 =C2=A0return v; > +} > + > +unsigned int qemu_get_be32(QEMUFile *f) > +{ > + =C2=A0 =C2=A0unsigned int v; > + =C2=A0 =C2=A0v =3D qemu_get_byte(f) << 24; > + =C2=A0 =C2=A0v |=3D qemu_get_byte(f) << 16; > + =C2=A0 =C2=A0v |=3D qemu_get_byte(f) << 8; > + =C2=A0 =C2=A0v |=3D qemu_get_byte(f); > + =C2=A0 =C2=A0return v; > +} > + > +uint64_t qemu_get_be64(QEMUFile *f) > +{ > + =C2=A0 =C2=A0uint64_t v; > + =C2=A0 =C2=A0v =3D (uint64_t)qemu_get_be32(f) << 32; > + =C2=A0 =C2=A0v |=3D qemu_get_be32(f); > + =C2=A0 =C2=A0return v; > +} > + > +typedef struct QEMUFileStdio > +{ > + =C2=A0 =C2=A0FILE *stdio_file; > + =C2=A0 =C2=A0QEMUFile *file; > +} QEMUFileStdio; > + > +typedef struct QEMUFileSocket > +{ > + =C2=A0 =C2=A0int fd; > + =C2=A0 =C2=A0QEMUFile *file; > +} QEMUFileSocket; > + > +static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, in= t size) > +{ > + =C2=A0 =C2=A0QEMUFileSocket *s =3D opaque; > + =C2=A0 =C2=A0ssize_t len; > + > + =C2=A0 =C2=A0do { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0len =3D qemu_recv(s->fd, buf, size, 0); > + =C2=A0 =C2=A0} while (len =3D=3D -1 && socket_error() =3D=3D EINTR); > + > + =C2=A0 =C2=A0if (len =3D=3D -1) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0len =3D -socket_error(); > + > + =C2=A0 =C2=A0return len; > +} > + > +static int socket_close(void *opaque) > +{ > + =C2=A0 =C2=A0QEMUFileSocket *s =3D opaque; > + =C2=A0 =C2=A0g_free(s); > + =C2=A0 =C2=A0return 0; > +} > + > +int qemu_stdio_fd(QEMUFile *f) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *p; > + =C2=A0 =C2=A0int fd; > + > + =C2=A0 =C2=A0p =3D (QEMUFileStdio *)f->opaque; > + =C2=A0 =C2=A0fd =3D fileno(p->stdio_file); > + > + =C2=A0 =C2=A0return fd; > +} > + > +static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t po= s, int size) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > + =C2=A0 =C2=A0return fwrite(buf, 1, size, s->stdio_file); > +} > + > +static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int= size) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > + =C2=A0 =C2=A0FILE *fp =3D s->stdio_file; > + =C2=A0 =C2=A0int bytes; > + > + =C2=A0 =C2=A0do { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0clearerr(fp); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0bytes =3D fread(buf, 1, size, fp); > + =C2=A0 =C2=A0} while ((bytes =3D=3D 0) && ferror(fp) && (errno =3D=3D E= INTR)); > + =C2=A0 =C2=A0return bytes; > +} > + > +static int stdio_pclose(void *opaque) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > + =C2=A0 =C2=A0int ret; > + =C2=A0 =C2=A0ret =3D pclose(s->stdio_file); > + =C2=A0 =C2=A0g_free(s); > + =C2=A0 =C2=A0return ret; > +} > + > +static int stdio_fclose(void *opaque) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > + =C2=A0 =C2=A0fclose(s->stdio_file); > + =C2=A0 =C2=A0g_free(s); > + =C2=A0 =C2=A0return 0; > +} > + > +QEMUFile *qemu_popen(FILE *stdio_file, const char *mode) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *s; > + > + =C2=A0 =C2=A0if (stdio_file =3D=3D NULL || mode =3D=3D NULL || (mode[0]= !=3D 'r' && mode[0] !=3D 'w') || mode[1] !=3D 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu_popen: Argument validi= ty check failed\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return NULL; > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0s =3D g_malloc0(sizeof(QEMUFileStdio)); > + > + =C2=A0 =C2=A0s->stdio_file =3D stdio_file; > + > + =C2=A0 =C2=A0if(mode[0] =3D=3D 'r') { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, NULL, stdio_ge= t_buffer, stdio_pclose, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > + =C2=A0 =C2=A0} else { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, stdio_put_buff= er, NULL, stdio_pclose, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0return s->file; > +} > + > +QEMUFile *qemu_popen_cmd(const char *command, const char *mode) > +{ > + =C2=A0 =C2=A0FILE *popen_file; > + > + =C2=A0 =C2=A0popen_file =3D popen(command, mode); > + =C2=A0 =C2=A0if(popen_file =3D=3D NULL) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return NULL; > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0return qemu_popen(popen_file, mode); > +} > + > +QEMUFile *qemu_fdopen(int fd, const char *mode) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *s; > + > + =C2=A0 =C2=A0if (mode =3D=3D NULL || > + =C2=A0 =C2=A0 =C2=A0 (mode[0] !=3D 'r' && mode[0] !=3D 'w') || > + =C2=A0 =C2=A0 =C2=A0 mode[1] !=3D 'b' || mode[2] !=3D 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu_fdopen: Argument valid= ity check failed\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return NULL; > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0s =3D g_malloc0(sizeof(QEMUFileStdio)); > + =C2=A0 =C2=A0s->stdio_file =3D fdopen(fd, mode); > + =C2=A0 =C2=A0if (!s->stdio_file) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0goto fail; > + > + =C2=A0 =C2=A0if(mode[0] =3D=3D 'r') { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, NULL, stdio_ge= t_buffer, stdio_fclose, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > + =C2=A0 =C2=A0} else { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, stdio_put_buff= er, NULL, stdio_fclose, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0return s->file; > + > +fail: > + =C2=A0 =C2=A0g_free(s); > + =C2=A0 =C2=A0return NULL; > +} > + > +QEMUFile *qemu_fopen_socket(int fd) > +{ > + =C2=A0 =C2=A0QEMUFileSocket *s =3D g_malloc0(sizeof(QEMUFileSocket)); > + > + =C2=A0 =C2=A0s->fd =3D fd; > + =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, NULL, socket_get_buffer, soc= ket_close, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > + =C2=A0 =C2=A0return s->file; > +} > + > +static int file_put_buffer(void *opaque, const uint8_t *buf, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0int64_t pos, int size) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > + =C2=A0 =C2=A0fseek(s->stdio_file, pos, SEEK_SET); > + =C2=A0 =C2=A0return fwrite(buf, 1, size, s->stdio_file); > +} > + > +static int file_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int = size) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > + =C2=A0 =C2=A0fseek(s->stdio_file, pos, SEEK_SET); > + =C2=A0 =C2=A0return fread(buf, 1, size, s->stdio_file); > +} > + > +QEMUFile *qemu_fopen(const char *filename, const char *mode) > +{ > + =C2=A0 =C2=A0QEMUFileStdio *s; > + > + =C2=A0 =C2=A0if (mode =3D=3D NULL || > + =C2=A0 =C2=A0 =C2=A0 (mode[0] !=3D 'r' && mode[0] !=3D 'w') || > + =C2=A0 =C2=A0 =C2=A0 mode[1] !=3D 'b' || mode[2] !=3D 0) { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu_fopen: Argument validi= ty check failed\n"); > + =C2=A0 =C2=A0 =C2=A0 =C2=A0return NULL; > + =C2=A0 =C2=A0} > + > + =C2=A0 =C2=A0s =3D g_malloc0(sizeof(QEMUFileStdio)); > + > + =C2=A0 =C2=A0s->stdio_file =3D fopen(filename, mode); > + =C2=A0 =C2=A0if (!s->stdio_file) > + =C2=A0 =C2=A0 =C2=A0 =C2=A0goto fail; > + > + =C2=A0 =C2=A0if(mode[0] =3D=3D 'w') { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, file_put_buffe= r, NULL, stdio_fclose, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > + =C2=A0 =C2=A0} else { > + =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, NULL, file_get= _buffer, stdio_fclose, > + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > + =C2=A0 =C2=A0} > + =C2=A0 =C2=A0return s->file; > +fail: > + =C2=A0 =C2=A0g_free(s); > + =C2=A0 =C2=A0return NULL; > +} > diff --git a/savevm.c b/savevm.c > index 1feaa70..db1e0cd 100644 > --- a/savevm.c > +++ b/savevm.c > @@ -155,228 +155,6 @@ void qemu_announce_self(void) > =C2=A0/***********************************************************/ > =C2=A0/* savevm/loadvm support */ > > -#define IO_BUF_SIZE 32768 > - > -struct QEMUFile { > - =C2=A0 =C2=A0QEMUFilePutBufferFunc *put_buffer; > - =C2=A0 =C2=A0QEMUFileGetBufferFunc *get_buffer; > - =C2=A0 =C2=A0QEMUFileCloseFunc *close; > - =C2=A0 =C2=A0QEMUFileRateLimit *rate_limit; > - =C2=A0 =C2=A0QEMUFileSetRateLimit *set_rate_limit; > - =C2=A0 =C2=A0QEMUFileGetRateLimit *get_rate_limit; > - =C2=A0 =C2=A0void *opaque; > - =C2=A0 =C2=A0int is_write; > - > - =C2=A0 =C2=A0int64_t buf_offset; /* start of buffer when writing, end o= f buffer > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 when reading */ > - =C2=A0 =C2=A0int buf_index; > - =C2=A0 =C2=A0int buf_size; /* 0 when writing */ > - =C2=A0 =C2=A0uint8_t buf[IO_BUF_SIZE]; > - > - =C2=A0 =C2=A0int has_error; > -}; > - > -typedef struct QEMUFileStdio > -{ > - =C2=A0 =C2=A0FILE *stdio_file; > - =C2=A0 =C2=A0QEMUFile *file; > -} QEMUFileStdio; > - > -typedef struct QEMUFileSocket > -{ > - =C2=A0 =C2=A0int fd; > - =C2=A0 =C2=A0QEMUFile *file; > -} QEMUFileSocket; > - > -static int socket_get_buffer(void *opaque, uint8_t *buf, int64_t pos, in= t size) > -{ > - =C2=A0 =C2=A0QEMUFileSocket *s =3D opaque; > - =C2=A0 =C2=A0ssize_t len; > - > - =C2=A0 =C2=A0do { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0len =3D qemu_recv(s->fd, buf, size, 0); > - =C2=A0 =C2=A0} while (len =3D=3D -1 && socket_error() =3D=3D EINTR); > - > - =C2=A0 =C2=A0if (len =3D=3D -1) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0len =3D -socket_error(); > - > - =C2=A0 =C2=A0return len; > -} > - > -static int socket_close(void *opaque) > -{ > - =C2=A0 =C2=A0QEMUFileSocket *s =3D opaque; > - =C2=A0 =C2=A0g_free(s); > - =C2=A0 =C2=A0return 0; > -} > - > -static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t po= s, int size) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > - =C2=A0 =C2=A0return fwrite(buf, 1, size, s->stdio_file); > -} > - > -static int stdio_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int= size) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > - =C2=A0 =C2=A0FILE *fp =3D s->stdio_file; > - =C2=A0 =C2=A0int bytes; > - > - =C2=A0 =C2=A0do { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0clearerr(fp); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0bytes =3D fread(buf, 1, size, fp); > - =C2=A0 =C2=A0} while ((bytes =3D=3D 0) && ferror(fp) && (errno =3D=3D E= INTR)); > - =C2=A0 =C2=A0return bytes; > -} > - > -static int stdio_pclose(void *opaque) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > - =C2=A0 =C2=A0int ret; > - =C2=A0 =C2=A0ret =3D pclose(s->stdio_file); > - =C2=A0 =C2=A0g_free(s); > - =C2=A0 =C2=A0return ret; > -} > - > -static int stdio_fclose(void *opaque) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > - =C2=A0 =C2=A0fclose(s->stdio_file); > - =C2=A0 =C2=A0g_free(s); > - =C2=A0 =C2=A0return 0; > -} > - > -QEMUFile *qemu_popen(FILE *stdio_file, const char *mode) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *s; > - > - =C2=A0 =C2=A0if (stdio_file =3D=3D NULL || mode =3D=3D NULL || (mode[0]= !=3D 'r' && mode[0] !=3D 'w') || mode[1] !=3D 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu_popen: Argument validi= ty check failed\n"); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return NULL; > - =C2=A0 =C2=A0} > - > - =C2=A0 =C2=A0s =3D g_malloc0(sizeof(QEMUFileStdio)); > - > - =C2=A0 =C2=A0s->stdio_file =3D stdio_file; > - > - =C2=A0 =C2=A0if(mode[0] =3D=3D 'r') { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, NULL, stdio_ge= t_buffer, stdio_pclose, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > - =C2=A0 =C2=A0} else { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, stdio_put_buff= er, NULL, stdio_pclose, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > - =C2=A0 =C2=A0} > - =C2=A0 =C2=A0return s->file; > -} > - > -QEMUFile *qemu_popen_cmd(const char *command, const char *mode) > -{ > - =C2=A0 =C2=A0FILE *popen_file; > - > - =C2=A0 =C2=A0popen_file =3D popen(command, mode); > - =C2=A0 =C2=A0if(popen_file =3D=3D NULL) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return NULL; > - =C2=A0 =C2=A0} > - > - =C2=A0 =C2=A0return qemu_popen(popen_file, mode); > -} > - > -int qemu_stdio_fd(QEMUFile *f) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *p; > - =C2=A0 =C2=A0int fd; > - > - =C2=A0 =C2=A0p =3D (QEMUFileStdio *)f->opaque; > - =C2=A0 =C2=A0fd =3D fileno(p->stdio_file); > - > - =C2=A0 =C2=A0return fd; > -} > - > -QEMUFile *qemu_fdopen(int fd, const char *mode) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *s; > - > - =C2=A0 =C2=A0if (mode =3D=3D NULL || > - =C2=A0 =C2=A0 =C2=A0 (mode[0] !=3D 'r' && mode[0] !=3D 'w') || > - =C2=A0 =C2=A0 =C2=A0 mode[1] !=3D 'b' || mode[2] !=3D 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu_fdopen: Argument valid= ity check failed\n"); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return NULL; > - =C2=A0 =C2=A0} > - > - =C2=A0 =C2=A0s =3D g_malloc0(sizeof(QEMUFileStdio)); > - =C2=A0 =C2=A0s->stdio_file =3D fdopen(fd, mode); > - =C2=A0 =C2=A0if (!s->stdio_file) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0goto fail; > - > - =C2=A0 =C2=A0if(mode[0] =3D=3D 'r') { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, NULL, stdio_ge= t_buffer, stdio_fclose, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > - =C2=A0 =C2=A0} else { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, stdio_put_buff= er, NULL, stdio_fclose, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > - =C2=A0 =C2=A0} > - =C2=A0 =C2=A0return s->file; > - > -fail: > - =C2=A0 =C2=A0g_free(s); > - =C2=A0 =C2=A0return NULL; > -} > - > -QEMUFile *qemu_fopen_socket(int fd) > -{ > - =C2=A0 =C2=A0QEMUFileSocket *s =3D g_malloc0(sizeof(QEMUFileSocket)); > - > - =C2=A0 =C2=A0s->fd =3D fd; > - =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, NULL, socket_get_buffer, soc= ket_close, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > - =C2=A0 =C2=A0return s->file; > -} > - > -static int file_put_buffer(void *opaque, const uint8_t *buf, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0int64_t pos, int size) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > - =C2=A0 =C2=A0fseek(s->stdio_file, pos, SEEK_SET); > - =C2=A0 =C2=A0return fwrite(buf, 1, size, s->stdio_file); > -} > - > -static int file_get_buffer(void *opaque, uint8_t *buf, int64_t pos, int = size) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *s =3D opaque; > - =C2=A0 =C2=A0fseek(s->stdio_file, pos, SEEK_SET); > - =C2=A0 =C2=A0return fread(buf, 1, size, s->stdio_file); > -} > - > -QEMUFile *qemu_fopen(const char *filename, const char *mode) > -{ > - =C2=A0 =C2=A0QEMUFileStdio *s; > - > - =C2=A0 =C2=A0if (mode =3D=3D NULL || > - =C2=A0 =C2=A0 =C2=A0 (mode[0] !=3D 'r' && mode[0] !=3D 'w') || > - =C2=A0 =C2=A0 =C2=A0 mode[1] !=3D 'b' || mode[2] !=3D 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, "qemu_fopen: Argument validi= ty check failed\n"); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return NULL; > - =C2=A0 =C2=A0} > - > - =C2=A0 =C2=A0s =3D g_malloc0(sizeof(QEMUFileStdio)); > - > - =C2=A0 =C2=A0s->stdio_file =3D fopen(filename, mode); > - =C2=A0 =C2=A0if (!s->stdio_file) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0goto fail; > - > - =C2=A0 =C2=A0if(mode[0] =3D=3D 'w') { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, file_put_buffe= r, NULL, stdio_fclose, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > - =C2=A0 =C2=A0} else { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0s->file =3D qemu_fopen_ops(s, NULL, file_get= _buffer, stdio_fclose, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NULL, NULL, NULL); > - =C2=A0 =C2=A0} > - =C2=A0 =C2=A0return s->file; > -fail: > - =C2=A0 =C2=A0g_free(s); > - =C2=A0 =C2=A0return NULL; > -} > - > =C2=A0static int block_put_buffer(void *opaque, const uint8_t *buf, > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0int64_t pos, int size) > =C2=A0{ > @@ -402,278 +180,6 @@ static QEMUFile *qemu_fopen_bdrv(BlockDriverState *= bs, int is_writable) > =C2=A0 =C2=A0 return qemu_fopen_ops(bs, NULL, block_get_buffer, bdrv_fclo= se, NULL, NULL, NULL); > =C2=A0} > > -QEMUFile *qemu_fopen_ops(void *opaque, QEMUFilePutBufferFunc *put_buffer= , > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileGetBufferFunc *get_buffer, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileCloseFunc *close, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileRateLimit *rate_limit, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileSetRateLimit *set_rate_limit, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 QEMUFileGetRateLimit *get_rate_limit) > -{ > - =C2=A0 =C2=A0QEMUFile *f; > - > - =C2=A0 =C2=A0f =3D g_malloc0(sizeof(QEMUFile)); > - > - =C2=A0 =C2=A0f->opaque =3D opaque; > - =C2=A0 =C2=A0f->put_buffer =3D put_buffer; > - =C2=A0 =C2=A0f->get_buffer =3D get_buffer; > - =C2=A0 =C2=A0f->close =3D close; > - =C2=A0 =C2=A0f->rate_limit =3D rate_limit; > - =C2=A0 =C2=A0f->set_rate_limit =3D set_rate_limit; > - =C2=A0 =C2=A0f->get_rate_limit =3D get_rate_limit; > - =C2=A0 =C2=A0f->is_write =3D 0; > - > - =C2=A0 =C2=A0return f; > -} > - > -int qemu_file_has_error(QEMUFile *f) > -{ > - =C2=A0 =C2=A0return f->has_error; > -} > - > -void qemu_file_set_error(QEMUFile *f) > -{ > - =C2=A0 =C2=A0f->has_error =3D 1; > -} > - > -void qemu_fflush(QEMUFile *f) > -{ > - =C2=A0 =C2=A0if (!f->put_buffer) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return; > - > - =C2=A0 =C2=A0if (f->is_write && f->buf_index > 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0int len; > - > - =C2=A0 =C2=A0 =C2=A0 =C2=A0len =3D f->put_buffer(f->opaque, f->buf, f->= buf_offset, f->buf_index); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0if (len > 0) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_offset +=3D f->buf_inde= x; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0else > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0f->has_error =3D 1; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index =3D 0; > - =C2=A0 =C2=A0} > -} > - > -static void qemu_fill_buffer(QEMUFile *f) > -{ > - =C2=A0 =C2=A0int len; > - > - =C2=A0 =C2=A0if (!f->get_buffer) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return; > - > - =C2=A0 =C2=A0if (f->is_write) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > - > - =C2=A0 =C2=A0len =3D f->get_buffer(f->opaque, f->buf, f->buf_offset, IO= _BUF_SIZE); > - =C2=A0 =C2=A0if (len > 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index =3D 0; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_size =3D len; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_offset +=3D len; > - =C2=A0 =C2=A0} else if (len !=3D -EAGAIN) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->has_error =3D 1; > -} > - > -int qemu_fclose(QEMUFile *f) > -{ > - =C2=A0 =C2=A0int ret =3D 0; > - =C2=A0 =C2=A0qemu_fflush(f); > - =C2=A0 =C2=A0if (f->close) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0ret =3D f->close(f->opaque); > - =C2=A0 =C2=A0g_free(f); > - =C2=A0 =C2=A0return ret; > -} > - > -void qemu_file_put_notify(QEMUFile *f) > -{ > - =C2=A0 =C2=A0f->put_buffer(f->opaque, NULL, 0, 0); > -} > - > -void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size) > -{ > - =C2=A0 =C2=A0int l; > - > - =C2=A0 =C2=A0if (!f->has_error && f->is_write =3D=3D 0 && f->buf_index = > 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"Attempted to wr= ite to buffer while read buffer is not empty\n"); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > - =C2=A0 =C2=A0} > - > - =C2=A0 =C2=A0while (!f->has_error && size > 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D IO_BUF_SIZE - f->buf_index; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l > size) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D size; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0memcpy(f->buf + f->buf_index, buf, l); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->is_write =3D 1; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index +=3D l; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0buf +=3D l; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0size -=3D l; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0if (f->buf_index >=3D IO_BUF_SIZE) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fflush(f); > - =C2=A0 =C2=A0} > -} > - > -void qemu_put_byte(QEMUFile *f, int v) > -{ > - =C2=A0 =C2=A0if (!f->has_error && f->is_write =3D=3D 0 && f->buf_index = > 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0fprintf(stderr, > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0"Attempted to wr= ite to buffer while read buffer is not empty\n"); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > - =C2=A0 =C2=A0} > - > - =C2=A0 =C2=A0f->buf[f->buf_index++] =3D v; > - =C2=A0 =C2=A0f->is_write =3D 1; > - =C2=A0 =C2=A0if (f->buf_index >=3D IO_BUF_SIZE) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fflush(f); > -} > - > -int qemu_get_buffer(QEMUFile *f, uint8_t *buf, int size1) > -{ > - =C2=A0 =C2=A0int size, l; > - > - =C2=A0 =C2=A0if (f->is_write) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > - > - =C2=A0 =C2=A0size =3D size1; > - =C2=A0 =C2=A0while (size > 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D f->buf_size - f->buf_index; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l =3D=3D 0) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fill_buffer(f); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D f->buf_size - f->buf_ind= ex; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l =3D=3D 0) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0} > - =C2=A0 =C2=A0 =C2=A0 =C2=A0if (l > size) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0l =3D size; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0memcpy(buf, f->buf + f->buf_index, l); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index +=3D l; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0buf +=3D l; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0size -=3D l; > - =C2=A0 =C2=A0} > - =C2=A0 =C2=A0return size1 - size; > -} > - > -static int qemu_peek_byte(QEMUFile *f) > -{ > - =C2=A0 =C2=A0if (f->is_write) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > - > - =C2=A0 =C2=A0if (f->buf_index >=3D f->buf_size) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fill_buffer(f); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0if (f->buf_index >=3D f->buf_size) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0; > - =C2=A0 =C2=A0} > - =C2=A0 =C2=A0return f->buf[f->buf_index]; > -} > - > -int qemu_get_byte(QEMUFile *f) > -{ > - =C2=A0 =C2=A0if (f->is_write) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0abort(); > - > - =C2=A0 =C2=A0if (f->buf_index >=3D f->buf_size) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fill_buffer(f); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0if (f->buf_index >=3D f->buf_size) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return 0; > - =C2=A0 =C2=A0} > - =C2=A0 =C2=A0return f->buf[f->buf_index++]; > -} > - > -int64_t qemu_ftell(QEMUFile *f) > -{ > - =C2=A0 =C2=A0return f->buf_offset - f->buf_size + f->buf_index; > -} > - > -int64_t qemu_fseek(QEMUFile *f, int64_t pos, int whence) > -{ > - =C2=A0 =C2=A0if (whence =3D=3D SEEK_SET) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0/* nothing to do */ > - =C2=A0 =C2=A0} else if (whence =3D=3D SEEK_CUR) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0pos +=3D qemu_ftell(f); > - =C2=A0 =C2=A0} else { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0/* SEEK_END not supported */ > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1; > - =C2=A0 =C2=A0} > - =C2=A0 =C2=A0if (f->put_buffer) { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_fflush(f); > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_offset =3D pos; > - =C2=A0 =C2=A0} else { > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_offset =3D pos; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_index =3D 0; > - =C2=A0 =C2=A0 =C2=A0 =C2=A0f->buf_size =3D 0; > - =C2=A0 =C2=A0} > - =C2=A0 =C2=A0return pos; > -} > - > -int qemu_file_rate_limit(QEMUFile *f) > -{ > - =C2=A0 =C2=A0if (f->rate_limit) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return f->rate_limit(f->opaque); > - > - =C2=A0 =C2=A0return 0; > -} > - > -int64_t qemu_file_get_rate_limit(QEMUFile *f) > -{ > - =C2=A0 =C2=A0if (f->get_rate_limit) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return f->get_rate_limit(f->opaque); > - > - =C2=A0 =C2=A0return 0; > -} > - > -int64_t qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate) > -{ > - =C2=A0 =C2=A0/* any failed or completed migration keeps its state to al= low probing of > - =C2=A0 =C2=A0 * migration data, but has no associated file anymore */ > - =C2=A0 =C2=A0if (f && f->set_rate_limit) > - =C2=A0 =C2=A0 =C2=A0 =C2=A0return f->set_rate_limit(f->opaque, new_rate= ); > - > - =C2=A0 =C2=A0return 0; > -} > - > -void qemu_put_be16(QEMUFile *f, unsigned int v) > -{ > - =C2=A0 =C2=A0qemu_put_byte(f, v >> 8); > - =C2=A0 =C2=A0qemu_put_byte(f, v); > -} > - > -void qemu_put_be32(QEMUFile *f, unsigned int v) > -{ > - =C2=A0 =C2=A0qemu_put_byte(f, v >> 24); > - =C2=A0 =C2=A0qemu_put_byte(f, v >> 16); > - =C2=A0 =C2=A0qemu_put_byte(f, v >> 8); > - =C2=A0 =C2=A0qemu_put_byte(f, v); > -} > - > -void qemu_put_be64(QEMUFile *f, uint64_t v) > -{ > - =C2=A0 =C2=A0qemu_put_be32(f, v >> 32); > - =C2=A0 =C2=A0qemu_put_be32(f, v); > -} > - > -unsigned int qemu_get_be16(QEMUFile *f) > -{ > - =C2=A0 =C2=A0unsigned int v; > - =C2=A0 =C2=A0v =3D qemu_get_byte(f) << 8; > - =C2=A0 =C2=A0v |=3D qemu_get_byte(f); > - =C2=A0 =C2=A0return v; > -} > - > -unsigned int qemu_get_be32(QEMUFile *f) > -{ > - =C2=A0 =C2=A0unsigned int v; > - =C2=A0 =C2=A0v =3D qemu_get_byte(f) << 24; > - =C2=A0 =C2=A0v |=3D qemu_get_byte(f) << 16; > - =C2=A0 =C2=A0v |=3D qemu_get_byte(f) << 8; > - =C2=A0 =C2=A0v |=3D qemu_get_byte(f); > - =C2=A0 =C2=A0return v; > -} > - > -uint64_t qemu_get_be64(QEMUFile *f) > -{ > - =C2=A0 =C2=A0uint64_t v; > - =C2=A0 =C2=A0v =3D (uint64_t)qemu_get_be32(f) << 32; > - =C2=A0 =C2=A0v |=3D qemu_get_be32(f); > - =C2=A0 =C2=A0return v; > -} > - > =C2=A0/* bool */ > > =C2=A0static int get_bool(QEMUFile *f, void *pv, size_t size) > -- > 1.7.0.4 > > >