Commit 513d80ed authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20140623' into staging



migration/next for 20140623

# gpg: Signature made Mon 23 Jun 2014 18:18:57 BST using RSA key ID 5872D723
# gpg: Can't check signature: public key not found

* remotes/juanquintela/tags/migration/20140623: (22 commits)
  vmstate: Refactor & increase tests for primitive types
  vmstate: Return error in case of error
  migration: Remove unneeded minimum_version_id_old
  tests: vmstate static checker: add size mismatch inside substructure
  tests: vmstate static checker: add substructure for usb-kbd for hid section
  tests: vmstate static checker: remove Subsections
  tests: vmstate static checker: remove a subsection
  tests: vmstate static checker: remove Description inside Fields
  tests: vmstate static checker: remove Description
  tests: vmstate static checker: remove Fields
  tests: vmstate static checker: change description name
  tests: vmstate static checker: remove last field in a struct
  tests: vmstate static checker: remove a field
  tests: vmstate static checker: remove a section
  tests: vmstate static checker: minimum_version_id check
  tests: vmstate static checker: version mismatch inside a Description
  tests: vmstate static checker: add version error in main section
  tests: vmstate static checker: incompat machine types
  tests: vmstate static checker: add dump1 and dump2 files
  vmstate-static-checker: script to validate vmstate changes
  ...

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 089a3948 4ea7df4e
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -1988,7 +1988,6 @@ static const VMStateDescription vmstate_ohci_state_port = {
    .name = "ohci-core/port",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(ctrl, OHCIPort),
        VMSTATE_END_OF_LIST()
@@ -2015,7 +2014,6 @@ static const VMStateDescription vmstate_ohci_eof_timer = {
    .name = "ohci-core/eof-timer",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .pre_load = ohci_eof_timer_pre_load,
    .fields = (VMStateField[]) {
        VMSTATE_TIMER(eof_timer, OHCIState),
@@ -2078,7 +2076,6 @@ static const VMStateDescription vmstate_ohci = {
    .name = "ohci",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields = (VMStateField[]) {
        VMSTATE_PCI_DEVICE(parent_obj, OHCIPCIState),
        VMSTATE_STRUCT(state, OHCIPCIState, 1, vmstate_ohci_state, OHCIState),
+2 −0
Original line number Diff line number Diff line
@@ -788,4 +788,6 @@ int64_t self_announce_delay(int round)
    return 50 + (SELF_ANNOUNCE_ROUNDS - round - 1) * 100;
}

void dump_vmstate_json_to_file(FILE *out_fp);

#endif
+10 −10
Original line number Diff line number Diff line
@@ -1590,13 +1590,11 @@ static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,
    }


    if (ibv_post_send(rdma->qp, &send_wr, &bad_wr)) {
        return -1;
    }
    ret = ibv_post_send(rdma->qp, &send_wr, &bad_wr);

    if (ret < 0) {
    if (ret > 0) {
        fprintf(stderr, "Failed to use post IB SEND for control!\n");
        return ret;
        return -ret;
    }

    ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_SEND_CONTROL, NULL);
@@ -2238,10 +2236,6 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
        }
    }

    if (rdma->qp) {
        rdma_destroy_qp(rdma->cm_id);
        rdma->qp = NULL;
    }
    if (rdma->cq) {
        ibv_destroy_cq(rdma->cq);
        rdma->cq = NULL;
@@ -2259,6 +2253,10 @@ static void qemu_rdma_cleanup(RDMAContext *rdma)
        rdma->listen_id = NULL;
    }
    if (rdma->cm_id) {
        if (rdma->qp) {
            rdma_destroy_qp(rdma->cm_id);
            rdma->qp = NULL;
        }
        rdma_destroy_id(rdma->cm_id);
        rdma->cm_id = NULL;
    }
@@ -2513,8 +2511,10 @@ static void *qemu_rdma_data_init(const char *host_port, Error **errp)
        } else {
            ERROR(errp, "bad RDMA migration address '%s'", host_port);
            g_free(rdma);
            return NULL;
            rdma = NULL;
        }

        qapi_free_InetSocketAddress(addr);
    }

    return rdma;
+14 −0
Original line number Diff line number Diff line
@@ -3252,6 +3252,20 @@ STEXI
prepend a timestamp to each log message.(default:on)
ETEXI

DEF("dump-vmstate", HAS_ARG, QEMU_OPTION_dump_vmstate,
    "-dump-vmstate <file>\n"
    "                Output vmstate information in JSON format to file.\n"
    "                Use the scripts/vmstate-static-checker.py file to\n"
    "                check for possible regressions in migration code\n"
    "                by comparing two such vmstate dumps.",
    QEMU_ARCH_ALL)
STEXI
@item -dump-vmstate @var{file}
@findex -dump-vmstate
Dump json-encoded vmstate information for current machine type to file
in @var{file}
ETEXI

HXCOMM This is the last statement. Insert new options before this line!
STEXI
@end table
+139 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@

#include "config-host.h"
#include "qemu-common.h"
#include "hw/boards.h"
#include "hw/hw.h"
#include "hw/qdev.h"
#include "net/net.h"
@@ -240,6 +241,144 @@ static QTAILQ_HEAD(savevm_handlers, SaveStateEntry) savevm_handlers =
    QTAILQ_HEAD_INITIALIZER(savevm_handlers);
static int global_section_id;

static void dump_vmstate_vmsd(FILE *out_file,
                              const VMStateDescription *vmsd, int indent,
                              bool is_subsection);

static void dump_vmstate_vmsf(FILE *out_file, const VMStateField *field,
                              int indent)
{
    fprintf(out_file, "%*s{\n", indent, "");
    indent += 2;
    fprintf(out_file, "%*s\"field\": \"%s\",\n", indent, "", field->name);
    fprintf(out_file, "%*s\"version_id\": %d,\n", indent, "",
            field->version_id);
    fprintf(out_file, "%*s\"field_exists\": %s,\n", indent, "",
            field->field_exists ? "true" : "false");
    fprintf(out_file, "%*s\"size\": %zu", indent, "", field->size);
    if (field->vmsd != NULL) {
        fprintf(out_file, ",\n");
        dump_vmstate_vmsd(out_file, field->vmsd, indent, false);
    }
    fprintf(out_file, "\n%*s}", indent - 2, "");
}

static void dump_vmstate_vmss(FILE *out_file,
                              const VMStateSubsection *subsection,
                              int indent)
{
    if (subsection->vmsd != NULL) {
        dump_vmstate_vmsd(out_file, subsection->vmsd, indent, true);
    }
}

static void dump_vmstate_vmsd(FILE *out_file,
                              const VMStateDescription *vmsd, int indent,
                              bool is_subsection)
{
    if (is_subsection) {
        fprintf(out_file, "%*s{\n", indent, "");
    } else {
        fprintf(out_file, "%*s\"%s\": {\n", indent, "", "Description");
    }
    indent += 2;
    fprintf(out_file, "%*s\"name\": \"%s\",\n", indent, "", vmsd->name);
    fprintf(out_file, "%*s\"version_id\": %d,\n", indent, "",
            vmsd->version_id);
    fprintf(out_file, "%*s\"minimum_version_id\": %d", indent, "",
            vmsd->minimum_version_id);
    if (vmsd->fields != NULL) {
        const VMStateField *field = vmsd->fields;
        bool first;

        fprintf(out_file, ",\n%*s\"Fields\": [\n", indent, "");
        first = true;
        while (field->name != NULL) {
            if (field->flags & VMS_MUST_EXIST) {
                /* Ignore VMSTATE_VALIDATE bits; these don't get migrated */
                field++;
                continue;
            }
            if (!first) {
                fprintf(out_file, ",\n");
            }
            dump_vmstate_vmsf(out_file, field, indent + 2);
            field++;
            first = false;
        }
        fprintf(out_file, "\n%*s]", indent, "");
    }
    if (vmsd->subsections != NULL) {
        const VMStateSubsection *subsection = vmsd->subsections;
        bool first;

        fprintf(out_file, ",\n%*s\"Subsections\": [\n", indent, "");
        first = true;
        while (subsection->vmsd != NULL) {
            if (!first) {
                fprintf(out_file, ",\n");
            }
            dump_vmstate_vmss(out_file, subsection, indent + 2);
            subsection++;
            first = false;
        }
        fprintf(out_file, "\n%*s]", indent, "");
    }
    fprintf(out_file, "\n%*s}", indent - 2, "");
}

static void dump_machine_type(FILE *out_file)
{
    MachineClass *mc;

    mc = MACHINE_GET_CLASS(current_machine);

    fprintf(out_file, "  \"vmschkmachine\": {\n");
    fprintf(out_file, "    \"Name\": \"%s\"\n", mc->name);
    fprintf(out_file, "  },\n");
}

void dump_vmstate_json_to_file(FILE *out_file)
{
    GSList *list, *elt;
    bool first;

    fprintf(out_file, "{\n");
    dump_machine_type(out_file);

    first = true;
    list = object_class_get_list(TYPE_DEVICE, true);
    for (elt = list; elt; elt = elt->next) {
        DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
                                             TYPE_DEVICE);
        const char *name;
        int indent = 2;

        if (!dc->vmsd) {
            continue;
        }

        if (!first) {
            fprintf(out_file, ",\n");
        }
        name = object_class_get_name(OBJECT_CLASS(dc));
        fprintf(out_file, "%*s\"%s\": {\n", indent, "", name);
        indent += 2;
        fprintf(out_file, "%*s\"Name\": \"%s\",\n", indent, "", name);
        fprintf(out_file, "%*s\"version_id\": %d,\n", indent, "",
                dc->vmsd->version_id);
        fprintf(out_file, "%*s\"minimum_version_id\": %d,\n", indent, "",
                dc->vmsd->minimum_version_id);

        dump_vmstate_vmsd(out_file, dc->vmsd, indent, false);

        fprintf(out_file, "\n%*s}", indent - 2, "");
        first = false;
    }
    fprintf(out_file, "\n}\n");
    fclose(out_file);
}

static int calculate_new_instance_id(const char *idstr)
{
    SaveStateEntry *se;
Loading