• D
    hyperv: add support for Hyper-V 2012 and newer · 3372f8fb
    Dawid Zamirski 提交于
    This patch reworks the Hyper-V driver structs and the code generator
    to provide seamless support for both Hyper-V 2008 and 2012 or newer.
    This does not implement any new libvirt APIs, it just adapts existing
    2008-only driver to also handle 2012 and newer by sharing as much
    driver code as possible (currently it's all of it :-)). This is needed
    to set the foundation before we can move forward with implementing the
    rest of the driver APIs.
    
    With the 2012 release, Microsoft introduced "v2" version of Msvm_* WMI
    classes. Those are largely the same as "v1" (used in 2008) but have some
    new properties as well as need different wsman request URIs. To
    accomodate those differences, most of work went into the code generator
    so that it's "aware" of possibility of multiple versions of the same WMI
    class and produce C code accordingly.
    
    To accomplish this the following changes were made:
    
     * the abstract hypervObject struct's data member was changed to a union
       that has "common", "v1" and "v2" members. Those are structs that
       represent WMI classes that we get back from wsman response. The
       "common" struct has members that are present in both "v1" and "v2"
       which the driver API callbacks can use to read the data from in
       version-independent manner (if version-specific member needs to be
       accessed the driver can check priv->wmiVersion and read from "v1" or
       "v2" as needed). Those structs are guaranteed to be  memory aligned
       by the code generator (see the align_property_members implementation
       that takes care of that)
     * the generator produces *_WmiInfo for each WMI class "family" that
       holds an array of hypervWmiClassInfoPtr each providing information
       as to which request URI to use for each "version" of given WMI class
       as well as XmlSerializerInfo struct needed to unserilize WS-MAN
       responsed into the data structs. The driver uses those to make proper
       WS-MAN request depending on which version it's connected to.
     * the generator no longer produces "helper" functions such as
       hypervGetMsvmComputerSystemList as those were originally just simple
       wrappers around hypervEnumAndPull, instead those were hand-written
       now (to keep driver changes minimal). The reason is that we'll have
       more code coming implementing missing libvirt APIs and surely code
       patterns will emerge that would warrant more useful "utility" functions
       like that.
     * a hypervInitConnection was added to the driver which "detects"
       Hyper-V version by testing simple wsman request using v2 then falling
       back to v1, obviously if both fail, the we're erroring out.
    
    To express how the above translates in code:
    
    void
    hypervImplementSomeLibvirtApi(virConnectPtr conn, ...)
    {
        hypervPrivate *priv = conn->privateData;
        virBuffer query = VIR_BUFFER_INITIALIZER;
        hypervWqlQuery wqlQuery = HYPERV_WQL_QUERY_INITIALIZER;
        Msvm_ComputerSystem *list = NULL; /* typed hypervObject instance */
    
        /* the WmiInfo struct has the data needed for wsman request and
         * response handling for both v1 and v2 */
        wqlQuery.info = Msvm_ComputerSystem_WmiInfo;
        wqlQuery.query = &query;
    
        virBufferAddLit(&query, "select * from Msvm_ComputerSystem");
    
        if (hypervEnumAndPull(priv, &wqlQuery, (hypervObject **) &list) < 0) {
            goto cleanup;
        }
    
        if (list == NULL) {
            /* none found */
            goto cleanup;
        }
    
        /* works with v1 and v2 */
        char *vmName = list->data.common->Name;
    
        /* access property that is in v2 only */
        if (priv->wmiVersion == HYPERV_WMI_VERSION_V2)
            char *foo = list->data.v2->V2Property;
        else
            char *foo = list->data.v1->V1Property;
    
     cleanup:
        hypervFreeObject(priv, (hypervObject *)list);
    }
    3372f8fb
hyperv_driver.c 41.5 KB