From patchwork Fri Mar 1 19:15:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 10835929 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7300E1805 for ; Fri, 1 Mar 2019 19:18:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 62E082FD29 for ; Fri, 1 Mar 2019 19:18:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 564E02FD2D; Fri, 1 Mar 2019 19:18:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id B7FF82FD29 for ; Fri, 1 Mar 2019 19:18:42 +0000 (UTC) Received: from localhost ([127.0.0.1]:42754 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzngA-00044Z-15 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 01 Mar 2019 14:18:42 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34709) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzndh-0002Ab-2k for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gzndc-0008BP-Vv for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:06 -0500 Received: from mx1.redhat.com ([209.132.183.28]:39826) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gzndS-0007vt-Vz; Fri, 01 Mar 2019 14:15:57 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2C5E2C067C30; Fri, 1 Mar 2019 19:15:53 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-206.bos.redhat.com [10.18.17.206]) by smtp.corp.redhat.com (Postfix) with ESMTP id EBED81001E62; Fri, 1 Mar 2019 19:15:51 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 1 Mar 2019 14:15:39 -0500 Message-Id: <20190301191545.8728-2-jsnow@redhat.com> In-Reply-To: <20190301191545.8728-1-jsnow@redhat.com> References: <20190301191545.8728-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 01 Mar 2019 19:15:53 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 1/7] block/dirty-bitmaps: add inconsistent bit 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: Fam Zheng , Kevin Wolf , vsementsov@virtuozzo.com, Juan Quintela , Markus Armbruster , Max Reitz , Stefan Hajnoczi , John Snow , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Add an inconsistent bit to dirty-bitmaps that allows us to report a bitmap as persistent but potentially inconsistent, i.e. if we find bitmaps on a qcow2 that have been marked as "in use". Signed-off-by: John Snow Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- qapi/block-core.json | 13 +++++++++---- include/block/dirty-bitmap.h | 2 ++ block/dirty-bitmap.c | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 6e543594b3..e639ef6d1c 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -467,15 +467,20 @@ # and cannot be modified via QMP or used by another operation. # Replaces `locked` and `frozen` statuses. (since 4.0) # -# @persistent: true if the bitmap will eventually be flushed to persistent -# storage (since 4.0) +# @persistent: true if the bitmap was stored on disk, is scheduled to be stored +# on disk, or both. (since 4.0) +# +# @inconsistent: true if this is a persistent bitmap that was improperly +# stored. Implies @persistent to be true; @recording and +# @busy to be false. This bitmap cannot be used. To remove +# it, use @block-dirty-bitmap-remove. (Since 4.0) # # Since: 1.3 ## { 'struct': 'BlockDirtyInfo', 'data': {'*name': 'str', 'count': 'int', 'granularity': 'uint32', - 'recording': 'bool', 'busy': 'bool', - 'status': 'DirtyBitmapStatus', 'persistent': 'bool' } } + 'recording': 'bool', 'busy': 'bool', 'status': 'DirtyBitmapStatus', + 'persistent': 'bool', '*inconsistent': 'bool' } } ## # @Qcow2BitmapInfoFlags: diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h index ba8477b73f..bd1b6479df 100644 --- a/include/block/dirty-bitmap.h +++ b/include/block/dirty-bitmap.h @@ -68,6 +68,7 @@ void bdrv_dirty_bitmap_deserialize_finish(BdrvDirtyBitmap *bitmap); void bdrv_dirty_bitmap_set_readonly(BdrvDirtyBitmap *bitmap, bool value); void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent); +void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap); void bdrv_dirty_bitmap_set_busy(BdrvDirtyBitmap *bitmap, bool busy); void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src, HBitmap **backup, Error **errp); @@ -91,6 +92,7 @@ bool bdrv_dirty_bitmap_readonly(const BdrvDirtyBitmap *bitmap); bool bdrv_has_readonly_bitmaps(BlockDriverState *bs); bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap); +bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_busy(BdrvDirtyBitmap *bitmap); bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs); BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 980cae4fa3..9e8630e1ac 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -46,6 +46,9 @@ struct BdrvDirtyBitmap { and this bitmap must remain unchanged while this flag is set. */ bool persistent; /* bitmap must be saved to owner disk image */ + bool inconsistent; /* bitmap is persistent, but inconsistent. + * It cannot be used at all in any way, except + * a QMP user can remove it. */ bool migration; /* Bitmap is selected for migration, it should not be stored on the next inactivation (persistent flag doesn't matter until next @@ -464,6 +467,8 @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) info->recording = bdrv_dirty_bitmap_recording(bm); info->busy = bdrv_dirty_bitmap_busy(bm); info->persistent = bm->persistent; + info->has_inconsistent = bm->inconsistent; + info->inconsistent = bm->inconsistent; entry->value = info; *plist = entry; plist = &entry->next; @@ -711,6 +716,15 @@ void bdrv_dirty_bitmap_set_persistance(BdrvDirtyBitmap *bitmap, bool persistent) qemu_mutex_unlock(bitmap->mutex); } +/* Called with BQL taken. */ +void bdrv_dirty_bitmap_set_inconsistent(BdrvDirtyBitmap *bitmap) +{ + qemu_mutex_lock(bitmap->mutex); + bitmap->inconsistent = true; + bitmap->disabled = true; + qemu_mutex_unlock(bitmap->mutex); +} + /* Called with BQL taken. */ void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration) { @@ -724,6 +738,11 @@ bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap) return bitmap->persistent && !bitmap->migration; } +bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap) +{ + return bitmap->inconsistent; +} + bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs) { BdrvDirtyBitmap *bm; From patchwork Fri Mar 1 19:15:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 10835925 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B02D11805 for ; Fri, 1 Mar 2019 19:17:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9DFFE2FD25 for ; Fri, 1 Mar 2019 19:17:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 918FC2FD2A; Fri, 1 Mar 2019 19:17:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3E55C2FD25 for ; Fri, 1 Mar 2019 19:17:54 +0000 (UTC) Received: from localhost ([127.0.0.1]:42744 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gznfN-0003UD-1I for patchwork-qemu-devel@patchwork.kernel.org; Fri, 01 Mar 2019 14:17:53 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34750) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzndj-0002CU-2o for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gzndg-0008EX-Vt for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:3136) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gzndV-0007yx-F4; Fri, 01 Mar 2019 14:15:58 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 808FA30C250C; Fri, 1 Mar 2019 19:15:54 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-206.bos.redhat.com [10.18.17.206]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4B95D1001DE2; Fri, 1 Mar 2019 19:15:53 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 1 Mar 2019 14:15:40 -0500 Message-Id: <20190301191545.8728-3-jsnow@redhat.com> In-Reply-To: <20190301191545.8728-1-jsnow@redhat.com> References: <20190301191545.8728-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Fri, 01 Mar 2019 19:15:54 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 2/7] block/dirty-bitmap: add inconsistent status 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: Fam Zheng , Kevin Wolf , vsementsov@virtuozzo.com, Juan Quintela , Markus Armbruster , Max Reitz , Stefan Hajnoczi , John Snow , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Even though the status field is deprecated, we still have to support it for a few more releases. Since this is a very new kind of bitmap state, it makes sense for it to have its own status field. Reviewed-by: Eric Blake Signed-off-by: John Snow Reviewed-by: Vladimir Sementsov-Ogievskiy --- qapi/block-core.json | 7 ++++++- block/dirty-bitmap.c | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index e639ef6d1c..ae55cd0704 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -442,10 +442,15 @@ # recording new writes. If the bitmap was @disabled, it is not # recording new writes. (Since 2.12) # +# @inconsistent: This is a persistent dirty bitmap that was marked in-use on +# disk, and is unusable by QEMU. It can only be deleted. +# Please rely on the inconsistent field in @BlockDirtyInfo +# instead, as the status field is deprecated. (Since 4.0) +# # Since: 2.4 ## { 'enum': 'DirtyBitmapStatus', - 'data': ['active', 'disabled', 'frozen', 'locked'] } + 'data': ['active', 'disabled', 'frozen', 'locked', 'inconsistent'] } ## # @BlockDirtyInfo: diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 9e8630e1ac..71e0098396 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -209,10 +209,15 @@ bool bdrv_dirty_bitmap_enabled(BdrvDirtyBitmap *bitmap) * or it can be Disabled and not recording writes. * (4) Locked: Whether Active or Disabled, the user cannot modify this bitmap * in any way from the monitor. + * (5) Inconsistent: This is a persistent bitmap whose "in use" bit is set, and + * is unusable by QEMU. It can be deleted to remove it from + * the qcow2. */ DirtyBitmapStatus bdrv_dirty_bitmap_status(BdrvDirtyBitmap *bitmap) { - if (bdrv_dirty_bitmap_has_successor(bitmap)) { + if (bdrv_dirty_bitmap_inconsistent(bitmap)) { + return DIRTY_BITMAP_STATUS_INCONSISTENT; + } else if (bdrv_dirty_bitmap_has_successor(bitmap)) { return DIRTY_BITMAP_STATUS_FROZEN; } else if (bdrv_dirty_bitmap_busy(bitmap)) { return DIRTY_BITMAP_STATUS_LOCKED; From patchwork Fri Mar 1 19:15:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 10835935 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 835091805 for ; Fri, 1 Mar 2019 19:21:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 720892F443 for ; Fri, 1 Mar 2019 19:21:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 668712F4EC; Fri, 1 Mar 2019 19:21:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id A0A482F443 for ; Fri, 1 Mar 2019 19:21:14 +0000 (UTC) Received: from localhost ([127.0.0.1]:42811 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gznib-0006Ub-Rv for patchwork-qemu-devel@patchwork.kernel.org; Fri, 01 Mar 2019 14:21:13 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34792) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzndm-0002GQ-NX for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gzndj-0008Gu-1Q for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47894) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gzndW-00081R-Pi; Fri, 01 Mar 2019 14:16:00 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D3981306D33A; Fri, 1 Mar 2019 19:15:55 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-206.bos.redhat.com [10.18.17.206]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9FD1D1001DE2; Fri, 1 Mar 2019 19:15:54 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 1 Mar 2019 14:15:41 -0500 Message-Id: <20190301191545.8728-4-jsnow@redhat.com> In-Reply-To: <20190301191545.8728-1-jsnow@redhat.com> References: <20190301191545.8728-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.47]); Fri, 01 Mar 2019 19:15:55 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 3/7] block/dirty-bitmaps: add block_dirty_bitmap_check function 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: Fam Zheng , Kevin Wolf , vsementsov@virtuozzo.com, Juan Quintela , Markus Armbruster , Max Reitz , Stefan Hajnoczi , John Snow , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Instead of checking against busy, inconsistent, or read only directly, use a check function with permissions bits that let us streamline the checks without reproducing them in many places. Included in this patch are permissions changes that simply add the inconsistent check to existing permissions call spots, without addressing existing bugs. In general, this means that busy+readonly checks become BDRV_BITMAP_DEFAULT, which checks against all three conditions. busy-only checks become BDRV_BITMAP_ALLOW_RO. Notably, remove allows inconsistent bitmaps, so it doesn't follow the pattern. Signed-off-by: John Snow Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/block/dirty-bitmap.h | 13 ++++++++- block/dirty-bitmap.c | 38 +++++++++++++++++++------- blockdev.c | 49 +++++++--------------------------- migration/block-dirty-bitmap.c | 12 +++------ nbd/server.c | 3 +-- 5 files changed, 54 insertions(+), 61 deletions(-) diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h index bd1b6479df..2a78243954 100644 --- a/include/block/dirty-bitmap.h +++ b/include/block/dirty-bitmap.h @@ -5,6 +5,16 @@ #include "qapi/qapi-types-block-core.h" #include "qemu/hbitmap.h" +typedef enum BitmapCheckFlags { + BDRV_BITMAP_BUSY = 1, + BDRV_BITMAP_RO = 2, + BDRV_BITMAP_INCONSISTENT = 4, +} BitmapCheckFlags; + +#define BDRV_BITMAP_DEFAULT (BDRV_BITMAP_BUSY | BDRV_BITMAP_RO | \ + BDRV_BITMAP_INCONSISTENT) +#define BDRV_BITMAP_ALLOW_RO (BDRV_BITMAP_BUSY | BDRV_BITMAP_INCONSISTENT) + BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, uint32_t granularity, const char *name, @@ -24,6 +34,8 @@ BdrvDirtyBitmap *bdrv_reclaim_dirty_bitmap(BlockDriverState *bs, void bdrv_dirty_bitmap_enable_successor(BdrvDirtyBitmap *bitmap); BdrvDirtyBitmap *bdrv_find_dirty_bitmap(BlockDriverState *bs, const char *name); +int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags, + Error **errp); void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs); void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, @@ -93,7 +105,6 @@ bool bdrv_has_readonly_bitmaps(BlockDriverState *bs); bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap); bool bdrv_dirty_bitmap_inconsistent(const BdrvDirtyBitmap *bitmap); -bool bdrv_dirty_bitmap_busy(BdrvDirtyBitmap *bitmap); bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs); BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 71e0098396..769668ccdc 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -174,7 +174,7 @@ bool bdrv_dirty_bitmap_has_successor(BdrvDirtyBitmap *bitmap) return bitmap->successor; } -bool bdrv_dirty_bitmap_busy(BdrvDirtyBitmap *bitmap) { +static bool bdrv_dirty_bitmap_busy(const BdrvDirtyBitmap *bitmap) { return bitmap->busy; } @@ -235,6 +235,33 @@ static bool bdrv_dirty_bitmap_recording(BdrvDirtyBitmap *bitmap) !bitmap->successor->disabled); } +int bdrv_dirty_bitmap_check(const BdrvDirtyBitmap *bitmap, uint32_t flags, + Error **errp) +{ + if ((flags & BDRV_BITMAP_BUSY) && bdrv_dirty_bitmap_busy(bitmap)) { + error_setg(errp, "Bitmap '%s' is currently in use by another" + " operation and cannot be used", bitmap->name); + return -1; + } + + if ((flags & BDRV_BITMAP_RO) && bdrv_dirty_bitmap_readonly(bitmap)) { + error_setg(errp, "Bitmap '%s' is readonly and cannot be modified", + bitmap->name); + return -1; + } + + if ((flags & BDRV_BITMAP_INCONSISTENT) && + bdrv_dirty_bitmap_inconsistent(bitmap)) { + error_setg(errp, "Bitmap '%s' is inconsistent and cannot be used", + bitmap->name); + error_append_hint(errp, "Try block-dirty-bitmap-remove to delete " + "this bitmap from disk"); + return -1; + } + + return 0; +} + /** * Create a successor bitmap destined to replace this bitmap after an operation. * Requires that the bitmap is not marked busy and has no successor. @@ -794,17 +821,10 @@ void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src, qemu_mutex_lock(dest->mutex); - if (bdrv_dirty_bitmap_busy(dest)) { - error_setg(errp, "Bitmap '%s' is currently in use by another" - " operation and cannot be modified", dest->name); + if (bdrv_dirty_bitmap_check(dest, BDRV_BITMAP_DEFAULT, errp)) { goto out; } - if (bdrv_dirty_bitmap_readonly(dest)) { - error_setg(errp, "Bitmap '%s' is readonly and cannot be modified", - dest->name); - goto out; - } if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) { error_setg(errp, "Bitmaps are incompatible and can't be merged"); diff --git a/blockdev.c b/blockdev.c index cbce44877d..5d74479ba7 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2007,11 +2007,7 @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common, return; } - if (bdrv_dirty_bitmap_busy(state->bitmap)) { - error_setg(errp, "Cannot modify a bitmap in use by another operation"); - return; - } else if (bdrv_dirty_bitmap_readonly(state->bitmap)) { - error_setg(errp, "Cannot clear a readonly bitmap"); + if (bdrv_dirty_bitmap_check(state->bitmap, BDRV_BITMAP_DEFAULT, errp)) { return; } @@ -2056,10 +2052,7 @@ static void block_dirty_bitmap_enable_prepare(BlkActionState *common, return; } - if (bdrv_dirty_bitmap_busy(state->bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be enabled", action->name); + if (bdrv_dirty_bitmap_check(state->bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { return; } @@ -2097,10 +2090,7 @@ static void block_dirty_bitmap_disable_prepare(BlkActionState *common, return; } - if (bdrv_dirty_bitmap_busy(state->bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be disabled", action->name); + if (bdrv_dirty_bitmap_check(state->bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { return; } @@ -2891,10 +2881,7 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_busy(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation and" - " cannot be removed", name); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY, errp)) { return; } @@ -2930,13 +2917,7 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_busy(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be cleared", name); - return; - } else if (bdrv_dirty_bitmap_readonly(bitmap)) { - error_setg(errp, "Bitmap '%s' is readonly and cannot be cleared", name); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) { return; } @@ -2954,10 +2935,7 @@ void qmp_block_dirty_bitmap_enable(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_busy(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be enabled", name); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { return; } @@ -2975,10 +2953,7 @@ void qmp_block_dirty_bitmap_disable(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_busy(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be disabled", name); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { return; } @@ -3551,10 +3526,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn, bdrv_unref(target_bs); goto out; } - if (bdrv_dirty_bitmap_busy(bmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be used for backup", backup->bitmap); + if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_ALLOW_RO, errp)) { goto out; } } @@ -3664,10 +3636,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn, error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap); goto out; } - if (bdrv_dirty_bitmap_busy(bmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be used for backup", backup->bitmap); + if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_ALLOW_RO, errp)) { goto out; } } diff --git a/migration/block-dirty-bitmap.c b/migration/block-dirty-bitmap.c index 7057fff242..0fcf897f32 100644 --- a/migration/block-dirty-bitmap.c +++ b/migration/block-dirty-bitmap.c @@ -274,6 +274,7 @@ static int init_dirty_bitmap_migration(void) BdrvDirtyBitmap *bitmap; DirtyBitmapMigBitmapState *dbms; BdrvNextIterator it; + Error *local_err = NULL; dirty_bitmap_mig_state.bulk_completed = false; dirty_bitmap_mig_state.prev_bs = NULL; @@ -301,15 +302,8 @@ static int init_dirty_bitmap_migration(void) goto fail; } - if (bdrv_dirty_bitmap_busy(bitmap)) { - error_report("Can't migrate a bitmap that is in use by another operation: '%s'", - bdrv_dirty_bitmap_name(bitmap)); - goto fail; - } - - if (bdrv_dirty_bitmap_readonly(bitmap)) { - error_report("Can't migrate read-only dirty bitmap: '%s", - bdrv_dirty_bitmap_name(bitmap)); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, &local_err)) { + error_report_err(local_err); goto fail; } diff --git a/nbd/server.c b/nbd/server.c index 02773e2836..9b87c7f243 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1510,8 +1510,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, goto fail; } - if (bdrv_dirty_bitmap_busy(bm)) { - error_setg(errp, "Bitmap '%s' is in use", bitmap); + if (bdrv_dirty_bitmap_check(bm, BDRV_BITMAP_ALLOW_RO, errp)) { goto fail; } From patchwork Fri Mar 1 19:15:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 10835931 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BD423188E for ; Fri, 1 Mar 2019 19:19:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A88EF2F33D for ; Fri, 1 Mar 2019 19:19:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 987052F3F3; Fri, 1 Mar 2019 19:19:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4DAC52F33D for ; Fri, 1 Mar 2019 19:19:49 +0000 (UTC) Received: from localhost ([127.0.0.1]:42762 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gznhE-0005A7-H0 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 01 Mar 2019 14:19:48 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34751) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzndj-0002CY-30 for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:11 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gzndh-0008F5-2N for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:10 -0500 Received: from mx1.redhat.com ([209.132.183.28]:54810) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gzndW-00082l-RP; Fri, 01 Mar 2019 14:16:00 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2F1493087BD7; Fri, 1 Mar 2019 19:15:57 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-206.bos.redhat.com [10.18.17.206]) by smtp.corp.redhat.com (Postfix) with ESMTP id F29331001E62; Fri, 1 Mar 2019 19:15:55 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 1 Mar 2019 14:15:42 -0500 Message-Id: <20190301191545.8728-5-jsnow@redhat.com> In-Reply-To: <20190301191545.8728-1-jsnow@redhat.com> References: <20190301191545.8728-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Fri, 01 Mar 2019 19:15:57 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 4/7] block/dirty-bitmaps: prohibit readonly bitmaps for backups 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: Fam Zheng , Kevin Wolf , vsementsov@virtuozzo.com, Juan Quintela , Markus Armbruster , Max Reitz , Stefan Hajnoczi , John Snow , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP drive and blockdev backup cannot use readonly bitmaps, because the sync=incremental mechanism actually edits the bitmaps on success. If you really want to do this operation, use a copied bitmap. Signed-off-by: John Snow Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blockdev.c b/blockdev.c index 5d74479ba7..c8255dda0b 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3526,7 +3526,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn, bdrv_unref(target_bs); goto out; } - if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_ALLOW_RO, errp)) { + if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) { goto out; } } @@ -3636,7 +3636,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn, error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap); goto out; } - if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_ALLOW_RO, errp)) { + if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) { goto out; } } From patchwork Fri Mar 1 19:15:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 10835941 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 94395139A for ; Fri, 1 Mar 2019 19:21:46 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8502D2F4DF for ; Fri, 1 Mar 2019 19:21:46 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 78F7B2F701; Fri, 1 Mar 2019 19:21:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 203182F4DF for ; Fri, 1 Mar 2019 19:21:46 +0000 (UTC) Received: from localhost ([127.0.0.1]:42821 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gznj7-0006w0-AU for patchwork-qemu-devel@patchwork.kernel.org; Fri, 01 Mar 2019 14:21:45 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34787) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzndm-0002GM-Mq for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gzndj-0008H0-1B for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:12 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52132) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gzndY-00083S-SY; Fri, 01 Mar 2019 14:16:03 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7DCA3A0A57; Fri, 1 Mar 2019 19:15:58 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-206.bos.redhat.com [10.18.17.206]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4D5C81001E68; Fri, 1 Mar 2019 19:15:57 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 1 Mar 2019 14:15:43 -0500 Message-Id: <20190301191545.8728-6-jsnow@redhat.com> In-Reply-To: <20190301191545.8728-1-jsnow@redhat.com> References: <20190301191545.8728-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Fri, 01 Mar 2019 19:15:58 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 5/7] block/dirty-bitmaps: prohibit removing readonly 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: Fam Zheng , Kevin Wolf , vsementsov@virtuozzo.com, Juan Quintela , Markus Armbruster , Max Reitz , Stefan Hajnoczi , John Snow , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Remove is an inherently RW operation, so this will fail anyway, but we can fail it very quickly instead of trying and failing, so do so. Signed-off-by: John Snow Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- blockdev.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/blockdev.c b/blockdev.c index c8255dda0b..a9a059c570 100644 --- a/blockdev.c +++ b/blockdev.c @@ -2881,7 +2881,8 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY, errp)) { + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO, + errp)) { return; } From patchwork Fri Mar 1 19:15:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 10835949 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D44BE139A for ; Fri, 1 Mar 2019 19:24:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C50CB2DBBF for ; Fri, 1 Mar 2019 19:24:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B93E52DC09; Fri, 1 Mar 2019 19:24:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 75D902DBBF for ; Fri, 1 Mar 2019 19:24:38 +0000 (UTC) Received: from localhost ([127.0.0.1]:42848 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gznlt-0000wT-Mp for patchwork-qemu-devel@patchwork.kernel.org; Fri, 01 Mar 2019 14:24:37 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34825) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzndp-0002JM-C6 for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gzndm-0008Je-Ml for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:17 -0500 Received: from mx1.redhat.com ([209.132.183.28]:51034) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gzndc-00086P-PV; Fri, 01 Mar 2019 14:16:05 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CFBFAA8BE7; Fri, 1 Mar 2019 19:15:59 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-206.bos.redhat.com [10.18.17.206]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9EE1D1001E62; Fri, 1 Mar 2019 19:15:58 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 1 Mar 2019 14:15:44 -0500 Message-Id: <20190301191545.8728-7-jsnow@redhat.com> In-Reply-To: <20190301191545.8728-1-jsnow@redhat.com> References: <20190301191545.8728-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 01 Mar 2019 19:15:59 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 6/7] block/dirty-bitmaps: disallow busy bitmaps as merge source 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: Fam Zheng , Kevin Wolf , vsementsov@virtuozzo.com, Juan Quintela , Markus Armbruster , Max Reitz , Stefan Hajnoczi , John Snow , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP We didn't do any state checking on source bitmaps at all, so this adds inconsistent and busy checks. readonly is allowed, so you can still copy a readonly bitmap to a new destination to use it for operations like drive-backup. Signed-off-by: John Snow Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/dirty-bitmap.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 769668ccdc..8403c9981d 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -825,6 +825,9 @@ void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src, goto out; } + if (bdrv_dirty_bitmap_check(src, BDRV_BITMAP_ALLOW_RO, errp)) { + goto out; + } if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) { error_setg(errp, "Bitmaps are incompatible and can't be merged"); From patchwork Fri Mar 1 19:15:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: John Snow X-Patchwork-Id: 10835927 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3672417E9 for ; Fri, 1 Mar 2019 19:18:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 252E02FD25 for ; Fri, 1 Mar 2019 19:18:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 167372FD2A; Fri, 1 Mar 2019 19:18:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 810CF2FD25 for ; Fri, 1 Mar 2019 19:18:23 +0000 (UTC) Received: from localhost ([127.0.0.1]:42752 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gznfq-0003q7-O6 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 01 Mar 2019 14:18:22 -0500 Received: from eggs.gnu.org ([209.51.188.92]:34824) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gzndp-0002JL-C4 for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gzndm-0008Jh-N6 for qemu-devel@nongnu.org; Fri, 01 Mar 2019 14:16:17 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44160) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gznda-00087w-Uh; Fri, 01 Mar 2019 14:16:05 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2EB562FE56B; Fri, 1 Mar 2019 19:16:01 +0000 (UTC) Received: from probe.bos.redhat.com (dhcp-17-206.bos.redhat.com [10.18.17.206]) by smtp.corp.redhat.com (Postfix) with ESMTP id F09FE1001E62; Fri, 1 Mar 2019 19:15:59 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Fri, 1 Mar 2019 14:15:45 -0500 Message-Id: <20190301191545.8728-8-jsnow@redhat.com> In-Reply-To: <20190301191545.8728-1-jsnow@redhat.com> References: <20190301191545.8728-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Fri, 01 Mar 2019 19:16:01 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v3 7/7] block/dirty-bitmaps: implement inconsistent bit 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: Fam Zheng , Kevin Wolf , vsementsov@virtuozzo.com, Juan Quintela , Markus Armbruster , Max Reitz , Stefan Hajnoczi , John Snow , "Dr. David Alan Gilbert" Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Set the inconsistent bit on load instead of rejecting such bitmaps. There is no way to un-set it; the only option is to delete it. Obvervations: - bitmap loading does not need to update the header for in_use bitmaps. - inconsistent bitmaps don't need to have their data loaded; they're glorified corruption sentinels. - bitmap saving does not need to save inconsistent bitmaps back to disk. - bitmap reopening DOES need to drop the readonly flag from inconsistent bitmaps to allow reopening of qcow2 files with non-qemu-owned bitmaps being eventually flushed back to disk. Signed-off-by: John Snow Reviewed-by: Eric Blake --- block/qcow2-bitmap.c | 103 ++++++++++++++++++++++--------------------- 1 file changed, 53 insertions(+), 50 deletions(-) diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 3ee524da4b..c3b210ede1 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -343,9 +343,15 @@ static BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs, uint32_t granularity; BdrvDirtyBitmap *bitmap = NULL; + granularity = 1U << bm->granularity_bits; + bitmap = bdrv_create_dirty_bitmap(bs, granularity, bm->name, errp); + if (bitmap == NULL) { + goto fail; + } + if (bm->flags & BME_FLAG_IN_USE) { - error_setg(errp, "Bitmap '%s' is in use", bm->name); - goto fail; + /* Data is unusable, skip loading it */ + return bitmap; } ret = bitmap_table_load(bs, &bm->table, &bitmap_table); @@ -356,12 +362,6 @@ static BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs, goto fail; } - granularity = 1U << bm->granularity_bits; - bitmap = bdrv_create_dirty_bitmap(bs, granularity, bm->name, errp); - if (bitmap == NULL) { - goto fail; - } - ret = load_bitmap_data(bs, bitmap_table, bm->table.size, bitmap); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read bitmap '%s' from image", @@ -949,6 +949,7 @@ bool qcow2_load_dirty_bitmaps(BlockDriverState *bs, Error **errp) 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 */ @@ -962,35 +963,39 @@ 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; - } - - if (!(bm->flags & BME_FLAG_AUTO)) { - 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); + BdrvDirtyBitmap *bitmap = load_bitmap(bs, bm, errp); + if (bitmap == NULL) { + goto fail; } - } - 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; - } - header_updated = true; + if (bm->flags & BME_FLAG_IN_USE) { + bdrv_dirty_bitmap_set_inconsistent(bitmap); } else { - g_slist_foreach(created_dirty_bitmaps, set_readonly_helper, - (gpointer)true); + /* NB: updated flags only get written if can_write(bs) is true. */ + bm->flags |= BME_FLAG_IN_USE; + needs_update = true; } + if (!(bm->flags & BME_FLAG_AUTO)) { + bdrv_disable_dirty_bitmap(bitmap); + } + bdrv_dirty_bitmap_set_persistance(bitmap, true); + created_dirty_bitmaps = + g_slist_append(created_dirty_bitmaps, bitmap); + } + + if (needs_update && 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; + } + header_updated = true; + } + + if (!can_write(bs)) { + g_slist_foreach(created_dirty_bitmaps, set_readonly_helper, + (gpointer)true); } g_slist_free(created_dirty_bitmaps); @@ -1112,23 +1117,21 @@ int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated, } QSIMPLEQ_FOREACH(bm, bm_list, entry) { - if (!(bm->flags & BME_FLAG_IN_USE)) { - BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(bs, bm->name); - if (bitmap == NULL) { - continue; - } - - if (!bdrv_dirty_bitmap_readonly(bitmap)) { - error_setg(errp, "Bitmap %s is not readonly but not marked" - "'IN_USE' in the image. Something went wrong," - "all the bitmaps may be corrupted", bm->name); - ret = -EINVAL; - goto out; - } + BdrvDirtyBitmap *bitmap = bdrv_find_dirty_bitmap(bs, bm->name); + if (bitmap == NULL) { + continue; + } - bm->flags |= BME_FLAG_IN_USE; - ro_dirty_bitmaps = g_slist_append(ro_dirty_bitmaps, bitmap); + if (!bdrv_dirty_bitmap_readonly(bitmap)) { + error_setg(errp, "Bitmap %s was loaded prior to rw-reopen, but was " + "not marked as readonly. This is a bug, something went " + "wrong. All of the bitmaps may be corrupted", bm->name); + ret = -EINVAL; + goto out; } + + bm->flags |= BME_FLAG_IN_USE; + ro_dirty_bitmaps = g_slist_append(ro_dirty_bitmaps, bitmap); } if (ro_dirty_bitmaps != NULL) { @@ -1424,8 +1427,8 @@ void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **errp) Qcow2Bitmap *bm; if (!bdrv_dirty_bitmap_get_persistance(bitmap) || - bdrv_dirty_bitmap_readonly(bitmap)) - { + bdrv_dirty_bitmap_readonly(bitmap) || + bdrv_dirty_bitmap_inconsistent(bitmap)) { continue; }