|
|
1bdc94 |
From 28b3e17abefac49221fe9b8826ed10f4e0f3f585 Mon Sep 17 00:00:00 2001
|
|
|
1bdc94 |
From: Max Reitz <mreitz@redhat.com>
|
|
|
1bdc94 |
Date: Wed, 16 May 2018 12:00:18 +0200
|
|
|
1bdc94 |
Subject: [PATCH 1/8] qemu-img: Check post-truncation size
|
|
|
1bdc94 |
|
|
|
1bdc94 |
RH-Author: Max Reitz <mreitz@redhat.com>
|
|
|
1bdc94 |
Message-id: <20180516120018.27565-2-mreitz@redhat.com>
|
|
|
1bdc94 |
Patchwork-id: 80281
|
|
|
1bdc94 |
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH 1/1] qemu-img: Check post-truncation size
|
|
|
1bdc94 |
Bugzilla: 1523065
|
|
|
1bdc94 |
RH-Acked-by: John Snow <jsnow@redhat.com>
|
|
|
1bdc94 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
1bdc94 |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
1bdc94 |
|
|
|
1bdc94 |
Some block drivers (iscsi and file-posix when dealing with device files)
|
|
|
1bdc94 |
do not actually support truncation, even though they provide a
|
|
|
1bdc94 |
.bdrv_truncate() method and will happily return success when providing a
|
|
|
1bdc94 |
new size that does not exceed the current size. This is because these
|
|
|
1bdc94 |
drivers expect the user to resize the image outside of qemu and then
|
|
|
1bdc94 |
provide qemu with that information through the block_resize command
|
|
|
1bdc94 |
(compare cb1b83e740384b4e0d950f3d7c81c02b8ce86c2e).
|
|
|
1bdc94 |
|
|
|
1bdc94 |
Of course, anyone using qemu-img resize will find that behavior useless.
|
|
|
1bdc94 |
So we should check the actual size of the image after the supposedly
|
|
|
1bdc94 |
successful truncation took place, emit an error if nothing changed and
|
|
|
1bdc94 |
emit a warning if the target size was not met.
|
|
|
1bdc94 |
|
|
|
1bdc94 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
1bdc94 |
Message-id: 20180421163957.29872-1-mreitz@redhat.com
|
|
|
1bdc94 |
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
1bdc94 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
1bdc94 |
(cherry picked from commit 5279b30392da7a3248b320c75f20c61e3a95863c)
|
|
|
1bdc94 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
1bdc94 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
1bdc94 |
---
|
|
|
1bdc94 |
qemu-img.c | 39 +++++++++++++++++++++++++++++++++++----
|
|
|
1bdc94 |
1 file changed, 35 insertions(+), 4 deletions(-)
|
|
|
1bdc94 |
|
|
|
1bdc94 |
diff --git a/qemu-img.c b/qemu-img.c
|
|
|
1bdc94 |
index 855fa52..8320887 100644
|
|
|
1bdc94 |
--- a/qemu-img.c
|
|
|
1bdc94 |
+++ b/qemu-img.c
|
|
|
1bdc94 |
@@ -3381,7 +3381,7 @@ static int img_resize(int argc, char **argv)
|
|
|
1bdc94 |
Error *err = NULL;
|
|
|
1bdc94 |
int c, ret, relative;
|
|
|
1bdc94 |
const char *filename, *fmt, *size;
|
|
|
1bdc94 |
- int64_t n, total_size, current_size;
|
|
|
1bdc94 |
+ int64_t n, total_size, current_size, new_size;
|
|
|
1bdc94 |
bool quiet = false;
|
|
|
1bdc94 |
BlockBackend *blk = NULL;
|
|
|
1bdc94 |
PreallocMode prealloc = PREALLOC_MODE_OFF;
|
|
|
1bdc94 |
@@ -3557,11 +3557,42 @@ static int img_resize(int argc, char **argv)
|
|
|
1bdc94 |
}
|
|
|
1bdc94 |
|
|
|
1bdc94 |
ret = blk_truncate(blk, total_size, prealloc, &err;;
|
|
|
1bdc94 |
- if (!ret) {
|
|
|
1bdc94 |
- qprintf(quiet, "Image resized.\n");
|
|
|
1bdc94 |
- } else {
|
|
|
1bdc94 |
+ if (ret < 0) {
|
|
|
1bdc94 |
error_report_err(err);
|
|
|
1bdc94 |
+ goto out;
|
|
|
1bdc94 |
+ }
|
|
|
1bdc94 |
+
|
|
|
1bdc94 |
+ new_size = blk_getlength(blk);
|
|
|
1bdc94 |
+ if (new_size < 0) {
|
|
|
1bdc94 |
+ error_report("Failed to verify truncated image length: %s",
|
|
|
1bdc94 |
+ strerror(-new_size));
|
|
|
1bdc94 |
+ ret = -1;
|
|
|
1bdc94 |
+ goto out;
|
|
|
1bdc94 |
}
|
|
|
1bdc94 |
+
|
|
|
1bdc94 |
+ /* Some block drivers implement a truncation method, but only so
|
|
|
1bdc94 |
+ * the user can cause qemu to refresh the image's size from disk.
|
|
|
1bdc94 |
+ * The idea is that the user resizes the image outside of qemu and
|
|
|
1bdc94 |
+ * then invokes block_resize to inform qemu about it.
|
|
|
1bdc94 |
+ * (This includes iscsi and file-posix for device files.)
|
|
|
1bdc94 |
+ * Of course, that is not the behavior someone invoking
|
|
|
1bdc94 |
+ * qemu-img resize would find useful, so we catch that behavior
|
|
|
1bdc94 |
+ * here and tell the user. */
|
|
|
1bdc94 |
+ if (new_size != total_size && new_size == current_size) {
|
|
|
1bdc94 |
+ error_report("Image was not resized; resizing may not be supported "
|
|
|
1bdc94 |
+ "for this image");
|
|
|
1bdc94 |
+ ret = -1;
|
|
|
1bdc94 |
+ goto out;
|
|
|
1bdc94 |
+ }
|
|
|
1bdc94 |
+
|
|
|
1bdc94 |
+ if (new_size != total_size) {
|
|
|
1bdc94 |
+ warn_report("Image should have been resized to %" PRIi64
|
|
|
1bdc94 |
+ " bytes, but was resized to %" PRIi64 " bytes",
|
|
|
1bdc94 |
+ total_size, new_size);
|
|
|
1bdc94 |
+ }
|
|
|
1bdc94 |
+
|
|
|
1bdc94 |
+ qprintf(quiet, "Image resized.\n");
|
|
|
1bdc94 |
+
|
|
|
1bdc94 |
out:
|
|
|
1bdc94 |
blk_unref(blk);
|
|
|
1bdc94 |
if (ret) {
|
|
|
1bdc94 |
--
|
|
|
1bdc94 |
1.8.3.1
|
|
|
1bdc94 |
|