qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-block] [PATCH] qemu-img: Saner printing of large file sizes


From: Eric Blake
Subject: [Qemu-block] [PATCH] qemu-img: Saner printing of large file sizes
Date: Sat, 30 Mar 2019 10:07:02 -0500

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>
---
 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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]