mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
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.
This commit is contained in:
parent
98c7d8b278
commit
b9dfbf5723
@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
144
src/esx/esx_vi.c
144
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@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,
|
||||
|
Loading…
Reference in New Issue
Block a user