[libvirt] [PATCH] fix virParseVersionString with linux 3.0

linux 3.0 has no micro version number, and that is causing problems for virParseVersionString. The patch below should allow for: major major.minor major.minor.micro If major or minor are not present they just default to zero. We found this in Ubuntu (https://bugs.launchpad.net/bugs/802977) diff --git a/src/util/util.c b/src/util/util.c index 463d2b8..01848a1 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1598,17 +1598,17 @@ virParseNumber(const char **str) int virParseVersionString(const char *str, unsigned long *version) { - unsigned int major, minor, micro; + unsigned int major, minor=0, micro=0; char *tmp; - if (virStrToLong_ui(str, &tmp, 10, &major) < 0 || *tmp != '.') + if (virStrToLong_ui(str, &tmp, 10, &major) < 0) return -1; - if (virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0 || *tmp != '.') - return -1; + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0) + return -1; - if (virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) - return -1; + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) + return -1; *version = 1000000 * major + 1000 * minor + micro;

2011/7/1 Scott Moser <smoser@ubuntu.com>:
linux 3.0 has no micro version number, and that is causing problems for virParseVersionString. The patch below should allow for: major major.minor major.minor.micro
If major or minor are not present they just default to zero. We found this in Ubuntu (https://bugs.launchpad.net/bugs/802977)
diff --git a/src/util/util.c b/src/util/util.c index 463d2b8..01848a1 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1598,17 +1598,17 @@ virParseNumber(const char **str) int virParseVersionString(const char *str, unsigned long *version) { - unsigned int major, minor, micro; + unsigned int major, minor=0, micro=0; char *tmp;
- if (virStrToLong_ui(str, &tmp, 10, &major) < 0 || *tmp != '.') + if (virStrToLong_ui(str, &tmp, 10, &major) < 0) return -1;
- if (virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0 || *tmp != '.') - return -1; + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0) + return -1;
- if (virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) - return -1; + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) + return -1;
*version = 1000000 * major + 1000 * minor + micro;
Well, your patch fixes the problem, but virParseVersionString is used in more places than just kernel version parsing, therefore I think it relaxes parsing too much and we need a stricter approach for this. -- Matthias Bolte http://photron.blogspot.com

On 07/01/2011 07:00 AM, Matthias Bolte wrote:
2011/7/1 Scott Moser <smoser@ubuntu.com>:
linux 3.0 has no micro version number, and that is causing problems for virParseVersionString. The patch below should allow for: major major.minor major.minor.micro
If major or minor are not present they just default to zero. We found this in Ubuntu (https://bugs.launchpad.net/bugs/802977)
Well, your patch fixes the problem, but virParseVersionString is used in more places than just kernel version parsing, therefore I think it relaxes parsing too much and we need a stricter approach for this.
Hmm, I was just about to apply this patch. Maybe the stricter approach is to add a bool argument that states whether omitted arguments should be treated as 0 or as an error, and update all (12) callers to choose which context is important. I'll do that as a followup after pushing Scott's patch. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

To avoid regressions, we let callers specify whether to require a micro version. Callers that were parsing uname() output benefit from the defaults, whereas callers that were parsing version strings from other sources should not change in behavior. * src/util/util.c (virParseVersionString): Allow caller to choose whether to fail if micro is missing. * src/util/util.h (virParseVersionString): Update signature. * src/esx/esx_driver.c (esxGetVersion): Update callers. * src/lxc/lxc_driver.c (lxcVersion): Likewise. * src/openvz/openvz_conf.c (openvzExtractVersionInfo): Likewise. * src/uml/uml_driver.c (umlGetVersion): Likewise. * src/vbox/vbox_MSCOMGlue.c (vboxLookupVersionInRegistry): Likewise. * src/vbox/vbox_tmpl.c (vboxExtractVersion): Likewise. * src/vmware/vmware_conf.c (vmwareExtractVersion): Likewise. * src/xenapi/xenapi_driver.c (xenapiGetVersion): Likewise. Reported by Matthias Bolte. --- src/esx/esx_driver.c | 2 +- src/lxc/lxc_driver.c | 2 +- src/openvz/openvz_conf.c | 2 +- src/uml/uml_driver.c | 2 +- src/util/util.c | 11 ++++++++++- src/util/util.h | 3 ++- src/vbox/vbox_MSCOMGlue.c | 2 +- src/vbox/vbox_tmpl.c | 2 +- src/vmware/vmware_conf.c | 2 +- src/xenapi/xenapi_driver.c | 2 +- 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 3a140e9..a6e47a4 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -1202,7 +1202,7 @@ esxGetVersion(virConnectPtr conn, unsigned long *version) esxPrivate *priv = conn->privateData; if (virParseVersionString(priv->primary->service->about->version, - version) < 0) { + version, false) < 0) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not parse version number from '%s'"), priv->primary->service->about->version); diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index d0f7158..7220a9b 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2249,7 +2249,7 @@ static int lxcVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *versio uname(&ver); - if (virParseVersionString(ver.release, version) < 0) { + if (virParseVersionString(ver.release, version, true) < 0) { lxcError(VIR_ERR_INTERNAL_ERROR, _("Unknown release: %s"), ver.release); return -1; } diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index 189279d..561cc99 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -99,7 +99,7 @@ openvzExtractVersionInfo(const char *cmdstr, int *retversion) if ((tmp = STRSKIP(tmp, "vzctl version ")) == NULL) goto cleanup; - if (virParseVersionString(tmp, &version) < 0) + if (virParseVersionString(tmp, &version, false) < 0) goto cleanup; if (retversion) diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index e557fe8..a71ea21 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1227,7 +1227,7 @@ static int umlGetVersion(virConnectPtr conn, unsigned long *version) { if (driver->umlVersion == 0) { uname(&ut); - if (virParseVersionString(ut.release, &driver->umlVersion) < 0) { + if (virParseVersionString(ut.release, &driver->umlVersion, true) < 0) { umlReportError(VIR_ERR_INTERNAL_ERROR, _("cannot parse version %s"), ut.release); goto cleanup; diff --git a/src/util/util.c b/src/util/util.c index da24859..8e12e5f 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1585,6 +1585,8 @@ virParseNumber(const char **str) * virParseVersionString: * @str: const char pointer to the version string * @version: unsigned long pointer to output the version number + * @allowMissing: true to treat 3 like 3.0.0, false to error out on + * missing minor or micro * * Parse an unsigned version number from a version string. Expecting * 'major.minor.micro' format, ignoring an optional suffix. @@ -1596,7 +1598,8 @@ virParseNumber(const char **str) * Returns the 0 for success, -1 for error. */ int -virParseVersionString(const char *str, unsigned long *version) +virParseVersionString(const char *str, unsigned long *version, + bool allowMissing) { unsigned int major, minor = 0, micro = 0; char *tmp; @@ -1604,9 +1607,15 @@ virParseVersionString(const char *str, unsigned long *version) if (virStrToLong_ui(str, &tmp, 10, &major) < 0) return -1; + if (!allowMissing && *tmp != '.') + return -1; + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0) return -1; + if (!allowMissing && *tmp != '.') + return -1; + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) return -1; diff --git a/src/util/util.h b/src/util/util.h index 0c43f7a..1555653 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -168,7 +168,8 @@ int virMacAddrCompare (const char *mac1, const char *mac2); void virSkipSpaces(const char **str); int virParseNumber(const char **str); -int virParseVersionString(const char *str, unsigned long *version); +int virParseVersionString(const char *str, unsigned long *version, + bool allowMissing); int virAsprintf(char **strp, const char *fmt, ...) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3); int virVasprintf(char **strp, const char *fmt, va_list list) diff --git a/src/vbox/vbox_MSCOMGlue.c b/src/vbox/vbox_MSCOMGlue.c index 8aef266..31e14a1 100644 --- a/src/vbox/vbox_MSCOMGlue.c +++ b/src/vbox/vbox_MSCOMGlue.c @@ -430,7 +430,7 @@ vboxLookupVersionInRegistry(void) } } - if (virParseVersionString(value, &vboxVersion) < 0) { + if (virParseVersionString(value, &vboxVersion, false) < 0) { VIR_ERROR(_("Could not parse version number from '%s'"), value); goto cleanup; } diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 7fd1200..37fe248 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -929,7 +929,7 @@ static int vboxExtractVersion(vboxGlobalData *data) { VBOX_UTF16_TO_UTF8(versionUtf16, &vboxVersion); - if (virParseVersionString(vboxVersion, &data->version) >= 0) + if (virParseVersionString(vboxVersion, &data->version, false) >= 0) ret = 0; VBOX_UTF8_FREE(vboxVersion); diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c index 4ec33ae..044784e 100644 --- a/src/vmware/vmware_conf.c +++ b/src/vmware/vmware_conf.c @@ -248,7 +248,7 @@ vmwareExtractVersion(struct vmware_driver *driver) goto cleanup; } - if (virParseVersionString(tmp, &version) < 0) { + if (virParseVersionString(tmp, &version, false) < 0) { vmwareError(VIR_ERR_INTERNAL_ERROR, "%s", _("version parsing error")); goto cleanup; diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 77d17ee..0a618ab 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -302,7 +302,7 @@ xenapiGetVersion (virConnectPtr conn, unsigned long *hvVer) } } if (version) { - if (virParseVersionString(version, hvVer) < 0) + if (virParseVersionString(version, hvVer, false) < 0) xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, _("Couldn't parse version info")); else -- 1.7.4.4

On 07/01/2011 07:25 AM, Eric Blake wrote:
To avoid regressions, we let callers specify whether to require a micro version. Callers that were parsing uname() output benefit from the defaults, whereas callers that were parsing version strings from other sources should not change in behavior.
* src/util/util.c (virParseVersionString): Allow caller to choose whether to fail if micro is missing. * src/util/util.h (virParseVersionString): Update signature. * src/esx/esx_driver.c (esxGetVersion): Update callers. * src/lxc/lxc_driver.c (lxcVersion): Likewise. * src/openvz/openvz_conf.c (openvzExtractVersionInfo): Likewise. * src/uml/uml_driver.c (umlGetVersion): Likewise. * src/vbox/vbox_MSCOMGlue.c (vboxLookupVersionInRegistry): Likewise. * src/vbox/vbox_tmpl.c (vboxExtractVersion): Likewise. * src/vmware/vmware_conf.c (vmwareExtractVersion): Likewise. * src/xenapi/xenapi_driver.c (xenapiGetVersion): Likewise. Reported by Matthias Bolte.
I plan to squash this in (I figured it was easier to show this diff than to send a full v2): diff --git i/src/util/util.c w/src/util/util.c index 8e12e5f..6e1f4f5 100644 --- i/src/util/util.c +++ w/src/util/util.c @@ -1619,6 +1619,9 @@ virParseVersionString(const char *str, unsigned long *version, if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) return -1; + if (major > ULONG_MAX / 1000000 || minor > 999 || micro > 999) + return -1; + *version = 1000000 * major + 1000 * minor + micro; return 0; -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On 07/01/2011 10:54 AM, Eric Blake wrote:
+++ w/src/util/util.c @@ -1619,6 +1619,9 @@ virParseVersionString(const char *str, unsigned long *version, if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) return -1;
+ if (major > ULONG_MAX / 1000000 || minor > 999 || micro > 999)
s/ULONG_MAX/UINT_MAX/ to silence a compiler warning, and to deal with the fact that even though this function populates an 'unsigned long *version', the only reason it does so is because of our (poor) choice in making virGetVersion use unsigned long. But for portability to 32-bit hosts, we can never exceed a 32-bit version computation, even on hosts where long is 64-bits. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

To avoid regressions, we let callers specify whether to require a micro version. Callers that were parsing uname() output benefit from the defaults, whereas callers that were parsing version strings from other sources should not change in behavior. * src/util/util.c (virParseVersionString): Allow caller to choose whether to fail if micro is missing. * src/util/util.h (virParseVersionString): Update signature. * src/esx/esx_driver.c (esxGetVersion): Update callers. * src/lxc/lxc_driver.c (lxcVersion): Likewise. * src/openvz/openvz_conf.c (openvzExtractVersionInfo): Likewise. * src/uml/uml_driver.c (umlGetVersion): Likewise. * src/vbox/vbox_MSCOMGlue.c (vboxLookupVersionInRegistry): Likewise. * src/vbox/vbox_tmpl.c (vboxExtractVersion): Likewise. * src/vmware/vmware_conf.c (vmwareExtractVersion): Likewise. * src/xenapi/xenapi_driver.c (xenapiGetVersion): Likewise. Reported by Matthias Bolte. --- For the avoidance of any doubt, I'm posting a complete v3. v2: check for overflow v3: constrain result to 32-bits src/esx/esx_driver.c | 2 +- src/lxc/lxc_driver.c | 2 +- src/openvz/openvz_conf.c | 2 +- src/uml/uml_driver.c | 2 +- src/util/util.c | 14 +++++++++++++- src/util/util.h | 3 ++- src/vbox/vbox_MSCOMGlue.c | 2 +- src/vbox/vbox_tmpl.c | 2 +- src/vmware/vmware_conf.c | 2 +- src/xenapi/xenapi_driver.c | 2 +- 10 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c index 3a140e9..a6e47a4 100644 --- a/src/esx/esx_driver.c +++ b/src/esx/esx_driver.c @@ -1202,7 +1202,7 @@ esxGetVersion(virConnectPtr conn, unsigned long *version) esxPrivate *priv = conn->privateData; if (virParseVersionString(priv->primary->service->about->version, - version) < 0) { + version, false) < 0) { ESX_ERROR(VIR_ERR_INTERNAL_ERROR, _("Could not parse version number from '%s'"), priv->primary->service->about->version); diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index d0f7158..7220a9b 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -2249,7 +2249,7 @@ static int lxcVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *versio uname(&ver); - if (virParseVersionString(ver.release, version) < 0) { + if (virParseVersionString(ver.release, version, true) < 0) { lxcError(VIR_ERR_INTERNAL_ERROR, _("Unknown release: %s"), ver.release); return -1; } diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index 189279d..561cc99 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -99,7 +99,7 @@ openvzExtractVersionInfo(const char *cmdstr, int *retversion) if ((tmp = STRSKIP(tmp, "vzctl version ")) == NULL) goto cleanup; - if (virParseVersionString(tmp, &version) < 0) + if (virParseVersionString(tmp, &version, false) < 0) goto cleanup; if (retversion) diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c index e557fe8..a71ea21 100644 --- a/src/uml/uml_driver.c +++ b/src/uml/uml_driver.c @@ -1227,7 +1227,7 @@ static int umlGetVersion(virConnectPtr conn, unsigned long *version) { if (driver->umlVersion == 0) { uname(&ut); - if (virParseVersionString(ut.release, &driver->umlVersion) < 0) { + if (virParseVersionString(ut.release, &driver->umlVersion, true) < 0) { umlReportError(VIR_ERR_INTERNAL_ERROR, _("cannot parse version %s"), ut.release); goto cleanup; diff --git a/src/util/util.c b/src/util/util.c index da24859..13973c3 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1585,6 +1585,8 @@ virParseNumber(const char **str) * virParseVersionString: * @str: const char pointer to the version string * @version: unsigned long pointer to output the version number + * @allowMissing: true to treat 3 like 3.0.0, false to error out on + * missing minor or micro * * Parse an unsigned version number from a version string. Expecting * 'major.minor.micro' format, ignoring an optional suffix. @@ -1596,7 +1598,8 @@ virParseNumber(const char **str) * Returns the 0 for success, -1 for error. */ int -virParseVersionString(const char *str, unsigned long *version) +virParseVersionString(const char *str, unsigned long *version, + bool allowMissing) { unsigned int major, minor = 0, micro = 0; char *tmp; @@ -1604,12 +1607,21 @@ virParseVersionString(const char *str, unsigned long *version) if (virStrToLong_ui(str, &tmp, 10, &major) < 0) return -1; + if (!allowMissing && *tmp != '.') + return -1; + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0) return -1; + if (!allowMissing && *tmp != '.') + return -1; + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, µ) < 0) return -1; + if (major > UINT_MAX / 1000000 || minor > 999 || micro > 999) + return -1; + *version = 1000000 * major + 1000 * minor + micro; return 0; diff --git a/src/util/util.h b/src/util/util.h index 0c43f7a..1555653 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -168,7 +168,8 @@ int virMacAddrCompare (const char *mac1, const char *mac2); void virSkipSpaces(const char **str); int virParseNumber(const char **str); -int virParseVersionString(const char *str, unsigned long *version); +int virParseVersionString(const char *str, unsigned long *version, + bool allowMissing); int virAsprintf(char **strp, const char *fmt, ...) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_FMT_PRINTF(2, 3); int virVasprintf(char **strp, const char *fmt, va_list list) diff --git a/src/vbox/vbox_MSCOMGlue.c b/src/vbox/vbox_MSCOMGlue.c index 8aef266..31e14a1 100644 --- a/src/vbox/vbox_MSCOMGlue.c +++ b/src/vbox/vbox_MSCOMGlue.c @@ -430,7 +430,7 @@ vboxLookupVersionInRegistry(void) } } - if (virParseVersionString(value, &vboxVersion) < 0) { + if (virParseVersionString(value, &vboxVersion, false) < 0) { VIR_ERROR(_("Could not parse version number from '%s'"), value); goto cleanup; } diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index 7fd1200..37fe248 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -929,7 +929,7 @@ static int vboxExtractVersion(vboxGlobalData *data) { VBOX_UTF16_TO_UTF8(versionUtf16, &vboxVersion); - if (virParseVersionString(vboxVersion, &data->version) >= 0) + if (virParseVersionString(vboxVersion, &data->version, false) >= 0) ret = 0; VBOX_UTF8_FREE(vboxVersion); diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c index 4ec33ae..044784e 100644 --- a/src/vmware/vmware_conf.c +++ b/src/vmware/vmware_conf.c @@ -248,7 +248,7 @@ vmwareExtractVersion(struct vmware_driver *driver) goto cleanup; } - if (virParseVersionString(tmp, &version) < 0) { + if (virParseVersionString(tmp, &version, false) < 0) { vmwareError(VIR_ERR_INTERNAL_ERROR, "%s", _("version parsing error")); goto cleanup; diff --git a/src/xenapi/xenapi_driver.c b/src/xenapi/xenapi_driver.c index 77d17ee..0a618ab 100644 --- a/src/xenapi/xenapi_driver.c +++ b/src/xenapi/xenapi_driver.c @@ -302,7 +302,7 @@ xenapiGetVersion (virConnectPtr conn, unsigned long *hvVer) } } if (version) { - if (virParseVersionString(version, hvVer) < 0) + if (virParseVersionString(version, hvVer, false) < 0) xenapiSessionErrorHandler(conn, VIR_ERR_INTERNAL_ERROR, _("Couldn't parse version info")); else -- 1.7.4.4

2011/7/1 Eric Blake <eblake@redhat.com>:
To avoid regressions, we let callers specify whether to require a micro version. Callers that were parsing uname() output benefit
Actually this affects minor and micro.
from the defaults, whereas callers that were parsing version strings from other sources should not change in behavior.
* src/util/util.c (virParseVersionString): Allow caller to choose whether to fail if micro is missing.
Here too.
* src/util/util.h (virParseVersionString): Update signature. * src/esx/esx_driver.c (esxGetVersion): Update callers. * src/lxc/lxc_driver.c (lxcVersion): Likewise. * src/openvz/openvz_conf.c (openvzExtractVersionInfo): Likewise. * src/uml/uml_driver.c (umlGetVersion): Likewise. * src/vbox/vbox_MSCOMGlue.c (vboxLookupVersionInRegistry): Likewise. * src/vbox/vbox_tmpl.c (vboxExtractVersion): Likewise. * src/vmware/vmware_conf.c (vmwareExtractVersion): Likewise. * src/xenapi/xenapi_driver.c (xenapiGetVersion): Likewise. Reported by Matthias Bolte. ---
For the avoidance of any doubt, I'm posting a complete v3.
v2: check for overflow v3: constrain result to 32-bits
src/esx/esx_driver.c | 2 +- src/lxc/lxc_driver.c | 2 +- src/openvz/openvz_conf.c | 2 +- src/uml/uml_driver.c | 2 +- src/util/util.c | 14 +++++++++++++- src/util/util.h | 3 ++- src/vbox/vbox_MSCOMGlue.c | 2 +- src/vbox/vbox_tmpl.c | 2 +- src/vmware/vmware_conf.c | 2 +- src/xenapi/xenapi_driver.c | 2 +- 10 files changed, 23 insertions(+), 10 deletions(-)
ACK. -- Matthias Bolte http://photron.blogspot.com

On 07/01/2011 11:12 AM, Matthias Bolte wrote:
2011/7/1 Eric Blake <eblake@redhat.com>:
To avoid regressions, we let callers specify whether to require a micro version. Callers that were parsing uname() output benefit
Actually this affects minor and micro.
from the defaults, whereas callers that were parsing version strings from other sources should not change in behavior.
* src/util/util.c (virParseVersionString): Allow caller to choose whether to fail if micro is missing.
Here too.
ACK.
Pushed with the adjusted commit message. -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org

On 07/01/2011 04:40 AM, Scott Moser wrote:
linux 3.0 has no micro version number, and that is causing problems for virParseVersionString. The patch below should allow for: major major.minor major.minor.micro
If major or minor are not present they just default to zero. We found this in Ubuntu (https://bugs.launchpad.net/bugs/802977)
diff --git a/src/util/util.c b/src/util/util.c index 463d2b8..01848a1 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -1598,17 +1598,17 @@ virParseNumber(const char **str) int virParseVersionString(const char *str, unsigned long *version) { - unsigned int major, minor, micro; + unsigned int major, minor=0, micro=0;
Formatting - we tend to put spaces around operators.
char *tmp;
- if (virStrToLong_ui(str, &tmp, 10, &major) < 0 || *tmp != '.') + if (virStrToLong_ui(str, &tmp, 10, &major) < 0) return -1;
- if (virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0 || *tmp != '.') - return -1; + if ((*tmp == '.') && virStrToLong_ui(tmp + 1, &tmp, 10, &minor) < 0) + return -1;
Spurious whitespace change in the return statements. ACK (see my other reply in this thread) and pushed with that fixed, as well as adding you to AUTHORS (let me know if you prefer any alternate spellings). -- Eric Blake eblake@redhat.com +1-801-349-2682 Libvirt virtualization library http://libvirt.org
participants (3)
-
Eric Blake
-
Matthias Bolte
-
Scott Moser