From 3aab7f2d6b068f0547d10f35588ec7f1ab6882a8 Mon Sep 17 00:00:00 2001 From: Taisuke Yamada Date: Thu, 26 May 2011 19:28:54 +0200 Subject: [PATCH] openvz: Fix regression in config file parsing As reported by Diego Blanco in https://bugzilla.redhat.com/show_bug.cgi?id=702602 commit f0443765 which replaced openvz_readline to getline(3) broke OpenVZ driver as it changed semantics of EOF-handling when parsing OpenVZ configuration. There're several other issues reported with current OpenVZ driver: #1: unclear error message when parsing "CPUS=" line #2: openvz driver goes into crashing loop #3: "NETIF=" line in configuration is not parsed correctly #4: aborts even when optional parameter is missing #5: there's a potential memory leak This updated patch to fix #[145]. This patch does not fix #[23] as I haven't verified these yet, but this at least got me to run OpenVZ on libvirt once again. --- AUTHORS | 1 + src/openvz/openvz_conf.c | 50 +++++++++++++++++----------------------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/AUTHORS b/AUTHORS index 21ac53efec..6e0276e34c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -171,6 +171,7 @@ Patches have also been contributed by: Yufang Zhang Supriya Kannery Dirk Herrendoerfer + Taisuke Yamada [....send patches to get your name here....] diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index cfb691745f..c106b07f63 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -642,53 +642,45 @@ openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value) /* * value will be freed before a new value is assigned to it, the caller is * responsible for freeing it afterwards. + * + * Returns <0 on error, 0 if not found, 1 if found. */ static int openvzReadConfigParam(const char *conf_file, const char *param, char **value) { char *line = NULL; size_t line_size = 0; - ssize_t ret; FILE *fp; - int found = 0; - char *sf, *token; - char *saveptr = NULL; - - value[0] = 0; + int err = 0; + char *sf, *token, *saveptr = NULL; fp = fopen(conf_file, "r"); if (fp == NULL) return -1; - while (1) { - ret = getline(&line, &line_size, fp); - if (ret <= 0) - break; + VIR_FREE(*value); + while (getline(&line, &line_size, fp) >= 0) { + if (! STREQLEN(line, param, strlen(param))) + continue; + + sf = line + strlen(param); + if (*sf++ != '=') continue; + saveptr = NULL; - if (STREQLEN(line, param, strlen(param))) { - sf = line; - sf += strlen(param); - if (sf[0] == '=' && sf[1] != '\0' ) { - sf++; - if ((token = strtok_r(sf,"\"\t\n", &saveptr)) != NULL) { - VIR_FREE(*value); - *value = strdup(token); - if (value == NULL) { - ret = -1; - break; - } - found = 1; - } + if ((token = strtok_r(sf, "\"\t\n", &saveptr)) != NULL) { + VIR_FREE(*value); + *value = strdup(token); + if (*value == NULL) { + err = 1; + break; } - } + /* keep going - last entry wins */ + } } VIR_FREE(line); VIR_FORCE_FCLOSE(fp); - if (ret == 0 && found) - ret = 1; - - return ret; + return err ? -1 : *value ? 1 : 0; } /*