From 1a8a4ece5def912e7cfa5ef8565fc8ecef6e72c3 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Tue, 2 Jun 2020 02:34:11 +0100 Subject: [PATCH 06/26] qemu_img: add cvtnum_full to print error reports RH-Author: Eric Blake Message-id: <20200602023420.2133649-4-eblake@redhat.com> Patchwork-id: 97067 O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 03/12] qemu_img: add cvtnum_full to print error reports Bugzilla: 1779893 1779904 RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Max Reitz RH-Acked-by: Kevin Wolf From: Eyal Moscovici All calls to cvtnum check the return value and print the same error message more or less. And so error reporting moved to cvtnum_full to reduce code duplication and provide a single error message. Additionally, cvtnum now wraps cvtnum_full with the existing default range of 0 to MAX_INT64. Acked-by: Mark Kanda Signed-off-by: Eyal Moscovici Message-Id: <20200513133629.18508-2-eyal.moscovici@oracle.com> Reviewed-by: Eric Blake [eblake: fix printf formatting, avoid trailing space, change error wording, reformat commit message] Signed-off-by: Eric Blake (cherry picked from commit 43d589b074370ebc9b340340b5f641b385da9df8) Signed-off-by: Eric Blake Signed-off-by: Danilo C. L. de Paula --- qemu-img.c | 76 +++++++++++++++++++++------------------------- tests/qemu-iotests/049.out | 8 ++--- 2 files changed, 38 insertions(+), 46 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index 95a24b9..e69529b 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -422,19 +422,31 @@ static int add_old_style_options(const char *fmt, QemuOpts *opts, return 0; } -static int64_t cvtnum(const char *s) +static int64_t cvtnum_full(const char *name, const char *value, int64_t min, + int64_t max) { int err; - uint64_t value; - - err = qemu_strtosz(s, NULL, &value); - if (err < 0) { + uint64_t res; + + err = qemu_strtosz(value, NULL, &res); + if (err < 0 && err != -ERANGE) { + error_report("Invalid %s specified. You may use " + "k, M, G, T, P or E suffixes for", name); + error_report("kilobytes, megabytes, gigabytes, terabytes, " + "petabytes and exabytes."); return err; } - if (value > INT64_MAX) { + if (err == -ERANGE || res > max || res < min) { + error_report("Invalid %s specified. Must be between %" PRId64 + " and %" PRId64 ".", name, min, max); return -ERANGE; } - return value; + return res; +} + +static int64_t cvtnum(const char *name, const char *value) +{ + return cvtnum_full(name, value, 0, INT64_MAX); } static int img_create(int argc, char **argv) @@ -532,16 +544,8 @@ static int img_create(int argc, char **argv) if (optind < argc) { int64_t sval; - sval = cvtnum(argv[optind++]); + sval = cvtnum("image size", argv[optind++]); if (sval < 0) { - if (sval == -ERANGE) { - error_report("Image size must be less than 8 EiB!"); - } else { - error_report("Invalid image size specified! You may use k, M, " - "G, T, P or E suffixes for "); - error_report("kilobytes, megabytes, gigabytes, terabytes, " - "petabytes and exabytes."); - } goto fail; } img_size = (uint64_t)sval; @@ -2148,8 +2152,10 @@ static int img_convert(int argc, char **argv) { int64_t sval; - sval = cvtnum(optarg); - if (sval < 0 || !QEMU_IS_ALIGNED(sval, BDRV_SECTOR_SIZE) || + sval = cvtnum("buffer size for sparse output", optarg); + if (sval < 0) { + goto fail_getopt; + } else if (!QEMU_IS_ALIGNED(sval, BDRV_SECTOR_SIZE) || sval / BDRV_SECTOR_SIZE > MAX_BUF_SECTORS) { error_report("Invalid buffer size for sparse output specified. " "Valid sizes are multiples of %llu up to %llu. Select " @@ -4229,9 +4235,8 @@ static int img_bench(int argc, char **argv) break; case 'o': { - offset = cvtnum(optarg); + offset = cvtnum("offset", optarg); if (offset < 0) { - error_report("Invalid offset specified"); return 1; } break; @@ -4244,9 +4249,8 @@ static int img_bench(int argc, char **argv) { int64_t sval; - sval = cvtnum(optarg); - if (sval < 0 || sval > INT_MAX) { - error_report("Invalid buffer size specified"); + sval = cvtnum_full("buffer size", optarg, 0, INT_MAX); + if (sval < 0) { return 1; } @@ -4257,9 +4261,8 @@ static int img_bench(int argc, char **argv) { int64_t sval; - sval = cvtnum(optarg); - if (sval < 0 || sval > INT_MAX) { - error_report("Invalid step size specified"); + sval = cvtnum_full("step_size", optarg, 0, INT_MAX); + if (sval < 0) { return 1; } @@ -4429,10 +4432,9 @@ static int img_dd_bs(const char *arg, { int64_t res; - res = cvtnum(arg); + res = cvtnum_full("bs", arg, 1, INT_MAX); - if (res <= 0 || res > INT_MAX) { - error_report("invalid number: '%s'", arg); + if (res < 0) { return 1; } in->bsz = out->bsz = res; @@ -4444,10 +4446,9 @@ static int img_dd_count(const char *arg, struct DdIo *in, struct DdIo *out, struct DdInfo *dd) { - dd->count = cvtnum(arg); + dd->count = cvtnum("count", arg); if (dd->count < 0) { - error_report("invalid number: '%s'", arg); return 1; } @@ -4476,10 +4477,9 @@ static int img_dd_skip(const char *arg, struct DdIo *in, struct DdIo *out, struct DdInfo *dd) { - in->offset = cvtnum(arg); + in->offset = cvtnum("skip", arg); if (in->offset < 0) { - error_report("invalid number: '%s'", arg); return 1; } @@ -4869,16 +4869,8 @@ static int img_measure(int argc, char **argv) { int64_t sval; - sval = cvtnum(optarg); + sval = cvtnum("image size", optarg); if (sval < 0) { - if (sval == -ERANGE) { - error_report("Image size must be less than 8 EiB!"); - } else { - error_report("Invalid image size specified! You may use " - "k, M, G, T, P or E suffixes for "); - error_report("kilobytes, megabytes, gigabytes, terabytes, " - "petabytes and exabytes."); - } goto out; } img_size = (uint64_t)sval; diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out index 6b50540..8b35f3d 100644 --- a/tests/qemu-iotests/049.out +++ b/tests/qemu-iotests/049.out @@ -92,19 +92,19 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 l == 3. Invalid sizes == qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1024 -qemu-img: Image size must be less than 8 EiB! +qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807. qemu-img create -f qcow2 -o size=-1024 TEST_DIR/t.qcow2 qemu-img: TEST_DIR/t.qcow2: Value '-1024' is out of range for parameter 'size' qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1k -qemu-img: Image size must be less than 8 EiB! +qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807. qemu-img create -f qcow2 -o size=-1k TEST_DIR/t.qcow2 qemu-img: TEST_DIR/t.qcow2: Value '-1k' is out of range for parameter 'size' qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte -qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for +qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes. qemu-img create -f qcow2 -o size=1kilobyte TEST_DIR/t.qcow2 @@ -113,7 +113,7 @@ Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta- and exabytes, respectively. qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- foobar -qemu-img: Invalid image size specified! You may use k, M, G, T, P or E suffixes for +qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes. qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2 -- 1.8.3.1