[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] qemu-img: Saner printing of large file sizes
From: |
Richard W.M. Jones |
Subject: |
Re: [Qemu-devel] [PATCH] qemu-img: Saner printing of large file sizes |
Date: |
Sat, 30 Mar 2019 16:40:41 +0000 |
User-agent: |
Mutt/1.5.21 (2010-09-15) |
On Sat, Mar 30, 2019 at 10:07:02AM -0500, Eric Blake wrote:
> Disk sizes close to INT64_MAX cause overflow, for some pretty
> ridiculous output:
>
> $ ./nbdkit -U - memory size=$((2**63 - 512)) --run 'qemu-img info $nbd'
> image: nbd+unix://?socket=/tmp/nbdkitHSAzNz/socket
> file format: raw
> virtual size: -8388607T (9223372036854775296 bytes)
> disk size: unavailable
>
> But there's no reason to have two separate implementations of integer
> to human-readable abbreviation, where one has overflow and stops at
> 'T', while the other avoids overflow and goes all the way to 'E'. With
> this patch, the output now claims 8EiB instead of -8388607T, which
> really is the correct rounding of largest file size supported by qemu
> (we could go 511 bytes larger if we used byte-accurate sizing instead
> of rounding up to the next sector boundary, but that wouldn't change
> the human-readable result).
>
> Reported-by: Richard W.M. Jones <address@hidden>
> Signed-off-by: Eric Blake <address@hidden>
I tested this with a few large and a few more reasonable values and
couldn't see anything wrong, so:
Tested-by: Richard W.M. Jones <address@hidden>
Rich.
> block/qapi.c | 49 +++++++++++--------------------------------------
> 1 file changed, 11 insertions(+), 38 deletions(-)
>
> diff --git a/block/qapi.c b/block/qapi.c
> index 21edab34fca..110d05dc575 100644
> --- a/block/qapi.c
> +++ b/block/qapi.c
> @@ -630,43 +630,14 @@ BlockStatsList *qmp_query_blockstats(bool
> has_query_nodes,
> return head;
> }
>
> -#define NB_SUFFIXES 4
> -
> -static char *get_human_readable_size(char *buf, int buf_size, int64_t size)
> -{
> - static const char suffixes[NB_SUFFIXES] = {'K', 'M', 'G', 'T'};
> - int64_t base;
> - int i;
> -
> - if (size <= 999) {
> - snprintf(buf, buf_size, "%" PRId64, size);
> - } else {
> - base = 1024;
> - for (i = 0; i < NB_SUFFIXES; i++) {
> - if (size < (10 * base)) {
> - snprintf(buf, buf_size, "%0.1f%c",
> - (double)size / base,
> - suffixes[i]);
> - break;
> - } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
> - snprintf(buf, buf_size, "%" PRId64 "%c",
> - ((size + (base >> 1)) / base),
> - suffixes[i]);
> - break;
> - }
> - base = base * 1024;
> - }
> - }
> - return buf;
> -}
> -
> void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f,
> QEMUSnapshotInfo *sn)
> {
> - char buf1[128], date_buf[128], clock_buf[128];
> + char date_buf[128], clock_buf[128];
> struct tm tm;
> time_t ti;
> int64_t secs;
> + char *sizing = NULL;
>
> if (!sn) {
> func_fprintf(f,
> @@ -684,14 +655,15 @@ void bdrv_snapshot_dump(fprintf_function func_fprintf,
> void *f,
> (int)((secs / 60) % 60),
> (int)(secs % 60),
> (int)((sn->vm_clock_nsec / 1000000) % 1000));
> + sizing = size_to_str(sn->vm_state_size);
> func_fprintf(f,
> "%-10s%-20s%7s%20s%15s",
> sn->id_str, sn->name,
> - get_human_readable_size(buf1, sizeof(buf1),
> - sn->vm_state_size),
> + sizing,
> date_buf,
> clock_buf);
> }
> + g_free(sizing);
> }
>
> static void dump_qdict(fprintf_function func_fprintf, void *f, int
> indentation,
> @@ -796,14 +768,13 @@ void bdrv_image_info_specific_dump(fprintf_function
> func_fprintf, void *f,
> void bdrv_image_info_dump(fprintf_function func_fprintf, void *f,
> ImageInfo *info)
> {
> - char size_buf[128], dsize_buf[128];
> + char *size_buf, *dsize_buf;
> if (!info->has_actual_size) {
> - snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
> + dsize_buf = g_strdup("unavailable");
> } else {
> - get_human_readable_size(dsize_buf, sizeof(dsize_buf),
> - info->actual_size);
> + dsize_buf = size_to_str(info->actual_size);
> }
> - get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
> + size_buf = size_to_str(info->virtual_size);
> func_fprintf(f,
> "image: %s\n"
> "file format: %s\n"
> @@ -812,6 +783,8 @@ void bdrv_image_info_dump(fprintf_function func_fprintf,
> void *f,
> info->filename, info->format, size_buf,
> info->virtual_size,
> dsize_buf);
> + g_free(size_buf);
> + g_free(dsize_buf);
>
> if (info->has_encrypted && info->encrypted) {
> func_fprintf(f, "encrypted: yes\n");
> --
> 2.20.1
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html