From patchwork Wed Dec 23 07:46:54 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 560384 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 6DBC1140BC1 for ; Wed, 23 Dec 2015 18:51:04 +1100 (AEDT) Received: from localhost ([::1]:54758 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aBeCM-0002he-E3 for incoming@patchwork.ozlabs.org; Wed, 23 Dec 2015 02:51:02 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39722) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aBe8j-0004Ls-Cg for qemu-devel@nongnu.org; Wed, 23 Dec 2015 02:47:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aBe8i-0006lm-3o for qemu-devel@nongnu.org; Wed, 23 Dec 2015 02:47:17 -0500 Received: from mailhub.sw.ru ([195.214.232.25]:34274 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aBe8h-0006l9-N4 for qemu-devel@nongnu.org; Wed, 23 Dec 2015 02:47:16 -0500 Received: from irbis.sw.ru ([10.30.2.139]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id tBN7kuRc003382; Wed, 23 Dec 2015 10:47:03 +0300 (MSK) From: "Denis V. Lunev" To: Date: Wed, 23 Dec 2015 10:46:54 +0300 Message-Id: <1450856816-9816-4-git-send-email-den@openvz.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1450856816-9816-1-git-send-email-den@openvz.org> References: <567A4EB0.1040807@parallels.com> <1450856816-9816-1-git-send-email-den@openvz.org> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x X-Received-From: 195.214.232.25 Cc: Kevin Wolf , Fam Zheng , qemu-devel@nongnu.org, Max Reitz , Olga Krishtal , "Denis V. Lunev" Subject: [Qemu-devel] [PATCH 3/5] block: added check image option and callback bdrv_is_opened_unclean X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Olga Krishtal If image is opened for writing and it was not closed correctly (the image is dirty) we have to check and repair it. By default the option is off. bdrv_is_opened_unclean - cheks if the image is dirty This callbsck will be used to ensure that image was closed correctly, and if not - to check and repair it. Signed-off-by: Olga Krishtal Signed-off-by: Denis V. Lunev CC: Kevin Wolf CC: Max Reitz CC: Eric Blake CC: Fam Zheng --- block.c | 32 ++++++++++++++++++++++++++++++++ include/block/block.h | 1 + include/block/block_int.h | 1 + 3 files changed, 34 insertions(+) diff --git a/block.c b/block.c index 74228b8..1f704f5 100644 --- a/block.c +++ b/block.c @@ -903,6 +903,12 @@ static QemuOptsList bdrv_runtime_opts = { .help = "How to lock the image: none or lockfile", .def_value_str = "none", }, + { + .name = "check", + .type = QEMU_OPT_BOOL, + .help = "Check and repair the image if it is unclean", + .def_value_str = "off", + }, { /* end of list */ } }, }; @@ -1042,6 +1048,16 @@ static int bdrv_open_common(BlockDriverState *bs, BdrvChild *file, } } + if (!bs->read_only && qemu_opt_get_bool_del(opts, "check", true) && + bdrv_is_opened_unclean(bs) && !(flags | BDRV_O_CHECK)) { + BdrvCheckResult result = {0}; + ret = bdrv_check(bs, &result, BDRV_FIX_ERRORS); + if (ret < 0) { + error_setg_errno(errp, -ret, "Could not repair dirty image"); + bdrv_close(bs); + goto fail_opts; + } + } if (bs->encrypted) { error_report("Encrypted images are deprecated"); error_printf("Support for them will be removed in a future release.\n" @@ -4361,3 +4377,19 @@ int bdrv_lock_image(BlockDriverState *bs, BdrvLockImage lock) } return -EOPNOTSUPP; } + +bool bdrv_is_opened_unclean(BlockDriverState *bs) +{ + BlockDriver *drv = bs->drv; + if (drv != NULL && drv->bdrv_is_opened_unclean != NULL) { + return drv->bdrv_is_opened_unclean(bs); + } + if (bs->file == NULL) { + return false; + } + drv = bs->file->bs->drv; + if (drv != NULL && drv->bdrv_is_opened_unclean != NULL) { + return drv->bdrv_is_opened_unclean; + } + return false; +} diff --git a/include/block/block.h b/include/block/block.h index 27fc434..c366990 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -507,6 +507,7 @@ void bdrv_dirty_iter_init(BdrvDirtyBitmap *bitmap, struct HBitmapIter *hbi); void bdrv_set_dirty_iter(struct HBitmapIter *hbi, int64_t offset); int64_t bdrv_get_dirty_count(BdrvDirtyBitmap *bitmap); int bdrv_lock_image(BlockDriverState *bs, BdrvLockImage lock); +bool bdrv_is_opened_unclean(BlockDriverState *bs); void bdrv_enable_copy_on_read(BlockDriverState *bs); void bdrv_disable_copy_on_read(BlockDriverState *bs); diff --git a/include/block/block_int.h b/include/block/block_int.h index 755f342..fc3f4a6 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -137,6 +137,7 @@ struct BlockDriver { int (*bdrv_make_empty)(BlockDriverState *bs); int (*bdrv_lock_image)(BlockDriverState *bs, BdrvLockImage lock); + bool (*bdrv_is_opened_unclean)(BlockDriverState *bs); void (*bdrv_refresh_filename)(BlockDriverState *bs, QDict *options); /* aio */