[libvirt] [PATCH v3 2/2] ESX: Add routines to interface driver- Use ATTRIBUTE_UNUSED for unused variable.
by Ata E Husain Bohra
---
src/esx/esx_interface_driver.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/src/esx/esx_interface_driver.c b/src/esx/esx_interface_driver.c
index b1ba5e2..01caed0 100644
--- a/src/esx/esx_interface_driver.c
+++ b/src/esx/esx_interface_driver.c
@@ -107,10 +107,8 @@ cleanup:
static int
-esxNumOfDefinedInterfaces(virConnectPtr conn)
+esxNumOfDefinedInterfaces(virConnectPtr conn ATTRIBUTE_UNUSED)
{
- conn->interfacePrivateData = NULL;
-
// ESX interfaces are always active
return 0;
}
@@ -162,14 +160,10 @@ esxListInterfaces(virConnectPtr conn, char **names, int maxnames)
static int
-esxListDefinedInterfaces(virConnectPtr conn, char **names, int maxnames)
+esxListDefinedInterfaces(virConnectPtr conn ATTRIBUTE_UNUSED,
+ char **names ATTRIBUTE_UNUSED,
+ int maxnames ATTRIBUTE_UNUSED)
{
- conn->interfacePrivateData = conn->privateData;
- *names = NULL;
-
- /* keeps compiler happy */
- VIR_DEBUG("max interfaces: %d", maxnames);
-
// ESX interfaces are always active
return 0;
}
--
1.7.9.5
12 years, 5 months
[libvirt] [PATCH v3 1/2] ESX: Add routines to interface driver
by Ata E Husain Bohra
Add following routines to esx_interface_driver:
esxNumOfInterfaces,
esxNumOfDefinedInterfaces,
esxListInterfaces,
esxListDefinedInterfaces,
esxInterfaceLookupByMACString,
esxInterfaceGetXMLDesc,
esxInterfaceUndefine,
esxInterfaceCreate,
esxInterfaceDestroy
Signed-off-by: Ata E Husain Bohra <ata.husain(a)hotmail.com>
---
src/esx/esx_interface_driver.c | 506 +++++++++++++++++++++++++++++++++++++++-
src/esx/esx_vi.c | 126 ++++++++++
src/esx/esx_vi.h | 10 +
src/esx/esx_vi_generator.input | 227 ++++++++++++++++++
src/esx/esx_vi_generator.py | 31 ++-
src/esx/esx_vi_types.c | 18 +-
6 files changed, 913 insertions(+), 5 deletions(-)
diff --git a/src/esx/esx_interface_driver.c b/src/esx/esx_interface_driver.c
index 5713137..b1ba5e2 100644
--- a/src/esx/esx_interface_driver.c
+++ b/src/esx/esx_interface_driver.c
@@ -23,6 +23,9 @@
*/
#include <config.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include "internal.h"
#include "util.h"
@@ -34,6 +37,7 @@
#include "esx_vi.h"
#include "esx_vi_methods.h"
#include "esx_util.h"
+#include "interface_conf.h"
#define VIR_FROM_THIS VIR_FROM_ESX
@@ -67,10 +71,508 @@ esxInterfaceClose(virConnectPtr conn)
+static int
+esxNumOfInterfaces(virConnectPtr conn)
+{
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ int count = 0;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupVirtualNicList(priv->primary, &virtualNicList) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualNicList == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve vNic List"));
+
+ goto cleanup;
+ }
+
+ for (virtualNic = virtualNicList;
+ virtualNic != NULL;
+ virtualNic = virtualNic->_next) {
+ count++;
+ }
+
+cleanup:
+
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+
+ return count;
+}
+
+
+
+static int
+esxNumOfDefinedInterfaces(virConnectPtr conn)
+{
+ conn->interfacePrivateData = NULL;
+
+ // ESX interfaces are always active
+ return 0;
+}
+
+
+
+static int
+esxListInterfaces(virConnectPtr conn, char **names, int maxnames)
+{
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ int result = -1;
+ int i = 0;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupVirtualNicList(priv->primary,
+ &virtualNicList) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualNicList == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve vNIC List"));
+ goto cleanup;
+ }
+
+ for (i= 0, virtualNic = virtualNicList;
+ virtualNic != NULL && i < maxnames;
+ ++i, virtualNic = virtualNic->_next) {
+ names[i] = strdup(virtualNic->device);
+
+ if (names[i] == NULL) {
+ for(;i >=0;--i) {
+ VIR_FREE(names[i]);
+ }
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ result = i;
+ cleanup:
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+
+ return result;
+}
+
+
+
+static int
+esxListDefinedInterfaces(virConnectPtr conn, char **names, int maxnames)
+{
+ conn->interfacePrivateData = conn->privateData;
+ *names = NULL;
+
+ /* keeps compiler happy */
+ VIR_DEBUG("max interfaces: %d", maxnames);
+
+ // ESX interfaces are always active
+ return 0;
+}
+
+
+
+static virInterfacePtr
+esxInterfaceLookupByName(virConnectPtr conn, const char *name)
+{
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ virInterfacePtr ret = NULL;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupVirtualNicList(priv->primary,
+ &virtualNicList) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualNicList == 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve vNIC List"));
+ goto cleanup;
+ }
+
+
+ for(virtualNic = virtualNicList;
+ virtualNic != NULL;
+ virtualNic = virtualNic->_next) {
+ if (STREQ(virtualNic->device, name)) {
+ if (virtualNic->spec == NULL ||
+ virtualNic->spec->mac == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Malformed HostVirtualNicSpec"));
+ goto cleanup;
+ }
+
+ ret = virGetInterface(conn, virtualNic->device, virtualNic->spec->mac);
+ break;
+ }
+ }
+
+ cleanup:
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+
+ return ret;
+}
+
+
+
+static virInterfacePtr
+esxInterfaceLookupByMACString(virConnectPtr conn, const char *mac)
+{
+ esxPrivate *priv = conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ virInterfacePtr ret = NULL;
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_LookupVirtualNicList(priv->primary,
+ &virtualNicList) < 0) {
+ goto cleanup;
+ }
+
+ if (virtualNicList == 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve vNIC List"));
+ goto cleanup;
+ }
+
+
+ for(virtualNic = virtualNicList;
+ virtualNic != NULL;
+ virtualNic = virtualNic->_next) {
+ if (virtualNic->spec == NULL ||
+ virtualNic->spec->mac == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Malformed HostVirtualNicSpec"));
+ goto cleanup;
+ }
+
+ if (STREQ(virtualNic->spec->mac, mac)) {
+ ret = virGetInterface(conn, virtualNic->device, virtualNic->spec->mac);
+ break;
+ }
+ }
+
+ cleanup:
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+
+ return ret;
+}
+
+
+
+static char*
+esxInterfaceGetXMLDesc(virInterfacePtr iface, unsigned int flags)
+{
+ esxPrivate *priv = iface->conn->interfacePrivateData;
+ esxVI_HostVirtualNic *virtualNicList = NULL;
+ const esxVI_HostVirtualNic *virtualNic = NULL;
+ esxVI_PhysicalNic *physicalNicList = NULL;
+ const esxVI_PhysicalNic *physicalNic = NULL;
+ esxVI_PhysicalNic *matchingPhysicalNicList = NULL;
+ esxVI_HostIpRouteConfig *ipRouteConfig = NULL;
+ esxVI_HostPortGroup *portGroupList = NULL;
+ esxVI_HostVirtualSwitch *virtualSwitchList = NULL;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *hostSystem = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ virInterfaceDefPtr def = NULL;
+ int use_static = 0;
+ struct in_addr addr;
+ uint32_t host_addr = 0;
+ int zero_count = 0;
+ int masklen = 0;
+ int i = 0;
+ char *ret = NULL;
+
+ if (VIR_INTERFACE_XML_INACTIVE & flags) {
+ use_static = 1;
+ }
+
+ if (esxVI_EnsureSession(priv->primary) < 0 ||
+ esxVI_String_AppendValueListToList(&propertyNameList,
+ "config.network.vnic\0"
+ "config.network.ipRouteConfig\0"
+ "config.network.vswitch\0"
+ "config.network.pnic\0"
+ "config.network.portgroup\0") < 0 ||
+ esxVI_LookupHostSystemProperties(priv->primary, propertyNameList,
+ &hostSystem) < 0) {
+ goto cleanup;
+ }
+
+ for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "config.network.vnic")) {
+ if (esxVI_HostVirtualNic_CastListFromAnyType(
+ dynamicProperty->val, &virtualNicList) < 0) {
+ goto cleanup;
+ }
+ } else if (STREQ(dynamicProperty->name,
+ "config.network.ipRouteConfig")) {
+ if (esxVI_HostIpRouteConfig_CastFromAnyType(
+ dynamicProperty->val, &ipRouteConfig)) {
+ goto cleanup;
+ }
+ } else if (STREQ(dynamicProperty->name, "config.network.vswitch")) {
+ if (esxVI_HostVirtualSwitch_CastListFromAnyType
+ (dynamicProperty->val, &virtualSwitchList) < 0) {
+ goto cleanup;
+ }
+ } else if (STREQ(dynamicProperty->name, "config.network.pnic")) {
+ if (esxVI_PhysicalNic_CastListFromAnyType(
+ dynamicProperty->val, &physicalNicList) < 0) {
+ goto cleanup;
+ }
+ } else if (STREQ(dynamicProperty->name, "config.network.portgroup")) {
+ if (esxVI_HostPortGroup_CastListFromAnyType(
+ dynamicProperty->val, &portGroupList) < 0) {
+ goto cleanup;
+ }
+ } else {
+ VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+ }
+ }
+
+ if (!virtualNicList ||
+ !ipRouteConfig ||
+ !virtualSwitchList ||
+ !portGroupList) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unable to retrieve network parameters"));
+
+ goto cleanup;
+ }
+
+ for (virtualNic = virtualNicList;
+ virtualNic != NULL;
+ virtualNic = virtualNic->_next) {
+ if (STREQ(virtualNic->device, iface->name)) {
+ break;
+ }
+ }
+
+ if (virtualNic == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find Interface"));
+ goto cleanup;
+ }
+
+ if (esxVI_LookupPhysicalNicFromPortGroup(virtualNic->portgroup,
+ portGroupList,
+ virtualSwitchList,
+ physicalNicList,
+ &matchingPhysicalNicList) < 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No Physical NIC found matching Virtual NIC's portgroup"));
+ goto cleanup;
+ }
+
+ /*
+ * populate virInterfaceDef object to obtain
+ * libvirt interface domain xml.
+ */
+ if (VIR_ALLOC(def) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ def->type = VIR_INTERFACE_TYPE_BRIDGE;
+ def->name = strdup(virtualNic->device);
+ if (virtualNic->spec->mtu && virtualNic->spec->mtu->value) {
+ def->mtu = virtualNic->spec->mtu->value;
+ } else {
+ def->mtu = 1500;
+ }
+
+ def->startmode = VIR_INTERFACE_START_ONBOOT;
+
+ if (!use_static && virtualNic->spec->mac) {
+ def->mac = strdup(virtualNic->spec->mac);
+ }
+
+ /* TODO - Handle VLAN (via portgroup?) */
+ if (virtualNic->spec->ip->subnetMask &&
+ *virtualNic->spec->ip->subnetMask &&
+ inet_aton(virtualNic->spec->ip->subnetMask, &addr) == 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Error parsing netmask"));
+ goto cleanup;
+ }
+
+ host_addr = ntohl(addr.s_addr);
+ /* Calculate masklen */
+ for (i = 0; i < 32; ++i) {
+ if (host_addr & 0x01) {
+ break;
+ }
+ zero_count++;
+ host_addr >>= 1;
+ }
+ masklen = 32 - zero_count;
+
+ /* append protocol field */
+ def->nprotos = 1;
+ if (VIR_ALLOC_N(def->protos, def->nprotos) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* TODO - Add IPv6 Support */
+ for (i = 0; i < def->nprotos; ++i) {
+ if (VIR_ALLOC(def->protos[i]) < 0) {
+ goto cleanup;
+ }
+
+ def->protos[i]->family = strdup("ipv4");
+ if (virtualNic->spec->ip->dhcp == 1) {
+ def->protos[i]->dhcp = 1;
+ }
+ def->protos[i]->nips = 1;
+ if (virtualNic->spec->ip->dhcp != 1 || !use_static) {
+ if (virtualNic->spec->ip->ipAddress &&
+ *virtualNic->spec->ip->ipAddress) {
+ int j =0;
+ if (VIR_ALLOC_N(def->protos[i]->ips, def->protos[i]->nips)
+ < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ for (j=0; j < def->protos[i]->nips; ++j) {
+ if (VIR_ALLOC(def->protos[i]->ips[j]) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->protos[i]->ips[0]->address =
+ strdup(virtualNic->spec->ip->ipAddress);
+ def->protos[i]->ips[0]->prefix = masklen;
+ def->protos[i]->gateway =
+ strdup(ipRouteConfig->defaultGateway);
+ }
+ }
+ }
+ }
+
+ /* Add bridge information */
+ def->data.bridge.stp = 0; /* off */
+
+ /**
+ * traversing physical nic list twice, first to get total
+ * interfaces and second to populate interface items.
+ * Total Complexity ~= O(N); also total physical nics
+ * cannot be that large number
+ */
+ for (physicalNic = matchingPhysicalNicList, i = 0; physicalNic != NULL;
+ physicalNic = physicalNic->_next, ++i) {
+ }
+
+ if ( i > 0) {
+ if (VIR_ALLOC_N(def->data.bridge.itf, i) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ def->data.bridge.nbItf = i;
+ for (physicalNic = matchingPhysicalNicList, i = 0; physicalNic != NULL;
+ physicalNic = physicalNic->_next, ++i) {
+ virInterfaceDefPtr itf = NULL;
+ if (VIR_ALLOC(itf) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ itf->type = VIR_INTERFACE_TYPE_ETHERNET;
+ itf->name = strdup(physicalNic->device);
+ itf->mac = strdup(physicalNic->mac);
+
+ def->data.bridge.itf[i] = itf;
+ }
+ }
+
+ ret = virInterfaceDefFormat(def);
+ if (!ret) {
+ goto cleanup;
+ }
+
+ cleanup:
+ esxVI_HostVirtualNic_Free(&virtualNicList);
+ esxVI_PhysicalNic_Free(&physicalNicList);
+ esxVI_PhysicalNic_Free(&matchingPhysicalNicList);
+ esxVI_HostPortGroup_Free(&portGroupList);
+ esxVI_HostVirtualSwitch_Free(&virtualSwitchList);
+ esxVI_HostIpRouteConfig_Free(&ipRouteConfig);
+ esxVI_ObjectContent_Free(&hostSystem);
+ esxVI_String_Free(&propertyNameList);
+ virInterfaceDefFree(def);
+
+ return ret;
+}
+
+
+
+static int
+esxInterfaceUndefine(virInterfacePtr iface)
+{
+ esxPrivate *priv = iface->conn->interfacePrivateData;
+
+ if (esxVI_RemoveVirtualNic(
+ priv->primary,
+ priv->primary->hostSystem->configManager->networkSystem,
+ iface->name) < 0) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Error deleting interface"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+
+static int
+esxInterfaceCreate(virInterfacePtr iface, unsigned int flags)
+{
+ iface->conn->interfacePrivateData = NULL;
+
+ virCheckFlags(0, -1);
+
+ /* ESX interfaces are always active */
+ return 0;
+}
+
+
+
+static int
+esxInterfaceDestroy(virInterfacePtr iface, unsigned int flags)
+{
+ iface->conn->interfacePrivateData = NULL;
+
+ virCheckFlags(0, -1);
+
+ /* ESX interfaces can not be deactivated */
+ return 1;
+}
+
+
+
static virInterfaceDriver esxInterfaceDriver = {
.name = "ESX",
- .open = esxInterfaceOpen, /* 0.7.6 */
- .close = esxInterfaceClose, /* 0.7.6 */
+ .open = esxInterfaceOpen, /* 0.7.6 */
+ .close = esxInterfaceClose, /* 0.7.6 */
+ .numOfInterfaces = esxNumOfInterfaces, /* 0.9.x */
+ .numOfDefinedInterfaces = esxNumOfDefinedInterfaces, /* 0.9.x */
+ .listInterfaces = esxListInterfaces, /* 0.9.x */
+ .listDefinedInterfaces = esxListDefinedInterfaces, /* 0.9.x */
+ .interfaceLookupByName = esxInterfaceLookupByName, /* 0.9.x */
+ .interfaceLookupByMACString = esxInterfaceLookupByMACString, /* 0.9.x */
+ .interfaceGetXMLDesc = esxInterfaceGetXMLDesc, /* 0.9.x */
+ .interfaceUndefine = esxInterfaceUndefine, /* 0.9.x */
+ .interfaceCreate = esxInterfaceCreate, /* 0.9.x */
+ .interfaceDestroy = esxInterfaceDestroy, /* 0.9.x */
};
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 48718b6..80ddb76 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -4523,6 +4523,132 @@ esxVI_LookupManagedObjectHelper(esxVI_Context *ctx,
return result;
}
+int
+esxVI_LookupVirtualNicList(esxVI_Context* ctx,
+ esxVI_HostVirtualNic** virtualNicList)
+{
+ int result = -1;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ esxVI_ObjectContent* hostSystem = NULL;
+
+ if (esxVI_String_AppendValueListToList(
+ &propertyNameList, "config.network.vnic\0") < 0 ||
+ esxVI_LookupHostSystemProperties(ctx, propertyNameList, &hostSystem) < 0) {
+ goto cleanup;
+ }
+ if (hostSystem == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve the HostSystem object"));
+
+ goto cleanup;
+ }
+
+ for (dynamicProperty = hostSystem->propSet;
+ dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "config.network.vnic")) {
+ if (esxVI_HostVirtualNic_CastListFromAnyType(dynamicProperty->val,
+ virtualNicList) < 0) {
+ goto cleanup;
+ }
+ break;
+ } else {
+ VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+ }
+ }
+
+ result = 0;
+
+cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&hostSystem);
+
+ return result;
+}
+
+int
+esxVI_LookupPhysicalNicFromPortGroup(
+ const char *portgroup,
+ const esxVI_HostPortGroup *portGroupList,
+ const esxVI_HostVirtualSwitch *virtualSwitchList,
+ const esxVI_PhysicalNic *physicalNicList,
+ esxVI_PhysicalNic **ret_physicalNicList)
+{
+ int result = -1;
+ const esxVI_HostPortGroup *portGroup = NULL;
+ const esxVI_HostVirtualSwitch *virtualSwitch = NULL;
+ esxVI_PhysicalNic *matchingPhysicalNicList = NULL;
+ const esxVI_PhysicalNic *physicalNic = NULL;
+ esxVI_PhysicalNic *tempPhysicalNic = NULL;
+ const esxVI_String *pnicKey = NULL;
+
+ if (portgroup == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No Portgroup found!"));
+ goto cleanup;
+ }
+
+ /* Go through all the port groups to find the one that matches. */
+ for (portGroup = portGroupList;
+ portGroup != NULL;
+ portGroup = portGroup->_next) {
+ if (STREQ(portGroup->spec->name, portgroup)) {
+ break;
+ }
+ }
+
+ if (portGroup == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find Host port group"));
+ goto cleanup;
+ }
+
+ /* Go through all the virtual switches to find the one that matches */
+ for (virtualSwitch = virtualSwitchList;
+ virtualSwitch != NULL;
+ virtualSwitch = virtualSwitch->_next) {
+ if (STREQ(portGroup->spec->vswitchName, virtualSwitch->name)) {
+ break;
+ }
+ }
+
+ if (virtualSwitch == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not find Virtual Switch"));
+ goto cleanup;
+ }
+
+ /* Go through all physical nics */
+ for (pnicKey = virtualSwitch->pnic;
+ pnicKey != NULL;
+ pnicKey = pnicKey->_next) {
+ /* O(n^2), but probably faster than a hash due to small N */
+ for (physicalNic = physicalNicList;
+ physicalNic != NULL;
+ physicalNic = physicalNic->_next) {
+
+ if (STREQ(pnicKey->value, physicalNic->key)) {
+ if (esxVI_PhysicalNic_DeepCopy(&tempPhysicalNic,
+ (esxVI_PhysicalNic *)physicalNic) < 0 ||
+ esxVI_PhysicalNic_AppendToList(&matchingPhysicalNicList,
+ tempPhysicalNic) < 0) {
+ goto cleanup;
+ }
+ tempPhysicalNic = NULL;
+ }
+ }
+ }
+
+ *ret_physicalNicList = matchingPhysicalNicList;
+ matchingPhysicalNicList = NULL; /* no cleanup needed */
+ tempPhysicalNic = NULL; /* no cleanup needed */
+ result = 0;
+ cleanup:
+ esxVI_PhysicalNic_Free(&matchingPhysicalNicList);
+ esxVI_PhysicalNic_Free(&tempPhysicalNic);
+ return result;
+}
#include "esx_vi.generated.c"
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 9560bd2..9b694b5 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -505,6 +505,16 @@ int esxVI_ParseHostCpuIdInfo(esxVI_ParsedHostCpuIdInfo *parsedHostCpuIdInfo,
int esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion productVersion);
+int esxVI_LookupVirtualNicList(esxVI_Context* ctx,
+ esxVI_HostVirtualNic** virtualNicList);
+
+int esxVI_LookupPhysicalNicFromPortGroup(
+ const char *portgroup,
+ const esxVI_HostPortGroup *portGroupList,
+ const esxVI_HostVirtualSwitch *virtualSwitchList,
+ const esxVI_PhysicalNic *physicalNicList,
+ esxVI_PhysicalNic **ret_physicalNicList);
+
# include "esx_vi.generated.h"
#endif /* __ESX_VI_H__ */
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index 1a67a8c..64f8389 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -57,6 +57,29 @@ enum AutoStartWaitHeartbeatSetting
systemDefault
end
+enum HostConfigChangeOperation
+ add
+ edit
+ remove
+end
+
+enum HostIpConfigIpV6AdressStatus
+ deprecated
+ duplicate
+ inaccessible
+ invalid
+ preferred
+ tentative
+ unknown
+end
+
+enum HostIpConfigV6AdressConfigType
+ dhcp
+ linklayer
+ manual
+ other
+ random
+end
enum ManagedEntityStatus
gray
@@ -197,6 +220,12 @@ object DeviceBackedVirtualDiskSpec extends VirtualDiskSpec
String device r
end
+object DistributedVirtualSwitchPortConnection
+ Int connectionCookie o
+ String portgroupKey o
+ String portKey o
+ String switchUuid r
+end
object DynamicProperty
String name r
@@ -316,6 +345,34 @@ object HostFileSystemVolume
Long capacity r
end
+object HostIpConfig
+ Boolean dhcp r
+ String ipAddress o
+ HostIpConfigIpV6AddressConfiguration ipV6Config o
+ String subnetMask o
+end
+
+object HostIpConfigIpV6Address
+ String dadState o
+ String ipAddress r
+ DateTime lifetime o
+ String operation o
+ String origin o
+ Int prefixLength r
+end
+
+object HostIpConfigIpV6AddressConfiguration
+ Boolean autoConfigurationEnabled o
+ Boolean dhcpV6Enabled o
+ HostIpConfigIpV6Address ipV6Address ol
+end
+
+object HostIpRouteConfig
+ String defaultGateway o
+ String gatewayDevice o
+ String ipV6DefaultGateway o
+ String ipV6GatewayDevice o
+end
object HostMountInfo
String path o
@@ -331,11 +388,131 @@ object HostNasVolume extends HostFileSystemVolume
end
+object HostNicTeamingPolicy
+ String policy o
+ Boolean reversePolicy o
+ Boolean notifySwitches o
+ Boolean rollingOrder o
+ HostNicFailureCriteria failureCriteria o
+ HostNicOrderPolicy nicOrder o
+end
+
+object HostNetOffloadCapabilities
+ Boolean csumOffload o
+ Boolean tcpSegmentation o
+ Boolean zeroCopyXmit o
+end
+
+object HostNetworkSecurityPolicy
+ Boolean allowPromiscuous o
+ Boolean macChanges o
+ Boolean forgedTransmits o
+end
+
+object HostNetworkPolicy
+ HostNetworkSecurityPolicy security o
+ HostNicTeamingPolicy nicTeaming o
+ HostNetOffloadCapabilities offloadPolicy o
+ HostNetworkTrafficShapingPolicy shapingPolicy o
+end
+
+object HostNetworkTrafficShapingPolicy
+ Boolean enabled o
+end
+
+object HostNicFailureCriteria
+ String checkSpeed o
+ Int speed o
+ Boolean checkDuplex o
+ Boolean fullDuplex o
+ Boolean checkErrorPercent o
+ Int percentage o
+ Boolean checkBeacon o
+end
+
+object HostNicOrderPolicy
+ String activeNic ol
+ String standbyNic ol
+end
+
+object HostPortGroup
+ String key r
+ HostPortGroupPort port ol
+ String vswitch r
+ HostNetworkPolicy computedPolicy r
+ HostPortGroupSpec spec r
+end
+
+object HostPortGroupPort
+ String key o
+ String mac ol
+ String type r
+end
+
+object HostPortGroupSpec
+ String name r
+ Int vlanId r
+ String vswitchName r
+ HostNetworkPolicy policy r
+end
+
object HostScsiDiskPartition
String diskName r
Int partition r
end
+object HostVirtualNic
+ String device r
+ String key r
+ String port o
+ String portgroup r
+ HostVirtualNicSpec spec r
+end
+
+object HostVirtualNicSpec
+ DistributedVirtualSwitchPortConnection distributedVirtualPort o
+ HostIpConfig ip o
+ String mac o
+ Int mtu o
+ String portgroup o
+ Boolean tsoEnabled o
+end
+
+
+object HostVirtualSwitch
+ String key r
+ Int mtu o
+ String name r
+ Int numPorts r
+ Int numPortsAvailable r
+ String pnic ol
+ String portgroup ol
+ HostVirtualSwitchSpec spec r
+end
+
+object HostVirtualSwitchBridge
+end
+
+object HostVirtualSwitchAutoBridge extends HostVirtualSwitchBridge
+ String excludedNicDevice ol
+end
+
+object HostVirtualSwitchBeaconBridge extends HostVirtualSwitchBridge
+ Int interval r
+end
+
+object HostVirtualSwitchBondBridge extends HostVirtualSwitchBridge
+ HostVirtualSwitchBeaconBridge beacon o
+ LinkDiscoveryProtocolConfig linkDiscoveryProtocolConfig o
+ String nicDevice rl
+end
+
+object HostVirtualSwitchSpec
+ HostVirtualSwitchBridge bridge o
+ Int mtu o
+ Int numPorts r
+ HostNetworkPolicy policy o
+end
object HostVmfsVolume extends HostFileSystemVolume
Int blockSizeMb r
@@ -355,6 +532,10 @@ end
object IsoImageFileQuery extends FileQuery
end
+object LinkDiscoveryProtocolConfig
+ String operation r
+ String protocol r
+end
object LocalDatastoreInfo extends DatastoreInfo
String path o
@@ -398,6 +579,10 @@ object OptionType
Boolean valueIsReadonly o
end
+object OptionValue
+ String key r
+ AnyType value r
+end
object PerfCounterInfo
Int key r
@@ -454,6 +639,27 @@ object PerfSampleInfo
Int interval r
end
+object PhysicalNic
+ String device r
+ String driver o
+ String key o
+ PhysicalNicInfo linkSpeed o
+ String mac r
+ String pci r
+ PhysicalNicSpec spec r
+ PhysicalNicInfo validLinkSpecification ol
+ Boolean wakeOnLanSupported r
+end
+
+object PhysicalNicInfo
+ Boolean duplex r
+ Int speedMb r
+end
+
+object PhysicalNicSpec
+ HostIpConfig ip o
+ PhysicalNicInfo linkSpeed o
+end
object PropertyChange
String name r
@@ -773,6 +979,13 @@ end
# Methods
#
+method AddVirtualNic returns String r
+ ManagedObjectReference _this r
+ String portgroup r
+ HostVirtualNicSpec nic r
+end
+
+
method AnswerVM
ManagedObjectReference _this r
String questionId r
@@ -954,6 +1167,10 @@ method RemoveSnapshot_Task returns ManagedObjectReference r
Boolean removeChildren r
end
+method RemoveVirtualNic
+ ManagedObjectReference _this r
+ String device r
+end
method RetrieveProperties returns ObjectContent ol
ManagedObjectReference _this:propertyCollector r
@@ -1002,6 +1219,16 @@ method UnregisterVM
ManagedObjectReference _this r
end
+method UpdateIpRouteConfig
+ ManagedObjectReference _this r
+ HostIpRouteConfig config r
+end
+
+method UpdateVirtualNic
+ ManagedObjectReference _this r
+ String device r
+ HostVirtualNicSpec nic r
+end
method WaitForUpdates returns UpdateSet r
ManagedObjectReference _this:propertyCollector r
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index 8a128df..f4e4a11 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -371,8 +371,12 @@ class Property(Member):
% self.name
elif self.occurrence in [OCCURRENCE__REQUIRED_LIST,
OCCURRENCE__OPTIONAL_LIST]:
- return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_LIST(%s, %s)\n" \
- % (self.type, self.name)
+ if self.type == "String":
+ return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_STRING_LIST(%s, %s)\n" \
+ % (self.type, self.name)
+ else:
+ return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_LIST(%s, %s)\n" \
+ % (self.type, self.name)
elif self.type == "String":
return " ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_VALUE(String, %s)\n" \
% self.name
@@ -1519,8 +1523,31 @@ additional_object_features = { "AutoStartDefaults" : Object.FEATURE__AN
Object.FEATURE__ANY_TYPE,
"HostDatastoreBrowserSearchResults" : Object.FEATURE__LIST |
Object.FEATURE__ANY_TYPE,
+ "HostIpConfig" : Object.FEATURE__DEEP_COPY,
+ "HostIpRouteConfig" : Object.FEATURE__ANY_TYPE,
+ "HostIpConfigIpV6Address" : Object.FEATURE__LIST |
+ Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__DEEP_COPY,
+ "HostIpConfigIpV6AddressConfiguration" : Object.FEATURE__DEEP_COPY,
+ "HostPortGroup" : Object.FEATURE__LIST |
+ Object.FEATURE__ANY_TYPE,
+ "HostVirtualNic" : Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__LIST,
+ "HostVirtualSwitch" : Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__LIST,
+ "KeyValue" : Object.FEATURE__ANY_TYPE,
"ManagedObjectReference" : Object.FEATURE__ANY_TYPE,
+ "PhysicalNic" : Object.FEATURE__LIST |
+ Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__DEEP_COPY,
"ObjectContent" : Object.FEATURE__DEEP_COPY,
+ "OptionValue" : Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__LIST,
+ "PhysicalNic" : Object.FEATURE__LIST |
+ Object.FEATURE__ANY_TYPE |
+ Object.FEATURE__DEEP_COPY,
+ "PhysicalNicSpec" : Object.FEATURE__DEEP_COPY,
+ "PhysicalNicLinkInfo" : Object.FEATURE__LIST,
"ResourcePoolResourceUsage" : Object.FEATURE__ANY_TYPE,
"ServiceContent" : Object.FEATURE__DESERIALIZE,
"SharesInfo" : Object.FEATURE__ANY_TYPE,
diff --git a/src/esx/esx_vi_types.c b/src/esx/esx_vi_types.c
index bcc310f..f23af8d 100644
--- a/src/esx/esx_vi_types.c
+++ b/src/esx/esx_vi_types.c
@@ -475,7 +475,23 @@
continue; \
}
-
+#define ESX_VI__TEMPLATE__PROPERTY__DESERIALIZE_STRING_LIST(_type, _name) \
+ if (xmlStrEqual(childNode->name, BAD_CAST #_name)) { \
+ char *value = NULL; \
+ \
+ if (esxVI_String_DeserializeValue(childNode, &value) < 0 || \
+ value == NULL) { \
+ goto failure; \
+ } \
+ \
+ if (esxVI_##_type##_AppendValueToList(&(*ptrptr)->_name, \
+ value) < 0) { \
+ VIR_FREE(value); \
+ goto failure; \
+ } \
+ \
+ continue; \
+ }
/*
* A required property must be != 0 (NULL for pointers, "undefined" == 0 for
--
1.7.9.5
12 years, 5 months
[libvirt] [PATCH v3 0/2] ESX: Add routines to interface driver
by Ata E Husain Bohra
Updated code to use ATTRIBUTE_UNUSED for un-used variable.
Ata E Husain Bohra (2):
ESX: Add routines to interface driver
Use ATTRIBUTE_UNUSED for unused variable.
src/esx/esx_interface_driver.c | 500 +++++++++++++++++++++++++++++++++++++++-
src/esx/esx_vi.c | 126 ++++++++++
src/esx/esx_vi.h | 10 +
src/esx/esx_vi_generator.input | 227 ++++++++++++++++++
src/esx/esx_vi_generator.py | 31 ++-
src/esx/esx_vi_types.c | 18 +-
6 files changed, 907 insertions(+), 5 deletions(-)
--
1.7.9.5
12 years, 5 months
[libvirt] Intend to add OVA installation API
by Ata Bohra
Hi Everyone,
I am relatively new to libvirt community; have worked on it from last half year mostly towards adding few missing APIs especially for ESX driver. One of the features I worked was installing a domain (VM) using OVAs. It is been a long time OVA became defacto standard for distributing and installing Virtual Machines, but surprisingly libvirt does not provide support for it. I wanted to perform a quick sanity int the community so that I am not stepping on anyone feet here. So far, I have working code, but to contribute upstream would require a bit of a cleanup work.
One of the concern that I intend to get inputs on:
OVA is a tar format archive, the first pre-requisite is to parse OVA and get following information:
1. XML descriptor.
2. VMDKs for transfer after domain is created on the hypervisor. (in ESX world that is done by getting a lease object and then transmitting the disk bits to hypervisor)
I am wondering, where should I put the common code to parse OVA? My initial thought is to enhance conf/domain_conf.* file, given it already provides parsing routines for XML descriptor. Waiting for your feedback on this one.
As I am familiar with ESX libvirt interaction, so the immediate plan is to enhance ESX driver, hopefully in near future will contribute the same feature to KVM/Xen etc.
Thanks!
Ata
12 years, 5 months
[libvirt] Different mac address used in libvirtd
by Yong Sheng Gong
Hi,
I found libvirtd will create vnet0 with a different mac other than the one defined in domain file. The mac in Domain file will be used by qemu-kvm.
I want to know how libvirtd decides the mac for vnet0, Who can give me a hint about the location of the libvirtd codes which does this work?
I cannot find how the libvirtd translates the mac from one defined in domain file to vnet0's one in src/util/bridge.c: brSetInterfaceMac()
Thanks
Yong Sheng Gong
[root@robinlinux eclipsecdt]# virsh dumpxml 2
<domain type='kvm' id='2'>
<name>instance-00000002</name>
<uuid>03e9993b-eafa-4021-b929-4a51ce9635d5</uuid>
<memory>524288</memory>
<currentMemory>524288</currentMemory>
<vcpu>1</vcpu>
<os>
<type arch='x86_64' machine='pc-0.14'>hvm</type>
<kernel>/var/lib/nova/instances/instance-00000002/kernel</kernel>
<initrd>/var/lib/nova/instances/instance-00000002/ramdisk</initrd>
<cmdline>root=/dev/vda console=ttyS0</cmdline>
<boot dev='hd'/>
</os>
<features>
<acpi/>
</features>
<clock offset='utc'>
<timer name='pit' tickpolicy='delay'/>
<timer name='rtc' tickpolicy='catchup'/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='qcow2' cache='none'/>
<source file='/var/lib/nova/instances/instance-00000002/disk'/>
<target dev='vda' bus='virtio'/>
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</disk>
<interface type='bridge'>
<mac address='fa:16:3e:28:64:c2'/>
<source bridge='br100'/>
<target dev='vnet0'/>
<filterref filter='nova-instance-instance-00000002-fa163e2864c2'>
<parameter name='DHCPSERVER' value='10.0.1.1'/>
<parameter name='PROJNET' value='10.0.1.0'/>
<parameter name='PROJMASK' value='255.255.255.0'/>
<parameter name='IP' value='10.0.1.2'/>
</filterref>
<alias name='net0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>
<serial type='file'>
<source path='/var/lib/nova/instances/instance-00000002/console.log'/>
<target port='0'/>
<alias name='serial0'/>
</serial>
<serial type='pty'>
<source path='/dev/pts/1'/>
<target port='1'/>
<alias name='serial1'/>
</serial>
<console type='file'>
<source path='/var/lib/nova/instances/instance-00000002/console.log'/>
<target type='serial' port='0'/>
<alias name='serial0'/>
</console>
<input type='tablet' bus='usb'>
<alias name='input0'/>
</input>
<input type='mouse' bus='ps2'/>
<graphics type='vnc' port='5900' autoport='yes' listen='127.0.0.1' keymap='en-us'>
<listen type='address' address='127.0.0.1'/>
</graphics>
<video>
<model type='cirrus' vram='9216' heads='1'/>
<alias name='video0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
</video>
<memballoon model='virtio'>
<alias name='balloon0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</memballoon>
</devices>
</domain>
[root@robinlinux eclipsecdt]# ifconfig vnet0
vnet0 Link encap:Ethernet HWaddr FE:16:3E:28:64:C2
inet6 addr: fe80::fc16:3eff:fe28:64c2/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:553 errors:0 dropped:0 overruns:0 frame:0
TX packets:1485 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:136360 (133.1 KiB) TX bytes:280590 (274.0 KiB)
12 years, 5 months
[libvirt] [PATCH] Fix Xen driver to have sensible error messages
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The Xen driver had a number of error reports which passed a
constant string without format specifiers and was missing
"%s". Furthermore the errors were related to failing system
calls, but virReportSystemError was not used. So the only
useful piece of info (the errno) was being discarded
---
cfg.mk | 2 +-
src/xen/xen_hypervisor.c | 114 ++++++++++++++++++++++------------------------
2 files changed, 55 insertions(+), 61 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index 4225336..46331fd 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -540,6 +540,7 @@ msg_gen_function += virReportError
msg_gen_function += virReportErrorHelper
msg_gen_function += virReportSystemError
msg_gen_function += virSecurityReportError
+msg_gen_function += virXenError
msg_gen_function += virXenInotifyError
msg_gen_function += virXenStoreError
msg_gen_function += virXendError
@@ -552,7 +553,6 @@ msg_gen_function += xenXMError
# so that they are translatable.
# msg_gen_function += fprintf
# msg_gen_function += testError
-# msg_gen_function += virXenError
# msg_gen_function += vshPrint
# msg_gen_function += vshError
diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
index b4ec579..9747010 100644
--- a/src/xen/xen_hypervisor.c
+++ b/src/xen/xen_hypervisor.c
@@ -526,9 +526,15 @@ static int
lock_pages(void *addr, size_t len)
{
#ifdef __linux__
- return mlock(addr, len);
+ if (mlock(addr, len) < 0) {
+ virReportSystemError(errno,
+ _("Unable to lock %zu bytes of memory"),
+ len);
+ return -1;
+ }
+ return 0;
#elif defined(__sun)
- return 0;
+ return 0;
#endif
}
@@ -536,9 +542,15 @@ static int
unlock_pages(void *addr, size_t len)
{
#ifdef __linux__
- return munlock(addr, len);
+ if (munlock(addr, len) < 0) {
+ virReportSystemError(errno,
+ _("Unable to unlock %zu bytes of memory"),
+ len);
+ return -1;
+ }
+ return 0;
#elif defined(__sun)
- return 0;
+ return 0;
#endif
}
@@ -900,21 +912,18 @@ xenHypervisorDoV0Op(int handle, xen_op_v0 * op)
hc.op = __HYPERVISOR_dom0_op;
hc.arg[0] = (unsigned long) op;
- if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
+ if (lock_pages(op, sizeof(dom0_op_t)) < 0)
return -1;
- }
ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
if (ret < 0) {
- virXenError(VIR_ERR_XEN_CALL, " ioctl %d",
- xen_ioctl_hypercall_cmd);
+ virReportSystemError(errno,
+ _("Unable to issue hypervisor ioctl %d"),
+ xen_ioctl_hypercall_cmd);
}
- if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " releasing");
+ if (unlock_pages(op, sizeof(dom0_op_t)) < 0)
ret = -1;
- }
if (ret < 0)
return -1;
@@ -942,21 +951,18 @@ xenHypervisorDoV1Op(int handle, xen_op_v1* op)
hc.op = __HYPERVISOR_dom0_op;
hc.arg[0] = (unsigned long) op;
- if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
+ if (lock_pages(op, sizeof(dom0_op_t)) < 0)
return -1;
- }
ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
if (ret < 0) {
- virXenError(VIR_ERR_XEN_CALL, " ioctl %d",
- xen_ioctl_hypercall_cmd);
+ virReportSystemError(errno,
+ _("Unable to issue hypervisor ioctl %d"),
+ xen_ioctl_hypercall_cmd);
}
- if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " releasing");
+ if (unlock_pages(op, sizeof(dom0_op_t)) < 0)
ret = -1;
- }
if (ret < 0)
return -1;
@@ -985,21 +991,18 @@ xenHypervisorDoV2Sys(int handle, xen_op_v2_sys* op)
hc.op = __HYPERVISOR_sysctl;
hc.arg[0] = (unsigned long) op;
- if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
+ if (lock_pages(op, sizeof(dom0_op_t)) < 0)
return -1;
- }
ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
if (ret < 0) {
- virXenError(VIR_ERR_XEN_CALL, " sys ioctl %d",
- xen_ioctl_hypercall_cmd);
+ virReportSystemError(errno,
+ _("Unable to issue hypervisor ioctl %d"),
+ xen_ioctl_hypercall_cmd);
}
- if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " releasing");
+ if (unlock_pages(op, sizeof(dom0_op_t)) < 0)
ret = -1;
- }
if (ret < 0)
return -1;
@@ -1028,21 +1031,18 @@ xenHypervisorDoV2Dom(int handle, xen_op_v2_dom* op)
hc.op = __HYPERVISOR_domctl;
hc.arg[0] = (unsigned long) op;
- if (lock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
+ if (lock_pages(op, sizeof(dom0_op_t)) < 0)
return -1;
- }
ret = ioctl(handle, xen_ioctl_hypercall_cmd, (unsigned long) &hc);
if (ret < 0) {
- virXenError(VIR_ERR_XEN_CALL, " ioctl %d",
- xen_ioctl_hypercall_cmd);
+ virReportSystemError(errno,
+ _("Unable to issue hypervisor ioctl %d"),
+ xen_ioctl_hypercall_cmd);
}
- if (unlock_pages(op, sizeof(dom0_op_t)) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " releasing");
+ if (unlock_pages(op, sizeof(dom0_op_t)) < 0)
ret = -1;
- }
if (ret < 0)
return -1;
@@ -1068,10 +1068,9 @@ virXen_getdomaininfolist(int handle, int first_domain, int maxids,
int ret = -1;
if (lock_pages(XEN_GETDOMAININFOLIST_DATA(dominfos),
- XEN_GETDOMAININFO_SIZE * maxids) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
+ XEN_GETDOMAININFO_SIZE * maxids) < 0)
return -1;
- }
+
if (hv_versions.hypervisor > 1) {
xen_op_v2_sys op;
@@ -1123,10 +1122,9 @@ virXen_getdomaininfolist(int handle, int first_domain, int maxids,
ret = op.u.getdomaininfolist.num_domains;
}
if (unlock_pages(XEN_GETDOMAININFOLIST_DATA(dominfos),
- XEN_GETDOMAININFO_SIZE * maxids) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " release");
+ XEN_GETDOMAININFO_SIZE * maxids) < 0)
ret = -1;
- }
+
return ret;
}
@@ -1747,10 +1745,9 @@ virXen_setvcpumap(int handle, int id, unsigned int vcpu,
if (hv_versions.hypervisor > 1) {
xen_op_v2_dom op;
- if (lock_pages(cpumap, maplen) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
+ if (lock_pages(cpumap, maplen) < 0)
return -1;
- }
+
memset(&op, 0, sizeof(op));
op.cmd = XEN_V2_OP_SETVCPUMAP;
op.domain = (domid_t) id;
@@ -1782,10 +1779,8 @@ virXen_setvcpumap(int handle, int id, unsigned int vcpu,
ret = xenHypervisorDoV2Dom(handle, &op);
VIR_FREE(new);
- if (unlock_pages(cpumap, maplen) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " release");
+ if (unlock_pages(cpumap, maplen) < 0)
ret = -1;
- }
} else {
cpumap_t xen_cpumap; /* limited to 64 CPUs in old hypervisors */
uint64_t *pm = &xen_cpumap;
@@ -1879,10 +1874,9 @@ virXen_getvcpusinfo(int handle, int id, unsigned int vcpu, virVcpuInfoPtr ipt,
ipt->cpu = op.u.getvcpuinfod5.online ? (int)op.u.getvcpuinfod5.cpu : -1;
}
if ((cpumap != NULL) && (maplen > 0)) {
- if (lock_pages(cpumap, maplen) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " locking");
+ if (lock_pages(cpumap, maplen) < 0)
return -1;
- }
+
memset(cpumap, 0, maplen);
memset(&op, 0, sizeof(op));
op.cmd = XEN_V2_OP_GETVCPUMAP;
@@ -1897,10 +1891,8 @@ virXen_getvcpusinfo(int handle, int id, unsigned int vcpu, virVcpuInfoPtr ipt,
op.u.getvcpumapd5.cpumap.nr_cpus = maplen * 8;
}
ret = xenHypervisorDoV2Dom(handle, &op);
- if (unlock_pages(cpumap, maplen) < 0) {
- virXenError(VIR_ERR_XEN_CALL, " release");
+ if (unlock_pages(cpumap, maplen) < 0)
ret = -1;
- }
}
} else {
int mapl = maplen;
@@ -2079,8 +2071,9 @@ xenHypervisorInit(struct xenHypervisorVersions *override_versions)
*/
hv_versions.hypervisor = -1;
- virXenError(VIR_ERR_XEN_CALL, " ioctl %lu",
- (unsigned long) IOCTL_PRIVCMD_HYPERCALL);
+ virReportSystemError(errno,
+ _("Unable to issue hypervisor ioctl %lu"),
+ (unsigned long)IOCTL_PRIVCMD_HYPERCALL);
VIR_FORCE_CLOSE(fd);
in_init = 0;
return -1;
@@ -2178,14 +2171,15 @@ xenHypervisorInit(struct xenHypervisorVersions *override_versions)
goto done;
}
+
/*
* we failed to make the getdomaininfolist hypercall
*/
-
- VIR_DEBUG("Failed to find any Xen hypervisor method");
hv_versions.hypervisor = -1;
- virXenError(VIR_ERR_XEN_CALL, " ioctl %lu",
- (unsigned long)IOCTL_PRIVCMD_HYPERCALL);
+ virReportSystemError(errno,
+ _("Unable to issue hypervisor ioctl %lu"),
+ (unsigned long)IOCTL_PRIVCMD_HYPERCALL);
+ VIR_DEBUG("Failed to find any Xen hypervisor method");
VIR_FORCE_CLOSE(fd);
in_init = 0;
VIR_FREE(ipt);
--
1.7.10.4
12 years, 5 months
[libvirt] [PATCH] qemu: Set reasonable RSS limit on domain startup
by Michal Privoznik
If there's a memory leak in qemu or qemu is exploited the host's
system will sooner or later start trashing instead of killing
the bad process. This however has impact on performance and other
guests as well. Therefore we should set a reasonable RSS limit
even when user hasn't set any. It's better to be secure by default.
---
src/qemu/qemu_cgroup.c | 73 +++++++++++++++++++++++++++---------------------
1 files changed, 41 insertions(+), 32 deletions(-)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index e39f5e1..2c158c1 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -339,42 +339,51 @@ int qemuSetupCgroup(struct qemud_driver *driver,
}
}
- if (vm->def->mem.hard_limit != 0 ||
- vm->def->mem.soft_limit != 0 ||
- vm->def->mem.swap_hard_limit != 0) {
- if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
- if (vm->def->mem.hard_limit != 0) {
- rc = virCgroupSetMemoryHardLimit(cgroup, vm->def->mem.hard_limit);
- if (rc != 0) {
- virReportSystemError(-rc,
- _("Unable to set memory hard limit for domain %s"),
- vm->def->name);
- goto cleanup;
- }
- }
- if (vm->def->mem.soft_limit != 0) {
- rc = virCgroupSetMemorySoftLimit(cgroup, vm->def->mem.soft_limit);
- if (rc != 0) {
- virReportSystemError(-rc,
- _("Unable to set memory soft limit for domain %s"),
- vm->def->name);
- goto cleanup;
- }
+ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) {
+ unsigned long long hard_limit = vm->def->mem.hard_limit;
+
+ if (!hard_limit) {
+ /* If there is no hard_limit set, set a reasonable
+ * one to avoid system trashing caused by exploited qemu.
+ * As 'reasonable limit' has been chosen:
+ * (1 + k) * (domain memory) + F
+ * where k = 0.02 and F = 200MB. */
+ hard_limit = vm->def->mem.max_balloon * 1.02 + 204800;
+ }
+
+ rc = virCgroupSetMemoryHardLimit(cgroup, hard_limit);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to set memory hard limit for domain %s"),
+ vm->def->name);
+ goto cleanup;
+ }
+ if (vm->def->mem.soft_limit != 0) {
+ rc = virCgroupSetMemorySoftLimit(cgroup, vm->def->mem.soft_limit);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to set memory soft limit for domain %s"),
+ vm->def->name);
+ goto cleanup;
}
+ }
- if (vm->def->mem.swap_hard_limit != 0) {
- rc = virCgroupSetMemSwapHardLimit(cgroup, vm->def->mem.swap_hard_limit);
- if (rc != 0) {
- virReportSystemError(-rc,
- _("Unable to set swap hard limit for domain %s"),
- vm->def->name);
- goto cleanup;
- }
+ if (vm->def->mem.swap_hard_limit != 0) {
+ rc = virCgroupSetMemSwapHardLimit(cgroup, vm->def->mem.swap_hard_limit);
+ if (rc != 0) {
+ virReportSystemError(-rc,
+ _("Unable to set swap hard limit for domain %s"),
+ vm->def->name);
+ goto cleanup;
}
- } else {
- qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("Memory cgroup is not available on this host"));
}
+ } else if (vm->def->mem.hard_limit != 0 ||
+ vm->def->mem.soft_limit != 0 ||
+ vm->def->mem.swap_hard_limit != 0) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Memory cgroup is not available on this host"));
+ } else {
+ VIR_WARN("Could not autoset a RSS limit for domain %s", vm->def->name);
}
if (vm->def->cputune.shares != 0) {
--
1.7.8.6
12 years, 5 months
[libvirt] libvirt qemu cgroup problem
by faicker mo
I want to use the cgroup with libvirt+qemu. The VM runs well.
But the libvirt report error, here is the libvirt debug info:
2012-07-19 09:40:10.726+0000: 32341: debug : virCgroupNew:603 : New group /
2012-07-19 09:40:10.726+0000: 32341: info : qemudStartup:597 : Unable to create cgroup for driver: No such device or address
2012-07-19 09:40:10.726+0000: 32341: debug : virLockManagerNopInit:35 : version=1000000 configFile=(null) flags=0
2012-07-19 09:40:10.726+0000: 32341: info : qemudLoadDriverConfig:332 : Configured cgroup controller 'cpu'
2012-07-19 09:40:10.726+0000: 32341: info : qemudLoadDriverConfig:332 : Configured cgroup controller 'cpuacct'
2012-07-19 09:40:10.726+0000: 32341: info : qemudLoadDriverConfig:332 : Configured cgroup controller 'cpuset'
2012-07-19 09:40:10.726+0000: 32341: info : qemudLoadDriverConfig:332 : Configured cgroup controller 'memory'
2012-07-19 09:40:10.726+0000: 32341: info : qemudLoadDriverConfig:332 : Configured cgroup controller 'devices'
2012-07-19 09:40:10.726+0000: 32341: info : qemudLoadDriverConfig:332 : Configured cgroup controller 'blkio'
I can't find the /sys/fs/cgroup dir or any other dir?
virsh blkiotune test
error: Unable to get blkio parameters
error: Requested operation is not valid: blkio cgroup isn't mounted
------
thank you.
12 years, 5 months
[libvirt] Unable to startVM in Power PC
by B Veera-B37207
Hi,
Here is my xml file
<domain type='qemu' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
<name>Test</name>
<uuid>aaec5748-56a9-e2fe-655c-c08ca3a4c097</uuid>
<memory unit='KiB'>65536</memory>
<currentMemory unit='KiB'>65536</currentMemory>
<vcpu placement='static'>1</vcpu>
<os>
<type arch='i686' machine='ppce500v2'>hvm</type>
<kernel>/boot/uImage-p2020rdb.bin</kernel>
<initrd>/home/root/guest.rootfs.ext2.gz</initrd>
<cmdline>root=/dev/ram rw console=ttyS0,115200</cmdline>
</os>
<features>
<acpi/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/bin/qemu-system-ppc</emulator>
<interface type='ethernet'>
<mac address='52:54:00:dd:fa:40'/>
<script path='/home/root/qemu-ifup'/>
<model type='virtio'/>
</interface>
<serial type='tcp'>
<source mode='bind' host='' service='4444'/>
<protocol type='raw'/>
<target port='0'/>
</serial>
<console type='tcp'>
<source mode='bind' host='' service='4444'/>
<protocol type='raw'/>
<target type='serial' port='0'/>
</console>
<memballoon model='virtio'/>
</devices>
<qemu:commandline>
<qemu:arg value='200M'/>
<qemu:arg value='-mem-path'/>
<qemu:arg value='/var/lib/hugetlbfs/pagesize-4MB'/>
<qemu:arg value='-dtb'/>
<qemu:arg value='/usr/share/qemu/ppce500v2.dtb'/>
</qemu:commandline>
</domain>
While starting VM I am getting following error
root@p2020rdb:~# virsh start Test
error: Failed to start domain Test
error: Unable to read from monitor: Connection reset by peer
#############################
Test.log Log file
############ ################
LC_ALL=C PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin HOME=/home/root USER=root LOGNAME=root /usr/bin/qemu-system-ppc -name Test -S -M ppce500v2 -m 256 -smp 1,sockets=1,cores=1,threads=1 -uuid aaec5748-56a9-e2fe-655c-c08ca3a4c097 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/usr/local/var/lib/libvirt/qemu/Test.monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -kernel /boot/uImage-p2020rdb.bin -initrd /home/root/guest.rootfs.ext2.gz -append root=/dev/ram rw console=ttyS0,115200 -device piix3-usb-uhci,id=usb,bus=pci,addr=0x1.0x2 -netdev tap,script=/home/root/qemu-ifup,id=hostnet0 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:dd:fa:40,bus=pci,addr=0x3 -chardev socket,id=charserial0,host=,port=4444,server,nowait -device isa-serial,chardev=charserial0,id=serial0 -device virtio-balloon-pci,id=balloon0,bus=pci,addr=0x4 -mem-path /var/lib/hugetlbfs/pagesize-4MB -dtb /usr/share/qemu/ppce500v2.dtb
Domain id=24 is tainted: high-privileges
Domain id=24 is tainted: custom-argv
Domain id=24 is tainted: shell-scripts
qemu-system-ppc: -device piix3-usb-uhci,id=usb,bus=pci,addr=0x1.0x2: Bus 'pci' not found
2012-07-19 09:06:25.215+0000: shutting down
Please help me regarding this issue
Regards,
Veera.
12 years, 5 months