From: yvinter <[email protected]>

---
 src/hyperv/hyperv_driver.c            | 218 ++++++++++++++++++++++++++++++++++
 src/hyperv/hyperv_wmi_generator.input |  87 ++++++++++++++
 2 files changed, 305 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index cbe4397..8b8e612 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -2801,6 +2801,224 @@ hypervDomainAttachDisk(virDomainPtr domain, 
virDomainDiskDefPtr disk)
 
 
 
+/*
+ * Create the attribute __PATH for the SwitchPort object.
+ * The attribute is build like this:
+ *   
\\<host_name>\root\virtualization:Msvm_SwitchPort.CreationClassName="Msvm_SwitchPort",
+ *   Name="<switchPortName>",SystemCreationClassName="Msvm_VirtualSwitch",
+ *   SystemName="<virtualSwitchSystemName>"
+ */
+static int
+hypervGetSwitchPortPATH(virDomainPtr domain, char *switchPortName, char 
*virtualSwitchSystemName, char **__path)
+{
+    char uuid_string[VIR_UUID_STRING_BUFLEN];
+    hypervPrivate *priv = domain->conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    Msvm_ComputerSystem *computerSystem = NULL;
+    int result = -1;
+    
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    /* Get host name */
+    virBufferAsprintf(&query,
+                      "associators of "
+                      
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+                      "Name=\"%s\"} "
+                      "where AssocClass = Msvm_HostedDependency "
+                      "ResultClass = Msvm_ComputerSystem",
+                      uuid_string);
+    if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+        goto cleanup;
+    }
+    if (computerSystem == NULL) {
+        virReportError(VIR_ERR_NO_DOMAIN,
+                       _("No domain with UUID %s"), uuid_string);
+        goto cleanup;
+    }
+    
+    /* Create the attribute __PATH */
+    /* FIXME: *__path is allocated with 512 characters (static value) */
+    if (VIR_ALLOC_N(*__path, 512) < 0)
+        goto cleanup;
+    sprintf(*__path,
+            
"\\\\%s\\root\\virtualization:Msvm_SwitchPort.CreationClassName=\"Msvm_SwitchPort\","
+            
"Name=\"%s\",SystemCreationClassName=\"Msvm_VirtualSwitch\",SystemName=\"%s\"",
+            computerSystem->data->ElementName, switchPortName, 
virtualSwitchSystemName);
+    
+    result = 0;
+    
+ cleanup:
+    hypervFreeObject(priv, (hypervObject *) computerSystem);
+    virBufferFreeAndReset(&query);
+    return result;
+}
+
+
+
+/* hypervDomainAttachNetwork
+ * FIXME:
+ *   - implement associated detach method
+ */
+ATTRIBUTE_UNUSED static int
+hypervDomainAttachNetwork(virDomainPtr domain, virDomainNetDefPtr net)
+{
+    int result = -1, nb_params;
+    const char *selector1 = 
"CreationClassName=Msvm_VirtualSwitchManagementService";
+    const char *selector2 = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+    char uuid_string[VIR_UUID_STRING_BUFLEN], 
guid_string[VIR_UUID_STRING_BUFLEN];
+    unsigned char guid[VIR_UUID_BUFLEN];
+    char *virtualSystemIdentifiers = NULL, *switchPortPATH = NULL;
+    hypervPrivate *priv = domain->conn->privateData;
+    virBuffer query = VIR_BUFFER_INITIALIZER;
+    eprParam eprparam1, eprparam2;
+    simpleParam simpleparam1, simpleparam2, simpleparam3;
+    embeddedParam embeddedparam;
+    properties_t *tab_props = NULL;
+    invokeXmlParam *params = NULL;
+    Msvm_SwitchPort *switchPort = NULL;
+    Msvm_VirtualSwitch *virtualSwitch = NULL;
+    
+    /* Initialization */
+    virUUIDFormat(domain->uuid, uuid_string);
+    
+    VIR_DEBUG("network=%s, uuid=%s", net->data.network.name, uuid_string);
+    
+    /* Create virtual switch port */
+    /* Prepare EPR param 1 */
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where ElementName = \"%s\"", 
net->data.network.name);
+    eprparam1.query = &query;
+    eprparam1.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    /* Prepare SIMPLE params */
+    virUUIDGenerate(guid);
+    virUUIDFormat(guid, guid_string);
+    simpleparam1.value = guid_string;
+    simpleparam2.value = "Dynamic Ethernet Switch Port";
+    simpleparam3.value = "";
+    
+    /* Create invokeXmlParam tab */
+    nb_params = 4;
+    if (VIR_ALLOC_N(params, nb_params) < 0)
+        goto cleanup;
+    (*params).name = "VirtualSwitch";
+    (*params).type = EPR_PARAM;
+    (*params).param = &eprparam1;
+    (*(params+1)).name = "Name";
+    (*(params+1)).type = SIMPLE_PARAM;
+    (*(params+1)).param = &simpleparam1;
+    (*(params+2)).name = "FriendlyName";
+    (*(params+2)).type = SIMPLE_PARAM;
+    (*(params+2)).param = &simpleparam2;
+    (*(params+3)).name = "ScopeOfResidence";
+    (*(params+3)).type = SIMPLE_PARAM;
+    (*(params+3)).param = &simpleparam3;
+    
+    if (hypervInvokeMethod(priv, params, nb_params, "CreateSwitchPort",
+                           MSVM_VIRTUALSWITCHMANAGEMENTSERVICE_RESOURCE_URI, 
selector1) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not create port for virtual switch '%s'"), 
net->data.network.name);
+        goto cleanup;
+    }
+    
+    /* Get a reference of the switch port created previously */
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_SWITCHPORT_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"", guid_string);
+    if (hypervGetMsvmSwitchPortList(priv, &query, &switchPort) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Method hypervGetMsvmSwitchPortList failed with 
query=%s"), query.e);
+        goto cleanup;
+    }
+    if (switchPort == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not get switch port with Name=%s"), 
guid_string);
+        goto cleanup;
+    }
+    
+    /* Get a reference of the given virtual switch */
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+    virBufferAsprintf(&query, "where ElementName = \"%s\"", 
net->data.network.name);
+    if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitch) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Method hypervGetMsvmVirtualSwitchList failed with 
query=%s"), query.e);
+        goto cleanup;
+    }
+    if (virtualSwitch == NULL) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not get virtual switch '%s'"), 
net->data.network.name);
+        goto cleanup;
+    }
+    
+    /* Add the synthetic ethernet port to the VM */
+    /* Prepare EPR param 2 */
+    virBufferFreeAndReset(&query);
+    virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+    virBufferAsprintf(&query, "where Name = \"%s\"", uuid_string);
+    eprparam2.query = &query;
+    eprparam2.wmiProviderURI = ROOT_VIRTUALIZATION;
+    
+    /* Prepare EMBEDDED param */
+    virUUIDGenerate(guid);
+    virUUIDFormat(guid, guid_string);
+    virtualSystemIdentifiers = (char *) malloc((strlen(guid_string)+3) * 
sizeof(char));
+    sprintf(virtualSystemIdentifiers, "{%s}", guid_string);
+    if (hypervGetSwitchPortPATH(domain, switchPort->data->Name, 
virtualSwitch->data->Name, &switchPortPATH) < 0) {
+        goto cleanup;
+    }
+
+    embeddedparam.nbProps = 5;
+    if (VIR_ALLOC_N(tab_props, embeddedparam.nbProps) < 0)
+        goto cleanup;
+    (*tab_props).name = "Connection";
+    (*tab_props).val = switchPortPATH;
+    (*(tab_props+1)).name = "ElementName";
+    (*(tab_props+1)).val = "Network Adapter";
+    (*(tab_props+2)).name = "VirtualSystemIdentifiers";
+    (*(tab_props+2)).val = virtualSystemIdentifiers;
+    (*(tab_props+3)).name = "ResourceType";
+    (*(tab_props+3)).val = "10";
+    (*(tab_props+4)).name = "ResourceSubType";
+    (*(tab_props+4)).val = "Microsoft Synthetic Ethernet Port";
+    embeddedparam.instanceName =  
MSVM_SYNTHETICETHERNETPORTSETTINGDATA_CLASSNAME;
+    embeddedparam.prop_t = tab_props;
+    
+    /* Create invokeXmlParam tab */
+    VIR_FREE(params);
+    nb_params = 2;
+    if (VIR_ALLOC_N(params, nb_params) < 0)
+        goto cleanup;
+    (*params).name = "TargetSystem";
+    (*params).type = EPR_PARAM;
+    (*params).param = &eprparam2;
+    (*(params+1)).name = "ResourceSettingData";
+    (*(params+1)).type = EMBEDDED_PARAM;
+    (*(params+1)).param = &embeddedparam;
+    
+    if (hypervInvokeMethod(priv, params, nb_params, 
"AddVirtualSystemResources",
+                           MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector2) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not attach the network"));
+        goto cleanup;
+    }
+    
+    result = 0;
+    
+ cleanup:
+    VIR_FREE(virtualSystemIdentifiers);
+    VIR_FREE(switchPortPATH);
+    VIR_FREE(tab_props);
+    VIR_FREE(params);
+    hypervFreeObject(priv, (hypervObject *)switchPort);
+    hypervFreeObject(priv, (hypervObject *)virtualSwitch);
+    virBufferFreeAndReset(&query);
+
+    return result;
+}
+
+
+
 static virDriver hypervDriver = {
     .no = VIR_DRV_HYPERV,
     .name = "Hyper-V",
diff --git a/src/hyperv/hyperv_wmi_generator.input 
b/src/hyperv/hyperv_wmi_generator.input
index 24d399f..74e0c94 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -646,3 +646,90 @@ class Msvm_AllocationCapabilities
        uint16 SupportedAddStates[]
        uint16 SupportedRemoveStates[]
 end
+
+
+class Msvm_SwitchPort
+       string Caption
+       string ElementName
+       datetime InstallDate
+       string StatusDescriptions[]
+       string Status
+       uint16 HealthState
+       string OtherEnabledState
+       uint16 RequestedState
+       uint16 EnabledDefault
+       string SystemCreationClassName
+       string SystemName
+       string CreationClassName
+       string Description
+       uint16 OperationalStatus[]
+       uint16 EnabledState
+       datetime TimeOfLastStateChange
+       string Name
+       string NameFormat
+       uint16 ProtocolType
+       uint16 ProtocolIFType
+       string OtherTypeDescription
+       boolean BroadcastResetSupported
+       uint16 PortNumber
+       string ScopeOfResidence
+       uint32 VMQOffloadWeight
+       uint32 ChimneyOffloadWeight
+       uint32 VMQOffloadUsage
+       uint32 ChimneyOffloadUsage
+       uint32 VMQOffloadLimit
+       uint32 ChimneyOffloadLimit
+       boolean AllowMacSpoofing
+end
+
+
+class Msvm_SyntheticEthernetPortSettingData
+       string Caption
+       string Description
+       string InstanceID
+       string ElementName
+       uint16 ResourceType
+       string OtherResourceType
+       string ResourceSubType
+       string PoolID
+       uint16 ConsumerVisibility
+       string HostResource[]
+       string AllocationUnits
+       uint64 VirtualQuantity
+       uint64 Reservation
+       uint64 Limit
+       uint32 Weight
+       boolean AutomaticAllocation
+       boolean AutomaticDeallocation
+       string Parent
+       string Connection[]
+       string Address
+       uint16 MappingBehavior
+       string VirtualSystemIdentifiers[]
+       boolean StaticMacAddress
+end
+
+
+class Msvm_VirtualSwitchManagementService
+       string Caption
+       string Description
+       string ElementName
+       datetime InstallDate
+       uint16 OperationalStatus[]
+       string StatusDescriptions[]
+       string Status
+       uint16 HealthState
+       uint16 EnabledState
+       string OtherEnabledState
+       uint16 RequestedState
+       uint16 EnabledDefault
+       datetime TimeOfLastStateChange
+       string SystemCreationClassName
+       string SystemName
+       string CreationClassName
+       string Name
+       string PrimaryOwnerName
+       string PrimaryOwnerContact
+       string StartMode
+       boolean Started
+end
-- 
1.9.1

--
libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to