Commit d8903441 authored by Marc-André Lureau's avatar Marc-André Lureau Committed by Samuel Thibault
Browse files

slirp: use libslirp migration code



slirp migration code uses QEMU vmstate so far, when building WITH_QEMU.

Introduce slirp_state_{load,save,version}() functions to move the
state saving handling to libslirp side.

So far, the bitstream compatibility should remain equal with current
QEMU, as this is effectively using the same code, with the same format
etc. When libslirp is made standalone, we will need some mechanism to
ensure bitstream compatibility regardless of the libslirp version
installed. See the FIXME note in the code.

Signed-off-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20190212162524.31504-3-marcandre.lureau@redhat.com>
Signed-off-by: default avatarSamuel Thibault <samuel.thibault@ens-lyon.org>
parent b92a1ff4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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);

+0 −1
Original line number Diff line number Diff line
@@ -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);
+55 −0
Original line number Diff line number Diff line
@@ -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);

+8 −0
Original line number Diff line number Diff line
@@ -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
+0 −9
Original line number Diff line number Diff line
@@ -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);
Loading