* [Qemu-devel] [PATCH v5] qemu-img: change opening method for the output in dd
@ 2016-08-26 7:19 Reda Sallahi
2016-09-13 15:35 ` Stefan Hajnoczi
0 siblings, 1 reply; 3+ messages in thread
From: Reda Sallahi @ 2016-08-26 7:19 UTC (permalink / raw)
To: qemu-devel
Cc: qemu-block, Kevin Wolf, Max Reitz, Fam Zheng, Stefan Hajnoczi,
Reda Sallahi
The subcommand dd was creating an output image regardless of whether there
was one already created. With this patch we try to check first if the output
image exists and resize it if necessary.
We also make it mandatory to specify conv=notrunc when the file already
exists.
Signed-off-by: Reda Sallahi <fullmanet@gmail.com>
---
Depends on:
[PATCH v3] qemu-img: add conv=notrunc option to dd
Changes from v4:
* Use access() to check file existence first and remove blk_new_open()
Changes from v3:
* Remove unnecessary checks
Changes from v2:
* Remove redundant code
Changes from v1:
* add --image-opts handling
qemu-img.c | 142 +++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 92 insertions(+), 50 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index f8ba5e5..816a406 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -3919,14 +3919,15 @@ static int img_dd(int argc, char **argv)
char *tmp;
BlockDriver *drv = NULL, *proto_drv = NULL;
BlockBackend *blk1 = NULL, *blk2 = NULL;
- QemuOpts *opts = NULL;
+ QemuOpts *opts = NULL, *qopts = NULL;
QemuOptsList *create_opts = NULL;
Error *local_err = NULL;
bool image_opts = false;
int c, i;
const char *out_fmt = "raw";
const char *fmt = NULL;
- int64_t size = 0;
+ const char *out_filename;
+ int64_t size = 0, out_size;
int64_t block_count = 0, out_pos, in_pos;
struct DdInfo dd = {
.flags = 0,
@@ -4030,36 +4031,6 @@ static int img_dd(int argc, char **argv)
goto out;
}
- drv = bdrv_find_format(out_fmt);
- if (!drv) {
- error_report("Unknown file format");
- ret = -1;
- goto out;
- }
- proto_drv = bdrv_find_protocol(out.filename, true, &local_err);
-
- if (!proto_drv) {
- error_report_err(local_err);
- ret = -1;
- goto out;
- }
- if (!drv->create_opts) {
- error_report("Format driver '%s' does not support image creation",
- drv->format_name);
- ret = -1;
- goto out;
- }
- if (!proto_drv->create_opts) {
- error_report("Protocol driver '%s' does not support image creation",
- proto_drv->format_name);
- ret = -1;
- goto out;
- }
- create_opts = qemu_opts_append(create_opts, drv->create_opts);
- create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
-
- opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
-
size = blk_getlength(blk1);
if (size < 0) {
error_report("Failed to get size for '%s'", in.filename);
@@ -4071,31 +4042,101 @@ static int img_dd(int argc, char **argv)
dd.count * in.bsz < size) {
size = dd.count * in.bsz;
}
-
/* Overflow means the specified offset is beyond input image's size */
- if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
- size < in.bsz * in.offset)) {
- qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, &error_abort);
+ if (in.offset > INT64_MAX / in.bsz || size < in.offset * in.bsz) {
+ out_size = 0;
} else {
- qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
- size - in.bsz * in.offset, &error_abort);
+ out_size = size - in.offset * in.bsz;
}
- ret = bdrv_create(drv, out.filename, opts, &local_err);
- if (ret < 0) {
- error_reportf_err(local_err,
- "%s: error while creating output image: ",
- out.filename);
- ret = -1;
- goto out;
+ out_filename = out.filename;
+ if (image_opts) {
+ qopts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ out.filename, true);
+ out_filename = qemu_opt_get(qopts, "filename");
}
- blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR,
- false, false);
+ ret = access(out_filename, F_OK); /* Check if file exists */
- if (!blk2) {
- ret = -1;
- goto out;
+ if (ret == -1) {
+ ret = 0; /* Reset */
+ drv = bdrv_find_format(out_fmt);
+ if (!drv) {
+ error_report("Unknown file format");
+ ret = -1;
+ goto out;
+ }
+ proto_drv = bdrv_find_protocol(out.filename, true, &local_err);
+
+ if (!proto_drv) {
+ error_report_err(local_err);
+ ret = -1;
+ goto out;
+ }
+ if (!drv->create_opts) {
+ error_report("Format driver '%s' does not support image creation",
+ drv->format_name);
+ ret = -1;
+ goto out;
+ }
+ if (!proto_drv->create_opts) {
+ error_report("Protocol driver '%s' does not support image creation",
+ proto_drv->format_name);
+ ret = -1;
+ goto out;
+ }
+ create_opts = qemu_opts_append(create_opts, drv->create_opts);
+ create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
+
+ opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
+
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, out_size, &error_abort);
+
+ ret = bdrv_create(drv, out.filename, opts, &local_err);
+ if (ret < 0) {
+ error_reportf_err(local_err,
+ "%s: error while creating output image: ",
+ out.filename);
+ ret = -1;
+ goto out;
+ }
+ blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR,
+ false, false);
+ if (!blk2) {
+ ret = -1;
+ goto out;
+ }
+ } else {
+ int64_t blk2sz = 0;
+
+ blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR,
+ false, false);
+ if (!blk2) {
+ ret = -1;
+ goto out;
+ }
+
+ if (!(dd.conv & C_NOTRUNC)) {
+ /* We make conv=notrunc mandatory for the moment to avoid
+ accidental destruction of the output image. Needs to be
+ changed when a better solution is found */
+ error_report("conv=notrunc not specified");
+ ret = -1;
+ goto out;
+ }
+
+ blk2sz = blk_getlength(blk2);
+ if (blk2sz < 0) {
+ error_report("Failed to get size for '%s'", in.filename);
+ ret = -1;
+ goto out;
+ }
+
+ if (in.offset <= INT64_MAX / in.bsz && size >= in.offset * in.bsz) {
+ if (blk2sz < out_size) {
+ blk_truncate(blk2, out_size);
+ }
+ }
}
if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
@@ -4141,6 +4182,7 @@ static int img_dd(int argc, char **argv)
out:
g_free(arg);
qemu_opts_del(opts);
+ qemu_opts_del(qopts);
qemu_opts_free(create_opts);
blk_unref(blk1);
blk_unref(blk2);
--
2.9.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH v5] qemu-img: change opening method for the output in dd
2016-08-26 7:19 [Qemu-devel] [PATCH v5] qemu-img: change opening method for the output in dd Reda Sallahi
@ 2016-09-13 15:35 ` Stefan Hajnoczi
2016-09-30 15:33 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
0 siblings, 1 reply; 3+ messages in thread
From: Stefan Hajnoczi @ 2016-09-13 15:35 UTC (permalink / raw)
To: Reda Sallahi; +Cc: qemu-devel, qemu-block, Kevin Wolf, Max Reitz, Fam Zheng
[-- Attachment #1: Type: text/plain, Size: 523 bytes --]
On Fri, Aug 26, 2016 at 09:19:40AM +0200, Reda Sallahi wrote:
> - blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR,
> - false, false);
> + ret = access(out_filename, F_OK); /* Check if file exists */
The QEMU block layer does not use POSIX file I/O because it needs to
support protocols like iSCSI and ssh.
The only way to test for the existence of a disk image is by opening it
with block layer APIs.
Can you just move the img_open() call from the else statement up here
instead?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [Qemu-block] [PATCH v5] qemu-img: change opening method for the output in dd
2016-09-13 15:35 ` Stefan Hajnoczi
@ 2016-09-30 15:33 ` Stefan Hajnoczi
0 siblings, 0 replies; 3+ messages in thread
From: Stefan Hajnoczi @ 2016-09-30 15:33 UTC (permalink / raw)
To: Stefan Hajnoczi
Cc: Reda Sallahi, Kevin Wolf, Fam Zheng, qemu-devel, qemu block,
Max Reitz
On Tue, Sep 13, 2016 at 4:35 PM, Stefan Hajnoczi <stefanha@redhat.com> wrote:
> On Fri, Aug 26, 2016 at 09:19:40AM +0200, Reda Sallahi wrote:
>> - blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR,
>> - false, false);
>> + ret = access(out_filename, F_OK); /* Check if file exists */
>
> The QEMU block layer does not use POSIX file I/O because it needs to
> support protocols like iSCSI and ssh.
>
> The only way to test for the existence of a disk image is by opening it
> with block layer APIs.
>
> Can you just move the img_open() call from the else statement up here
> instead?
Ping
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-09-30 15:33 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-26 7:19 [Qemu-devel] [PATCH v5] qemu-img: change opening method for the output in dd Reda Sallahi
2016-09-13 15:35 ` Stefan Hajnoczi
2016-09-30 15:33 ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
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).