提交 b9dfbf57 编写于 作者: M Matthias Bolte

esx: Implement interface driver

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.
上级 98c7d8b2
......@@ -4,7 +4,7 @@
* host interfaces
*
* Copyright (C) 2010-2011 Red Hat, Inc.
* Copyright (C) 2010 Matthias Bolte <matthias.bolte@googlemail.com>
* Copyright (C) 2010-2012 Matthias Bolte <matthias.bolte@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 */
};
......
......@@ -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@googlemail.com>
* Copyright (C) 2009-2012 Matthias Bolte <matthias.bolte@googlemail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
......@@ -3948,6 +3948,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,
......
......@@ -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@googlemail.com>
* Copyright (C) 2009-2012 Matthias Bolte <matthias.bolte@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,
......
......@@ -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
......
......@@ -3,7 +3,7 @@
#
# esx_vi_generator.py: generates most of the SOAP type mapping code
#
# Copyright (C) 2010-2011 Matthias Bolte <matthias.bolte@googlemail.com>
# Copyright (C) 2010-2012 Matthias Bolte <matthias.bolte@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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册