mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/juanquintela/tags/migration/20150205' into staging
migration/next for 20150205 # gpg: Signature made Thu 05 Feb 2015 16:17:08 GMT using RSA key ID 5872D723 # gpg: Can't check signature: public key not found * remotes/juanquintela/tags/migration/20150205: fix mc146818rtc wrong subsection name to avoid vmstate_subsection_load() fail Tracify migration/rdma.c Add migration stream analyzation script migration: Append JSON description of migration stream qemu-file: Add fast ftell code path QJSON: Add JSON writer Print errors in some of the early migration failure cases. Migration: Add lots of trace events savevm: Convert fprintf to error_report vmstate-static-checker: update whitelist Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -51,6 +51,7 @@ common-obj-$(CONFIG_LINUX) += fsdev/
|
||||
common-obj-y += migration/
|
||||
common-obj-y += qemu-char.o #aio.o
|
||||
common-obj-y += page_cache.o
|
||||
common-obj-y += qjson.o
|
||||
|
||||
common-obj-$(CONFIG_SPICE) += spice-qemu-char.o
|
||||
|
||||
|
||||
+1
-1
@@ -513,7 +513,7 @@ void pci_device_save(PCIDevice *s, QEMUFile *f)
|
||||
* This makes us compatible with old devices
|
||||
* which never set or clear this bit. */
|
||||
s->config[PCI_STATUS] &= ~PCI_STATUS_INTERRUPT;
|
||||
vmstate_save_state(f, pci_get_vmstate(s), s);
|
||||
vmstate_save_state(f, pci_get_vmstate(s), s, NULL);
|
||||
/* Restore the interrupt status bit. */
|
||||
pci_update_irq_status(s);
|
||||
}
|
||||
|
||||
@@ -630,7 +630,7 @@ static void vscsi_save_request(QEMUFile *f, SCSIRequest *sreq)
|
||||
vscsi_req *req = sreq->hba_private;
|
||||
assert(req->active);
|
||||
|
||||
vmstate_save_state(f, &vmstate_spapr_vscsi_req, req);
|
||||
vmstate_save_state(f, &vmstate_spapr_vscsi_req, req, NULL);
|
||||
|
||||
DPRINTF("VSCSI: saving tag=%u, current desc#%d, offset=%x\n",
|
||||
req->qtag, req->cur_desc_num, req->cur_desc_offset);
|
||||
|
||||
@@ -734,7 +734,7 @@ static int rtc_post_load(void *opaque, int version_id)
|
||||
}
|
||||
|
||||
static const VMStateDescription vmstate_rtc_irq_reinject_on_ack_count = {
|
||||
.name = "irq_reinject_on_ack_count",
|
||||
.name = "mc146818rtc/irq_reinject_on_ack_count",
|
||||
.version_id = 1,
|
||||
.minimum_version_id = 1,
|
||||
.fields = (VMStateField[]) {
|
||||
|
||||
+1
-1
@@ -955,7 +955,7 @@ void virtio_save(VirtIODevice *vdev, QEMUFile *f)
|
||||
}
|
||||
|
||||
/* Subsections */
|
||||
vmstate_save_state(f, &vmstate_virtio, vdev);
|
||||
vmstate_save_state(f, &vmstate_virtio, vdev, NULL);
|
||||
}
|
||||
|
||||
int virtio_set_features(VirtIODevice *vdev, uint32_t val)
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#define QEMU_VM_SECTION_END 0x03
|
||||
#define QEMU_VM_SECTION_FULL 0x04
|
||||
#define QEMU_VM_SUBSECTION 0x05
|
||||
#define QEMU_VM_VMDESCRIPTION 0x06
|
||||
|
||||
struct MigrationParams {
|
||||
bool blk;
|
||||
|
||||
@@ -121,6 +121,7 @@ QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input);
|
||||
int qemu_get_fd(QEMUFile *f);
|
||||
int qemu_fclose(QEMUFile *f);
|
||||
int64_t qemu_ftell(QEMUFile *f);
|
||||
int64_t qemu_ftell_fast(QEMUFile *f);
|
||||
void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
|
||||
void qemu_put_byte(QEMUFile *f, int v);
|
||||
/*
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
#include <migration/qemu-file.h>
|
||||
#endif
|
||||
#include <qjson.h>
|
||||
|
||||
typedef void SaveStateHandler(QEMUFile *f, void *opaque);
|
||||
typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
|
||||
@@ -801,7 +802,7 @@ extern const VMStateInfo vmstate_info_bitmap;
|
||||
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
void *opaque, int version_id);
|
||||
void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
void *opaque);
|
||||
void *opaque, QJSON *vmdesc);
|
||||
|
||||
int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
|
||||
const VMStateDescription *vmsd,
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* QEMU JSON writer
|
||||
*
|
||||
* Copyright Alexander Graf
|
||||
*
|
||||
* Authors:
|
||||
* Alexander Graf <agraf@suse.de>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
#ifndef QEMU_QJSON_H
|
||||
#define QEMU_QJSON_H
|
||||
|
||||
#define TYPE_QJSON "QJSON"
|
||||
typedef struct QJSON QJSON;
|
||||
|
||||
QJSON *qjson_new(void);
|
||||
void json_prop_str(QJSON *json, const char *name, const char *str);
|
||||
void json_prop_int(QJSON *json, const char *name, int64_t val);
|
||||
void json_end_array(QJSON *json);
|
||||
void json_start_array(QJSON *json, const char *name);
|
||||
void json_end_object(QJSON *json);
|
||||
void json_start_object(QJSON *json, const char *name);
|
||||
const char *qjson_get_str(QJSON *json);
|
||||
void qjson_finish(QJSON *json);
|
||||
|
||||
#endif /* QEMU_QJSON_H */
|
||||
@@ -452,6 +452,22 @@ int qemu_get_byte(QEMUFile *f)
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t qemu_ftell_fast(QEMUFile *f)
|
||||
{
|
||||
int64_t ret = f->pos;
|
||||
int i;
|
||||
|
||||
if (f->ops->writev_buffer) {
|
||||
for (i = 0; i < f->iovcnt; i++) {
|
||||
ret += f->iov[i].iov_len;
|
||||
}
|
||||
} else {
|
||||
ret += f->buf_index;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t qemu_ftell(QEMUFile *f)
|
||||
{
|
||||
qemu_fflush(f);
|
||||
|
||||
+144
-189
File diff suppressed because it is too large
Load Diff
+204
-13
@@ -3,10 +3,12 @@
|
||||
#include "migration/qemu-file.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "qemu/bitops.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "trace.h"
|
||||
#include "qjson.h"
|
||||
|
||||
static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
void *opaque);
|
||||
void *opaque, QJSON *vmdesc);
|
||||
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
void *opaque);
|
||||
|
||||
@@ -72,16 +74,21 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
void *opaque, int version_id)
|
||||
{
|
||||
VMStateField *field = vmsd->fields;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
trace_vmstate_load_state(vmsd->name, version_id);
|
||||
if (version_id > vmsd->version_id) {
|
||||
trace_vmstate_load_state_end(vmsd->name, "too new", -EINVAL);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (version_id < vmsd->minimum_version_id) {
|
||||
if (vmsd->load_state_old &&
|
||||
version_id >= vmsd->minimum_version_id_old) {
|
||||
return vmsd->load_state_old(f, opaque, version_id);
|
||||
ret = vmsd->load_state_old(f, opaque, version_id);
|
||||
trace_vmstate_load_state_end(vmsd->name, "old path", ret);
|
||||
return ret;
|
||||
}
|
||||
trace_vmstate_load_state_end(vmsd->name, "too old", -EINVAL);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (vmsd->pre_load) {
|
||||
@@ -91,6 +98,7 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
}
|
||||
}
|
||||
while (field->name) {
|
||||
trace_vmstate_load_state_field(vmsd->name, field->name);
|
||||
if ((field->field_exists &&
|
||||
field->field_exists(opaque, version_id)) ||
|
||||
(!field->field_exists &&
|
||||
@@ -122,8 +130,8 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
}
|
||||
}
|
||||
} else if (field->flags & VMS_MUST_EXIST) {
|
||||
fprintf(stderr, "Input validation failed: %s/%s\n",
|
||||
vmsd->name, field->name);
|
||||
error_report("Input validation failed: %s/%s",
|
||||
vmsd->name, field->name);
|
||||
return -1;
|
||||
}
|
||||
field++;
|
||||
@@ -133,48 +141,203 @@ int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
return ret;
|
||||
}
|
||||
if (vmsd->post_load) {
|
||||
return vmsd->post_load(opaque, version_id);
|
||||
ret = vmsd->post_load(opaque, version_id);
|
||||
}
|
||||
return 0;
|
||||
trace_vmstate_load_state_end(vmsd->name, "end", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vmfield_name_num(VMStateField *start, VMStateField *search)
|
||||
{
|
||||
VMStateField *field;
|
||||
int found = 0;
|
||||
|
||||
for (field = start; field->name; field++) {
|
||||
if (!strcmp(field->name, search->name)) {
|
||||
if (field == search) {
|
||||
return found;
|
||||
}
|
||||
found++;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool vmfield_name_is_unique(VMStateField *start, VMStateField *search)
|
||||
{
|
||||
VMStateField *field;
|
||||
int found = 0;
|
||||
|
||||
for (field = start; field->name; field++) {
|
||||
if (!strcmp(field->name, search->name)) {
|
||||
found++;
|
||||
/* name found more than once, so it's not unique */
|
||||
if (found > 1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *vmfield_get_type_name(VMStateField *field)
|
||||
{
|
||||
const char *type = "unknown";
|
||||
|
||||
if (field->flags & VMS_STRUCT) {
|
||||
type = "struct";
|
||||
} else if (field->info->name) {
|
||||
type = field->info->name;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static bool vmsd_can_compress(VMStateField *field)
|
||||
{
|
||||
if (field->field_exists) {
|
||||
/* Dynamically existing fields mess up compression */
|
||||
return false;
|
||||
}
|
||||
|
||||
if (field->flags & VMS_STRUCT) {
|
||||
VMStateField *sfield = field->vmsd->fields;
|
||||
while (sfield->name) {
|
||||
if (!vmsd_can_compress(sfield)) {
|
||||
/* Child elements can't compress, so can't we */
|
||||
return false;
|
||||
}
|
||||
sfield++;
|
||||
}
|
||||
|
||||
if (field->vmsd->subsections) {
|
||||
/* Subsections may come and go, better don't compress */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
|
||||
VMStateField *field, int i, int max)
|
||||
{
|
||||
char *name, *old_name;
|
||||
bool is_array = max > 1;
|
||||
bool can_compress = vmsd_can_compress(field);
|
||||
|
||||
if (!vmdesc) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = g_strdup(field->name);
|
||||
|
||||
/* Field name is not unique, need to make it unique */
|
||||
if (!vmfield_name_is_unique(vmsd->fields, field)) {
|
||||
int num = vmfield_name_num(vmsd->fields, field);
|
||||
old_name = name;
|
||||
name = g_strdup_printf("%s[%d]", name, num);
|
||||
g_free(old_name);
|
||||
}
|
||||
|
||||
json_start_object(vmdesc, NULL);
|
||||
json_prop_str(vmdesc, "name", name);
|
||||
if (is_array) {
|
||||
if (can_compress) {
|
||||
json_prop_int(vmdesc, "array_len", max);
|
||||
} else {
|
||||
json_prop_int(vmdesc, "index", i);
|
||||
}
|
||||
}
|
||||
json_prop_str(vmdesc, "type", vmfield_get_type_name(field));
|
||||
|
||||
if (field->flags & VMS_STRUCT) {
|
||||
json_start_object(vmdesc, "struct");
|
||||
}
|
||||
|
||||
g_free(name);
|
||||
}
|
||||
|
||||
static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
|
||||
VMStateField *field, size_t size, int i)
|
||||
{
|
||||
if (!vmdesc) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (field->flags & VMS_STRUCT) {
|
||||
/* We printed a struct in between, close its child object */
|
||||
json_end_object(vmdesc);
|
||||
}
|
||||
|
||||
json_prop_int(vmdesc, "size", size);
|
||||
json_end_object(vmdesc);
|
||||
}
|
||||
|
||||
void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
void *opaque)
|
||||
void *opaque, QJSON *vmdesc)
|
||||
{
|
||||
VMStateField *field = vmsd->fields;
|
||||
|
||||
if (vmsd->pre_save) {
|
||||
vmsd->pre_save(opaque);
|
||||
}
|
||||
|
||||
if (vmdesc) {
|
||||
json_prop_str(vmdesc, "vmsd_name", vmsd->name);
|
||||
json_prop_int(vmdesc, "version", vmsd->version_id);
|
||||
json_start_array(vmdesc, "fields");
|
||||
}
|
||||
|
||||
while (field->name) {
|
||||
if (!field->field_exists ||
|
||||
field->field_exists(opaque, vmsd->version_id)) {
|
||||
void *base_addr = vmstate_base_addr(opaque, field, false);
|
||||
int i, n_elems = vmstate_n_elems(opaque, field);
|
||||
int size = vmstate_size(opaque, field);
|
||||
int64_t old_offset, written_bytes;
|
||||
QJSON *vmdesc_loop = vmdesc;
|
||||
|
||||
for (i = 0; i < n_elems; i++) {
|
||||
void *addr = base_addr + size * i;
|
||||
|
||||
vmsd_desc_field_start(vmsd, vmdesc_loop, field, i, n_elems);
|
||||
old_offset = qemu_ftell_fast(f);
|
||||
|
||||
if (field->flags & VMS_ARRAY_OF_POINTER) {
|
||||
addr = *(void **)addr;
|
||||
}
|
||||
if (field->flags & VMS_STRUCT) {
|
||||
vmstate_save_state(f, field->vmsd, addr);
|
||||
vmstate_save_state(f, field->vmsd, addr, vmdesc_loop);
|
||||
} else {
|
||||
field->info->put(f, addr, size);
|
||||
}
|
||||
|
||||
written_bytes = qemu_ftell_fast(f) - old_offset;
|
||||
vmsd_desc_field_end(vmsd, vmdesc_loop, field, written_bytes, i);
|
||||
|
||||
/* Compressed arrays only care about the first element */
|
||||
if (vmdesc_loop && vmsd_can_compress(field)) {
|
||||
vmdesc_loop = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (field->flags & VMS_MUST_EXIST) {
|
||||
fprintf(stderr, "Output state validation failed: %s/%s\n",
|
||||
error_report("Output state validation failed: %s/%s",
|
||||
vmsd->name, field->name);
|
||||
assert(!(field->flags & VMS_MUST_EXIST));
|
||||
}
|
||||
}
|
||||
field++;
|
||||
}
|
||||
vmstate_subsection_save(f, vmsd, opaque);
|
||||
|
||||
if (vmdesc) {
|
||||
json_end_array(vmdesc);
|
||||
}
|
||||
|
||||
vmstate_subsection_save(f, vmsd, opaque, vmdesc);
|
||||
}
|
||||
|
||||
static const VMStateDescription *
|
||||
@@ -192,6 +355,8 @@ static const VMStateDescription *
|
||||
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
void *opaque)
|
||||
{
|
||||
trace_vmstate_subsection_load(vmsd->name);
|
||||
|
||||
while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) {
|
||||
char idstr[256];
|
||||
int ret;
|
||||
@@ -201,20 +366,24 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
len = qemu_peek_byte(f, 1);
|
||||
if (len < strlen(vmsd->name) + 1) {
|
||||
/* subsection name has be be "section_name/a" */
|
||||
trace_vmstate_subsection_load_bad(vmsd->name, "(short)");
|
||||
return 0;
|
||||
}
|
||||
size = qemu_peek_buffer(f, (uint8_t *)idstr, len, 2);
|
||||
if (size != len) {
|
||||
trace_vmstate_subsection_load_bad(vmsd->name, "(peek fail)");
|
||||
return 0;
|
||||
}
|
||||
idstr[size] = 0;
|
||||
|
||||
if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) {
|
||||
trace_vmstate_subsection_load_bad(vmsd->name, idstr);
|
||||
/* it don't have a valid subsection name */
|
||||
return 0;
|
||||
}
|
||||
sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr);
|
||||
if (sub_vmsd == NULL) {
|
||||
trace_vmstate_subsection_load_bad(vmsd->name, "(lookup)");
|
||||
return -ENOENT;
|
||||
}
|
||||
qemu_file_skip(f, 1); /* subsection */
|
||||
@@ -224,31 +393,53 @@ static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
|
||||
ret = vmstate_load_state(f, sub_vmsd, opaque, version_id);
|
||||
if (ret) {
|
||||
trace_vmstate_subsection_load_bad(vmsd->name, "(child)");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
trace_vmstate_subsection_load_good(vmsd->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
|
||||
void *opaque)
|
||||
void *opaque, QJSON *vmdesc)
|
||||
{
|
||||
const VMStateSubsection *sub = vmsd->subsections;
|
||||
bool subsection_found = false;
|
||||
|
||||
while (sub && sub->needed) {
|
||||
if (sub->needed(opaque)) {
|
||||
const VMStateDescription *vmsd = sub->vmsd;
|
||||
uint8_t len;
|
||||
|
||||
if (vmdesc) {
|
||||
/* Only create subsection array when we have any */
|
||||
if (!subsection_found) {
|
||||
json_start_array(vmdesc, "subsections");
|
||||
subsection_found = true;
|
||||
}
|
||||
|
||||
json_start_object(vmdesc, NULL);
|
||||
}
|
||||
|
||||
qemu_put_byte(f, QEMU_VM_SUBSECTION);
|
||||
len = strlen(vmsd->name);
|
||||
qemu_put_byte(f, len);
|
||||
qemu_put_buffer(f, (uint8_t *)vmsd->name, len);
|
||||
qemu_put_be32(f, vmsd->version_id);
|
||||
vmstate_save_state(f, vmsd, opaque);
|
||||
vmstate_save_state(f, vmsd, opaque, vmdesc);
|
||||
|
||||
if (vmdesc) {
|
||||
json_end_object(vmdesc);
|
||||
}
|
||||
}
|
||||
sub++;
|
||||
}
|
||||
|
||||
if (vmdesc && subsection_found) {
|
||||
json_end_array(vmdesc);
|
||||
}
|
||||
}
|
||||
|
||||
/* bool */
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* QEMU JSON writer
|
||||
*
|
||||
* Copyright Alexander Graf
|
||||
*
|
||||
* Authors:
|
||||
* Alexander Graf <agraf@suse.de
|
||||
*
|
||||
* This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
|
||||
* See the COPYING.LIB file in the top-level directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <qapi/qmp/qstring.h>
|
||||
#include <stdbool.h>
|
||||
#include <glib.h>
|
||||
#include <qjson.h>
|
||||
#include <qemu/module.h>
|
||||
#include <qom/object.h>
|
||||
|
||||
struct QJSON {
|
||||
Object obj;
|
||||
QString *str;
|
||||
bool omit_comma;
|
||||
};
|
||||
|
||||
static void json_emit_element(QJSON *json, const char *name)
|
||||
{
|
||||
/* Check whether we need to print a , before an element */
|
||||
if (json->omit_comma) {
|
||||
json->omit_comma = false;
|
||||
} else {
|
||||
qstring_append(json->str, ", ");
|
||||
}
|
||||
|
||||
if (name) {
|
||||
qstring_append(json->str, "\"");
|
||||
qstring_append(json->str, name);
|
||||
qstring_append(json->str, "\" : ");
|
||||
}
|
||||
}
|
||||
|
||||
void json_start_object(QJSON *json, const char *name)
|
||||
{
|
||||
json_emit_element(json, name);
|
||||
qstring_append(json->str, "{ ");
|
||||
json->omit_comma = true;
|
||||
}
|
||||
|
||||
void json_end_object(QJSON *json)
|
||||
{
|
||||
qstring_append(json->str, " }");
|
||||
json->omit_comma = false;
|
||||
}
|
||||
|
||||
void json_start_array(QJSON *json, const char *name)
|
||||
{
|
||||
json_emit_element(json, name);
|
||||
qstring_append(json->str, "[ ");
|
||||
json->omit_comma = true;
|
||||
}
|
||||
|
||||
void json_end_array(QJSON *json)
|
||||
{
|
||||
qstring_append(json->str, " ]");
|
||||
json->omit_comma = false;
|
||||
}
|
||||
|
||||
void json_prop_int(QJSON *json, const char *name, int64_t val)
|
||||
{
|
||||
json_emit_element(json, name);
|
||||
qstring_append_int(json->str, val);
|
||||
}
|
||||
|
||||
void json_prop_str(QJSON *json, const char *name, const char *str)
|
||||
{
|
||||
json_emit_element(json, name);
|
||||
qstring_append_chr(json->str, '"');
|
||||
qstring_append(json->str, str);
|
||||
qstring_append_chr(json->str, '"');
|
||||
}
|
||||
|
||||
const char *qjson_get_str(QJSON *json)
|
||||
{
|
||||
return qstring_get_str(json->str);
|
||||
}
|
||||
|
||||
QJSON *qjson_new(void)
|
||||
{
|
||||
QJSON *json = (QJSON *)object_new(TYPE_QJSON);
|
||||
return json;
|
||||
}
|
||||
|
||||
void qjson_finish(QJSON *json)
|
||||
{
|
||||
json_end_object(json);
|
||||
}
|
||||
|
||||
static void qjson_initfn(Object *obj)
|
||||
{
|
||||
QJSON *json = (QJSON *)object_dynamic_cast(obj, TYPE_QJSON);
|
||||
assert(json);
|
||||
|
||||
json->str = qstring_from_str("{ ");
|
||||
json->omit_comma = true;
|
||||
}
|
||||
|
||||
static void qjson_finalizefn(Object *obj)
|
||||
{
|
||||
QJSON *json = (QJSON *)object_dynamic_cast(obj, TYPE_QJSON);
|
||||
|
||||
assert(json);
|
||||
qobject_decref(QOBJECT(json->str));
|
||||
}
|
||||
|
||||
static const TypeInfo qjson_type_info = {
|
||||
.name = TYPE_QJSON,
|
||||
.parent = TYPE_OBJECT,
|
||||
.instance_size = sizeof(QJSON),
|
||||
.instance_init = qjson_initfn,
|
||||
.instance_finalize = qjson_finalizefn,
|
||||
};
|
||||
|
||||
static void qjson_register_types(void)
|
||||
{
|
||||
type_register_static(&qjson_type_info);
|
||||
}
|
||||
|
||||
type_init(qjson_register_types)
|
||||
@@ -572,14 +572,34 @@ static int vmstate_load(QEMUFile *f, SaveStateEntry *se, int version_id)
|
||||
return vmstate_load_state(f, se->vmsd, se->opaque, version_id);
|
||||
}
|
||||
|
||||
static void vmstate_save(QEMUFile *f, SaveStateEntry *se)
|
||||
static void vmstate_save_old_style(QEMUFile *f, SaveStateEntry *se, QJSON *vmdesc)
|
||||
{
|
||||
int64_t old_offset, size;
|
||||
|
||||
old_offset = qemu_ftell_fast(f);
|
||||
se->ops->save_state(f, se->opaque);
|
||||
size = qemu_ftell_fast(f) - old_offset;
|
||||
|
||||
if (vmdesc) {
|
||||
json_prop_int(vmdesc, "size", size);
|
||||
json_start_array(vmdesc, "fields");
|
||||
json_start_object(vmdesc, NULL);
|
||||
json_prop_str(vmdesc, "name", "data");
|
||||
json_prop_int(vmdesc, "size", size);
|
||||
json_prop_str(vmdesc, "type", "buffer");
|
||||
json_end_object(vmdesc);
|
||||
json_end_array(vmdesc);
|
||||
}
|
||||
}
|
||||
|
||||
static void vmstate_save(QEMUFile *f, SaveStateEntry *se, QJSON *vmdesc)
|
||||
{
|
||||
trace_vmstate_save(se->idstr, se->vmsd ? se->vmsd->name : "(old)");
|
||||
if (!se->vmsd) { /* Old style */
|
||||
se->ops->save_state(f, se->opaque);
|
||||
if (!se->vmsd) {
|
||||
vmstate_save_old_style(f, se, vmdesc);
|
||||
return;
|
||||
}
|
||||
vmstate_save_state(f, se->vmsd, se->opaque);
|
||||
vmstate_save_state(f, se->vmsd, se->opaque, vmdesc);
|
||||
}
|
||||
|
||||
bool qemu_savevm_state_blocked(Error **errp)
|
||||
@@ -674,7 +694,7 @@ int qemu_savevm_state_iterate(QEMUFile *f)
|
||||
qemu_put_be32(f, se->section_id);
|
||||
|
||||
ret = se->ops->save_live_iterate(f, se->opaque);
|
||||
trace_savevm_section_end(se->idstr, se->section_id);
|
||||
trace_savevm_section_end(se->idstr, se->section_id, ret);
|
||||
|
||||
if (ret < 0) {
|
||||
qemu_file_set_error(f, ret);
|
||||
@@ -692,6 +712,8 @@ int qemu_savevm_state_iterate(QEMUFile *f)
|
||||
|
||||
void qemu_savevm_state_complete(QEMUFile *f)
|
||||
{
|
||||
QJSON *vmdesc;
|
||||
int vmdesc_len;
|
||||
SaveStateEntry *se;
|
||||
int ret;
|
||||
|
||||
@@ -714,13 +736,16 @@ void qemu_savevm_state_complete(QEMUFile *f)
|
||||
qemu_put_be32(f, se->section_id);
|
||||
|
||||
ret = se->ops->save_live_complete(f, se->opaque);
|
||||
trace_savevm_section_end(se->idstr, se->section_id);
|
||||
trace_savevm_section_end(se->idstr, se->section_id, ret);
|
||||
if (ret < 0) {
|
||||
qemu_file_set_error(f, ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
vmdesc = qjson_new();
|
||||
json_prop_int(vmdesc, "page_size", TARGET_PAGE_SIZE);
|
||||
json_start_array(vmdesc, "devices");
|
||||
QTAILQ_FOREACH(se, &savevm_handlers, entry) {
|
||||
int len;
|
||||
|
||||
@@ -728,6 +753,11 @@ void qemu_savevm_state_complete(QEMUFile *f)
|
||||
continue;
|
||||
}
|
||||
trace_savevm_section_start(se->idstr, se->section_id);
|
||||
|
||||
json_start_object(vmdesc, NULL);
|
||||
json_prop_str(vmdesc, "name", se->idstr);
|
||||
json_prop_int(vmdesc, "instance_id", se->instance_id);
|
||||
|
||||
/* Section type */
|
||||
qemu_put_byte(f, QEMU_VM_SECTION_FULL);
|
||||
qemu_put_be32(f, se->section_id);
|
||||
@@ -740,11 +770,23 @@ void qemu_savevm_state_complete(QEMUFile *f)
|
||||
qemu_put_be32(f, se->instance_id);
|
||||
qemu_put_be32(f, se->version_id);
|
||||
|
||||
vmstate_save(f, se);
|
||||
trace_savevm_section_end(se->idstr, se->section_id);
|
||||
vmstate_save(f, se, vmdesc);
|
||||
|
||||
json_end_object(vmdesc);
|
||||
trace_savevm_section_end(se->idstr, se->section_id, 0);
|
||||
}
|
||||
|
||||
qemu_put_byte(f, QEMU_VM_EOF);
|
||||
|
||||
json_end_array(vmdesc);
|
||||
qjson_finish(vmdesc);
|
||||
vmdesc_len = strlen(qjson_get_str(vmdesc));
|
||||
|
||||
qemu_put_byte(f, QEMU_VM_VMDESCRIPTION);
|
||||
qemu_put_be32(f, vmdesc_len);
|
||||
qemu_put_buffer(f, (uint8_t *)qjson_get_str(vmdesc), vmdesc_len);
|
||||
object_unref(OBJECT(vmdesc));
|
||||
|
||||
qemu_fflush(f);
|
||||
}
|
||||
|
||||
@@ -843,7 +885,7 @@ static int qemu_save_device_state(QEMUFile *f)
|
||||
qemu_put_be32(f, se->instance_id);
|
||||
qemu_put_be32(f, se->version_id);
|
||||
|
||||
vmstate_save(f, se);
|
||||
vmstate_save(f, se, NULL);
|
||||
}
|
||||
|
||||
qemu_put_byte(f, QEMU_VM_EOF);
|
||||
@@ -883,25 +925,30 @@ int qemu_loadvm_state(QEMUFile *f)
|
||||
QLIST_HEAD(, LoadStateEntry) loadvm_handlers =
|
||||
QLIST_HEAD_INITIALIZER(loadvm_handlers);
|
||||
LoadStateEntry *le, *new_le;
|
||||
Error *local_err = NULL;
|
||||
uint8_t section_type;
|
||||
unsigned int v;
|
||||
int ret;
|
||||
|
||||
if (qemu_savevm_state_blocked(NULL)) {
|
||||
if (qemu_savevm_state_blocked(&local_err)) {
|
||||
error_report("%s", error_get_pretty(local_err));
|
||||
error_free(local_err);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
v = qemu_get_be32(f);
|
||||
if (v != QEMU_VM_FILE_MAGIC) {
|
||||
error_report("Not a migration stream");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
v = qemu_get_be32(f);
|
||||
if (v == QEMU_VM_FILE_VERSION_COMPAT) {
|
||||
fprintf(stderr, "SaveVM v2 format is obsolete and don't work anymore\n");
|
||||
error_report("SaveVM v2 format is obsolete and don't work anymore");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
if (v != QEMU_VM_FILE_VERSION) {
|
||||
error_report("Unsupported migration stream version");
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
@@ -911,6 +958,7 @@ int qemu_loadvm_state(QEMUFile *f)
|
||||
char idstr[257];
|
||||
int len;
|
||||
|
||||
trace_qemu_loadvm_state_section(section_type);
|
||||
switch (section_type) {
|
||||
case QEMU_VM_SECTION_START:
|
||||
case QEMU_VM_SECTION_FULL:
|
||||
@@ -922,18 +970,21 @@ int qemu_loadvm_state(QEMUFile *f)
|
||||
instance_id = qemu_get_be32(f);
|
||||
version_id = qemu_get_be32(f);
|
||||
|
||||
trace_qemu_loadvm_state_section_startfull(section_id, idstr,
|
||||
instance_id, version_id);
|
||||
/* Find savevm section */
|
||||
se = find_se(idstr, instance_id);
|
||||
if (se == NULL) {
|
||||
fprintf(stderr, "Unknown savevm section or instance '%s' %d\n", idstr, instance_id);
|
||||
error_report("Unknown savevm section or instance '%s' %d",
|
||||
idstr, instance_id);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Validate version */
|
||||
if (version_id > se->version_id) {
|
||||
fprintf(stderr, "savevm: unsupported version %d for '%s' v%d\n",
|
||||
version_id, idstr, se->version_id);
|
||||
error_report("savevm: unsupported version %d for '%s' v%d",
|
||||
version_id, idstr, se->version_id);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -948,8 +999,8 @@ int qemu_loadvm_state(QEMUFile *f)
|
||||
|
||||
ret = vmstate_load(f, le->se, le->version_id);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "qemu: warning: error while loading state for instance 0x%x of device '%s'\n",
|
||||
instance_id, idstr);
|
||||
error_report("error while loading state for instance 0x%x of"
|
||||
" device '%s'", instance_id, idstr);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
@@ -957,26 +1008,27 @@ int qemu_loadvm_state(QEMUFile *f)
|
||||
case QEMU_VM_SECTION_END:
|
||||
section_id = qemu_get_be32(f);
|
||||
|
||||
trace_qemu_loadvm_state_section_partend(section_id);
|
||||
QLIST_FOREACH(le, &loadvm_handlers, entry) {
|
||||
if (le->section_id == section_id) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (le == NULL) {
|
||||
fprintf(stderr, "Unknown savevm section %d\n", section_id);
|
||||
error_report("Unknown savevm section %d", section_id);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = vmstate_load(f, le->se, le->version_id);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "qemu: warning: error while loading state section id %d\n",
|
||||
section_id);
|
||||
error_report("error while loading state section id %d(%s)",
|
||||
section_id, le->se->idstr);
|
||||
goto out;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown savevm section type %d\n", section_type);
|
||||
error_report("Unknown savevm section type %d", section_type);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
Executable
+592
File diff suppressed because it is too large
Load Diff
@@ -53,6 +53,8 @@ def check_fields_match(name, s_field, d_field):
|
||||
'parent_obj.parent_obj.parent_obj',
|
||||
'port.br.dev.exp.aer_log',
|
||||
'parent_obj.parent_obj.parent_obj.exp.aer_log'],
|
||||
'cirrus_vga': ['hw_cursor_x', 'vga.hw_cursor_x',
|
||||
'hw_cursor_y', 'vga.hw_cursor_y'],
|
||||
'lsiscsi': ['dev', 'parent_obj'],
|
||||
'mch': ['d', 'parent_obj'],
|
||||
'pci_bridge': ['bridge.dev', 'parent_obj', 'bridge.dev.shpc', 'shpc'],
|
||||
|
||||
+2
-1
@@ -266,7 +266,8 @@ tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
|
||||
libqemuutil.a libqemustub.a
|
||||
tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
|
||||
migration/vmstate.o migration/qemu-file.o migration/qemu-file-buf.o \
|
||||
migration/qemu-file-unix.o \
|
||||
migration/qemu-file-unix.o qjson.o \
|
||||
$(qom-core-obj) \
|
||||
libqemuutil.a libqemustub.a
|
||||
|
||||
tests/test-qapi-types.c tests/test-qapi-types.h :\
|
||||
|
||||
@@ -85,7 +85,7 @@ static void save_vmstate(const VMStateDescription *desc, void *obj)
|
||||
QEMUFile *f = open_test_file(true);
|
||||
|
||||
/* Save file with vmstate */
|
||||
vmstate_save_state(f, desc, obj);
|
||||
vmstate_save_state(f, desc, obj, NULL);
|
||||
qemu_put_byte(f, QEMU_VM_EOF);
|
||||
g_assert(!qemu_file_get_error(f));
|
||||
qemu_fclose(f);
|
||||
@@ -394,7 +394,7 @@ static void test_save_noskip(void)
|
||||
QEMUFile *fsave = qemu_bufopen("w", NULL);
|
||||
TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
|
||||
.skip_c_e = false };
|
||||
vmstate_save_state(fsave, &vmstate_skipping, &obj);
|
||||
vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL);
|
||||
g_assert(!qemu_file_get_error(fsave));
|
||||
|
||||
uint8_t expected[] = {
|
||||
@@ -414,7 +414,7 @@ static void test_save_skip(void)
|
||||
QEMUFile *fsave = qemu_bufopen("w", NULL);
|
||||
TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
|
||||
.skip_c_e = true };
|
||||
vmstate_save_state(fsave, &vmstate_skipping, &obj);
|
||||
vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL);
|
||||
g_assert(!qemu_file_get_error(fsave));
|
||||
|
||||
uint8_t expected[] = {
|
||||
|
||||
+72
-1
@@ -1142,8 +1142,11 @@ vmware_scratch_write(uint32_t index, uint32_t value) "index %d, value 0x%x"
|
||||
vmware_setmode(uint32_t w, uint32_t h, uint32_t bpp) "%dx%d @ %d bpp"
|
||||
|
||||
# savevm.c
|
||||
qemu_loadvm_state_section(unsigned int section_type) "%d"
|
||||
qemu_loadvm_state_section_partend(uint32_t section_id) "%u"
|
||||
qemu_loadvm_state_section_startfull(uint32_t section_id, const char *idstr, uint32_t instance_id, uint32_t version_id) "%u(%s) %u %u"
|
||||
savevm_section_start(const char *id, unsigned int section_id) "%s, section_id %u"
|
||||
savevm_section_end(const char *id, unsigned int section_id) "%s, section_id %u"
|
||||
savevm_section_end(const char *id, unsigned int section_id, int ret) "%s, section_id %u -> %d"
|
||||
savevm_state_begin(void) ""
|
||||
savevm_state_iterate(void) ""
|
||||
savevm_state_complete(void) ""
|
||||
@@ -1154,6 +1157,12 @@ qemu_announce_self_iter(const char *mac) "%s"
|
||||
|
||||
# vmstate.c
|
||||
vmstate_load_field_error(const char *field, int ret) "field \"%s\" load failed, ret = %d"
|
||||
vmstate_load_state(const char *name, int version_id) "%s v%d"
|
||||
vmstate_load_state_end(const char *name, const char *reason, int val) "%s %s/%d"
|
||||
vmstate_load_state_field(const char *name, const char *field) "%s:%s"
|
||||
vmstate_subsection_load(const char *parent) "%s"
|
||||
vmstate_subsection_load_bad(const char *parent, const char *sub) "%s: %s"
|
||||
vmstate_subsection_load_good(const char *parent) "%s"
|
||||
|
||||
# qemu-file.c
|
||||
qemu_file_fclose(void) ""
|
||||
@@ -1326,6 +1335,68 @@ migrate_fd_cancel(void) ""
|
||||
migrate_pending(uint64_t size, uint64_t max) "pending size %" PRIu64 " max %" PRIu64
|
||||
migrate_transferred(uint64_t tranferred, uint64_t time_spent, double bandwidth, uint64_t size) "transferred %" PRIu64 " time_spent %" PRIu64 " bandwidth %g max_size %" PRId64
|
||||
|
||||
# migration/rdma.c
|
||||
__qemu_rdma_add_block(int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Added Block: %d, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
|
||||
__qemu_rdma_delete_block(int block, uint64_t addr, uint64_t offset, uint64_t len, uint64_t end, uint64_t bits, int chunks) "Deleted Block: %d, addr: %" PRIu64 ", offset: %" PRIu64 " length: %" PRIu64 " end: %" PRIu64 " bits %" PRIu64 " chunks %d"
|
||||
qemu_dma_accept_incoming_migration(void) ""
|
||||
qemu_dma_accept_incoming_migration_accepted(void) ""
|
||||
qemu_rdma_accept_pin_state(bool pin) "%d"
|
||||
qemu_rdma_accept_pin_verbsc(void *verbs) "Verbs context after listen: %p"
|
||||
qemu_rdma_block_for_wrid_miss(const char *wcompstr, int wcomp, const char *gcompstr, uint64_t req) "A Wanted wrid %s (%d) but got %s (%" PRIu64 ")"
|
||||
qemu_rdma_block_for_wrid_miss_b(const char *wcompstr, int wcomp, const char *gcompstr, uint64_t req) "B Wanted wrid %s (%d) but got %s (%" PRIu64 ")"
|
||||
qemu_rdma_cleanup_disconnect(void) ""
|
||||
qemu_rdma_cleanup_waiting_for_disconnect(void) ""
|
||||
qemu_rdma_close(void) ""
|
||||
qemu_rdma_connect_pin_all_requested(void) ""
|
||||
qemu_rdma_connect_pin_all_outcome(bool pin) "%d"
|
||||
qemu_rdma_dest_init_trying(const char *host, const char *ip) "%s => %s"
|
||||
qemu_rdma_dump_gid(const char *who, const char *src, const char *dst) "%s Source GID: %s, Dest GID: %s"
|
||||
qemu_rdma_exchange_get_response_start(const char *desc) "CONTROL: %s receiving..."
|
||||
qemu_rdma_exchange_get_response_none(const char *desc, int type) "Surprise: got %s (%d)"
|
||||
qemu_rdma_exchange_send_issue_callback(void) ""
|
||||
qemu_rdma_exchange_send_waiting(const char *desc) "Waiting for response %s"
|
||||
qemu_rdma_exchange_send_received(const char *desc) "Response %s received."
|
||||
qemu_rdma_fill(int64_t control_len, int size) "RDMA %" PRId64 " of %d bytes already in buffer"
|
||||
qemu_rdma_init_ram_blocks(int blocks) "Allocated %d local ram block structures"
|
||||
qemu_rdma_poll_recv(const char *compstr, int64_t comp, int64_t id, int sent) "completion %s #%" PRId64 " received (%" PRId64 ") left %d"
|
||||
qemu_rdma_poll_write(const char *compstr, int64_t comp, int left, uint64_t block, uint64_t chunk, void *local, void *remote) "completions %s (%" PRId64 ") left %d, block %" PRIu64 ", chunk: %" PRIu64 " %p %p"
|
||||
qemu_rdma_poll_other(const char *compstr, int64_t comp, int left) "other completion %s (%" PRId64 ") received left %d"
|
||||
qemu_rdma_post_send_control(const char *desc) "CONTROL: sending %s.."
|
||||
qemu_rdma_register_and_get_keys(uint64_t len, void *start) "Registering %" PRIu64 " bytes @ %p"
|
||||
qemu_rdma_registration_handle_compress(int64_t length, int index, int64_t offset) "Zapping zero chunk: %" PRId64 " bytes, index %d, offset %" PRId64
|
||||
qemu_rdma_registration_handle_finished(void) ""
|
||||
qemu_rdma_registration_handle_ram_blocks(void) ""
|
||||
qemu_rdma_registration_handle_register(int requests) "%d requests"
|
||||
qemu_rdma_registration_handle_register_loop(int req, int index, uint64_t addr, uint64_t chunks) "Registration request (%d): index %d, current_addr %" PRIu64 " chunks: %" PRIu64
|
||||
qemu_rdma_registration_handle_register_rkey(int rkey) "%x"
|
||||
qemu_rdma_registration_handle_unregister(int requests) "%d requests"
|
||||
qemu_rdma_registration_handle_unregister_loop(int count, int index, uint64_t chunk) "Unregistration request (%d): index %d, chunk %" PRIu64
|
||||
qemu_rdma_registration_handle_unregister_success(uint64_t chunk) "%" PRIu64
|
||||
qemu_rdma_registration_handle_wait(uint64_t flags) "Waiting for next request %" PRIu64
|
||||
qemu_rdma_registration_start(uint64_t flags) "%" PRIu64
|
||||
qemu_rdma_registration_stop(uint64_t flags) "%" PRIu64
|
||||
qemu_rdma_registration_stop_ram(void) ""
|
||||
qemu_rdma_resolve_host_trying(const char *host, const char *ip) "Trying %s => %s"
|
||||
qemu_rdma_signal_unregister_append(uint64_t chunk, int pos) "Appending unregister chunk %" PRIu64 " at position %d"
|
||||
qemu_rdma_signal_unregister_already(uint64_t chunk) "Unregister chunk %" PRIu64 " already in queue"
|
||||
qemu_rdma_unregister_waiting_inflight(uint64_t chunk) "Cannot unregister inflight chunk: %" PRIu64
|
||||
qemu_rdma_unregister_waiting_proc(uint64_t chunk, int pos) "Processing unregister for chunk: %" PRIu64 " at position %d"
|
||||
qemu_rdma_unregister_waiting_send(uint64_t chunk) "Sending unregister for chunk: %" PRIu64
|
||||
qemu_rdma_unregister_waiting_complete(uint64_t chunk) "Unregister for chunk: %" PRIu64 " complete."
|
||||
qemu_rdma_write_flush(int sent) "sent total: %d"
|
||||
qemu_rdma_write_one_block(int count, int block, uint64_t chunk, uint64_t current, uint64_t len, int nb_sent, int nb_chunks) "(%d) Not clobbering: block: %d chunk %" PRIu64 " current %" PRIu64 " len %" PRIu64 " %d %d"
|
||||
qemu_rdma_write_one_post(uint64_t chunk, long addr, long remote, uint32_t len) "Posting chunk: %" PRIu64 ", addr: %lx remote: %lx, bytes %" PRIu32
|
||||
qemu_rdma_write_one_queue_full(void) ""
|
||||
qemu_rdma_write_one_recvregres(int mykey, int theirkey, uint64_t chunk) "Received registration result: my key: %x their key %x, chunk %" PRIu64
|
||||
qemu_rdma_write_one_sendreg(uint64_t chunk, int len, int index, int64_t offset) "Sending registration request chunk %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
|
||||
qemu_rdma_write_one_top(uint64_t chunks, uint64_t size) "Writing %" PRIu64 " chunks, (%" PRIu64 " MB)"
|
||||
qemu_rdma_write_one_zero(uint64_t chunk, int len, int index, int64_t offset) "Entire chunk is zero, sending compress: %" PRIu64 " for %d bytes, index: %d, offset: %" PRId64
|
||||
rdma_start_incoming_migration(void) ""
|
||||
rdma_start_incoming_migration_after_dest_init(void) ""
|
||||
rdma_start_incoming_migration_after_rdma_listen(void) ""
|
||||
rdma_start_outgoing_migration_after_rdma_connect(void) ""
|
||||
rdma_start_outgoing_migration_after_rdma_source_init(void) ""
|
||||
|
||||
# kvm-all.c
|
||||
kvm_ioctl(int type, void *arg) "type 0x%x, arg %p"
|
||||
kvm_vm_ioctl(int type, void *arg) "type 0x%x, arg %p"
|
||||
|
||||
Reference in New Issue
Block a user