diff options
-rw-r--r-- | include/migration/qemu-file-types.h | 2 | ||||
-rw-r--r-- | migration/qemu-file.h | 1 | ||||
-rw-r--r-- | net/slirp.c | 55 | ||||
-rw-r--r-- | slirp/libslirp.h | 8 | ||||
-rw-r--r-- | slirp/slirp.c | 9 | ||||
-rw-r--r-- | slirp/state.c | 52 | ||||
-rw-r--r-- | slirp/state.h | 9 |
7 files changed, 88 insertions, 48 deletions
diff --git a/include/migration/qemu-file-types.h b/include/migration/qemu-file-types.h index bd6d7dd7f9..bbe04d4484 100644 --- a/include/migration/qemu-file-types.h +++ b/include/migration/qemu-file-types.h @@ -25,6 +25,8 @@ #ifndef QEMU_FILE_H #define QEMU_FILE_H +int qemu_file_get_error(QEMUFile *f); + void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, size_t size); void qemu_put_byte(QEMUFile *f, int v); diff --git a/migration/qemu-file.h b/migration/qemu-file.h index 2ccfcfb2a8..13baf896bd 100644 --- a/migration/qemu-file.h +++ b/migration/qemu-file.h @@ -149,7 +149,6 @@ void qemu_update_position(QEMUFile *f, size_t size); void qemu_file_reset_rate_limit(QEMUFile *f); void qemu_file_set_rate_limit(QEMUFile *f, int64_t new_rate); int64_t qemu_file_get_rate_limit(QEMUFile *f); -int qemu_file_get_error(QEMUFile *f); void qemu_file_set_error(QEMUFile *f, int ret); int qemu_file_shutdown(QEMUFile *f); QEMUFile *qemu_file_get_return_path(QEMUFile *f); diff --git a/net/slirp.c b/net/slirp.c index a8fd9e6364..059b2d9b08 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -44,6 +44,8 @@ #include "qapi/error.h" #include "qapi/qmp/qdict.h" #include "util.h" +#include "migration/register.h" +#include "migration/qemu-file-types.h" static int get_str_sep(char *buf, int buf_size, const char **pp, int sep) { @@ -146,6 +148,7 @@ static void net_slirp_cleanup(NetClientState *nc) g_slist_free_full(s->fwd, slirp_free_fwd); main_loop_poll_remove_notifier(&s->poll_notifier); + unregister_savevm(NULL, "slirp", s->slirp); slirp_cleanup(s->slirp); if (s->exit_notifier.notify) { qemu_remove_exit_notifier(&s->exit_notifier); @@ -303,6 +306,46 @@ static void net_slirp_poll_notify(Notifier *notifier, void *data) } } +static ssize_t +net_slirp_stream_read(void *buf, size_t size, void *opaque) +{ + QEMUFile *f = opaque; + + return qemu_get_buffer(f, buf, size); +} + +static ssize_t +net_slirp_stream_write(const void *buf, size_t size, void *opaque) +{ + QEMUFile *f = opaque; + + qemu_put_buffer(f, buf, size); + if (qemu_file_get_error(f)) { + return -1; + } + + return size; +} + +static int net_slirp_state_load(QEMUFile *f, void *opaque, int version_id) +{ + Slirp *slirp = opaque; + + return slirp_state_load(slirp, version_id, net_slirp_stream_read, f); +} + +static void net_slirp_state_save(QEMUFile *f, void *opaque) +{ + Slirp *slirp = opaque; + + slirp_state_save(slirp, net_slirp_stream_write, f); +} + +static SaveVMHandlers savevm_slirp_state = { + .save_state = net_slirp_state_save, + .load_state = net_slirp_state_load, +}; + static int net_slirp_init(NetClientState *peer, const char *model, const char *name, int restricted, bool ipv4, const char *vnetwork, const char *vhost, @@ -523,6 +566,18 @@ static int net_slirp_init(NetClientState *peer, const char *model, &slirp_cb, s); QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry); + /* + * Make sure the current bitstream version of slirp is 4, to avoid + * QEMU migration incompatibilities, if upstream slirp bumped the + * version. + * + * FIXME: use bitfields of features? teach libslirp to save with + * specific version? + */ + g_assert(slirp_state_version() == 4); + register_savevm_live(NULL, "slirp", 0, slirp_state_version(), + &savevm_slirp_state, s->slirp); + s->poll_notifier.notify = net_slirp_poll_notify; main_loop_poll_add_notifier(&s->poll_notifier); diff --git a/slirp/libslirp.h b/slirp/libslirp.h index 57bd6f597c..2d13950065 100644 --- a/slirp/libslirp.h +++ b/slirp/libslirp.h @@ -102,6 +102,14 @@ void slirp_socket_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port, const uint8_t *buf, int size); size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port); + +void slirp_state_save(Slirp *s, SlirpWriteCb write_cb, void *opaque); + +int slirp_state_load(Slirp *s, int version_id, + SlirpReadCb read_cb, void *opaque); + +int slirp_state_version(void); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/slirp/slirp.c b/slirp/slirp.c index cbdf9f778d..18af670a0a 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -23,9 +23,6 @@ */ #include "slirp.h" -#ifdef WITH_QEMU -#include "state.h" -#endif #ifndef _WIN32 #include <net/if.h> @@ -326,9 +323,6 @@ Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork, translate_dnssearch(slirp, vdnssearch); } -#ifdef WITH_QEMU - slirp_state_register(slirp); -#endif return slirp; } @@ -342,9 +336,6 @@ void slirp_cleanup(Slirp *slirp) g_free(e); } -#ifdef WITH_QEMU - slirp_state_unregister(slirp); -#endif ip_cleanup(slirp); ip6_cleanup(slirp); m_cleanup(slirp); diff --git a/slirp/state.c b/slirp/state.c index 0e5a706e87..f5dd80cdc8 100644 --- a/slirp/state.c +++ b/slirp/state.c @@ -21,13 +21,10 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#include "qemu/osdep.h" - #include "slirp.h" +#include "vmstate.h" #include "state.h" -#include "migration/vmstate.h" -#include "migration/qemu-file-types.h" -#include "migration/register.h" +#include "stream.h" static int slirp_tcp_post_load(void *opaque, int version) { @@ -180,7 +177,7 @@ static int slirp_socket_pre_load(void *opaque) #else /* Win uses u_long rather than uint32_t - but it's still 32bits long */ #define VMSTATE_SIN4_ADDR(f, s, t) VMSTATE_SINGLE_TEST(f, s, t, 0, \ - vmstate_info_uint32, u_long) + slirp_vmstate_info_uint32, u_long) #endif /* The OS provided ss_family field isn't that portable; it's size @@ -322,10 +319,13 @@ static const VMStateDescription vmstate_slirp = { } }; -static void slirp_state_save(QEMUFile *f, void *opaque) +void slirp_state_save(Slirp *slirp, SlirpWriteCb write_cb, void *opaque) { - Slirp *slirp = opaque; struct gfwd_list *ex_ptr; + SlirpOStream f = { + .write_cb = write_cb, + .opaque = opaque, + }; for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) if (ex_ptr->write_cb) { @@ -336,25 +336,29 @@ static void slirp_state_save(QEMUFile *f, void *opaque) continue; } - qemu_put_byte(f, 42); - vmstate_save_state(f, &vmstate_slirp_socket, so, NULL); + slirp_ostream_write_u8(&f, 42); + slirp_vmstate_save_state(&f, &vmstate_slirp_socket, so); } - qemu_put_byte(f, 0); + slirp_ostream_write_u8(&f, 0); - vmstate_save_state(f, &vmstate_slirp, slirp, NULL); + slirp_vmstate_save_state(&f, &vmstate_slirp, slirp); } -static int slirp_state_load(QEMUFile *f, void *opaque, int version_id) +int slirp_state_load(Slirp *slirp, int version_id, + SlirpReadCb read_cb, void *opaque) { - Slirp *slirp = opaque; struct gfwd_list *ex_ptr; + SlirpIStream f = { + .read_cb = read_cb, + .opaque = opaque, + }; - while (qemu_get_byte(f)) { + while (slirp_istream_read_u8(&f)) { int ret; struct socket *so = socreate(slirp); - ret = vmstate_load_state(f, &vmstate_slirp_socket, so, version_id); + ret = slirp_vmstate_load_state(&f, &vmstate_slirp_socket, so, version_id); if (ret < 0) { return ret; } @@ -375,20 +379,10 @@ static int slirp_state_load(QEMUFile *f, void *opaque, int version_id) } } - return vmstate_load_state(f, &vmstate_slirp, slirp, version_id); -} - -void slirp_state_register(Slirp *slirp) -{ - static SaveVMHandlers savevm_slirp_state = { - .save_state = slirp_state_save, - .load_state = slirp_state_load, - }; - - register_savevm_live(NULL, "slirp", 0, 4, &savevm_slirp_state, slirp); + return slirp_vmstate_load_state(&f, &vmstate_slirp, slirp, version_id); } -void slirp_state_unregister(Slirp *slirp) +int slirp_state_version(void) { - unregister_savevm(NULL, "slirp", slirp); + return 4; } diff --git a/slirp/state.h b/slirp/state.h index 154866898f..e69de29bb2 100644 --- a/slirp/state.h +++ b/slirp/state.h @@ -1,9 +0,0 @@ -#ifndef SLIRP_STATE_H_ -#define SLIRP_STATE_H_ - -#include "libslirp.h" - -void slirp_state_register(Slirp *slirp); -void slirp_state_unregister(Slirp *slirp); - -#endif /* SLIRP_STATE_H_ */ |