From: yvinter <yves.vinter@xxxxxxxx> --- 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 libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list