This patch added the support of showing internal snapshots on an image in the backing chain of a block device in hmp layer, by calling a qmp function.
Signed-off-by: Wenchao Xia <xiaw...@linux.vnet.ibm.com> --- hmp.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- monitor.c | 6 ++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/hmp.c b/hmp.c index 5e68b2f..ffa92ff 100644 --- a/hmp.c +++ b/hmp.c @@ -629,6 +629,73 @@ static void monitor_dump_snapshotinfolist(Monitor *mon, SnapshotInfoList *list) } } +/* Find the ImageInfo with correct image_name. If image_name = NULL, then + return the top one in the chain. */ +static ImageInfo *find_image_info(const DeviceImageInfoList *device_image_list, + const char *image_name) +{ + ImageInfo *image_info; + + /* return top one */ + if (!image_name) { + if (device_image_list->value->has_image) { + return device_image_list->value->image; + } else { + return NULL; + } + } + + /* search the chain */ + while (device_image_list) { + if (device_image_list->value->has_image) { + image_info = device_image_list->value->image; + if (!strcmp(image_info->filename, image_name)) { + return image_info; + } + } + device_image_list = device_image_list->next; + } + return NULL; +} + +static void hmp_info_snapshots_device(Monitor *mon, + const char *device_name, + const char *image_name) +{ + Error *err = NULL; + SnapshotInfoList *list; + + DeviceImageInfoList *device_image_list = qmp_query_images(true, + device_name, true, true, &err); + if (error_is_set(&err)) { + hmp_handle_error(mon, &err); + return; + } + if (!device_image_list) { + monitor_printf(mon, "Device '%s' can't get image info list.\n", + device_name); + return; + } + + ImageInfo *image_info = find_image_info(device_image_list, image_name); + if (image_info) { + if (image_info->has_snapshots) { + list = image_info->snapshots; + monitor_printf(mon, "Device '%s', Image name '%s':\n", + device_name, image_info->filename); + monitor_dump_snapshotinfolist(mon, list); + } else { + monitor_printf(mon, "Device '%s' have no valid " + "internal snapshot.\n", + device_name); + } + } else { + monitor_printf(mon, "Device '%s' have no correspond image now.\n", + device_name); + } + qapi_free_DeviceImageInfoList(device_image_list); +} + static void hmp_info_snapshots_vm(Monitor *mon) { Error *err = NULL; @@ -651,7 +718,19 @@ static void hmp_info_snapshots_vm(Monitor *mon) void hmp_info_snapshots(Monitor *mon, const QDict *qdict) { - hmp_info_snapshots_vm(mon); + const char *device_name = qdict_get_try_str(qdict, "device"); + const char *image_name = qdict_get_try_str(qdict, "image"); + + if (device_name) { + hmp_info_snapshots_device(mon, device_name, image_name); + } else { + if (image_name) { + monitor_printf(mon, "Parameter [image] is valid only when " + "device is specified.\n"); + return; + } + hmp_info_snapshots_vm(mon); + } } void hmp_quit(Monitor *mon, const QDict *qdict) diff --git a/monitor.c b/monitor.c index 5112375..1dca36f 100644 --- a/monitor.c +++ b/monitor.c @@ -2591,9 +2591,9 @@ static mon_cmd_t info_cmds[] = { }, { .name = "snapshots", - .args_type = "", - .params = "", - .help = "show the currently saved VM snapshots", + .args_type = "device:O?", + .params = "[device=str] [,image=str]", + .help = "show snapshots of whole vm or a single device", .mhandler.cmd = hmp_info_snapshots, }, { -- 1.7.1