diff mbox series

try to find out which cluster allocated in qcow2

Message ID 1663747050-122900-1-git-send-email-slf553@126.com (mailing list archive)
State New, archived
Headers show
Series try to find out which cluster allocated in qcow2 | expand

Commit Message

songlinfeng Sept. 21, 2022, 7:57 a.m. UTC
In our project,we want to full backup a disk only allocated area,but qmp block-dity-block-add can create a bitmap with all zero,so we can't find out which cluster is allocated.in qcow2,I think l2_table can help me find out which cluster should be backup.

Signed-off-by: songlinfeng <slf553@126.com>
---
 block/qcow2.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
 block/qcow2.h |  1 +
 2 files changed, 50 insertions(+)

Comments

Kevin Wolf Sept. 22, 2022, 3:12 p.m. UTC | #1
Am 21.09.2022 um 09:57 hat songlinfeng geschrieben:
> In our project,we want to full backup a disk only allocated area,but
> qmp block-dity-block-add can create a bitmap with all zero,so we can't
> find out which cluster is allocated.in qcow2,I think l2_table can help
> me find out which cluster should be backup.
> 
> Signed-off-by: songlinfeng <slf553@126.com>

You're just adding a new function without any callers. This would be
dead code. We don't generally commit dead code except as part of a
series where a later patch makes use of it.

Either way, since you just seem to print allocation status to stdout,
maybe 'qemu-img map' is actually the right tool for what you are
trying to do?

Kevin
diff mbox series

Patch

diff --git a/block/qcow2.c b/block/qcow2.c
index c6c6692..944cf4f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -4194,6 +4194,55 @@  fail:
     return ret;
 }
 
+void qcow2_get_cluster(BlockDriverState *bs, uint64_t size)
+{
+    BDRVQcow2State *s = bs->opaque;
+    int l1_size = s->l1_size;
+    int cluster_size = s->cluster_size;
+    int i;
+    int j;
+    uint64_t *l2_table = (uint64_t *)malloc(cluster_size);
+    int l2_entries = cluster_size / sizeof(uint64_t);
+    int total = (size + cluster_size + 1) / cluster_size;
+    for (i = 0; i < l1_size; i++) {
+        uint64_t l1_entry = s->l1_table[i];
+        uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;
+        if (l2_offset == 0) {
+            if (l2_entries < total) {
+                char *buf = (char *)malloc(l2_entries * sizeof(char));
+                memset(buf, '0', l2_entries);
+                printf("%s", buf);
+                free(buf);
+                total -= l2_entries;
+            } else {
+                char *buf = (char *)malloc(total * sizeof(char));
+                memset(buf, '0', total);
+                printf("%s", buf);
+                free(buf);
+                total -= total;
+            }
+            continue;
+        }
+        int ret = bdrv_pread(bs->file, l2_offset, l2_table, cluster_size);
+        if (ret < 0) {
+            error_report("can't get l2_table");
+            abort();
+        }
+        for (j = 0; j < l2_entries; j++) {
+            if (total) {
+                if (l2_table[j] == 0) {
+                    printf("0");
+                } else {
+                    printf("1");
+                }
+                total--;
+            }
+        }
+    }
+    free(l2_table);
+    printf("\n");
+}
+
 static int coroutine_fn qcow2_co_truncate(BlockDriverState *bs, int64_t offset,
                                           bool exact, PreallocMode prealloc,
                                           BdrvRequestFlags flags, Error **errp)
diff --git a/block/qcow2.h b/block/qcow2.h
index ba436a8..7079916 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -998,6 +998,7 @@  int qcow2_co_remove_persistent_dirty_bitmap(BlockDriverState *bs,
                                             const char *name,
                                             Error **errp);
 bool qcow2_supports_persistent_dirty_bitmap(BlockDriverState *bs);
+void qcow2_get_cluster(BlockDriverState *bs, uint64_t size);
 uint64_t qcow2_get_persistent_dirty_bitmap_size(BlockDriverState *bs,
                                                 uint32_t cluster_size);