From patchwork Sat May 12 01:25:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912336 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTsb6jsDz9s16 for ; Sat, 12 May 2018 11:29:55 +1000 (AEST) Received: from localhost ([::1]:33829 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJM9-0000yj-6M for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:29:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40262) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJIA-0006Mm-0c for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJI7-0006Tg-Tq for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:45 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33386 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI2-0006GW-QT; Fri, 11 May 2018 21:25:38 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 678E07D65F; Sat, 12 May 2018 01:25:38 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 07A76215CDA7; Sat, 12 May 2018 01:25:37 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:26 -0400 Message-Id: <20180512012537.22478-2-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sat, 12 May 2018 01:25:38 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sat, 12 May 2018 01:25:38 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 01/12] qcow2-bitmap: cache bm_list X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We don't need to re-read this list every time, exactly. We can keep it cached and delete our copy when we flush to disk. Because we don't try to flush bitmaps on close if there's nothing to flush, add a new conditional to delete the state anyway for a clean exit. Signed-off-by: John Snow --- block/qcow2-bitmap.c | 74 ++++++++++++++++++++++++++++++++-------------------- block/qcow2.c | 2 ++ block/qcow2.h | 2 ++ 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 6e93ec43e1..fb0a4f3ec4 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -536,8 +536,7 @@ static uint32_t bitmap_list_count(Qcow2BitmapList *bm_list) * Get bitmap list from qcow2 image. Actually reads bitmap directory, * checks it and convert to bitmap list. */ -static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset, - uint64_t size, Error **errp) +static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, Error **errp) { int ret; BDRVQcow2State *s = bs->opaque; @@ -545,6 +544,8 @@ static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, uint64_t offset, Qcow2BitmapDirEntry *e; uint32_t nb_dir_entries = 0; Qcow2BitmapList *bm_list = NULL; + uint64_t offset = s->bitmap_directory_offset; + uint64_t size = s->bitmap_directory_size; if (size == 0) { error_setg(errp, "Requested bitmap directory size is zero"); @@ -636,6 +637,30 @@ fail: return NULL; } +static Qcow2BitmapList *get_bitmap_list(BlockDriverState *bs, Error **errp) +{ + BDRVQcow2State *s = bs->opaque; + Qcow2BitmapList *bm_list; + + if (s->bitmap_list) { + return (Qcow2BitmapList *)s->bitmap_list; + } + + bm_list = bitmap_list_load(bs, errp); + s->bitmap_list = bm_list; + return bm_list; +} + +static void del_bitmap_list(BlockDriverState *bs) +{ + BDRVQcow2State *s = bs->opaque; + + if (s->bitmap_list) { + bitmap_list_free(s->bitmap_list); + s->bitmap_list = NULL; + } +} + int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, void **refcount_table, int64_t *refcount_table_size) @@ -656,8 +681,7 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, return ret; } - bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, NULL); + bm_list = get_bitmap_list(bs, NULL); if (bm_list == NULL) { res->corruptions++; return -EINVAL; @@ -707,8 +731,6 @@ int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, } out: - bitmap_list_free(bm_list); - return ret; } @@ -953,8 +975,7 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp) return false; } - bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list = get_bitmap_list(bs, errp); if (bm_list == NULL) { return false; } @@ -992,14 +1013,12 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp) } g_slist_free(created_dirty_bitmaps); - bitmap_list_free(bm_list); - return header_updated; fail: g_slist_foreach(created_dirty_bitmaps, release_dirty_bitmap_helper, bs); g_slist_free(created_dirty_bitmaps); - bitmap_list_free(bm_list); + del_bitmap_list(bs); return false; } @@ -1027,8 +1046,7 @@ int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated, return -EINVAL; } - bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list = get_bitmap_list(bs, errp); if (bm_list == NULL) { return -EINVAL; } @@ -1068,7 +1086,6 @@ int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated, out: g_slist_free(ro_dirty_bitmaps); - bitmap_list_free(bm_list); return ret; } @@ -1277,8 +1294,7 @@ void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs, return; } - bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list = get_bitmap_list(bs, errp); if (bm_list == NULL) { return; } @@ -1300,7 +1316,11 @@ void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs, fail: bitmap_free(bm); - bitmap_list_free(bm_list); +} + +void qcow2_persistent_dirty_bitmaps_cache_destroy(BlockDriverState *bs) +{ + del_bitmap_list(bs); } void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp) @@ -1317,12 +1337,12 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp) if (!bdrv_has_changed_persistent_bitmaps(bs)) { /* nothing to do */ - return; + goto out; } if (!can_write(bs)) { error_setg(errp, "No write access"); - return; + goto out; } QSIMPLEQ_INIT(&drop_tables); @@ -1330,10 +1350,9 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp) if (s->nb_bitmaps == 0) { bm_list = bitmap_list_new(); } else { - bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list = get_bitmap_list(bs, errp); if (bm_list == NULL) { - return; + goto out; } } @@ -1414,8 +1433,7 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp) g_free(tb); } - bitmap_list_free(bm_list); - return; + goto out; fail: QSIMPLEQ_FOREACH(bm, bm_list, entry) { @@ -1430,7 +1448,9 @@ fail: g_free(tb); } - bitmap_list_free(bm_list); + out: + del_bitmap_list(bs); + return; } int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp) @@ -1495,14 +1515,12 @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs, goto fail; } - bm_list = bitmap_list_load(bs, s->bitmap_directory_offset, - s->bitmap_directory_size, errp); + bm_list = get_bitmap_list(bs, errp); if (bm_list == NULL) { goto fail; } found = find_bitmap_by_name(bm_list, name); - bitmap_list_free(bm_list); if (found) { error_setg(errp, "Bitmap with the same name is already stored"); goto fail; diff --git a/block/qcow2.c b/block/qcow2.c index 2f36e632f9..7ae9000656 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2135,6 +2135,8 @@ static void qcow2_close(BlockDriverState *bs) if (!(s->flags & BDRV_O_INACTIVE)) { qcow2_inactivate(bs); + } else { + qcow2_persistent_dirty_bitmaps_cache_destroy(bs); } cache_clean_timer_del(bs); diff --git a/block/qcow2.h b/block/qcow2.h index adf5c3950f..796a8c914b 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -299,6 +299,7 @@ typedef struct BDRVQcow2State { uint64_t bitmap_directory_size; uint64_t bitmap_directory_offset; bool dirty_bitmaps_loaded; + void *bitmap_list; int flags; int qcow_version; @@ -675,6 +676,7 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp); int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated, Error **errp); int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); +void qcow2_persistent_dirty_bitmaps_cache_destroy(BlockDriverState *bs); void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp); int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp); bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs, From patchwork Sat May 12 01:25:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912328 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTnr6rFyz9s16 for ; Sat, 12 May 2018 11:26:39 +1000 (AEST) Received: from localhost ([::1]:33800 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJIy-0006YQ-3s for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:26:36 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40164) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJI7-0006KF-L5 for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:44 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJI6-0006SM-UE for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:43 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33920 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI4-0006Kf-8g; Fri, 11 May 2018 21:25:40 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CF0F71520DE; Sat, 12 May 2018 01:25:39 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 74852215CDA7; Sat, 12 May 2018 01:25:38 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:27 -0400 Message-Id: <20180512012537.22478-3-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:39 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:39 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 02/12] qcow2/dirty-bitmap: cache loaded bitmaps X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" For bitmaps that we succeeded in loading, we can cache a reference to that object. This will let us iterate over the more convenient form of in-memory bitmaps for qemu-img bitmap manipulation tools. Signed-off-by: John Snow --- block/qcow2-bitmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index fb0a4f3ec4..d89758f235 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -986,6 +986,7 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp) if (bitmap == NULL) { goto fail; } + bm->dirty_bitmap = bitmap; if (!(bm->flags & BME_FLAG_AUTO)) { bdrv_disable_dirty_bitmap(bitmap); From patchwork Sat May 12 01:25:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912337 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTwR18bsz9s1b for ; Sat, 12 May 2018 11:32:21 +1000 (AEST) Received: from localhost ([::1]:33841 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJOU-0004KI-FE for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:32:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40235) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJI9-0006MC-EX for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJI7-0006Tw-UY for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:45 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33390 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI4-0006Lh-KJ; Fri, 11 May 2018 21:25:40 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3EE827D664; Sat, 12 May 2018 01:25:40 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id DBD7C215CDA7; Sat, 12 May 2018 01:25:39 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:28 -0400 Message-Id: <20180512012537.22478-4-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sat, 12 May 2018 01:25:40 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sat, 12 May 2018 01:25:40 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 03/12] block/qcow2-bitmap: avoid adjusting bm->flags for RO bitmaps X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Instead of always setting IN_USE, handle whether or not the bitmap is read-only instead of a two-loop pass. This will allow us to show the flags exactly as they appear for bitmaps in `qemu-img info`. Signed-off-by: John Snow --- block/qcow2-bitmap.c | 48 ++++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index d89758f235..fc8d52fc3e 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -942,13 +942,6 @@ fail: return ret; } -/* for g_slist_foreach for GSList of BdrvDirtyBitmap* elements */ -static void release_dirty_bitmap_helper(gpointer bitmap, - gpointer bs) -{ - bdrv_release_dirty_bitmap(bs, bitmap); -} - /* for g_slist_foreach for GSList of BdrvDirtyBitmap* elements */ static void set_readonly_helper(gpointer bitmap, gpointer value) { @@ -967,8 +960,8 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp) BDRVQcow2State *s = bs->opaque; Qcow2BitmapList *bm_list; Qcow2Bitmap *bm; - GSList *created_dirty_bitmaps = NULL; bool header_updated = false; + bool needs_update = false; if (s->nb_bitmaps == 0) { /* No bitmaps - nothing to do */ @@ -992,33 +985,32 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp) bdrv_disable_dirty_bitmap(bitmap); } bdrv_dirty_bitmap_set_persistance(bitmap, true); - bm->flags |= BME_FLAG_IN_USE; - created_dirty_bitmaps = - g_slist_append(created_dirty_bitmaps, bitmap); - } - } - - if (created_dirty_bitmaps != NULL) { - if (can_write(bs)) { - /* in_use flags must be updated */ - int ret = update_ext_header_and_dir_in_place(bs, bm_list); - if (ret < 0) { - error_setg_errno(errp, -ret, "Can't update bitmap directory"); - goto fail; + if (can_write(bs)) { + bm->flags |= BME_FLAG_IN_USE; + needs_update = true; + } else { + bdrv_dirty_bitmap_set_readonly(bitmap, true); } - header_updated = true; - } else { - g_slist_foreach(created_dirty_bitmaps, set_readonly_helper, - (gpointer)true); } } - g_slist_free(created_dirty_bitmaps); + /* in_use flags must be updated */ + if (needs_update) { + int ret = update_ext_header_and_dir_in_place(bs, bm_list); + if (ret < 0) { + error_setg_errno(errp, -ret, "Can't update bitmap directory"); + goto fail; + } + header_updated = true; + } return header_updated; fail: - g_slist_foreach(created_dirty_bitmaps, release_dirty_bitmap_helper, bs); - g_slist_free(created_dirty_bitmaps); + QSIMPLEQ_FOREACH(bm, bm_list, entry) { + if (bm->dirty_bitmap) { + bdrv_release_dirty_bitmap(bs, bm->dirty_bitmap); + } + } del_bitmap_list(bs); return false; From patchwork Sat May 12 01:25:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912330 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTpG64h2z9s1b for ; Sat, 12 May 2018 11:27:02 +1000 (AEST) Received: from localhost ([::1]:33811 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJJM-0006sD-Ee for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:27:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40198) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJI8-0006Kl-Fo for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJI7-0006T3-FT for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:44 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33922 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI5-0006Mu-3Q; Fri, 11 May 2018 21:25:41 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id AEEF01520DF; Sat, 12 May 2018 01:25:40 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4CEA2215CDA7; Sat, 12 May 2018 01:25:40 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:29 -0400 Message-Id: <20180512012537.22478-5-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:40 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:40 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 04/12] qcow2/dirty-bitmaps: load IN_USE bitmaps if disk is RO X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" For the purposes of qemu-img manipulation and querying of bitmaps, load bitmaps that are "in use" -- if the image is read only. This will allow us to diagnose problems with this flag using the qemu-img tool. Signed-off-by: John Snow --- block/qcow2-bitmap.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index fc8d52fc3e..b556dbdccd 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -346,7 +346,7 @@ static BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs, uint32_t granularity; BdrvDirtyBitmap *bitmap = NULL; - if (bm->flags & BME_FLAG_IN_USE) { + if (can_write(bs) && (bm->flags & BME_FLAG_IN_USE)) { error_setg(errp, "Bitmap '%s' is in use", bm->name); goto fail; } @@ -974,23 +974,21 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp) } QSIMPLEQ_FOREACH(bm, bm_list, entry) { - if (!(bm->flags & BME_FLAG_IN_USE)) { - BdrvDirtyBitmap *bitmap = load_bitmap(bs, bm, errp); - if (bitmap == NULL) { - goto fail; - } - bm->dirty_bitmap = bitmap; + BdrvDirtyBitmap *bitmap = load_bitmap(bs, bm, errp); + if (bitmap == NULL) { + goto fail; + } + bm->dirty_bitmap = bitmap; - if (!(bm->flags & BME_FLAG_AUTO)) { - bdrv_disable_dirty_bitmap(bitmap); - } - bdrv_dirty_bitmap_set_persistance(bitmap, true); - if (can_write(bs)) { - bm->flags |= BME_FLAG_IN_USE; - needs_update = true; - } else { - bdrv_dirty_bitmap_set_readonly(bitmap, true); - } + if (!(bm->flags & BME_FLAG_AUTO)) { + bdrv_disable_dirty_bitmap(bitmap); + } + bdrv_dirty_bitmap_set_persistance(bitmap, true); + if (can_write(bs)) { + bm->flags |= BME_FLAG_IN_USE; + needs_update = true; + } else { + bdrv_dirty_bitmap_set_readonly(bitmap, true); } } From patchwork Sat May 12 01:25:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912332 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTrv2R66z9s16 for ; Sat, 12 May 2018 11:29:19 +1000 (AEST) Received: from localhost ([::1]:33821 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJLY-0000Sc-Tt for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:29:16 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40217) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJI9-0006LF-2X for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJI7-0006To-Ur for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:44 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:34108 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI5-0006OB-Iq; Fri, 11 May 2018 21:25:41 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3175D4075656; Sat, 12 May 2018 01:25:41 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id BD365215CDA7; Sat, 12 May 2018 01:25:40 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:30 -0400 Message-Id: <20180512012537.22478-6-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Sat, 12 May 2018 01:25:41 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Sat, 12 May 2018 01:25:41 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 05/12] qcow2-bitmap: track bitmap type X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" We only have one type of persistent bitmap right now, but I'd like the qemu-img tool to be able to give good diagnostic information if it sees an unknown/unsupported type. We do enforce it to be the dirty tracking type in check_dir_entry, but I wanted positive affirmation of the type in the forthcoming info script. Signed-off-by: John Snow --- block/qcow2-bitmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index b556dbdccd..60e01abfd7 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -83,6 +83,7 @@ typedef QSIMPLEQ_HEAD(Qcow2BitmapTableList, Qcow2BitmapTable) typedef struct Qcow2Bitmap { Qcow2BitmapTable table; uint32_t flags; + uint8_t type; uint8_t granularity_bits; char *name; @@ -608,6 +609,7 @@ static Qcow2BitmapList *bitmap_list_load(BlockDriverState *bs, Error **errp) bm->table.offset = e->bitmap_table_offset; bm->table.size = e->bitmap_table_size; bm->flags = e->flags; + bm->type = e->type; bm->granularity_bits = e->granularity_bits; bm->name = dir_entry_copy_name(e); QSIMPLEQ_INSERT_TAIL(bm_list, bm, entry); From patchwork Sat May 12 01:25:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912331 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTpR4bYdz9s16 for ; Sat, 12 May 2018 11:27:11 +1000 (AEST) Received: from localhost ([::1]:33814 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJJV-00071i-8X for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:27:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40256) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJI9-0006Me-Rq for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJI8-0006Ui-Ek for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:45 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33926 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI6-0006PS-2N; Fri, 11 May 2018 21:25:42 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A2D2615414D; Sat, 12 May 2018 01:25:41 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 405AF215CDA7; Sat, 12 May 2018 01:25:41 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:31 -0400 Message-Id: <20180512012537.22478-7-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:41 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:41 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 06/12] qapi: add bitmap info X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add some of the necessary scaffolding for reporting bitmap information. Signed-off-by: John Snow --- qapi/block-core.json | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index c50517bff3..8f33f41ce7 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -33,6 +33,61 @@ 'date-sec': 'int', 'date-nsec': 'int', 'vm-clock-sec': 'int', 'vm-clock-nsec': 'int' } } +## +# @BitmapTypeEnum: +# +# An enumeration of possible serialized bitmap types. +# +# @dirty-tracking: This bitmap records information on dirty +# segments within the file. +# +# @unknown: This bitmap is of an unknown or reserved type. +# +# Since: 2.13 +## +{ 'enum': 'BitmapTypeEnum', 'data': [ 'dirty-tracking', 'unknown' ] } + +## +# @BitmapFlagEnum: +# +# An enumeration of possible flags for serialized bitmaps. +# +# @in-use: This bitmap is considered to be in-use, and may now be inconsistent. +# +# @auto: This bitmap must reflect any and all changes to the file it describes. +# The type of this bitmap must be @DirtyTrackingBitmap. +# +# @extra-data-compatible: This bitmap has extra information associated with it. +# +# @unknown: This bitmap has unknown or reserved properties. +# +# Since: 2.13 +## +{ 'enum': 'BitmapFlagEnum', 'data': [ 'in-use', 'auto', + 'extra-data-compatible', 'unknown' ] } + +## +# @BitmapInfo: +# +# @name: The name of the bitmap. +# +# @type: The type of bitmap. +# +# @granularity: Bitmap granularity, in bytes. +# +# @count: Overall bitmap dirtiness, in bytes. +# +# @flags: Bitmap flags, if any. +# +# Since: 2.13 +# +## +{ 'struct': 'BitmapInfo', + 'data': { 'name': 'str', 'type': 'BitmapTypeEnum', 'granularity': 'int', + 'count': 'int', '*flags': ['BitmapFlagEnum'] + } +} + ## # @ImageInfoSpecificQCow2EncryptionBase: # @@ -69,6 +124,8 @@ # @encrypt: details about encryption parameters; only set if image # is encrypted (since 2.10) # +# @bitmaps: list of image bitmaps (since 2.13) +# # Since: 1.7 ## { 'struct': 'ImageInfoSpecificQCow2', @@ -77,7 +134,8 @@ '*lazy-refcounts': 'bool', '*corrupt': 'bool', 'refcount-bits': 'int', - '*encrypt': 'ImageInfoSpecificQCow2Encryption' + '*encrypt': 'ImageInfoSpecificQCow2Encryption', + '*bitmaps': ['BitmapInfo'] } } ## From patchwork Sat May 12 01:25:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912339 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTx76cB1z9s1b for ; Sat, 12 May 2018 11:32:59 +1000 (AEST) Received: from localhost ([::1]:33848 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJP7-0008I3-DY for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:32:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40300) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJIB-0006OB-3E for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJI9-0006WN-KI for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:47 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:34110 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI6-0006Qg-Ee; Fri, 11 May 2018 21:25:42 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 125294075659; Sat, 12 May 2018 01:25:42 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id AF72C215CDA7; Sat, 12 May 2018 01:25:41 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:32 -0400 Message-Id: <20180512012537.22478-8-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Sat, 12 May 2018 01:25:42 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Sat, 12 May 2018 01:25:42 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 07/12] qcow2-bitmap: add basic bitmaps info X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add functions for querying the basic information inside of bitmaps. Restructure the bitmaps flags masks to facilitate providing a list of flags belonging to the bitmap(s) being queried. Signed-off-by: John Snow --- block/qcow2-bitmap.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++-- block/qcow2.c | 7 +++++ block/qcow2.h | 1 + 3 files changed, 87 insertions(+), 2 deletions(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 60e01abfd7..811b82743a 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -49,8 +49,28 @@ /* Bitmap directory entry flags */ #define BME_RESERVED_FLAGS 0xfffffffcU -#define BME_FLAG_IN_USE (1U << 0) -#define BME_FLAG_AUTO (1U << 1) + +enum BME_FLAG_BITS { + BME_FLAG_BIT__BEGIN = 0, + BME_FLAG_BIT_IN_USE = BME_FLAG_BIT__BEGIN, + BME_FLAG_BIT_AUTO = 1, + BME_FLAG_BIT_EXTRA = 2, + BME_FLAG_BIT__MAX, +}; + +#define BME_FLAG_IN_USE (1U << BME_FLAG_BIT_IN_USE) +#define BME_FLAG_AUTO (1U << BME_FLAG_BIT_AUTO) +#define BME_FLAG_EXTRA (1U << BME_FLAG_BIT_EXTRA) + +/* Correlate canonical spec values to autogenerated QAPI values */ +struct { + uint32_t mask; + int qapi_value; +} BMEFlagMap[BME_FLAG_BIT__MAX] = { + [BME_FLAG_BIT_IN_USE] = { BME_FLAG_IN_USE, BITMAP_FLAG_ENUM_IN_USE }, + [BME_FLAG_BIT_AUTO] = { BME_FLAG_AUTO, BITMAP_FLAG_ENUM_AUTO }, + [BME_FLAG_BIT_EXTRA] = { BME_FLAG_EXTRA, BITMAP_FLAG_ENUM_EXTRA_DATA_COMPATIBLE }, +}; /* bits [1, 8] U [56, 63] are reserved */ #define BME_TABLE_ENTRY_RESERVED_MASK 0xff000000000001feULL @@ -663,6 +683,63 @@ static void del_bitmap_list(BlockDriverState *bs) } } +static BitmapFlagEnumList *get_bitmap_flags(uint32_t flags) +{ + int i; + BitmapFlagEnumList *flist = NULL; + BitmapFlagEnumList *ftmp; + + while (flags) { + i = ctz32(flags); + ftmp = g_new0(BitmapFlagEnumList, 1); + if (i >= BME_FLAG_BIT__BEGIN && i < BME_FLAG_BIT__MAX) { + ftmp->value = BMEFlagMap[i].qapi_value; + } else { + ftmp->value = BITMAP_FLAG_ENUM_UNKNOWN; + } + ftmp->next = flist; + flist = ftmp; + flags &= ~(1 << i); + } + + return flist; +} + +BitmapInfoList *qcow2_get_bitmap_info(BlockDriverState *bs) +{ + Qcow2BitmapList *bm_list; + Qcow2Bitmap *bm; + BitmapInfoList *info_list = NULL; + BitmapInfoList *tmp; + BitmapInfo *bitmap_info; + + bm_list = get_bitmap_list(bs, NULL); + if (!bm_list) { + return info_list; + } + + QSIMPLEQ_FOREACH(bm, bm_list, entry) { + bitmap_info = g_new0(BitmapInfo, 1); + bitmap_info->name = g_strdup(bm->name); + if (bm->type == BT_DIRTY_TRACKING_BITMAP) { + bitmap_info->type = BITMAP_TYPE_ENUM_DIRTY_TRACKING; + } else { + bitmap_info->type = BITMAP_TYPE_ENUM_UNKNOWN; + } + bitmap_info->granularity = 1 << bm->granularity_bits; + bitmap_info->count = bdrv_get_dirty_count(bm->dirty_bitmap); + bitmap_info->flags = get_bitmap_flags(bm->flags); + bitmap_info->has_flags = !!bitmap_info->flags; + + tmp = g_new0(BitmapInfoList, 1); + tmp->value = bitmap_info; + tmp->next = info_list; + info_list = tmp; + } + + return info_list; +} + int qcow2_check_bitmaps_refcounts(BlockDriverState *bs, BdrvCheckResult *res, void **refcount_table, int64_t *refcount_table_size) diff --git a/block/qcow2.c b/block/qcow2.c index 7ae9000656..0b24ecb6b2 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3960,6 +3960,7 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs) BDRVQcow2State *s = bs->opaque; ImageInfoSpecific *spec_info; QCryptoBlockInfo *encrypt_info = NULL; + BitmapInfoList *bitmap_list = NULL; if (s->crypto != NULL) { encrypt_info = qcrypto_block_get_info(s->crypto, &error_abort); @@ -4016,6 +4017,12 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs) spec_info->u.qcow2.data->encrypt = qencrypt; } + bitmap_list = qcow2_get_bitmap_info(bs); + if (bitmap_list) { + spec_info->u.qcow2.data->has_bitmaps = true; + spec_info->u.qcow2.data->bitmaps = bitmap_list; + } + return spec_info; } diff --git a/block/qcow2.h b/block/qcow2.h index 796a8c914b..76bf5fa55d 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -686,5 +686,6 @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs, void qcow2_remove_persistent_dirty_bitmap(BlockDriverState *bs, const char *name, Error **errp); +BitmapInfoList *qcow2_get_bitmap_info(BlockDriverState *bs); #endif From patchwork Sat May 12 01:25:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912335 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTsc11D9z9s1b for ; Sat, 12 May 2018 11:29:56 +1000 (AEST) Received: from localhost ([::1]:33830 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJM9-0000z3-Hv for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:29:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40267) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJIA-0006Mx-4Z for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJI9-0006VZ-2J for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:46 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33930 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI6-0006S0-RQ; Fri, 11 May 2018 21:25:42 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7C48C15414F; Sat, 12 May 2018 01:25:42 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1F4B8215CDA7; Sat, 12 May 2018 01:25:42 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:33 -0400 Message-Id: <20180512012537.22478-9-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:42 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:42 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 08/12] qjson: allow caller to ask for arbitrary indent X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The function already exists, just expose it. Signed-off-by: John Snow --- include/qapi/qmp/qjson.h | 1 + qobject/qjson.c | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/qapi/qmp/qjson.h b/include/qapi/qmp/qjson.h index b274ac3a86..0e8624c1fa 100644 --- a/include/qapi/qmp/qjson.h +++ b/include/qapi/qmp/qjson.h @@ -19,6 +19,7 @@ QObject *qobject_from_jsonf(const char *string, ...) GCC_FMT_ATTR(1, 2); QObject *qobject_from_jsonv(const char *string, va_list *ap, Error **errp) GCC_FMT_ATTR(1, 0); +QString *qobject_to_json_opt(const QObject *obj, int pretty, int indent); QString *qobject_to_json(const QObject *obj); QString *qobject_to_json_pretty(const QObject *obj); diff --git a/qobject/qjson.c b/qobject/qjson.c index 9816a65c7d..d603e1cce1 100644 --- a/qobject/qjson.c +++ b/qobject/qjson.c @@ -252,20 +252,21 @@ static void to_json(const QObject *obj, QString *str, int pretty, int indent) } } +QString *qobject_to_json_opt(const QObject *obj, int pretty, int indent) +{ + QString *str = qstring_new(); + + to_json(obj, str, pretty, indent); + + return str; +} + QString *qobject_to_json(const QObject *obj) { - QString *str = qstring_new(); - - to_json(obj, str, 0, 0); - - return str; + return qobject_to_json_opt(obj, 0, 0); } QString *qobject_to_json_pretty(const QObject *obj) { - QString *str = qstring_new(); - - to_json(obj, str, 1, 0); - - return str; + return qobject_to_json_opt(obj, 1, 0); } From patchwork Sat May 12 01:25:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912329 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTpG3xXkz9s16 for ; Sat, 12 May 2018 11:27:02 +1000 (AEST) Received: from localhost ([::1]:33813 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJJM-0006t0-4h for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:27:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40316) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJIB-0006Oh-C4 for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJIA-0006XJ-An for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:47 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:34114 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI7-0006Se-Bg; Fri, 11 May 2018 21:25:43 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EC5254075832; Sat, 12 May 2018 01:25:42 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 88438215CDA7; Sat, 12 May 2018 01:25:42 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:34 -0400 Message-Id: <20180512012537.22478-10-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Sat, 12 May 2018 01:25:42 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Sat, 12 May 2018 01:25:42 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 09/12] qapi/block-core: add BitmapMapping and BitmapEntry structs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Add two new structures for detailing the marked regions of bitmaps as saved in e.g. qcow2 files. Signed-off-by: John Snow --- qapi/block-core.json | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/qapi/block-core.json b/qapi/block-core.json index 8f33f41ce7..de8ad73a78 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -298,6 +298,38 @@ 'zero': 'bool', 'depth': 'int', '*offset': 'int', '*filename': 'str' } } +## +# @BitmapEntry: +# +# Dirty Bitmap region information for a virtual block range +# +# @offset: the start byte of the dirty virtual range +# +# @length: the number of bytes of the dirty virtual range +# +# Since: 2.13 +# +## +{ 'struct': 'BitmapEntry', + 'data': { 'offset': 'int', 'length': 'int' } } + +## +# @BitmapMapping: +# +# List of described regions correlated to a named bitmap. +# +# @name: The name of the bitmap whose range is described here +# +# @entries: A list of zero or more @BitmapEntry elements representing +# the range(s) described by the bitmap. +# +# Since: 2.13 +# +## +{ 'struct': 'BitmapMapping', + 'data': { 'name': 'str', + 'entries': [ 'BitmapEntry' ] } } + ## # @BlockdevCacheInfo: # From patchwork Sat May 12 01:25:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912338 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTwr1j60z9s16 for ; Sat, 12 May 2018 11:32:44 +1000 (AEST) Received: from localhost ([::1]:33843 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJOr-0006Fj-Nt for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:32:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40344) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJIE-0006SU-Ay for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJIB-0006Ye-Ms for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:50 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33394 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI7-0006TL-PK; Fri, 11 May 2018 21:25:43 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6D8D67D65F; Sat, 12 May 2018 01:25:43 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 07455215CDA7; Sat, 12 May 2018 01:25:42 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:35 -0400 Message-Id: <20180512012537.22478-11-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sat, 12 May 2018 01:25:43 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Sat, 12 May 2018 01:25:43 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 10/12] qemu-img: split off common chunk of map command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" It will be re-used for a bitmap listing command. Signed-off-by: John Snow --- qemu-img.c | 192 +++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 110 insertions(+), 82 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index ea62d2d61e..e31e38f674 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -69,8 +69,8 @@ enum { }; typedef enum OutputFormat { - OFORMAT_JSON, OFORMAT_HUMAN, + OFORMAT_JSON, } OutputFormat; /* Default to cache=writeback as data integrity is not important for qemu-img */ @@ -2728,96 +2728,122 @@ static inline bool entry_mergeable(const MapEntry *curr, const MapEntry *next) return true; } +typedef struct CommonOpts { + OutputFormat output_format; + const char *filename; + const char *fmt; + bool force_share; + bool image_opts; +} CommonOpts; + +static int parse_opts_common(CommonOpts *opts, int argc, char **argv) +{ + int c; + + for (;;) { + int option_index = 0; + static const struct option long_options[] = { + {"help", no_argument, 0, 'h'}, + {"format", required_argument, 0, 'f'}, + {"output", required_argument, 0, OPTION_OUTPUT}, + {"object", required_argument, 0, OPTION_OBJECT}, + {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, + {"force-share", no_argument, 0, 'U'}, + {0, 0, 0, 0} + }; + c = getopt_long(argc, argv, ":f:hU", + long_options, &option_index); + if (c == -1) { + break; + } + switch (c) { + case ':': + missing_argument(argv[optind - 1]); + break; + case '?': + unrecognized_option(argv[optind - 1]); + break; + case 'h': + help(); + break; + case 'f': + opts->fmt = optarg; + break; + case 'U': + opts->force_share = true; + break; + case OPTION_OUTPUT: + if (optarg && !strcmp(optarg, "json")) { + opts->output_format = OFORMAT_JSON; + } else if (optarg && !strcmp(optarg, "human")) { + opts->output_format = OFORMAT_HUMAN; + } else { + error_report("--output must be used with human or json as argument."); + return -EINVAL; + } + break; + case OPTION_OBJECT: { + QemuOpts *opts; + opts = qemu_opts_parse_noisily(&qemu_object_opts, + optarg, true); + if (!opts) { + return -EINVAL; + } + } break; + case OPTION_IMAGE_OPTS: + opts->image_opts = true; + break; + } + } + if (qemu_opts_foreach(&qemu_object_opts, + user_creatable_add_opts_foreach, + NULL, NULL)) { + return -EINVAL; + } + + return 0; +} + +static void parse_positional(int argc, char *argv[], + bool opt, const char **str, const char *name) { + if (!opt && optind >= argc) { + error_exit("Expecting '%s' positional parameter", name); + } else if (optind < argc) { + *str = argv[optind++]; + } +} + +static void parse_unexpected(int argc, char *argv[]) { + if (optind != argc) { + error_exit("Unexpected argument '%s'\n", argv[optind]); + } +} + static int img_map(int argc, char **argv) { - int c; - OutputFormat output_format = OFORMAT_HUMAN; BlockBackend *blk; BlockDriverState *bs; - const char *filename, *fmt, *output; int64_t length; + int ret = 0; MapEntry curr = { .length = 0 }, next; - int ret = 0; - bool image_opts = false; - bool force_share = false; + CommonOpts *opts; - fmt = NULL; - output = NULL; - for (;;) { - int option_index = 0; - static const struct option long_options[] = { - {"help", no_argument, 0, 'h'}, - {"format", required_argument, 0, 'f'}, - {"output", required_argument, 0, OPTION_OUTPUT}, - {"object", required_argument, 0, OPTION_OBJECT}, - {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, - {"force-share", no_argument, 0, 'U'}, - {0, 0, 0, 0} - }; - c = getopt_long(argc, argv, ":f:hU", - long_options, &option_index); - if (c == -1) { - break; - } - switch (c) { - case ':': - missing_argument(argv[optind - 1]); - break; - case '?': - unrecognized_option(argv[optind - 1]); - break; - case 'h': - help(); - break; - case 'f': - fmt = optarg; - break; - case 'U': - force_share = true; - break; - case OPTION_OUTPUT: - output = optarg; - break; - case OPTION_OBJECT: { - QemuOpts *opts; - opts = qemu_opts_parse_noisily(&qemu_object_opts, - optarg, true); - if (!opts) { - return 1; - } - } break; - case OPTION_IMAGE_OPTS: - image_opts = true; - break; - } - } - if (optind != argc - 1) { - error_exit("Expecting one image file name"); - } - filename = argv[optind]; - - if (output && !strcmp(output, "json")) { - output_format = OFORMAT_JSON; - } else if (output && !strcmp(output, "human")) { - output_format = OFORMAT_HUMAN; - } else if (output) { - error_report("--output must be used with human or json as argument."); - return 1; - } - - if (qemu_opts_foreach(&qemu_object_opts, - user_creatable_add_opts_foreach, - NULL, NULL)) { - return 1; + opts = g_new0(CommonOpts, 1); + if (parse_opts_common(opts, argc, argv)) { + return EXIT_FAILURE; } + parse_positional(argc, argv, 0, &opts->filename, "filename"); + parse_unexpected(argc, argv); - blk = img_open(image_opts, filename, fmt, 0, false, false, force_share); + blk = img_open(opts->image_opts, opts->filename, opts->fmt, 0, + false, false, opts->force_share); if (!blk) { - return 1; + ret = -1; + goto out1; } bs = blk_bs(blk); - if (output_format == OFORMAT_HUMAN) { + if (opts->output_format == OFORMAT_HUMAN) { printf("%-16s%-16s%-16s%s\n", "Offset", "Length", "Mapped to", "File"); } @@ -2832,7 +2858,7 @@ static int img_map(int argc, char **argv) if (ret < 0) { error_report("Could not read file metadata: %s", strerror(-ret)); - goto out; + goto out2; } if (entry_mergeable(&curr, &next)) { @@ -2841,15 +2867,17 @@ static int img_map(int argc, char **argv) } if (curr.length > 0) { - dump_map_entry(output_format, &curr, &next); + dump_map_entry(opts->output_format, &curr, &next); } curr = next; } - dump_map_entry(output_format, &curr, NULL); + dump_map_entry(opts->output_format, &curr, NULL); -out: +out2: blk_unref(blk); +out1: + g_free(opts); return ret < 0; } From patchwork Sat May 12 01:25:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912340 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTyW3q09z9s16 for ; Sat, 12 May 2018 11:34:11 +1000 (AEST) Received: from localhost ([::1]:33851 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJQH-0008Ay-3p for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:34:09 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40342) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJIE-0006SQ-Ae for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJIB-0006Ym-PB for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:50 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:46944 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI8-0006UJ-CA; Fri, 11 May 2018 21:25:44 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D255D4077B9C; Sat, 12 May 2018 01:25:43 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id 79AE7215CDA7; Sat, 12 May 2018 01:25:43 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:36 -0400 Message-Id: <20180512012537.22478-12-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Sat, 12 May 2018 01:25:43 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.7]); Sat, 12 May 2018 01:25:43 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 11/12] qemu-img: add bitmap dump X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: John Snow --- qemu-img-cmds.hx | 6 ++ qemu-img.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 191 insertions(+) diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx index 2fe31893cf..d25f359f5a 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -22,6 +22,12 @@ STEXI @item bench [-c @var{count}] [-d @var{depth}] [-f @var{fmt}] [--flush-interval=@var{flush_interval}] [-n] [--no-drain] [-o @var{offset}] [--pattern=@var{pattern}] [-q] [-s @var{buffer_size}] [-S @var{step_size}] [-t @var{cache}] [-w] [-U] @var{filename} ETEXI +DEF("bitmap", img_bitmap, + "bitmap dump [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [-U] filename [bitmap]") +STEXI +@item bitmap dump [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [--output=@var{ofmt}] [-U] @var{filename} [@var{bitmap}] +ETEXI + DEF("check", img_check, "check [-q] [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [-r [leaks | all]] [-T src_cache] [-U] filename") STEXI diff --git a/qemu-img.c b/qemu-img.c index e31e38f674..1141216617 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -2881,6 +2881,191 @@ out1: return ret < 0; } +static BitmapMapping *get_bitmap_mapping(BdrvDirtyBitmap *bitmap) +{ + BdrvDirtyBitmapIter *it = bdrv_dirty_iter_new(bitmap); + BitmapMapping *bm = g_new0(BitmapMapping, 1); + BitmapEntry *entry; + BitmapEntryList *tmp, **last; + int64_t offset; + int64_t zero_offset; + + bm->name = g_strdup(bdrv_dirty_bitmap_name(bitmap)); + bm->entries = NULL; + last = &bm->entries; + + while (true) { + offset = bdrv_dirty_iter_next(it); + if (offset == -1) { + break; + } + + zero_offset = bdrv_dirty_bitmap_next_zero(bitmap, offset); + if (zero_offset == -1) { + zero_offset = bdrv_dirty_bitmap_size(bitmap); + } + + entry = g_new0(BitmapEntry, 1); + entry->offset = offset; + entry->length = zero_offset - offset; + + tmp = g_new0(BitmapEntryList, 1); + tmp->value = entry; + *last = tmp; + last = &tmp->next; + + if (zero_offset >= bdrv_dirty_bitmap_size(bitmap)) { + break; + } + bdrv_set_dirty_iter(it, zero_offset); + } + + bdrv_dirty_iter_free(it); + return bm; +} + +static void dump_bitmap_mapping_json(BitmapMapping *bm, int indent, + FILE *stream) +{ + QString *str; + QObject *obj; + Visitor *v = qobject_output_visitor_new(&obj); + const int pretty = 1; + + visit_type_BitmapMapping(v, NULL, &bm, &error_abort); + visit_complete(v, &obj); + str = qobject_to_json_opt(obj, pretty, indent); + assert(str != NULL); + fprintf(stream, "%*s%s", 4 * indent, "", qstring_get_str(str)); + qobject_unref(obj); + visit_free(v); + qobject_unref(str); +} + +static void dump_bitmap_mapping_human(BitmapMapping *bm, FILE *stream) +{ + BitmapEntryList *bl = bm->entries; + + fprintf(stream, "# %s\n", bm->name); + fprintf(stream, "%-16s%-16s\n", "Offset", "Length"); + for ( ; bl; bl = bl->next) { + BitmapEntry *be = bl->value; + fprintf(stream, "%-16"PRId64"%-16"PRId64"\n", be->offset, be->length); + } +} + +static void dump_bitmap_mapping(BitmapMapping *bm, OutputFormat output_format, + int indent, FILE *stream) +{ + switch (output_format) { + case OFORMAT_JSON: + dump_bitmap_mapping_json(bm, indent, stream); + return; + case OFORMAT_HUMAN: + dump_bitmap_mapping_human(bm, stream); + return; + } +} + +/* img_bitmap subcommands: dump */ + +typedef struct BitmapOpts { + CommonOpts base; + const char *name; + uint32_t granularity; +} BitmapOpts; + +static int bitmap_cmd_dump(BlockDriverState *bs, BitmapOpts *opts) +{ + BdrvDirtyBitmap *bitmap; + BitmapMapping *bm; + bool printed; + OutputFormat ofmt = opts->base.output_format; + + if (opts->name) { + bitmap = bdrv_find_dirty_bitmap(bs, opts->name); + if (bitmap) { + bm = get_bitmap_mapping(bitmap); + dump_bitmap_mapping(bm, ofmt, 0, stdout); + qapi_free_BitmapMapping(bm); + } else { + if (ofmt == OFORMAT_HUMAN) { + fprintf(stdout, "Bitmap '%s' not found\n", opts->name); + } + } + } else { + if (ofmt == OFORMAT_JSON) { + fprintf(stdout, "[\n"); + } + for (bitmap = NULL, printed = false; + (bitmap = bdrv_dirty_bitmap_next(bs, bitmap)); printed = true) { + if (printed) { + fprintf(stdout, ofmt == OFORMAT_JSON ? ",\n" : "\n"); + } + bm = get_bitmap_mapping(bitmap); + dump_bitmap_mapping(bm, ofmt, 1, stdout); + qapi_free_BitmapMapping(bm); + } + if (ofmt == OFORMAT_JSON) { + fprintf(stdout, "%s%s", printed ? "\n" : "", "]\n"); + } + if (ofmt == OFORMAT_HUMAN && printed == false) { + fprintf(stdout, "No bitmaps are present in this image.\n"); + } + } + + return 0; +} + +static int img_bitmap(int argc, char **argv) +{ + const char *cmd; + BitmapOpts *opts; + BlockBackend *blk; + BlockDriverState *bs; + const char *bname = NULL; + int flags = 0; + int ret = EXIT_SUCCESS; + int (* handler)(BlockDriverState *b, BitmapOpts *opts); + + if (argc < 2) { + error_report("Expected a bitmap subcommand: "); + return EXIT_FAILURE; + } + cmd = argv[1]; + if (strcmp(cmd, "dump") == 0) { + handler = bitmap_cmd_dump; + } else { + error_report("Unrecognized bitmap subcommand '%s'", cmd); + return EXIT_FAILURE; + } + + opts = g_new0(BitmapOpts, 1); + if (parse_opts_common(&opts->base, --argc, ++argv)) { + return EXIT_FAILURE; + } + parse_positional(argc, argv, 0, &opts->base.filename, "filename"); + parse_positional(argc, argv, 1, &bname, "bitmap"); + parse_unexpected(argc, argv); + + blk = img_open(opts->base.image_opts, opts->base.filename, opts->base.fmt, + flags, false, false, opts->base.force_share); + if (!blk) { + ret = EXIT_FAILURE; + goto out; + } + bs = blk_bs(blk); + + if (handler(bs, opts)) { + ret = EXIT_FAILURE; + } + + blk_unref(blk); + out: + g_free(opts); + return ret; +} + #define SNAPSHOT_LIST 1 #define SNAPSHOT_CREATE 2 #define SNAPSHOT_APPLY 3 From patchwork Sat May 12 01:25:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 912334 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40jTsN4grdz9s16 for ; Sat, 12 May 2018 11:29:44 +1000 (AEST) Received: from localhost ([::1]:33827 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJLy-0000px-6q for incoming@patchwork.ozlabs.org; Fri, 11 May 2018 21:29:42 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40343) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fHJIE-0006SR-Af for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fHJIB-0006Yr-Pt for qemu-devel@nongnu.org; Fri, 11 May 2018 21:25:50 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:33936 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fHJI8-0006Ue-PQ; Fri, 11 May 2018 21:25:44 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 448B3F640A; Sat, 12 May 2018 01:25:44 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-231.bos.redhat.com [10.18.17.231]) by smtp.corp.redhat.com (Postfix) with ESMTP id E01BB215CDB7; Sat, 12 May 2018 01:25:43 +0000 (UTC) From: John Snow To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Fri, 11 May 2018 21:25:37 -0400 Message-Id: <20180512012537.22478-13-jsnow@redhat.com> In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com> References: <20180512012537.22478-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:44 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Sat, 12 May 2018 01:25:44 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'jsnow@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [RFC PATCH 12/12] qemu-img: add bitmap clear X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Markus Armbruster , Max Reitz , John Snow Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: John Snow --- qemu-img-cmds.hx | 4 ++-- qemu-img.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 4 deletions(-) diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx index d25f359f5a..7b6ec73488 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -23,9 +23,9 @@ STEXI ETEXI DEF("bitmap", img_bitmap, - "bitmap dump [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [-U] filename [bitmap]") + "bitmap [--object objectdef] [--image-opts] [-f fmt] [--output=ofmt] [-U] filename [bitmap]") STEXI -@item bitmap dump [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [--output=@var{ofmt}] [-U] @var{filename} [@var{bitmap}] +@item bitmap [--object @var{objectdef}] [--image-opts] [-f @var{fmt}] [--output=@var{ofmt}] [-U] @var{filename} [@var{bitmap}] ETEXI DEF("check", img_check, diff --git a/qemu-img.c b/qemu-img.c index 1141216617..b5ab8a3837 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -2967,7 +2967,22 @@ static void dump_bitmap_mapping(BitmapMapping *bm, OutputFormat output_format, } } -/* img_bitmap subcommands: dump */ +static int do_bitmap_clear(BlockDriverState *bs, BdrvDirtyBitmap *bitmap) +{ + bool enabled = bdrv_dirty_bitmap_enabled(bitmap); + + if (!enabled) { + bdrv_enable_dirty_bitmap(bitmap); + } + bdrv_clear_dirty_bitmap(bitmap, NULL); + if (!enabled) { + bdrv_disable_dirty_bitmap(bitmap); + } + + return 0; +} + +/* img_bitmap subcommands: dump, clear */ typedef struct BitmapOpts { CommonOpts base; @@ -3017,6 +3032,30 @@ static int bitmap_cmd_dump(BlockDriverState *bs, BitmapOpts *opts) return 0; } +static int bitmap_cmd_clear(BlockDriverState *bs, BitmapOpts *opts) +{ + BdrvDirtyBitmap *bitmap = NULL; + + if (opts->name) { + bitmap = bdrv_find_dirty_bitmap(bs, opts->name); + if (!bitmap) { + error_report("No bitmap named '%s' found", opts->name); + return -1; + } + if (do_bitmap_clear(bs, bitmap)) { + return -1; + } + } else { + while ((bitmap = bdrv_dirty_bitmap_next(bs, bitmap))) { + if (do_bitmap_clear(bs, bitmap)) { + return -1; + } + } + } + + return 0; +} + static int img_bitmap(int argc, char **argv) { const char *cmd; @@ -3029,12 +3068,15 @@ static int img_bitmap(int argc, char **argv) int (* handler)(BlockDriverState *b, BitmapOpts *opts); if (argc < 2) { - error_report("Expected a bitmap subcommand: "); + error_report("Expected a bitmap subcommand: "); return EXIT_FAILURE; } cmd = argv[1]; if (strcmp(cmd, "dump") == 0) { handler = bitmap_cmd_dump; + } else if (strcmp(cmd, "clear") == 0) { + flags |= BDRV_O_RDWR; + handler = bitmap_cmd_clear; } else { error_report("Unrecognized bitmap subcommand '%s'", cmd); return EXIT_FAILURE;