qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH RESEND v5 2/6] Introduce "save_devices"


From: Stefano Stabellini
Subject: Re: [Qemu-devel] [PATCH RESEND v5 2/6] Introduce "save_devices"
Date: Tue, 13 Mar 2012 11:51:56 +0000
User-agent: Alpine 2.00 (DEB 1167 2008-08-23)

On Mon, 12 Mar 2012, Anthony Liguori wrote:
> On 02/28/2012 09:51 AM, Stefano Stabellini wrote:
> > - add an "is_ram" flag to SaveStateEntry;
> >
> > - add an "is_ram" parameter to register_savevm_live;
> >
> > - introduce a "save_devices" monitor command that can be used to save
> > the state of non-ram devices.
> >
> > Signed-off-by: Stefano Stabellini<address@hidden>
> > ---
> >   block-migration.c |    2 +-
> >   hmp-commands.hx   |   14 ++++++++++
> >   qmp-commands.hx   |   17 ++++++++++++
> >   savevm.c          |   72 
> > ++++++++++++++++++++++++++++++++++++++++++++++++++++-
> >   sysemu.h          |    1 +
> >   vl.c              |    2 +-
> >   vmstate.h         |    1 +
> >   7 files changed, 106 insertions(+), 3 deletions(-)
> >
> > diff --git a/block-migration.c b/block-migration.c
> > index 4467468..d283fd0 100644
> > --- a/block-migration.c
> > +++ b/block-migration.c
> > @@ -722,6 +722,6 @@ void blk_mig_init(void)
> >       QSIMPLEQ_INIT(&block_mig_state.bmds_list);
> >       QSIMPLEQ_INIT(&block_mig_state.blk_list);
> >
> > -    register_savevm_live(NULL, "block", 0, 1, block_set_params,
> > +    register_savevm_live(NULL, "block", 0, 1, 0, block_set_params,
> >                            block_save_live, NULL, 
> > block_load,&block_mig_state);
> 
> Do you really want the block live migration to be part of Xen?
> 
> If not, then you can simplify by just making register_savevm_live always 
> imply 
> !device and adjust register_savevm() accordingly.  Otherwise, the likelihood 
> of 
> a casual observer knowing what '0, 1, 0' means is pretty bad...

That's a good point, I'll do that.


> >   }
> > diff --git a/hmp-commands.hx b/hmp-commands.hx
> > index 64b3656..873abc9 100644
> > --- a/hmp-commands.hx
> > +++ b/hmp-commands.hx
> > @@ -280,6 +280,20 @@ a snapshot with the same tag or ID, it is replaced. 
> > More info at
> >   ETEXI
> >
> >       {
> > +        .name       = "save_devices",
> > +        .args_type  = "filename:F",
> > +        .params     = "filename",
> > +        .help       = "save the state of non-ram devices.",
> > +        .mhandler.cmd_new = do_save_device_state,
> > +    },
> > +
> > +STEXI
> > address@hidden save_devices @var{filename}
> > address@hidden save_devices
> > +Save the state of non-ram devices.
> > +ETEXI
> > +
> > +    {
> >           .name       = "loadvm",
> >           .args_type  = "name:s",
> >           .params     = "tag|id",
> > diff --git a/qmp-commands.hx b/qmp-commands.hx
> > index 705f704..619d9de 100644
> > --- a/qmp-commands.hx
> > +++ b/qmp-commands.hx
> > @@ -444,6 +444,23 @@ Note: inject-nmi is only supported for x86 guest 
> > currently, it will
> >   EQMP
> >
> >       {
> > +        .name       = "save_devices",
> > +        .args_type  = "filename:F",
> > +        .params     = "filename",
> > +        .help       = "save the state of non-ram devices.",
> > +        .user_print = monitor_user_noop,   
> > +    .mhandler.cmd_new = do_save_device_state,
> > +    },
> > +
> > +SQMP
> > +save_devices
> > +-------
> > +
> > +Save the state of non-ram devices.
> > +
> > +EQMP
> > +
> > +    {
> >           .name       = "migrate",
> >           .args_type  = "detach:-d,blk:-b,inc:-i,uri:s",
> >           .params     = "[-d] [-b] [-i] uri",
> 
> 
> Should be QAPI commands and documented a great deal more (see other examples 
> in 
> qapi-schema.json).  Please CC Luiz too when adding new QMP commands.

OK, I'll do.


> > diff --git a/savevm.c b/savevm.c
> > index 80be1ff..d0e62bb 100644
> > --- a/savevm.c
> > +++ b/savevm.c
> > @@ -1177,6 +1177,7 @@ typedef struct SaveStateEntry {
> >       void *opaque;
> >       CompatEntry *compat;
> >       int no_migrate;
> > +    int is_ram;
> >   } SaveStateEntry;
> >
> >
> > @@ -1223,6 +1224,7 @@ int register_savevm_live(DeviceState *dev,
> >                            const char *idstr,
> >                            int instance_id,
> >                            int version_id,
> > +                         int is_ram,
> >                            SaveSetParamsHandler *set_params,
> >                            SaveLiveStateHandler *save_live_state,
> >                            SaveStateHandler *save_state,
> > @@ -1241,6 +1243,7 @@ int register_savevm_live(DeviceState *dev,
> >       se->opaque = opaque;
> >       se->vmsd = NULL;
> >       se->no_migrate = 0;
> > +    se->is_ram = is_ram;
> >
> >       if (dev&&  dev->parent_bus&&  dev->parent_bus->info->get_dev_path) {
> >           char *id = dev->parent_bus->info->get_dev_path(dev);
> > @@ -1277,7 +1280,7 @@ int register_savevm(DeviceState *dev,
> >                       LoadStateHandler *load_state,
> >                       void *opaque)
> >   {
> > -    return register_savevm_live(dev, idstr, instance_id, version_id,
> > +    return register_savevm_live(dev, idstr, instance_id, version_id, 0,
> >                                   NULL, NULL, save_state, load_state, 
> > opaque);
> >   }
> >
> > @@ -1728,6 +1731,43 @@ out:
> >       return ret;
> >   }
> >
> > +static int qemu_save_device_state(Monitor *mon, QEMUFile *f)
> > +{
> > +    SaveStateEntry *se;
> > +
> > +    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);
> > +    qemu_put_be32(f, QEMU_VM_FILE_VERSION);
> > +
> > +    cpu_synchronize_all_states();
> > +
> > +    QTAILQ_FOREACH(se,&savevm_handlers, entry) {
> > +        int len;
> > +
> > +        if (se->is_ram)
> > +            continue;
> 
> Violating CODING_STYLE.

I'll fix that.


> > +        if (se->save_state == NULL&&  se->vmsd == NULL)
> > +            continue;
> > +
> > +        /* Section type */
> > +        qemu_put_byte(f, QEMU_VM_SECTION_FULL);
> > +        qemu_put_be32(f, se->section_id);
> > +
> > +        /* ID string */
> > +        len = strlen(se->idstr);
> > +        qemu_put_byte(f, len);
> > +        qemu_put_buffer(f, (uint8_t *)se->idstr, len);
> > +
> > +        qemu_put_be32(f, se->instance_id);
> > +        qemu_put_be32(f, se->version_id);
> > +
> > +        vmstate_save(f, se);
> > +    }
> > +
> > +    qemu_put_byte(f, QEMU_VM_EOF);
> > +
> > +    return qemu_file_get_error(f);
> > +}
> 
> Please add something to docs/ documenting this format.

OK


> > +
> >   static SaveStateEntry *find_se(const char *idstr, int instance_id)
> >   {
> >       SaveStateEntry *se;
> > @@ -2109,6 +2149,36 @@ void do_savevm(Monitor *mon, const QDict *qdict)
> >           vm_start();
> >   }
> >
> > +int do_save_device_state(Monitor *mon, const QDict *qdict, QObject 
> > **ret_data)
> > +{
> > +    int ret;
> > +    QEMUFile *f;
> > +    int saved_vm_running;
> > +    const char *filename = qdict_get_try_str(qdict, "filename");
> > +
> > +    saved_vm_running = runstate_is_running();
> > +    vm_stop(RUN_STATE_SAVE_VM);
> > +
> > +    f = qemu_fopen(filename, "wb");
> > +    if (!f) {
> > +        monitor_printf(mon, "Could not open VM state file\n");
> > +        ret = -1;
> > +        goto the_end;
> > +    }
> > +    ret = qemu_save_device_state(mon, f);
> > +    qemu_fclose(f);
> > +    if (ret<  0) {
> > +        monitor_printf(mon, "Error %d while writing VM\n", ret);
> > +        goto the_end;
> > +    }
> > +    ret = 0;
> > +
> > + the_end:
> > +    if (saved_vm_running)
> > +        vm_start();
> > +    return ret;
> > +}
> > +
> 
> Would it be useful/interesting to return a binary blob via QMP instead of 
> writing to a file?

Yes, it is potentially useful. I have just gone with the file interface
because it is easier to handle but I could change it or maybe have QMP
return the binary as an alternative option.



reply via email to

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