*/
#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "migration.h"
#include "migration/vmstate.h"
#include "savevm.h"
static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque);
-static int vmstate_n_elems(void *opaque, VMStateField *field)
+static int vmstate_n_elems(void *opaque, const VMStateField *field)
{
int n_elems = 1;
return n_elems;
}
-static int vmstate_size(void *opaque, VMStateField *field)
+static int vmstate_size(void *opaque, const VMStateField *field)
{
int size = field->size;
return size;
}
-static void vmstate_handle_alloc(void *ptr, VMStateField *field, void *opaque)
+static void vmstate_handle_alloc(void *ptr, const VMStateField *field,
+ void *opaque)
{
if (field->flags & VMS_POINTER && field->flags & VMS_ALLOC) {
gsize size = vmstate_size(opaque, field);
int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
void *opaque, int version_id)
{
- VMStateField *field = vmsd->fields;
+ const VMStateField *field = vmsd->fields;
int ret = 0;
trace_vmstate_load_state(vmsd->name, version_id);
return ret;
}
-static int vmfield_name_num(VMStateField *start, VMStateField *search)
+static int vmfield_name_num(const VMStateField *start,
+ const VMStateField *search)
{
- VMStateField *field;
+ const VMStateField *field;
int found = 0;
for (field = start; field->name; field++) {
return -1;
}
-static bool vmfield_name_is_unique(VMStateField *start, VMStateField *search)
+static bool vmfield_name_is_unique(const VMStateField *start,
+ const VMStateField *search)
{
- VMStateField *field;
+ const VMStateField *field;
int found = 0;
for (field = start; field->name; field++) {
return true;
}
-static const char *vmfield_get_type_name(VMStateField *field)
+static const char *vmfield_get_type_name(const VMStateField *field)
{
const char *type = "unknown";
return type;
}
-static bool vmsd_can_compress(VMStateField *field)
+static bool vmsd_can_compress(const VMStateField *field)
{
if (field->field_exists) {
/* Dynamically existing fields mess up compression */
}
if (field->flags & VMS_STRUCT) {
- VMStateField *sfield = field->vmsd->fields;
+ const VMStateField *sfield = field->vmsd->fields;
while (sfield->name) {
if (!vmsd_can_compress(sfield)) {
/* Child elements can't compress, so can't we */
}
static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
- VMStateField *field, int i, int max)
+ const VMStateField *field, int i, int max)
{
char *name, *old_name;
bool is_array = max > 1;
}
static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
- VMStateField *field, size_t size, int i)
+ const VMStateField *field, size_t size, int i)
{
if (!vmdesc) {
return;
void *opaque, QJSON *vmdesc, int version_id)
{
int ret = 0;
- VMStateField *field = vmsd->fields;
+ const VMStateField *field = vmsd->fields;
trace_vmstate_save_state_top(vmsd->name);
if (ret) {
error_report("Save of field %s/%s failed",
vmsd->name, field->name);
+ if (vmsd->post_save) {
+ vmsd->post_save(opaque);
+ }
return ret;
}
json_end_array(vmdesc);
}
- return vmstate_subsection_save(f, vmsd, opaque, vmdesc);
+ ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc);
+
+ if (vmsd->post_save) {
+ int ps_ret = vmsd->post_save(opaque);
+ if (!ret) {
+ ret = ps_ret;
+ }
+ }
+ return ret;
}
static const VMStateDescription *
vmstate_get_subsection(const VMStateDescription **sub, char *idstr)
{
- while (sub && *sub && (*sub)->needed) {
+ while (sub && *sub) {
if (strcmp(idstr, (*sub)->name) == 0) {
return *sub;
}
void *opaque, QJSON *vmdesc)
{
const VMStateDescription **sub = vmsd->subsections;
- bool subsection_found = false;
+ bool vmdesc_has_subsections = false;
int ret = 0;
trace_vmstate_subsection_save_top(vmsd->name);
- while (sub && *sub && (*sub)->needed) {
- if ((*sub)->needed(opaque)) {
+ while (sub && *sub) {
+ if (vmstate_save_needed(*sub, opaque)) {
const VMStateDescription *vmsdsub = *sub;
uint8_t len;
trace_vmstate_subsection_save_loop(vmsd->name, vmsdsub->name);
if (vmdesc) {
/* Only create subsection array when we have any */
- if (!subsection_found) {
+ if (!vmdesc_has_subsections) {
json_start_array(vmdesc, "subsections");
- subsection_found = true;
+ vmdesc_has_subsections = true;
}
json_start_object(vmdesc, NULL);
sub++;
}
- if (vmdesc && subsection_found) {
+ if (vmdesc_has_subsections) {
json_end_array(vmdesc);
}