From: yvinter <yves.vinter(a)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