qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2 3/3] block: Introduce BlockDriver.requires_growin


From: Max Reitz
Subject: [Qemu-devel] [PATCH v2 3/3] block: Introduce BlockDriver.requires_growing_file
Date: Thu, 19 Mar 2015 15:03:21 -0400

This flag is set if write accesses to BDSs managed by the respective
driver may lead to writes beyond the end of the underlying file BDS,
expecting it to increase its size accordingly.

This behavior, however, is only supported by protocol BDSs having the
BDS.growing flag set. If they do not, emit a warning.

An example of such a misconfiguration is exporting a qcow2 file using
the reference NBD server implementation, which cannot interpret the
qcow2 format and will thus expose it directly over the network. When
accessing that export with qemu, qemu's qcow2 driver may try to allocate
clusters over the NBD connection, writing to addresses beyond the size
of the NBD export, which will then fail (without the user knowing why,
without this warning).

Signed-off-by: Max Reitz <address@hidden>
---
 block.c                   | 16 ++++++++++++++++
 block/qcow.c              |  1 +
 block/qcow2.c             |  2 ++
 block/qed.c               |  1 +
 block/vdi.c               |  2 ++
 block/vhdx.c              |  2 ++
 block/vmdk.c              |  1 +
 block/vpc.c               |  2 ++
 include/block/block_int.h |  4 ++++
 9 files changed, 31 insertions(+)

diff --git a/block.c b/block.c
index 6da30f8..2db27b5 100644
--- a/block.c
+++ b/block.c
@@ -1585,6 +1585,22 @@ int bdrv_open(BlockDriverState **pbs, const char 
*filename,
         goto fail;
     }
 
+    /* requires_growing_file may only be true for format block drivers */
+    assert(!bs->drv->requires_growing_file || bs->file);
+    if (bs->drv->requires_growing_file && !bs->file->growing &&
+        (flags & BDRV_O_RDWR))
+    {
+        error_report("WARNING: Writes to the image '%s' in format '%s'\n"
+                     "         may require the file to grow which is not "
+                     "supported for protocol '%s'.\n"
+                     "         Please open it read-only or try to export "
+                     "it in a different format\n"
+                     "         over the protocol (e.g. use qemu-nbd "
+                     "instead of nbd-server).",
+                     filename ?: "", drv->format_name,
+                     bs->file->drv->format_name);
+    }
+
     if (file && (bs->file != file)) {
         bdrv_unref(file);
         file = NULL;
diff --git a/block/qcow.c b/block/qcow.c
index 0558969..5719285 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -962,6 +962,7 @@ static BlockDriver bdrv_qcow = {
     .bdrv_create            = qcow_create,
     .bdrv_has_zero_init     = bdrv_has_zero_init_1,
     .supports_backing       = true,
+    .requires_growing_file  = true,
 
     .bdrv_co_readv          = qcow_co_readv,
     .bdrv_co_writev         = qcow_co_writev,
diff --git a/block/qcow2.c b/block/qcow2.c
index b4e2aa3..ad1028b 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2944,6 +2944,8 @@ BlockDriver bdrv_qcow2 = {
     .supports_backing           = true,
     .bdrv_change_backing_file   = qcow2_change_backing_file,
 
+    .requires_growing_file      = true,
+
     .bdrv_refresh_limits        = qcow2_refresh_limits,
     .bdrv_invalidate_cache      = qcow2_invalidate_cache,
 
diff --git a/block/qed.c b/block/qed.c
index 892b13c..1cd1233 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -1662,6 +1662,7 @@ static BlockDriver bdrv_qed = {
     .instance_size            = sizeof(BDRVQEDState),
     .create_opts              = &qed_create_opts,
     .supports_backing         = true,
+    .requires_growing_file    = true,
 
     .bdrv_probe               = bdrv_qed_probe,
     .bdrv_rebind              = bdrv_qed_rebind,
diff --git a/block/vdi.c b/block/vdi.c
index 53bd02f..13ffd91 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -903,6 +903,8 @@ static BlockDriver bdrv_vdi = {
 
     .create_opts = &vdi_create_opts,
     .bdrv_check = vdi_check,
+
+    .requires_growing_file = true,
 };
 
 static void bdrv_vdi_init(void)
diff --git a/block/vhdx.c b/block/vhdx.c
index bb3ed45..bc1aaca 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -1970,6 +1970,8 @@ static BlockDriver bdrv_vhdx = {
     .bdrv_has_zero_init     = bdrv_has_zero_init_1,
 
     .create_opts            = &vhdx_create_opts,
+
+    .requires_growing_file  = true,
 };
 
 static void bdrv_vhdx_init(void)
diff --git a/block/vmdk.c b/block/vmdk.c
index 8410a15..31ae764 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -2293,6 +2293,7 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_attach_aio_context      = vmdk_attach_aio_context,
 
     .supports_backing             = true,
+    .requires_growing_file        = true,
     .create_opts                  = &vmdk_create_opts,
 };
 
diff --git a/block/vpc.c b/block/vpc.c
index 43e768e..4c26273 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -924,6 +924,8 @@ static BlockDriver bdrv_vpc = {
 
     .create_opts            = &vpc_create_opts,
     .bdrv_has_zero_init     = vpc_has_zero_init,
+
+    .requires_growing_file  = true,
 };
 
 static void bdrv_vpc_init(void)
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 01dee2a..be44c80 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -109,6 +109,10 @@ struct BlockDriver {
     /* Set if a driver can support backing files */
     bool supports_backing;
 
+    /* Set if the underlying BDS.file needs to support writes beyond its size 
to
+     * be grown implicitly in order for this driver's BDSs to be writable */
+    bool requires_growing_file;
+
     /* For handling image reopen for split or non-split files */
     int (*bdrv_reopen_prepare)(BDRVReopenState *reopen_state,
                                BlockReopenQueue *queue, Error **errp);
-- 
2.1.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]