From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
Peter Maydell <peter.maydell@linaro.org>,
Roman Kagan <rkagan@parallels.com>,
Stefan Hajnoczi <stefanha@redhat.com>,
"Denis V. Lunev" <den@openvz.org>
Subject: [Qemu-devel] [PULL 20/38] block/parallels: implement incorrect close detection
Date: Fri, 22 May 2015 10:01:52 +0100 [thread overview]
Message-ID: <1432285330-13994-21-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1432285330-13994-1-git-send-email-stefanha@redhat.com>
From: "Denis V. Lunev" <den@openvz.org>
The software driver must set inuse field in Parallels header to
0x746F6E59 when the image is opened in read-write mode. The presence of
this magic in the header on open forces image consistency check.
There is an unfortunate trick here. We can not check for inuse in
parallels_check as this will happen too late. It is possible to do
that for simple check, but during the fix this would always report
an error as the image was opened in BDRV_O_RDWR mode. Thus we save
the flag in BDRVParallelsState for this.
On the other hand, nothing should be done to clear inuse in
parallels_check. Generic close will do the job right.
Signed-off-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Roman Kagan <rkagan@parallels.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Roman Kagan <rkagan@parallels.com>
Message-id: 1430207220-24458-21-git-send-email-den@openvz.org
CC: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/parallels.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/block/parallels.c b/block/parallels.c
index 35f231a..76e3a4e 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -36,6 +36,7 @@
#define HEADER_MAGIC "WithoutFreeSpace"
#define HEADER_MAGIC2 "WithouFreSpacExt"
#define HEADER_VERSION 2
+#define HEADER_INUSE_MAGIC (0x746F6E59)
#define DEFAULT_CLUSTER_SIZE 1048576 /* 1 MiB */
@@ -63,6 +64,8 @@ typedef struct BDRVParallelsState {
ParallelsHeader *header;
uint32_t header_size;
+ bool header_unclean;
+
uint32_t *bat_bitmap;
unsigned int bat_size;
@@ -259,6 +262,17 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
return size;
}
+ if (s->header_unclean) {
+ fprintf(stderr, "%s image was not closed correctly\n",
+ fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR");
+ res->corruptions++;
+ if (fix & BDRV_FIX_ERRORS) {
+ /* parallels_close will do the job right */
+ res->corruptions_fixed++;
+ s->header_unclean = false;
+ }
+ }
+
res->bfi.total_clusters = s->bat_size;
res->bfi.compressed_clusters = 0; /* compression is not supported */
@@ -417,6 +431,17 @@ static int parallels_probe(const uint8_t *buf, int buf_size,
return 0;
}
+static int parallels_update_header(BlockDriverState *bs)
+{
+ BDRVParallelsState *s = bs->opaque;
+ unsigned size = MAX(bdrv_opt_mem_align(bs->file), sizeof(ParallelsHeader));
+
+ if (size > s->header_size) {
+ size = s->header_size;
+ }
+ return bdrv_pwrite_sync(bs->file, 0, s->header, size);
+}
+
static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
@@ -484,6 +509,25 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
s->has_truncate = bdrv_has_zero_init(bs->file) &&
bdrv_truncate(bs->file, bdrv_getlength(bs->file)) == 0;
+ if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
+ /* Image was not closed correctly. The check is mandatory */
+ s->header_unclean = true;
+ if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {
+ error_setg(errp, "parallels: Image was not closed correctly; "
+ "cannot be opened read/write");
+ ret = -EACCES;
+ goto fail;
+ }
+ }
+
+ if (flags & BDRV_O_RDWR) {
+ s->header->inuse = cpu_to_le32(HEADER_INUSE_MAGIC);
+ ret = parallels_update_header(bs);
+ if (ret < 0) {
+ goto fail;
+ }
+ }
+
qemu_co_mutex_init(&s->lock);
return 0;
@@ -499,6 +543,12 @@ fail:
static void parallels_close(BlockDriverState *bs)
{
BDRVParallelsState *s = bs->opaque;
+
+ if (bs->open_flags & BDRV_O_RDWR) {
+ s->header->inuse = 0;
+ parallels_update_header(bs);
+ }
+
qemu_vfree(s->header);
}
--
2.1.0
next prev parent reply other threads:[~2015-05-22 9:03 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-22 9:01 [Qemu-devel] [PULL 00/38] Block patches Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 01/38] iotests, parallels: quote TEST_IMG in 076 test to be path-safe Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 02/38] block/parallels: rename parallels_header to ParallelsHeader Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 03/38] block/parallels: switch to bdrv_read Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 04/38] block/parallels: read up to cluster end in one go Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 05/38] block/parallels: add get_block_status Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 06/38] block/parallels: provide _co_readv routine for parallels format driver Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 07/38] block/parallels: replace magic constants 4, 64 with proper sizeofs Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 08/38] block/parallels: mark parallels format driver as zero inited Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 09/38] block/parallels: _co_writev callback for Parallels format Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 10/38] iotests, parallels: test for write into Parallels image Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 11/38] block/parallels: support parallels image creation Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 12/38] iotests, parallels: test for newly created parallels image via qemu-img Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 13/38] parallels: change copyright information in the image header Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 14/38] block/parallels: rename catalog_ names to bat_ Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 15/38] block/parallels: create bat2sect helper Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 16/38] block/parallels: keep BAT bitmap data in little endian in memory Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 17/38] block/parallels: read parallels image header and BAT into single buffer Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 18/38] block/parallels: move parallels_open/probe to the very end of the file Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 19/38] block/parallels: implement parallels_check method of block driver Stefan Hajnoczi
2015-05-22 9:01 ` Stefan Hajnoczi [this message]
2015-05-22 9:01 ` [Qemu-devel] [PULL 21/38] iotests, parallels: check for incorrectly closed image in tests Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 22/38] block/parallels: improve image reading performance Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 23/38] block/parallels: create bat_entry_off helper Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 24/38] block/parallels: delay writing to BAT till bdrv_co_flush_to_os Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 25/38] block/parallels: add prealloc-mode and prealloc-size open paramemets Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 26/38] block/parallels: optimize linear image expansion Stefan Hajnoczi
2015-05-22 9:01 ` [Qemu-devel] [PULL 27/38] block/parallels: improve image writing performance further Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 28/38] configure: handle clang -nopie argument warning Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 29/38] configure: factor out supported flag check Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 30/38] configure: silence glib unknown attribute __alloc_size__ Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 31/38] configure: Add workaround for ccache and clang Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 32/38] block: return EPERM on writes or discards to read-only devices Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 33/38] block: minimal bounce buffer alignment Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 34/38] block: align bounce buffers to page Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 35/38] Revert "block: Fix unaligned zero write" Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 36/38] block: Fix NULL deference for unaligned write if qiov is NULL Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 37/38] qemu-iotests: Test unaligned sub-block zero write Stefan Hajnoczi
2015-05-22 9:02 ` [Qemu-devel] [PULL 38/38] block: get_block_status: use "else" when testing the opposite condition Stefan Hajnoczi
2015-05-22 14:48 ` [Qemu-devel] [PULL 00/38] Block patches Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1432285330-13994-21-git-send-email-stefanha@redhat.com \
--to=stefanha@redhat.com \
--cc=den@openvz.org \
--cc=kwolf@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rkagan@parallels.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).