[PATCH 7/8] hyperv: implement connectGetVersion
Pino Toscano
ptoscano at redhat.com
Fri Oct 2 06:48:13 UTC 2020
On Thursday, 1 October 2020 23:47:16 CEST mcoleman at datto.com wrote:
> From: Matt Coleman <matt at datto.com>
>
> Hyper-V version numbers are not compatible with the encoding in
> virParseVersionString():
> https://gitlab.com/libvirt/libvirt/-/blob/master/src/util/virutil.c#L246
>
> For example, the Windows Server 2016 Hyper-V version is 10.0.14393: its
> micro is over 14 times larger than the encoding allows.
>
> This commit repacks the Hyper-V version number in order to preserve all
> of the digits. The major and minor are concatenated (with minor zero-
> padded to two digits) to form the repacked major value. This works
> because Microsoft's major and minor versions numbers are unlikely to
> exceed 99. The repacked minor value is derived from the digits in the
> thousands, ten-thousands, and hundred-thousands places of Hyper-V's
> micro. The repacked micro is derived from the digits in the ones, tens,
> and hundreds places of Hyper-V's micro.
> [...]
> + /*
> + * Mangle the version to work with virParseVersionString() while retaining all the digits.
> + *
> + * For example...
> + * 2008: 6.0.6001 => 600.6.1
> + * 2008 R2: 6.1.7600 => 601.7.600
> + * 2012: 6.2.9200 => 602.9.200
> + * 2012 R2: 6.3.9600 => 603.9.600
> + * 2016: 10.0.14393 => 1000.14.393
> + * 2019: 10.0.17763 => 1000.17.763
> + */
IMHO these explanations should be documented in the Hyper-V driver
page: docs/drvhyperv.html.in. This way, users know about the different
value returned by virConnectGetVersion() by the Hyper-V driver, and
can unmangle it to get the real Hyper-V version.
> + if (virStrToLong_ui(os->data.common->Version, &suffix, 10, &major) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Could not parse major from '%s'"),
> + os->data.common->Version);
> + goto cleanup;
> + }
> +
> + if (virStrToLong_ui(suffix + 1, &suffix, 10, &minor) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Could not parse minor from '%s'"),
> + os->data.common->Version);
> + goto cleanup;
> + }
> +
> + if (virStrToLong_ui(suffix + 1, NULL, 10, µ) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Could not parse micro from '%s'"),
> + os->data.common->Version);
> + goto cleanup;
> + }
> +
> + if (major > 99 || minor > 99 || micro > 999999) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Could not produce mangled version number from '%s'"),
> + os->data.common->Version);
> + goto cleanup;
> + }
I'd move the parsing code to an own helper, similar to
virParseVersionString():
int
hypervParseVersionString(const char *str, unsigned int *major,
unsigned int *minor, unsigned int *micro)
without virReportError() in it; then use a single virReportError() for
hypervParseVersionString() failure.
> +
> + virBufferAsprintf(&mangled_version, "%d%02d.%d.%d", major, minor,
> + micro > 999 ? micro / 1000 : 0,
> + micro > 999 ? micro % 1000 : micro);
> +
> + /* Parse version string to long */
> + if (virParseVersionString(virBufferCurrentContent(&mangled_version), version, true) < 0) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("Could not parse version number from '%s'"),
> + os->data.common->Version);
> + goto cleanup;
> + }
Considering the major, minor and micro parts of the version string are
already broken out here, why not directly encode the version number as
long? It seems a forced roundtrip to format it as string, and parse it
again.
> diff --git a/src/hyperv/hyperv_wmi_generator.input b/src/hyperv/hyperv_wmi_generator.input
> index 77543cf6ef..bbca550790 100644
> --- a/src/hyperv/hyperv_wmi_generator.input
> +++ b/src/hyperv/hyperv_wmi_generator.input
> @@ -673,7 +673,7 @@ class Win32_OperatingSystem
> string CSCreationClassName
> string CSDVersion
> string CSName
> - uint16 CurrentTimeZone
> + int16 CurrentTimeZone
> boolean DataExecutionPrevention_Available
> boolean DataExecutionPrevention_32BitApplications
> boolean DataExecutionPrevention_Drivers
This seems unrelated to the patch? Or it is needed because this class
is used by the hypervGetWmiClass(Win32_OperatingSystem, ...) call, and
the field needed to be fixed?
I'd split it as separate commit before this one.
--
Pino Toscano
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part.
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20201002/3c713cde/attachment-0001.sig>
More information about the libvir-list
mailing list