<div dir="ltr">Resend the email below.</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Sep 1, 2014 at 8:28 PM, Hongbin Lu <span dir="ltr"><<a href="mailto:hongbin034@gmail.com" target="_blank">hongbin034@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The OpenVZ driver reported an error on parsing some OpenVZ config<br>
parameters (e.g. diskspace). This issue is due to the driver made<br>
two incorrect assumptions about the value of the parameters:<br>
1. Assume paramaeter is just a number (e.g. 1024).<br>
2. Assume the number is an integer.<br>
Actually, an OpenVZ config parameter may consists of a scalar and<br>
a unit, and the scalar is not necessary an integer (e.g. 2.2G).<br>
This patch is for fixing this issue.<br>
---<br>
 src/openvz/openvz_conf.c |   99 ++++++++++++++++++++++++++++++++++++++++++++-<br>
 src/openvz/openvz_conf.h |    6 +++<br>
 2 files changed, 102 insertions(+), 3 deletions(-)<br>
<br>
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c<br>
index 856c9f5..7dba925 100644<br>
--- a/src/openvz/openvz_conf.c<br>
+++ b/src/openvz/openvz_conf.c<br>
@@ -127,6 +127,42 @@ int openvzExtractVersion(struct openvz_driver *driver)<br>
 }<br>
<br>
<br>
+static int<br>
+openvzParseParamUnit(char* str, openvzParamUnit *unit)<br>
+{<br>
+    int len = strlen(str);<br>
+    if (len == 0)<br>
+        return -1;<br>
+<br>
+    switch (str[len - 1]) {<br>
+    case 'G':<br>
+    case 'g':<br>
+        str[len - 1] = '\0';<br>
+        if (unit != NULL)<br>
+            *unit = OPENVZ_PARAM_UNIT_GIGABYTE;<br>
+        break;<br>
+    case 'M':<br>
+    case 'm':<br>
+        str[len - 1] = '\0';<br>
+        if (unit != NULL)<br>
+            *unit = OPENVZ_PARAM_UNIT_MEGABYTE;<br>
+        break;<br>
+    case 'K':<br>
+    case 'k':<br>
+        str[len - 1] = '\0';<br>
+        if (unit != NULL)<br>
+            *unit = OPENVZ_PARAM_UNIT_KILOBYTE;<br>
+        break;<br>
+    case 'P':<br>
+    case 'p':<br>
+        str[len - 1] = '\0';<br>
+        break;<br>
+    }<br>
+<br>
+    return 0;<br>
+}<br>
+<br>
+<br>
 /* Parse config values of the form barrier:limit into barrier and limit */<br>
 static int<br>
 openvzParseBarrierLimit(const char* value,<br>
@@ -146,7 +182,10 @@ openvzParseBarrierLimit(const char* value,<br>
         goto error;<br>
     } else {<br>
         if (barrier != NULL) {<br>
-            if (virStrToLong_ull(token, NULL, 10, barrier))<br>
+            if (openvzParseParamUnit(token, NULL) < 0)<br>
+                goto error;<br>
+<br>
+            if (virStrToLong_ull(token, NULL, 10, barrier) < 0)<br>
                 goto error;<br>
         }<br>
     }<br>
@@ -155,7 +194,10 @@ openvzParseBarrierLimit(const char* value,<br>
         goto error;<br>
     } else {<br>
         if (limit != NULL) {<br>
-            if (virStrToLong_ull(token, NULL, 10, limit))<br>
+            if (openvzParseParamUnit(token, NULL) < 0)<br>
+                goto error;<br>
+<br>
+            if (virStrToLong_ull(token, NULL, 10, limit) < 0)<br>
                 goto error;<br>
         }<br>
     }<br>
@@ -166,6 +208,57 @@ openvzParseBarrierLimit(const char* value,<br>
 }<br>
<br>
<br>
+static int<br>
+openvzParseBarrierLimit2(const char* value,<br>
+                         unsigned long long *barrier,<br>
+                         unsigned long long *limit,<br>
+                         openvzParamUnit targetunit)<br>
+{<br>
+    char *token;<br>
+    char *saveptr = NULL;<br>
+    char *str;<br>
+    double dbarrier, dlimit;<br>
+    openvzParamUnit unit = OPENVZ_PARAM_UNIT_KILOBYTE;<br>
+    int ret = -1;<br>
+<br>
+    if (VIR_STRDUP(str, value) < 0)<br>
+        goto error;<br>
+<br>
+    token = strtok_r(str, ":", &saveptr);<br>
+    if (token == NULL)<br>
+        goto error;<br>
+<br>
+    if (barrier != NULL) {<br>
+        if (openvzParseParamUnit(token, &unit) < 0)<br>
+            goto error;<br>
+<br>
+        if (virStrToDouble(token, NULL, &dbarrier) < 0)<br>
+            goto error;<br>
+<br>
+        *barrier = (unsigned long long)(dbarrier * unit / targetunit);<br>
+    }<br>
+<br>
+    token = strtok_r(NULL, ":", &saveptr);<br>
+    if (token == NULL)<br>
+        goto error;<br>
+<br>
+    if (limit != NULL) {<br>
+        if (openvzParseParamUnit(token, &unit) < 0)<br>
+            goto error;<br>
+<br>
+        if (virStrToDouble(token, NULL, &dlimit) < 0)<br>
+            goto error;<br>
+<br>
+        *limit = (unsigned long long)(dlimit * unit / targetunit);<br>
+    }<br>
+<br>
+    ret = 0;<br>
+ error:<br>
+    VIR_FREE(str);<br>
+    return ret;<br>
+}<br>
+<br>
+<br>
 virCapsPtr openvzCapsInit(void)<br>
 {<br>
     virCapsPtr caps;<br>
@@ -396,7 +489,7 @@ openvzReadFSConf(virDomainDefPtr def,<br>
     param = "DISKSPACE";<br>
     ret = openvzReadVPSConfigParam(veid, param, &temp);<br>
     if (ret > 0) {<br>
-        if (openvzParseBarrierLimit(temp, &barrier, &limit)) {<br>
+        if (openvzParseBarrierLimit2(temp, &barrier, &limit, OPENVZ_PARAM_UNIT_KILOBYTE)) {<br>
             virReportError(VIR_ERR_INTERNAL_ERROR,<br>
                            _("Could not read '%s' from config for container %d"),<br>
                            param, veid);<br>
diff --git a/src/openvz/openvz_conf.h b/src/openvz/openvz_conf.h<br>
index a7de7d2..788dae9 100644<br>
--- a/src/openvz/openvz_conf.h<br>
+++ b/src/openvz/openvz_conf.h<br>
@@ -41,6 +41,12 @@<br>
<br>
 # define VZCTL_BRIDGE_MIN_VERSION ((3 * 1000 * 1000) + (0 * 1000) + 22 + 1)<br>
<br>
+typedef enum {<br>
+    OPENVZ_PARAM_UNIT_KILOBYTE = 1,<br>
+    OPENVZ_PARAM_UNIT_MEGABYTE = 1024,<br>
+    OPENVZ_PARAM_UNIT_GIGABYTE = 1024 * 1024,<br>
+} openvzParamUnit;<br>
+<br>
 struct openvz_driver {<br>
     virMutex lock;<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
1.7.1<br>
<br>
</font></span></blockquote></div><br></div>