From nobody Sat May 4 11:40:33 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1553958644176970.125659361494; Sat, 30 Mar 2019 08:10:44 -0700 (PDT) Received: from localhost ([127.0.0.1]:60051 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hAFd3-00034I-4e for importer@patchew.org; Sat, 30 Mar 2019 11:10:41 -0400 Received: from eggs.gnu.org ([209.51.188.92]:51333) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hAFbB-0002EX-9U for qemu-devel@nongnu.org; Sat, 30 Mar 2019 11:08:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hAFb2-0003c2-RM for qemu-devel@nongnu.org; Sat, 30 Mar 2019 11:08:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:46048) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hAFaU-0003DQ-3b; Sat, 30 Mar 2019 11:08:06 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9E2573086209; Sat, 30 Mar 2019 15:07:07 +0000 (UTC) Received: from blue.redhat.com (ovpn-116-75.phx2.redhat.com [10.3.116.75]) by smtp.corp.redhat.com (Postfix) with ESMTP id ADB964D6F7; Sat, 30 Mar 2019 15:07:04 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Sat, 30 Mar 2019 10:07:02 -0500 Message-Id: <20190330150702.11687-1-eblake@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.42]); Sat, 30 Mar 2019 15:07:07 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH] qemu-img: Saner printing of large file sizes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , vsementsov@virtuozzo.com, qemu-block@nongnu.org, rjones@redhat.com, Markus Armbruster , Max Reitz , jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Disk sizes close to INT64_MAX cause overflow, for some pretty ridiculous output: $ ./nbdkit -U - memory size=3D$((2**63 - 512)) --run 'qemu-img info $nbd' image: nbd+unix://?socket=3D/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 Signed-off-by: Eric Blake Reviewed-by: Alberto Garcia Reviewed-by: Vladimir Sementsov-Ogievskiy Tested-by: Richard W.M. Jones --- 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_n= odes, 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] =3D {'K', 'M', 'G', 'T'}; - int64_t base; - int i; - - if (size <=3D 999) { - snprintf(buf, buf_size, "%" PRId64, size); - } else { - base =3D 1024; - for (i =3D 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 =3D=3D (NB_SUFFIXES - 1))= { - snprintf(buf, buf_size, "%" PRId64 "%c", - ((size + (base >> 1)) / base), - suffixes[i]); - break; - } - base =3D 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 =3D 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 =3D 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 indenta= tion, @@ -796,14 +768,13 @@ void bdrv_image_info_specific_dump(fprintf_function f= unc_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 =3D g_strdup("unavailable"); } else { - get_human_readable_size(dsize_buf, sizeof(dsize_buf), - info->actual_size); + dsize_buf =3D size_to_str(info->actual_size); } - get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size= ); + size_buf =3D 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"); --=20 2.20.1