On Tue, Oct 11, 2016 at 06:18:32PM +0100, Dr. David Alan Gilbert (git) wrote: > From: "Dr. David Alan Gilbert" <dgilb...@redhat.com> > > Convert the sbuf structure to a VMStateDescription. > Note this uses the VMSTATE_WITH_TMP mechanism to calculate > and reload the offsets based on the pointers. > > Signed-off-by: Dr. David Alan Gilbert <dgilb...@redhat.com>
Reviewed-by: David Gibson <da...@gibson.dropbear.id.au> > --- > slirp/sbuf.h | 4 +- > slirp/slirp.c | 116 > ++++++++++++++++++++++++++++++++++++++-------------------- > 2 files changed, 78 insertions(+), 42 deletions(-) > > diff --git a/slirp/sbuf.h b/slirp/sbuf.h > index efcec39..a722ecb 100644 > --- a/slirp/sbuf.h > +++ b/slirp/sbuf.h > @@ -12,8 +12,8 @@ > #define sbspace(sb) ((sb)->sb_datalen - (sb)->sb_cc) > > struct sbuf { > - u_int sb_cc; /* actual chars in buffer */ > - u_int sb_datalen; /* Length of data */ > + uint32_t sb_cc; /* actual chars in buffer */ > + uint32_t sb_datalen; /* Length of data */ > char *sb_wptr; /* write pointer. points to where the next > * bytes should be written in the sbuf */ > char *sb_rptr; /* read pointer. points to where the next > diff --git a/slirp/slirp.c b/slirp/slirp.c > index 6276315..2f7802e 100644 > --- a/slirp/slirp.c > +++ b/slirp/slirp.c > @@ -1185,19 +1185,72 @@ static const VMStateDescription vmstate_slirp_tcp = { > } > }; > > -static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf) > +/* The sbuf has a pair of pointers that are migrated as offsets; > + * we calculate the offsets and restore the pointers using > + * pre_save/post_load on a tmp structure. > + */ > +struct sbuf_tmp { > + struct sbuf *parent; > + uint32_t roff, woff; > +}; > + > +static void sbuf_tmp_pre_save(void *opaque) > +{ > + struct sbuf_tmp *tmp = opaque; > + tmp->woff = tmp->parent->sb_wptr - tmp->parent->sb_data; > + tmp->roff = tmp->parent->sb_rptr - tmp->parent->sb_data; > +} > + > +static int sbuf_tmp_post_load(void *opaque, int version) > { > - uint32_t off; > - > - qemu_put_be32(f, sbuf->sb_cc); > - qemu_put_be32(f, sbuf->sb_datalen); > - off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data); > - qemu_put_sbe32(f, off); > - off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data); > - qemu_put_sbe32(f, off); > - qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen); > + struct sbuf_tmp *tmp = opaque; > + uint32_t requested_len = tmp->parent->sb_datalen; > + > + /* Allocate the buffer space used by the field after the tmp */ > + sbreserve(tmp->parent, tmp->parent->sb_datalen); > + > + if (tmp->parent->sb_datalen != requested_len) { > + return -ENOMEM; > + } > + if (tmp->woff >= requested_len || > + tmp->roff >= requested_len) { > + error_report("invalid sbuf offsets r/w=%u/%u len=%u", > + tmp->roff, tmp->woff, requested_len); > + return -EINVAL; > + } > + > + tmp->parent->sb_wptr = tmp->parent->sb_data + tmp->woff; > + tmp->parent->sb_rptr = tmp->parent->sb_data + tmp->roff; > + > + return 0; > } > > + > +static const VMStateDescription vmstate_slirp_sbuf_tmp = { > + .name = "slirp-sbuf-tmp", > + .post_load = sbuf_tmp_post_load, > + .pre_save = sbuf_tmp_pre_save, > + .version_id = 0, > + .fields = (VMStateField[]) { > + VMSTATE_UINT32(woff, struct sbuf_tmp), > + VMSTATE_UINT32(roff, struct sbuf_tmp), > + VMSTATE_END_OF_LIST() > + } > +}; > + > +static const VMStateDescription vmstate_slirp_sbuf = { > + .name = "slirp-sbuf", > + .version_id = 0, > + .fields = (VMStateField[]) { > + VMSTATE_UINT32(sb_cc, struct sbuf), > + VMSTATE_UINT32(sb_datalen, struct sbuf), > + VMSTATE_WITH_TMP(struct sbuf, struct sbuf_tmp, > vmstate_slirp_sbuf_tmp), > + VMSTATE_VBUFFER_UINT32(sb_data, struct sbuf, 0, NULL, 0, sb_datalen), > + VMSTATE_END_OF_LIST() > + } > +}; > + > + > static void slirp_socket_save(QEMUFile *f, struct socket *so) > { > qemu_put_be32(f, so->so_urgc); > @@ -1225,8 +1278,9 @@ static void slirp_socket_save(QEMUFile *f, struct > socket *so) > qemu_put_byte(f, so->so_emu); > qemu_put_byte(f, so->so_type); > qemu_put_be32(f, so->so_state); > - slirp_sbuf_save(f, &so->so_rcv); > - slirp_sbuf_save(f, &so->so_snd); > + /* TODO: Build vmstate at this level */ > + vmstate_save_state(f, &vmstate_slirp_sbuf, &so->so_rcv, 0); > + vmstate_save_state(f, &vmstate_slirp_sbuf, &so->so_snd, 0); > vmstate_save_state(f, &vmstate_slirp_tcp, so->so_tcpcb, 0); > } > > @@ -1263,31 +1317,9 @@ static void slirp_state_save(QEMUFile *f, void *opaque) > slirp_bootp_save(f, slirp); > } > > -static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf) > -{ > - uint32_t off, sb_cc, sb_datalen; > - > - sb_cc = qemu_get_be32(f); > - sb_datalen = qemu_get_be32(f); > - > - sbreserve(sbuf, sb_datalen); > - > - if (sbuf->sb_datalen != sb_datalen) > - return -ENOMEM; > - > - sbuf->sb_cc = sb_cc; > - > - off = qemu_get_sbe32(f); > - sbuf->sb_wptr = sbuf->sb_data + off; > - off = qemu_get_sbe32(f); > - sbuf->sb_rptr = sbuf->sb_data + off; > - qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen); > - > - return 0; > -} > - > static int slirp_socket_load(QEMUFile *f, struct socket *so, int version_id) > { > + int ret = 0; > if (tcp_attach(so) < 0) > return -ENOMEM; > > @@ -1324,11 +1356,15 @@ static int slirp_socket_load(QEMUFile *f, struct > socket *so, int version_id) > so->so_emu = qemu_get_byte(f); > so->so_type = qemu_get_byte(f); > so->so_state = qemu_get_be32(f); > - if (slirp_sbuf_load(f, &so->so_rcv) < 0) > - return -ENOMEM; > - if (slirp_sbuf_load(f, &so->so_snd) < 0) > - return -ENOMEM; > - return vmstate_load_state(f, &vmstate_slirp_tcp, so->so_tcpcb, 0); > + /* TODO: VMState at this level */ > + ret = vmstate_load_state(f, &vmstate_slirp_sbuf, &so->so_rcv, 0); > + if (!ret) { > + ret = vmstate_load_state(f, &vmstate_slirp_sbuf, &so->so_snd, 0); > + } > + if (!ret) { > + ret = vmstate_load_state(f, &vmstate_slirp_tcp, so->so_tcpcb, 0); > + } > + return ret; > } > > static void slirp_bootp_load(QEMUFile *f, Slirp *slirp) -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature