Lists available PhysicalNic devices. A PhysicalNic is always active
and can neither be defined nor undefined.
A PhysicalNic is used to bridge a HostVirtualSwitch to the physical
network.
---
This implementation differs from Ata's. It just lists PhysicalNics
instead of listing HostVirtualNics as bridges.
src/esx/esx_interface_driver.c | 239 +++++++++++++++++++++++++++++++++++++++-
src/esx/esx_vi.c | 144 ++++++++++++++++++++++++-
src/esx/esx_vi.h | 13 ++-
src/esx/esx_vi_generator.input | 34 ++++++-
src/esx/esx_vi_generator.py | 5 +-
5 files changed, 430 insertions(+), 5 deletions(-)
diff --git a/src/esx/esx_interface_driver.c b/src/esx/esx_interface_driver.c
index 501409a..a78a744 100644
--- a/src/esx/esx_interface_driver.c
+++ b/src/esx/esx_interface_driver.c
@@ -4,7 +4,7 @@
* host interfaces
*
* Copyright (C) 2010-2011 Red Hat, Inc.
- * Copyright (C) 2010 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2010-2012 Matthias Bolte <matthias.bolte(a)googlemail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -29,6 +29,8 @@
#include "memory.h"
#include "logging.h"
#include "uuid.h"
+#include "interface_conf.h"
+#include "virsocketaddr.h"
#include "esx_private.h"
#include "esx_interface_driver.h"
#include "esx_vi.h"
@@ -67,10 +69,245 @@ esxInterfaceClose(virConnectPtr conn)
+static int
+esxNumberOfInterfaces(virConnectPtr conn)
+{
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_PhysicalNic *physicalNicList = NULL;
+ esxVI_PhysicalNic *physicalNic = NULL;
+ int count = 0;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupPhysicalNicList(priv->primary, &physicalNicList) < 0) {
+ return -1;
+ }
+
+ for (physicalNic = physicalNicList; physicalNic != NULL;
+ physicalNic = physicalNic->_next) {
+ ++count;
+ }
+
+ esxVI_PhysicalNic_Free(&physicalNicList);
+
+ return count;
+}
+
+
+
+static int
+esxListInterfaces(virConnectPtr conn, char **const names, int maxnames)
+{
+ bool success = false;
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_PhysicalNic *physicalNicList = NULL;
+ esxVI_PhysicalNic *physicalNic = NULL;
+ int count = 0;
+ int i;
+
+ if (maxnames == 0) {
+ return 0;
+ }
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupPhysicalNicList(priv->primary, &physicalNicList) < 0) {
+ return -1;
+ }
+
+ for (physicalNic = physicalNicList; physicalNic != NULL;
+ physicalNic = physicalNic->_next) {
+ names[count] = strdup(physicalNic->device);
+
+ if (names[count] == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ ++count;
+ }
+
+ success = true;
+
+ cleanup:
+ if (! success) {
+ for (i = 0; i < count; ++i) {
+ VIR_FREE(names[i]);
+ }
+
+ count = -1;
+ }
+
+ esxVI_PhysicalNic_Free(&physicalNicList);
+
+ return count;
+}
+
+
+
+static int
+esxNumberOfDefinedInterfaces(virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+ /* ESX interfaces are always active */
+ return 0;
+}
+
+
+
+static int
+esxListDefinedInterfaces(virConnectPtr conn ATTRIBUTE_UNUSED,
+ char **const names ATTRIBUTE_UNUSED,
+ int maxnames ATTRIBUTE_UNUSED)
+{
+ /* ESX interfaces are always active */
+ return 0;
+}
+
+
+
+static virInterfacePtr
+esxInterfaceLookupByName(virConnectPtr conn, const char *name)
+{
+ virInterfacePtr iface = NULL;
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_PhysicalNic *physicalNic = NULL;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupPhysicalNicByMACAddress(priv->primary, name, &physicalNic,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ return NULL;
+ }
+
+ iface = virGetInterface(conn, physicalNic->device, physicalNic->mac);
+
+ esxVI_PhysicalNic_Free(&physicalNic);
+
+ return iface;
+}
+
+
+
+static virInterfacePtr
+esxInterfaceLookupByMACString(virConnectPtr conn, const char *mac)
+{
+ virInterfacePtr iface = NULL;
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_PhysicalNic *physicalNic = NULL;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupPhysicalNicByMACAddress(priv->primary, mac, &physicalNic,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ return NULL;
+ }
+
+ iface = virGetInterface(conn, physicalNic->device, physicalNic->mac);
+
+ esxVI_PhysicalNic_Free(&physicalNic);
+
+ return iface;
+}
+
+
+
+static char *
+esxInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags)
+{
+ char *xml = NULL;
+ esxPrivate *priv = iface->conn->interfacePrivateData;
+ esxVI_PhysicalNic *physicalNic = NULL;
+ virInterfaceDef def;
+ bool hasAddress = false;
+ virInterfaceProtocolDefPtr protocols;
+ virInterfaceProtocolDef protocol;
+ virSocketAddr socketAddress;
+ virInterfaceIpDefPtr ips;
+ virInterfaceIpDef ip;
+
+ virCheckFlags(VIR_INTERFACE_XML_INACTIVE, NULL);
+
+ memset(&def, 0, sizeof(def));
+ memset(&protocol, 0, sizeof(protocol));
+ memset(&socketAddress, 0, sizeof(socketAddress));
+ memset(&ip, 0, sizeof(ip));
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupPhysicalNicByMACAddress(priv->primary, iface->mac,
+ &physicalNic,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ return NULL;
+ }
+
+ def.type = VIR_INTERFACE_TYPE_ETHERNET;
+ def.name = physicalNic->device;
+ def.mac = physicalNic->mac;
+ def.startmode = VIR_INTERFACE_START_ONBOOT;
+
+ /* FIXME: Add support for IPv6, requires to use vSphere API 4.0 */
+ if (physicalNic->spec->ip != NULL) {
+ protocol.family = (char *)"ipv4";
+
+ if (physicalNic->spec->ip->dhcp == esxVI_Boolean_True) {
+ protocol.dhcp = 1;
+ }
+
+ if (physicalNic->spec->ip->ipAddress != NULL &&
+ physicalNic->spec->ip->subnetMask != NULL &&
+ strlen(physicalNic->spec->ip->ipAddress) > 0 &&
+ strlen(physicalNic->spec->ip->subnetMask) > 0) {
+ hasAddress = true;
+ }
+
+ if (protocol.dhcp || hasAddress) {
+ protocols = &protocol;
+ def.nprotos = 1;
+ def.protos = &protocols;
+ }
+
+ if (hasAddress &&
+ !(protocol.dhcp && (flags & VIR_INTERFACE_XML_INACTIVE))) {
+ ips = &ip;
+ protocol.nips = 1;
+ protocol.ips = &ips;
+
+ if (virSocketAddrParseIPv4(&socketAddress,
+ physicalNic->spec->ip->subnetMask) <
0) {
+ goto cleanup;
+ }
+
+ ip.address = physicalNic->spec->ip->ipAddress;
+ ip.prefix = virSocketAddrGetNumNetmaskBits(&socketAddress);
+ }
+ }
+
+ xml = virInterfaceDefFormat(&def);
+
+ cleanup:
+ esxVI_PhysicalNic_Free(&physicalNic);
+
+ return xml;
+}
+
+
+
+static int
+esxInterfaceIsActive(virInterfacePtr iface ATTRIBUTE_UNUSED)
+{
+ /* ESX interfaces are always active */
+ return 1;
+}
+
+
+
static virInterfaceDriver esxInterfaceDriver = {
.name = "ESX",
.open = esxInterfaceOpen, /* 0.7.6 */
.close = esxInterfaceClose, /* 0.7.6 */
+ .numOfInterfaces = esxNumberOfInterfaces, /* 0.10.0 */
+ .listInterfaces = esxListInterfaces, /* 0.10.0 */
+ .numOfDefinedInterfaces = esxNumberOfDefinedInterfaces, /* 0.10.0 */
+ .listDefinedInterfaces = esxListDefinedInterfaces, /* 0.10.0 */
+ .interfaceLookupByName = esxInterfaceLookupByName, /* 0.10.0 */
+ .interfaceLookupByMACString = esxInterfaceLookupByMACString, /* 0.10.0 */
+ .interfaceGetXMLDesc = esxInterfaceGetXMLDesc, /* 0.10.0 */
+ .interfaceIsActive = esxInterfaceIsActive, /* 0.10.0 */
};
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 2c789e1..c4217c9 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -3,7 +3,7 @@
* esx_vi.c: client for the VMware VI API 2.5 to manage ESX hosts
*
* Copyright (C) 2010-2011 Red Hat, Inc.
- * Copyright (C) 2009-2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2009-2012 Matthias Bolte <matthias.bolte(a)googlemail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -3949,6 +3949,148 @@ esxVI_LookupAutoStartPowerInfoList(esxVI_Context *ctx,
int
+esxVI_LookupPhysicalNicList(esxVI_Context *ctx,
+ esxVI_PhysicalNic **physicalNicList)
+{
+ int result = -1;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *hostSystem = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+
+ if (physicalNicList == NULL || *physicalNicList != NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
+ return -1;
+ }
+
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "config.network.pnic") < 0 ||
+ esxVI_LookupHostSystemProperties(ctx, propertyNameList,
+ &hostSystem) < 0) {
+ goto cleanup;
+ }
+
+ for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "config.network.pnic")) {
+ if (esxVI_PhysicalNic_CastListFromAnyType(dynamicProperty->val,
+ physicalNicList) < 0) {
+ goto cleanup;
+ }
+ } else {
+ VIR_WARN("Unexpected '%s' property",
dynamicProperty->name);
+ }
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&hostSystem);
+
+ return result;
+}
+
+
+
+int
+esxVI_LookupPhysicalNicByName(esxVI_Context *ctx, const char *name,
+ esxVI_PhysicalNic **physicalNic,
+ esxVI_Occurrence occurrence)
+{
+ int result = -1;
+ esxVI_PhysicalNic *physicalNicList = NULL;
+ esxVI_PhysicalNic *candidate = NULL;
+
+ if (physicalNic == NULL || *physicalNic != NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
+ return -1;
+ }
+
+ if (esxVI_LookupPhysicalNicList(ctx, &physicalNicList) < 0) {
+ goto cleanup;
+ }
+
+ /* Search for a matching physical NIC */
+ for (candidate = physicalNicList; candidate != NULL;
+ candidate = candidate->_next) {
+ if (STRCASEEQ(candidate->device, name)) {
+ if (esxVI_PhysicalNic_DeepCopy(physicalNic, candidate) < 0) {
+ goto cleanup;
+ }
+
+ /* Found physical NIC with matching name */
+ result = 0;
+
+ goto cleanup;
+ }
+ }
+
+ if (*physicalNic == NULL && occurrence != esxVI_Occurrence_OptionalItem) {
+ virReportError(VIR_ERR_NO_INTERFACE,
+ _("Could not find physical NIC with name '%s'"),
name);
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_PhysicalNic_Free(&physicalNicList);
+
+ return result;
+}
+
+
+
+int
+esxVI_LookupPhysicalNicByMACAddress(esxVI_Context *ctx, const char *mac,
+ esxVI_PhysicalNic **physicalNic,
+ esxVI_Occurrence occurrence)
+{
+ int result = -1;
+ esxVI_PhysicalNic *physicalNicList = NULL;
+ esxVI_PhysicalNic *candidate = NULL;
+
+ if (physicalNic == NULL || *physicalNic != NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid
argument"));
+ return -1;
+ }
+
+ if (esxVI_LookupPhysicalNicList(ctx, &physicalNicList) < 0) {
+ goto cleanup;
+ }
+
+ /* Search for a matching physical NIC */
+ for (candidate = physicalNicList; candidate != NULL;
+ candidate = candidate->_next) {
+ if (STRCASEEQ(candidate->mac, mac)) {
+ if (esxVI_PhysicalNic_DeepCopy(physicalNic, candidate) < 0) {
+ goto cleanup;
+ }
+
+ /* Found physical NIC with matching MAC address */
+ result = 0;
+
+ goto cleanup;
+ }
+ }
+
+ if (*physicalNic == NULL && occurrence != esxVI_Occurrence_OptionalItem) {
+ virReportError(VIR_ERR_NO_INTERFACE,
+ _("Could not find physical NIC with MAC address
'%s'"), mac);
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_PhysicalNic_Free(&physicalNicList);
+
+ return result;
+}
+
+
+
+int
esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
esxVI_VirtualMachineQuestionInfo *questionInfo, bool autoAnswer,
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 4b84be8..597013c 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -3,7 +3,7 @@
* esx_vi.h: client for the VMware VI API 2.5 to manage ESX hosts
*
* Copyright (C) 2011 Red Hat, Inc.
- * Copyright (C) 2009-2010 Matthias Bolte <matthias.bolte(a)googlemail.com>
+ * Copyright (C) 2009-2012 Matthias Bolte <matthias.bolte(a)googlemail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -481,6 +481,17 @@ int esxVI_LookupAutoStartDefaults(esxVI_Context *ctx,
int esxVI_LookupAutoStartPowerInfoList(esxVI_Context *ctx,
esxVI_AutoStartPowerInfo **powerInfoList);
+int esxVI_LookupPhysicalNicList(esxVI_Context *ctx,
+ esxVI_PhysicalNic **physicalNicList);
+
+int esxVI_LookupPhysicalNicByName(esxVI_Context *ctx, const char *name,
+ esxVI_PhysicalNic **physicalNic,
+ esxVI_Occurrence occurrence);
+
+int esxVI_LookupPhysicalNicByMACAddress(esxVI_Context *ctx, const char *mac,
+ esxVI_PhysicalNic **physicalNic,
+ esxVI_Occurrence occurrence);
+
int esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
esxVI_VirtualMachineQuestionInfo *questionInfo, bool autoAnswer,
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index 1a67a8c..5572b36 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -317,6 +317,13 @@ object HostFileSystemVolume
end
+object HostIpConfig
+ Boolean dhcp r
+ String ipAddress o
+ String subnetMask o
+end
+
+
object HostMountInfo
String path o
String accessMode r
@@ -455,6 +462,31 @@ object PerfSampleInfo
end
+object PhysicalNic
+ String key o
+ String device r
+ String pci r
+ String driver o
+ PhysicalNicLinkInfo linkSpeed o
+ PhysicalNicLinkInfo validLinkSpecification ol
+ PhysicalNicSpec spec r
+ Boolean wakeOnLanSupported r
+ String mac r
+end
+
+
+object PhysicalNicLinkInfo
+ Int speedMb r
+ Boolean duplex r
+end
+
+
+object PhysicalNicSpec
+ HostIpConfig ip o
+ PhysicalNicLinkInfo linkSpeed o
+end
+
+
object PropertyChange
String name r
PropertyChangeOp op r
@@ -569,7 +601,7 @@ object TemplateConfigFileQuery extends VmConfigFileQuery
end
-object TraversalSpec extends SelectionSpec
+object TraversalSpec extends SelectionSpec
String type r
String path r
Boolean skip o
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index af2d57e..596bd16 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -3,7 +3,7 @@
#
# esx_vi_generator.py: generates most of the SOAP type mapping code
#
-# Copyright (C) 2010-2011 Matthias Bolte <matthias.bolte(a)googlemail.com>
+# Copyright (C) 2010-2012 Matthias Bolte <matthias.bolte(a)googlemail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -1522,6 +1522,9 @@ additional_object_features = { "AutoStartDefaults"
: Object.FEATURE__AN
Object.FEATURE__ANY_TYPE,
"ManagedObjectReference" :
Object.FEATURE__ANY_TYPE,
"ObjectContent" :
Object.FEATURE__DEEP_COPY,
+ "PhysicalNic" :
Object.FEATURE__DEEP_COPY |
+ Object.FEATURE__LIST |
+ Object.FEATURE__ANY_TYPE,
"ResourcePoolResourceUsage" :
Object.FEATURE__ANY_TYPE,
"ServiceContent" :
Object.FEATURE__DESERIALIZE,
"SharesInfo" :
Object.FEATURE__ANY_TYPE,
--
1.7.4.1