Message ID | 48c8d2bceafe7f37a637912ddd98c648a8c3d0be.1355404685.git.phrdina@redhat.com |
---|---|
State | New |
Headers | show |
On Thu, 13 Dec 2012 16:40:50 +0100 Pavel Hrdina <phrdina@redhat.com> wrote: > Signed-off-by: Pavel Hrdina <phrdina@redhat.com> > --- > hmp.c | 33 +++++++++++++++++++++++++++++++++ > hmp.h | 1 + > monitor.c | 2 +- > qapi-schema.json | 13 +++++++++++++ > qmp-commands.hx | 34 ++++++++++++++++++++++++++++++++++ > savevm.c | 52 +++++++++++++++++++++++++--------------------------- > sysemu.h | 2 -- > 7 files changed, 107 insertions(+), 30 deletions(-) > > diff --git a/hmp.c b/hmp.c > index 78c9a7c..1983210 100644 > --- a/hmp.c > +++ b/hmp.c > @@ -628,6 +628,39 @@ void hmp_info_block_jobs(Monitor *mon) > } > } > > +void hmp_info_snapshots(Monitor *mon) > +{ > + SnapshotInfoList *list; > + Error *err = NULL; > + char buf[256]; > + QEMUSnapshotInfo sn; > + > + list = qmp_query_vm_snapshots(&err); > + > + if (error_is_set(&err)) { > + hmp_handle_error(mon, &err); > + return; > + } > + > + if (!list) { > + monitor_printf(mon, "There is no snapshot available.\n"); > + return; > + } > + monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL)); > + while (list) { > + memcpy(&(sn.id_str), list->value->id, sizeof(sn.id_str)); > + memcpy(&(sn.name), list->value->name, sizeof(sn.name)); > + sn.date_sec = list->value->date_sec; > + sn.date_nsec = list->value->date_nsec; > + sn.vm_clock_nsec = list->value->vm_clock_nsec; > + sn.vm_state_size = list->value->vm_state_size; > + monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn)); > + list = list->next; > + } > + > + qapi_free_SnapshotInfoList(list); list should be NULL here, so you're actually leaking the list returned by qmp_query_vm_snapshots(). > +} > + > void hmp_quit(Monitor *mon, const QDict *qdict) > { > monitor_suspend(mon); > diff --git a/hmp.h b/hmp.h > index 8f929af..1c21a82 100644 > --- a/hmp.h > +++ b/hmp.h > @@ -36,6 +36,7 @@ void hmp_info_spice(Monitor *mon); > void hmp_info_balloon(Monitor *mon); > void hmp_info_pci(Monitor *mon); > void hmp_info_block_jobs(Monitor *mon); > +void hmp_info_snapshots(Monitor *mon); > void hmp_quit(Monitor *mon, const QDict *qdict); > void hmp_stop(Monitor *mon, const QDict *qdict); > void hmp_system_reset(Monitor *mon, const QDict *qdict); > diff --git a/monitor.c b/monitor.c > index b8abff2..2be93c0 100644 > --- a/monitor.c > +++ b/monitor.c > @@ -2596,7 +2596,7 @@ static mon_cmd_t info_cmds[] = { > .args_type = "", > .params = "", > .help = "show the currently saved VM snapshots", > - .mhandler.info = do_info_snapshots, > + .mhandler.info = hmp_info_snapshots, > }, > { > .name = "status", > diff --git a/qapi-schema.json b/qapi-schema.json > index 431df69..a8742a1 100644 > --- a/qapi-schema.json > +++ b/qapi-schema.json > @@ -1224,6 +1224,19 @@ > { 'command': 'query-block-jobs', 'returns': ['BlockJobInfo'] } > > ## > +# @query-vm-snapshots: > +# > +# List available snapshots for VM. > +# > +# Returns: an array of @SnapshotInfo describing each snapshot or an empty array > +# on success > +# If an error occurs, GenericError with error message We don't need the line above. > +# > +# Since: 1.3 > +## > +{ 'command': 'query-vm-snapshots', 'returns': ['SnapshotInfo'] } > + > +## > # @quit: > # > # This command will cause the QEMU process to exit gracefully. While every > diff --git a/qmp-commands.hx b/qmp-commands.hx > index c3671f7..f839c40 100644 > --- a/qmp-commands.hx > +++ b/qmp-commands.hx > @@ -2732,3 +2732,37 @@ EQMP > .args_type = "", > .mhandler.cmd_new = qmp_marshal_input_query_target, > }, > + > +SQMP > +query-vm-snapshots > +---------- > + > +List available snapshots for VM. > + > +Return an array of json-object, each with the following information: > + > +- "id": unique snapshot id > + > +- "name": user choosen name > + > +- "vm-state-size": size of the VM state > + > +- "date-sec": UTC date of the snapshot > + > +- "date-nsec": date in nano seconds > + > +- "vm-clock-nsec": VM clock relative to boot in nano seconds > + > +Example: > + > +-> { "execute": "query-vm-snapshots" } > +<- {"return": [{"vm-clock-nsec": 36420253254, "name": "my_snapshot", > + "date-sec": 1345120008, "date-nsec": 151984000, "id": "6", > + "vm-state-size": 166515500}]} > + > +EQMP > + { > + .name = "query-vm-snapshots", > + .args_type = "", > + .mhandler.cmd_new = qmp_marshal_input_query_vm_snapshots, > + }, > diff --git a/savevm.c b/savevm.c > index 8da888e..36ccc46 100644 > --- a/savevm.c > +++ b/savevm.c > @@ -2373,34 +2373,28 @@ void qmp_vm_snapshot_delete(const char *name, Error **errp) > } > } > > -void do_info_snapshots(Monitor *mon) > +SnapshotInfoList *qmp_query_vm_snapshots(Error **errp) > { > + SnapshotInfoList *snapshot_list = NULL, *last = NULL; > BlockDriverState *bs, *bs1; > QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s; > int nb_sns, i, ret, available; > - int total; > - int *available_snapshots; > - char buf[256]; > > bs = bdrv_snapshots(); > if (!bs) { > - monitor_printf(mon, "No available block device supports snapshots\n"); > - return; > + error_setg(errp, "No block device supports snapshots."); > + return NULL; > } > > - nb_sns = bdrv_snapshot_list(bs, &sn_tab, NULL); > - if (nb_sns < 0) { > - monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns); > - return; > + nb_sns = bdrv_snapshot_list(bs, &sn_tab, errp); You should not use errp to detect internal errors. > + if (error_is_set(errp)) { > + return NULL; > } > > if (nb_sns == 0) { > - monitor_printf(mon, "There is no snapshot available.\n"); > - return; > + return NULL; > } > > - available_snapshots = g_malloc0(sizeof(int) * nb_sns); > - total = 0; > for (i = 0; i < nb_sns; i++) { > sn = &sn_tab[i]; > available = 1; > @@ -2417,24 +2411,28 @@ void do_info_snapshots(Monitor *mon) > } > > if (available) { > - available_snapshots[total] = i; > - total++; > - } > - } > - > - if (total > 0) { > - monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL)); > - for (i = 0; i < total; i++) { > - sn = &sn_tab[available_snapshots[i]]; > - monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn)); > + SnapshotInfoList *info = g_malloc0(sizeof(*info)); > + info->value = g_malloc0(sizeof(*info->value)); > + info->value->id = g_strdup(sn->id_str); > + info->value->name = g_strdup(sn->name); > + info->value->vm_state_size = sn->vm_state_size; > + info->value->date_sec = sn->date_sec; > + info->value->date_nsec = sn->date_nsec; > + info->value->vm_clock_nsec = sn->vm_clock_nsec; > + > + if (!snapshot_list) { > + snapshot_list = info; > + last = info; > + } else { > + last->next = info; > + last = info; > + } > } > - } else { > - monitor_printf(mon, "There is no suitable snapshot available\n"); > } > > g_free(sn_tab); > - g_free(available_snapshots); > > + return snapshot_list; > } > > void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev) > diff --git a/sysemu.h b/sysemu.h > index e440dcc..e7182f4 100644 > --- a/sysemu.h > +++ b/sysemu.h > @@ -65,8 +65,6 @@ void qemu_remove_exit_notifier(Notifier *notify); > > void qemu_add_machine_init_done_notifier(Notifier *notify); > > -void do_info_snapshots(Monitor *mon); > - > void qemu_announce_self(void); > > bool qemu_savevm_state_blocked(Error **errp);
diff --git a/hmp.c b/hmp.c index 78c9a7c..1983210 100644 --- a/hmp.c +++ b/hmp.c @@ -628,6 +628,39 @@ void hmp_info_block_jobs(Monitor *mon) } } +void hmp_info_snapshots(Monitor *mon) +{ + SnapshotInfoList *list; + Error *err = NULL; + char buf[256]; + QEMUSnapshotInfo sn; + + list = qmp_query_vm_snapshots(&err); + + if (error_is_set(&err)) { + hmp_handle_error(mon, &err); + return; + } + + if (!list) { + monitor_printf(mon, "There is no snapshot available.\n"); + return; + } + monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL)); + while (list) { + memcpy(&(sn.id_str), list->value->id, sizeof(sn.id_str)); + memcpy(&(sn.name), list->value->name, sizeof(sn.name)); + sn.date_sec = list->value->date_sec; + sn.date_nsec = list->value->date_nsec; + sn.vm_clock_nsec = list->value->vm_clock_nsec; + sn.vm_state_size = list->value->vm_state_size; + monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), &sn)); + list = list->next; + } + + qapi_free_SnapshotInfoList(list); +} + void hmp_quit(Monitor *mon, const QDict *qdict) { monitor_suspend(mon); diff --git a/hmp.h b/hmp.h index 8f929af..1c21a82 100644 --- a/hmp.h +++ b/hmp.h @@ -36,6 +36,7 @@ void hmp_info_spice(Monitor *mon); void hmp_info_balloon(Monitor *mon); void hmp_info_pci(Monitor *mon); void hmp_info_block_jobs(Monitor *mon); +void hmp_info_snapshots(Monitor *mon); void hmp_quit(Monitor *mon, const QDict *qdict); void hmp_stop(Monitor *mon, const QDict *qdict); void hmp_system_reset(Monitor *mon, const QDict *qdict); diff --git a/monitor.c b/monitor.c index b8abff2..2be93c0 100644 --- a/monitor.c +++ b/monitor.c @@ -2596,7 +2596,7 @@ static mon_cmd_t info_cmds[] = { .args_type = "", .params = "", .help = "show the currently saved VM snapshots", - .mhandler.info = do_info_snapshots, + .mhandler.info = hmp_info_snapshots, }, { .name = "status", diff --git a/qapi-schema.json b/qapi-schema.json index 431df69..a8742a1 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -1224,6 +1224,19 @@ { 'command': 'query-block-jobs', 'returns': ['BlockJobInfo'] } ## +# @query-vm-snapshots: +# +# List available snapshots for VM. +# +# Returns: an array of @SnapshotInfo describing each snapshot or an empty array +# on success +# If an error occurs, GenericError with error message +# +# Since: 1.3 +## +{ 'command': 'query-vm-snapshots', 'returns': ['SnapshotInfo'] } + +## # @quit: # # This command will cause the QEMU process to exit gracefully. While every diff --git a/qmp-commands.hx b/qmp-commands.hx index c3671f7..f839c40 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -2732,3 +2732,37 @@ EQMP .args_type = "", .mhandler.cmd_new = qmp_marshal_input_query_target, }, + +SQMP +query-vm-snapshots +---------- + +List available snapshots for VM. + +Return an array of json-object, each with the following information: + +- "id": unique snapshot id + +- "name": user choosen name + +- "vm-state-size": size of the VM state + +- "date-sec": UTC date of the snapshot + +- "date-nsec": date in nano seconds + +- "vm-clock-nsec": VM clock relative to boot in nano seconds + +Example: + +-> { "execute": "query-vm-snapshots" } +<- {"return": [{"vm-clock-nsec": 36420253254, "name": "my_snapshot", + "date-sec": 1345120008, "date-nsec": 151984000, "id": "6", + "vm-state-size": 166515500}]} + +EQMP + { + .name = "query-vm-snapshots", + .args_type = "", + .mhandler.cmd_new = qmp_marshal_input_query_vm_snapshots, + }, diff --git a/savevm.c b/savevm.c index 8da888e..36ccc46 100644 --- a/savevm.c +++ b/savevm.c @@ -2373,34 +2373,28 @@ void qmp_vm_snapshot_delete(const char *name, Error **errp) } } -void do_info_snapshots(Monitor *mon) +SnapshotInfoList *qmp_query_vm_snapshots(Error **errp) { + SnapshotInfoList *snapshot_list = NULL, *last = NULL; BlockDriverState *bs, *bs1; QEMUSnapshotInfo *sn_tab, *sn, s, *sn_info = &s; int nb_sns, i, ret, available; - int total; - int *available_snapshots; - char buf[256]; bs = bdrv_snapshots(); if (!bs) { - monitor_printf(mon, "No available block device supports snapshots\n"); - return; + error_setg(errp, "No block device supports snapshots."); + return NULL; } - nb_sns = bdrv_snapshot_list(bs, &sn_tab, NULL); - if (nb_sns < 0) { - monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns); - return; + nb_sns = bdrv_snapshot_list(bs, &sn_tab, errp); + if (error_is_set(errp)) { + return NULL; } if (nb_sns == 0) { - monitor_printf(mon, "There is no snapshot available.\n"); - return; + return NULL; } - available_snapshots = g_malloc0(sizeof(int) * nb_sns); - total = 0; for (i = 0; i < nb_sns; i++) { sn = &sn_tab[i]; available = 1; @@ -2417,24 +2411,28 @@ void do_info_snapshots(Monitor *mon) } if (available) { - available_snapshots[total] = i; - total++; - } - } - - if (total > 0) { - monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL)); - for (i = 0; i < total; i++) { - sn = &sn_tab[available_snapshots[i]]; - monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn)); + SnapshotInfoList *info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + info->value->id = g_strdup(sn->id_str); + info->value->name = g_strdup(sn->name); + info->value->vm_state_size = sn->vm_state_size; + info->value->date_sec = sn->date_sec; + info->value->date_nsec = sn->date_nsec; + info->value->vm_clock_nsec = sn->vm_clock_nsec; + + if (!snapshot_list) { + snapshot_list = info; + last = info; + } else { + last->next = info; + last = info; + } } - } else { - monitor_printf(mon, "There is no suitable snapshot available\n"); } g_free(sn_tab); - g_free(available_snapshots); + return snapshot_list; } void vmstate_register_ram(MemoryRegion *mr, DeviceState *dev) diff --git a/sysemu.h b/sysemu.h index e440dcc..e7182f4 100644 --- a/sysemu.h +++ b/sysemu.h @@ -65,8 +65,6 @@ void qemu_remove_exit_notifier(Notifier *notify); void qemu_add_machine_init_done_notifier(Notifier *notify); -void do_info_snapshots(Monitor *mon); - void qemu_announce_self(void); bool qemu_savevm_state_blocked(Error **errp);
Signed-off-by: Pavel Hrdina <phrdina@redhat.com> --- hmp.c | 33 +++++++++++++++++++++++++++++++++ hmp.h | 1 + monitor.c | 2 +- qapi-schema.json | 13 +++++++++++++ qmp-commands.hx | 34 ++++++++++++++++++++++++++++++++++ savevm.c | 52 +++++++++++++++++++++++++--------------------------- sysemu.h | 2 -- 7 files changed, 107 insertions(+), 30 deletions(-)