Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/201…
Browse files Browse the repository at this point in the history
…40623' 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: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
pm215 committed Jun 24, 2014
2 parents 089a394 + 4ea7df4 commit 513d80e
Show file tree
Hide file tree
Showing 11 changed files with 2,872 additions and 76 deletions.
7 changes: 2 additions & 5 deletions hw/usb/hcd-ohci.c
Expand Up @@ -1988,8 +1988,7 @@ 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 []) {
.fields = (VMStateField[]) {
VMSTATE_UINT32(ctrl, OHCIPort),
VMSTATE_END_OF_LIST()
},
Expand All @@ -2015,9 +2014,8 @@ 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 []) {
.fields = (VMStateField[]) {
VMSTATE_TIMER(eof_timer, OHCIState),
VMSTATE_END_OF_LIST()
},
Expand Down Expand Up @@ -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),
Expand Down
2 changes: 2 additions & 0 deletions include/migration/vmstate.h
Expand Up @@ -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
20 changes: 10 additions & 10 deletions migration-rdma.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 14 additions & 0 deletions qemu-options.hx
Expand Up @@ -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
Expand Down
139 changes: 139 additions & 0 deletions savevm.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 513d80e

Please sign in to comment.