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