On 12/21/2011 03:45 PM, Anthony Liguori wrote:
On 12/21/2011 06:35 AM, Paolo Bonzini wrote:
On 12/20/2011 09:56 PM, Anthony Liguori wrote:
As always, you can implement that in many ways. However, I think the
point of using Visitors is not to remove QEMUFile.
Yes, it is.
The point of using Visitors is to provide a standard representation of
device
state. QEMUFile is but one consumer of that representation, along with
any other
migration filter.
Can you do a quick code mock up of how you'd expect this to work?
void
vmstate_get(Device *obj, Visitor *v, void *opaque, const char *name)
{
/* Use the VMStateDescription in opaque to add fields to Visitor
from the struct. */
}
void
vmstate_set(Device *obj, Visitor *v, void *opaque, const char *name)
{
/* Use the VMStateDescription in opaque to retrieve fields from
Visitor and store them in the struct. */
}
void
vmstate_load_state(Device *obj, Visitor *v, QEMUFile )
{
VMStateDescription *vmsd = ???; /* something from the DeviceClass */
/* Use the VMStateDescription in opaque to retrieve fields from
Visitor and store them in the struct. This is basically the
VMState interpreter currently in savevm.c, only fetching fields
from v rather than the file. */
}
void
vmstate_save_state(Device *obj, Visitor *v, QEMUFile *out)
{
VMStateDescription *vmsd = ???; /* something from the DeviceClass */
/* Use the VMStateDescription in opaque to fetch fields from
Visitor and store them in the file. This is basically the
other VMState interpreter currently in savevm.c, but fetching
fields from v rather than the struct. */
}
void
qdev_add_vmstate(Device *obj, VMStateDescription *vmsd)
{
qdev_add_property(obj, "vmstate", vmstate_get, vmstate_set, vmsd);
qdev_add_interface(obj, "QEMUFileSerializable", vmstate_load_state,
vmstate_save_state);
}
savevm.c:
Visitor *v = qmp_output_visitor_new();
qdev_property_get(obj, "vmstate", v);
QObject *qobj = qmp_visitor_get_obj(v);
qmp_visitor_free(v);
Visitor *v = qmp_input_visitor_new(qobj);
QEMUFileSerializable *s = QEMU_FILE_SERIALIZABLE(obj);
s->save_state(obj, v, outfile);
qmp_visitor_free(v);
...
Visitor *v = qmp_output_visitor_new();
QEMUFileSerializable *s = QEMU_FILE_SERIALIZABLE(obj);
s->load_state(obj, v, outfile);
QObject *qobj = qmp_visitor_get_obj(v);
qmp_visitor_free(v);
Visitor *v = qmp_input_visitor_new(qobj);
QEMUFileSerializable *s = QEMU_FILE_SERIALIZABLE(obj);
qdev_property_set(obj, "vmstate", v);
qmp_visitor_free(v);
---------------------
Yes, this makes QEMUFile serialization special. But that's because it's legacy,
and it needs to do strange things and store things beyond the contents of the
vmstate.
Take for example "unused" fields. In Mike's implementation, if you try to pass a
QMPOutputVisitor to save_state you might get a "unused" entry that is an array
of zeros. I have no idea what happens if a single VMStateDescription has more
than one VMSTATE_UNUSED field. QEMUFileOutputVisitor completely ignores the
field names, so it probably works but would break with QMPOutputVisitor.
Other serialization backends should not need any hooks in the devices beyond
save_state and load_state.
Paolo