9ae3a8
From c4aaafbe296b0e38a54191d294436ffd718a2c7b Mon Sep 17 00:00:00 2001
9ae3a8
From: Max Reitz <mreitz@redhat.com>
9ae3a8
Date: Wed, 6 Nov 2013 16:53:27 +0100
9ae3a8
Subject: [PATCH 70/87] block: add snapshot info query function bdrv_query_snapshot_info_list()
9ae3a8
9ae3a8
RH-Author: Max Reitz <mreitz@redhat.com>
9ae3a8
Message-id: <1383756824-6921-5-git-send-email-mreitz@redhat.com>
9ae3a8
Patchwork-id: 55559
9ae3a8
O-Subject: [RHEL-7.0 qemu-kvm PATCH v2 04/21] block: add snapshot info query function bdrv_query_snapshot_info_list()
9ae3a8
Bugzilla: 980771
9ae3a8
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
RH-Acked-by: Fam Zheng <famz@redhat.com>
9ae3a8
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
9ae3a8
9ae3a8
From: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
9ae3a8
9ae3a8
BZ: 980771
9ae3a8
9ae3a8
This patch adds function bdrv_query_snapshot_info_list(), which will
9ae3a8
retrieve snapshot info of an image in qmp object format. The implementation
9ae3a8
is based on the code moved from qemu-img.c with modification to fit more
9ae3a8
for qmp based block layer API.
9ae3a8
9ae3a8
Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com>
9ae3a8
Reviewed-by: Eric Blake <eblake@redhat.com>
9ae3a8
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
(cherry picked from commit fb0ed4539c6f02fa9e5a3cf9df2549713451eeca)
9ae3a8
9ae3a8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9ae3a8
---
9ae3a8
 block/qapi.c         | 55 +++++++++++++++++++++++++++++++++++++++-------------
9ae3a8
 include/block/qapi.h |  4 +++-
9ae3a8
 qemu-img.c           |  5 ++++-
9ae3a8
 3 files changed, 49 insertions(+), 15 deletions(-)
9ae3a8
9ae3a8
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
9ae3a8
---
9ae3a8
 block/qapi.c         |   55 ++++++++++++++++++++++++++++++++++++++-----------
9ae3a8
 include/block/qapi.h |    4 ++-
9ae3a8
 qemu-img.c           |    5 +++-
9ae3a8
 3 files changed, 49 insertions(+), 15 deletions(-)
9ae3a8
9ae3a8
diff --git a/block/qapi.c b/block/qapi.c
9ae3a8
index 794dbf8..1ed56da 100644
9ae3a8
--- a/block/qapi.c
9ae3a8
+++ b/block/qapi.c
9ae3a8
@@ -26,29 +26,56 @@
9ae3a8
 #include "block/block_int.h"
9ae3a8
 #include "qmp-commands.h"
9ae3a8
 
9ae3a8
-void bdrv_collect_snapshots(BlockDriverState *bs , ImageInfo *info)
9ae3a8
+/*
9ae3a8
+ * Returns 0 on success, with *p_list either set to describe snapshot
9ae3a8
+ * information, or NULL because there are no snapshots.  Returns -errno on
9ae3a8
+ * error, with *p_list untouched.
9ae3a8
+ */
9ae3a8
+int bdrv_query_snapshot_info_list(BlockDriverState *bs,
9ae3a8
+                                  SnapshotInfoList **p_list,
9ae3a8
+                                  Error **errp)
9ae3a8
 {
9ae3a8
     int i, sn_count;
9ae3a8
     QEMUSnapshotInfo *sn_tab = NULL;
9ae3a8
-    SnapshotInfoList *info_list, *cur_item = NULL;
9ae3a8
+    SnapshotInfoList *info_list, *cur_item = NULL, *head = NULL;
9ae3a8
+    SnapshotInfo *info;
9ae3a8
+
9ae3a8
     sn_count = bdrv_snapshot_list(bs, &sn_tab);
9ae3a8
+    if (sn_count < 0) {
9ae3a8
+        const char *dev = bdrv_get_device_name(bs);
9ae3a8
+        switch (sn_count) {
9ae3a8
+        case -ENOMEDIUM:
9ae3a8
+            error_setg(errp, "Device '%s' is not inserted", dev);
9ae3a8
+            break;
9ae3a8
+        case -ENOTSUP:
9ae3a8
+            error_setg(errp,
9ae3a8
+                       "Device '%s' does not support internal snapshots",
9ae3a8
+                       dev);
9ae3a8
+            break;
9ae3a8
+        default:
9ae3a8
+            error_setg_errno(errp, -sn_count,
9ae3a8
+                             "Can't list snapshots of device '%s'", dev);
9ae3a8
+            break;
9ae3a8
+        }
9ae3a8
+        return sn_count;
9ae3a8
+    }
9ae3a8
 
9ae3a8
     for (i = 0; i < sn_count; i++) {
9ae3a8
-        info->has_snapshots = true;
9ae3a8
-        info_list = g_new0(SnapshotInfoList, 1);
9ae3a8
+        info = g_new0(SnapshotInfo, 1);
9ae3a8
+        info->id            = g_strdup(sn_tab[i].id_str);
9ae3a8
+        info->name          = g_strdup(sn_tab[i].name);
9ae3a8
+        info->vm_state_size = sn_tab[i].vm_state_size;
9ae3a8
+        info->date_sec      = sn_tab[i].date_sec;
9ae3a8
+        info->date_nsec     = sn_tab[i].date_nsec;
9ae3a8
+        info->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
9ae3a8
+        info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
9ae3a8
 
9ae3a8
-        info_list->value                = g_new0(SnapshotInfo, 1);
9ae3a8
-        info_list->value->id            = g_strdup(sn_tab[i].id_str);
9ae3a8
-        info_list->value->name          = g_strdup(sn_tab[i].name);
9ae3a8
-        info_list->value->vm_state_size = sn_tab[i].vm_state_size;
9ae3a8
-        info_list->value->date_sec      = sn_tab[i].date_sec;
9ae3a8
-        info_list->value->date_nsec     = sn_tab[i].date_nsec;
9ae3a8
-        info_list->value->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
9ae3a8
-        info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
9ae3a8
+        info_list = g_new0(SnapshotInfoList, 1);
9ae3a8
+        info_list->value = info;
9ae3a8
 
9ae3a8
         /* XXX: waiting for the qapi to support qemu-queue.h types */
9ae3a8
         if (!cur_item) {
9ae3a8
-            info->snapshots = cur_item = info_list;
9ae3a8
+            head = cur_item = info_list;
9ae3a8
         } else {
9ae3a8
             cur_item->next = info_list;
9ae3a8
             cur_item = info_list;
9ae3a8
@@ -57,6 +84,8 @@ void bdrv_collect_snapshots(BlockDriverState *bs , ImageInfo *info)
9ae3a8
     }
9ae3a8
 
9ae3a8
     g_free(sn_tab);
9ae3a8
+    *p_list = head;
9ae3a8
+    return 0;
9ae3a8
 }
9ae3a8
 
9ae3a8
 void bdrv_collect_image_info(BlockDriverState *bs,
9ae3a8
diff --git a/include/block/qapi.h b/include/block/qapi.h
9ae3a8
index e6e568d..4f223d1 100644
9ae3a8
--- a/include/block/qapi.h
9ae3a8
+++ b/include/block/qapi.h
9ae3a8
@@ -29,7 +29,9 @@
9ae3a8
 #include "block/block.h"
9ae3a8
 #include "block/snapshot.h"
9ae3a8
 
9ae3a8
-void bdrv_collect_snapshots(BlockDriverState *bs , ImageInfo *info);
9ae3a8
+int bdrv_query_snapshot_info_list(BlockDriverState *bs,
9ae3a8
+                                  SnapshotInfoList **p_list,
9ae3a8
+                                  Error **errp);
9ae3a8
 void bdrv_collect_image_info(BlockDriverState *bs,
9ae3a8
                              ImageInfo *info,
9ae3a8
                              const char *filename);
9ae3a8
diff --git a/qemu-img.c b/qemu-img.c
9ae3a8
index 97b4212..e1fb148 100644
9ae3a8
--- a/qemu-img.c
9ae3a8
+++ b/qemu-img.c
9ae3a8
@@ -1686,7 +1686,10 @@ static ImageInfoList *collect_image_info_list(const char *filename,
9ae3a8
 
9ae3a8
         info = g_new0(ImageInfo, 1);
9ae3a8
         bdrv_collect_image_info(bs, info, filename);
9ae3a8
-        bdrv_collect_snapshots(bs, info);
9ae3a8
+        bdrv_query_snapshot_info_list(bs, &info->snapshots, NULL);
9ae3a8
+        if (info->snapshots) {
9ae3a8
+            info->has_snapshots = true;
9ae3a8
+        }
9ae3a8
 
9ae3a8
         elem = g_new0(ImageInfoList, 1);
9ae3a8
         elem->value = info;
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8