qemu-block
[Top][All Lists]
Advanced

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

[Qemu-block] [PATCH v6 02/15] qapi: Assert finite use of 'number'


From: Eric Blake
Subject: [Qemu-block] [PATCH v6 02/15] qapi: Assert finite use of 'number'
Date: Mon, 10 Oct 2016 08:23:44 -0500

Add assertions to all QMP commands that use a QAPI number (namely
migrate_set_downtime on input; query-migrate and query-blockstats
on output), to make it obvious where we would have to revisit the
code if we were to extend QMP to support Infinity or NaN.

Furthermore, make it part of our contract that we don't plan to
convert QObject to JSON unless all numbers are finite.

Signed-off-by: Eric Blake <address@hidden>

---
v6: new patch
---
 block/accounting.c    | 6 +++++-
 migration/migration.c | 4 ++++
 qobject/qjson.c       | 8 ++++----
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/block/accounting.c b/block/accounting.c
index 3f457c4..8b0e909 100644
--- a/block/accounting.c
+++ b/block/accounting.c
@@ -24,6 +24,7 @@
  */

 #include "qemu/osdep.h"
+#include <math.h>
 #include "block/accounting.h"
 #include "block/block_int.h"
 #include "qemu/timer.h"
@@ -164,10 +165,13 @@ double block_acct_queue_depth(BlockAcctTimedStats *stats,
                               enum BlockAcctType type)
 {
     uint64_t sum, elapsed;
+    double result;

     assert(type < BLOCK_MAX_IOTYPE);

     sum = timed_average_sum(&stats->latency[type], &elapsed);

-    return (double) sum / elapsed;
+    result = (double) sum / elapsed;
+    assert(isfinite(result));
+    return result;
 }
diff --git a/migration/migration.c b/migration/migration.c
index e7a425b..8ac4e90 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -14,6 +14,7 @@
  */

 #include "qemu/osdep.h"
+#include <math.h>
 #include "qemu/cutils.h"
 #include "qemu/error-report.h"
 #include "qemu/main-loop.h"
@@ -1192,6 +1193,7 @@ void qmp_migrate_set_speed(int64_t value, Error **errp)

 void qmp_migrate_set_downtime(double value, Error **errp)
 {
+    assert(isfinite(value)); /* JSON (thus QMP) doesn't permit inf or NaN */
     value *= 1000; /* Convert to milliseconds */
     value = MAX(0, MIN(INT64_MAX, value));

@@ -1811,6 +1813,7 @@ static void *migration_thread(void *opaque)

             s->mbps = (((double) transferred_bytes * 8.0) /
                     ((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
+            assert(isfinite(s->mbps));

             trace_migrate_transferred(transferred_bytes, time_spent,
                                       bandwidth, max_size);
@@ -1846,6 +1849,7 @@ static void *migration_thread(void *opaque)
         if (s->total_time) {
             s->mbps = (((double) transferred_bytes * 8.0) /
                        ((double) s->total_time)) / 1000;
+            assert(isfinite(s->mbps));
         }
         runstate_set(RUN_STATE_POSTMIGRATE);
     } else {
diff --git a/qobject/qjson.c b/qobject/qjson.c
index 9a0de89..906a8fc 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -12,6 +12,7 @@
  */

 #include "qemu/osdep.h"
+#include <math.h>
 #include "qapi/qmp/json-lexer.h"
 #include "qapi/qmp/json-parser.h"
 #include "qapi/qmp/json-streamer.h"
@@ -231,20 +232,19 @@ static void to_json(const QObject *obj, QString *str, int 
pretty, int indent)
         break;
     }
     case QTYPE_QFLOAT: {
-        QFloat *val = qobject_to_qfloat(obj);
+        double val = qfloat_get_double(qobject_to_qfloat(obj));
         char buffer[1024];
         int len;

+        assert(isfinite(val));
         /* FIXME: snprintf() is locale dependent; but JSON requires
          * numbers to be formatted as if in the C locale. Dependence
          * on C locale is a pervasive issue in QEMU. */
-        /* FIXME: This risks printing Inf or NaN, which are not valid
-         * JSON values. */
         /* FIXME: the default precision of 6 for %f often causes
          * rounding errors; we should be using DBL_DECIMAL_DIG (17),
          * and only rounding to a shorter number if the result would
          * still produce the same floating point value.  */
-        len = snprintf(buffer, sizeof(buffer), "%f", qfloat_get_double(val));
+        len = snprintf(buffer, sizeof(buffer), "%f", val);
         while (len > 0 && buffer[len - 1] == '0') {
             len--;
         }
-- 
2.7.4




reply via email to

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