[libvirt] [PATCH 19/21] Added hypervDomainAttachNetwork, internal implementation for network attachement (required Msvm_SwitchPort and Msvm_SyntheticEthernetPortSettingData classes)

Yves Vinter yves.vinter at bull.net
Wed Oct 8 12:34:04 UTC 2014


From: yvinter <yves.vinter at bull.net>

---
 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




More information about the libvir-list mailing list