qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] vmstate: struct (VMS_STRUCT) migration


From: Alexey Kardashevskiy
Subject: [Qemu-devel] vmstate: struct (VMS_STRUCT) migration
Date: Wed, 25 Jun 2014 16:36:59 +1000
User-agent: Mozilla/5.0 (X11; Linux i686 on x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.6.0

Hi!

VMStateDescription supports enclosed VMStateDescription's via .vmsd. This
is used in multiple places and VMStateDescription definitions look the same
way - name, version_id, minimum_version_id, etc.

QEMU handles first level VMStateDescription and enclosed VMStateDescription
slightly different - for the latter it ignores the version_id from the
source and always uses the version_id on the destination side so version
fields are useless (code is below).

Is that by design? Or a bug? I cannot see how we could fix it without
breaking backward compatibility but I am sure the community does know that :)

If this is by design, it probably makes sense to remove unused
version_id/minimum_version_id fields completely for vmsd's which we know
are enclosed (or embedded?).

What do I miss here? Thanks!



int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
                       void *opaque, int version_id)
{
    VMStateField *field = vmsd->fields;
    int ret;

    if (version_id > vmsd->version_id) {
        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);
        }
        return -EINVAL;
    }
    if (vmsd->pre_load) {
        int ret = vmsd->pre_load(opaque);
        if (ret) {
            return ret;
        }
    }
    while (field->name) {
        if ((field->field_exists &&
             field->field_exists(opaque, version_id)) ||
            (!field->field_exists &&
             field->version_id <= version_id)) {
            void *base_addr = vmstate_base_addr(opaque, field, true);
            int i, n_elems = vmstate_n_elems(opaque, field);
            int size = vmstate_size(opaque, field);

            for (i = 0; i < n_elems; i++) {
                void *addr = base_addr + size * i;

                if (field->flags & VMS_ARRAY_OF_POINTER) {
                    addr = *(void **)addr;
                }
                if (field->flags & VMS_STRUCT) {
                    ret = vmstate_load_state(f, field->vmsd, addr,
                                             field->vmsd->version_id);



-- 
Alexey



reply via email to

[Prev in Thread] Current Thread [Next in Thread]