[libvirt] [PATCH] openvz: fixed an config file parsing error

Hongbin Lu hongbin034 at gmail.com
Wed Sep 3 15:55:50 UTC 2014


Resend the email below.


On Mon, Sep 1, 2014 at 8:28 PM, Hongbin Lu <hongbin034 at gmail.com> wrote:

> The OpenVZ driver reported an error on parsing some OpenVZ config
> parameters (e.g. diskspace). This issue is due to the driver made
> two incorrect assumptions about the value of the parameters:
> 1. Assume paramaeter is just a number (e.g. 1024).
> 2. Assume the number is an integer.
> Actually, an OpenVZ config parameter may consists of a scalar and
> a unit, and the scalar is not necessary an integer (e.g. 2.2G).
> This patch is for fixing this issue.
> ---
>  src/openvz/openvz_conf.c |   99
> ++++++++++++++++++++++++++++++++++++++++++++-
>  src/openvz/openvz_conf.h |    6 +++
>  2 files changed, 102 insertions(+), 3 deletions(-)
>
> diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
> index 856c9f5..7dba925 100644
> --- a/src/openvz/openvz_conf.c
> +++ b/src/openvz/openvz_conf.c
> @@ -127,6 +127,42 @@ int openvzExtractVersion(struct openvz_driver *driver)
>  }
>
>
> +static int
> +openvzParseParamUnit(char* str, openvzParamUnit *unit)
> +{
> +    int len = strlen(str);
> +    if (len == 0)
> +        return -1;
> +
> +    switch (str[len - 1]) {
> +    case 'G':
> +    case 'g':
> +        str[len - 1] = '\0';
> +        if (unit != NULL)
> +            *unit = OPENVZ_PARAM_UNIT_GIGABYTE;
> +        break;
> +    case 'M':
> +    case 'm':
> +        str[len - 1] = '\0';
> +        if (unit != NULL)
> +            *unit = OPENVZ_PARAM_UNIT_MEGABYTE;
> +        break;
> +    case 'K':
> +    case 'k':
> +        str[len - 1] = '\0';
> +        if (unit != NULL)
> +            *unit = OPENVZ_PARAM_UNIT_KILOBYTE;
> +        break;
> +    case 'P':
> +    case 'p':
> +        str[len - 1] = '\0';
> +        break;
> +    }
> +
> +    return 0;
> +}
> +
> +
>  /* Parse config values of the form barrier:limit into barrier and limit */
>  static int
>  openvzParseBarrierLimit(const char* value,
> @@ -146,7 +182,10 @@ openvzParseBarrierLimit(const char* value,
>          goto error;
>      } else {
>          if (barrier != NULL) {
> -            if (virStrToLong_ull(token, NULL, 10, barrier))
> +            if (openvzParseParamUnit(token, NULL) < 0)
> +                goto error;
> +
> +            if (virStrToLong_ull(token, NULL, 10, barrier) < 0)
>                  goto error;
>          }
>      }
> @@ -155,7 +194,10 @@ openvzParseBarrierLimit(const char* value,
>          goto error;
>      } else {
>          if (limit != NULL) {
> -            if (virStrToLong_ull(token, NULL, 10, limit))
> +            if (openvzParseParamUnit(token, NULL) < 0)
> +                goto error;
> +
> +            if (virStrToLong_ull(token, NULL, 10, limit) < 0)
>                  goto error;
>          }
>      }
> @@ -166,6 +208,57 @@ openvzParseBarrierLimit(const char* value,
>  }
>
>
> +static int
> +openvzParseBarrierLimit2(const char* value,
> +                         unsigned long long *barrier,
> +                         unsigned long long *limit,
> +                         openvzParamUnit targetunit)
> +{
> +    char *token;
> +    char *saveptr = NULL;
> +    char *str;
> +    double dbarrier, dlimit;
> +    openvzParamUnit unit = OPENVZ_PARAM_UNIT_KILOBYTE;
> +    int ret = -1;
> +
> +    if (VIR_STRDUP(str, value) < 0)
> +        goto error;
> +
> +    token = strtok_r(str, ":", &saveptr);
> +    if (token == NULL)
> +        goto error;
> +
> +    if (barrier != NULL) {
> +        if (openvzParseParamUnit(token, &unit) < 0)
> +            goto error;
> +
> +        if (virStrToDouble(token, NULL, &dbarrier) < 0)
> +            goto error;
> +
> +        *barrier = (unsigned long long)(dbarrier * unit / targetunit);
> +    }
> +
> +    token = strtok_r(NULL, ":", &saveptr);
> +    if (token == NULL)
> +        goto error;
> +
> +    if (limit != NULL) {
> +        if (openvzParseParamUnit(token, &unit) < 0)
> +            goto error;
> +
> +        if (virStrToDouble(token, NULL, &dlimit) < 0)
> +            goto error;
> +
> +        *limit = (unsigned long long)(dlimit * unit / targetunit);
> +    }
> +
> +    ret = 0;
> + error:
> +    VIR_FREE(str);
> +    return ret;
> +}
> +
> +
>  virCapsPtr openvzCapsInit(void)
>  {
>      virCapsPtr caps;
> @@ -396,7 +489,7 @@ openvzReadFSConf(virDomainDefPtr def,
>      param = "DISKSPACE";
>      ret = openvzReadVPSConfigParam(veid, param, &temp);
>      if (ret > 0) {
> -        if (openvzParseBarrierLimit(temp, &barrier, &limit)) {
> +        if (openvzParseBarrierLimit2(temp, &barrier, &limit,
> OPENVZ_PARAM_UNIT_KILOBYTE)) {
>              virReportError(VIR_ERR_INTERNAL_ERROR,
>                             _("Could not read '%s' from config for
> container %d"),
>                             param, veid);
> diff --git a/src/openvz/openvz_conf.h b/src/openvz/openvz_conf.h
> index a7de7d2..788dae9 100644
> --- a/src/openvz/openvz_conf.h
> +++ b/src/openvz/openvz_conf.h
> @@ -41,6 +41,12 @@
>
>  # define VZCTL_BRIDGE_MIN_VERSION ((3 * 1000 * 1000) + (0 * 1000) + 22 +
> 1)
>
> +typedef enum {
> +    OPENVZ_PARAM_UNIT_KILOBYTE = 1,
> +    OPENVZ_PARAM_UNIT_MEGABYTE = 1024,
> +    OPENVZ_PARAM_UNIT_GIGABYTE = 1024 * 1024,
> +} openvzParamUnit;
> +
>  struct openvz_driver {
>      virMutex lock;
>
> --
> 1.7.1
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140903/9f0b9f97/attachment-0001.htm>


More information about the libvir-list mailing list