Devel
Threads by month
- ----- 2026 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 10 participants
- 40389 discussions
Hi Everyone,
I'm looking at implementing some functionality in libvirt that would
allow it to call functions in an unpublished iSCSI library. Some of the
functionality I wish to implement is not currently part of the libvirt
storage API. I wanted to suggest the following additions to the storage
API: grow volumes, show whether thin provisioning is enabled, enable
thin provisioning, disable thin provisioning, create snapshots, and
delete snapshots. I've added a patch at the end of the mail showing how
I think these functions should be implemented. Note that I have not
included details about the virStorageSnapshotDefPtr yet, that's the next
step.
Perhaps this should be in a separate mail for better threading, but it
seems a bit strange to me that the storage interface isn't pluggable in
the traditional sense. In order to add a backend to libvirt, one has to
make modifications all over the place, for example: virt-inst, the
Makefile.am, the configure.ac, storage_backend.h, and several other
places. It would make sense to me to make this pluggable such that
someone could just load in a library that implements the required
functions and some identifying information (eg type of storage,
description, etc). A list of supported backends could be stored in
empty files in a directory somewhere, or some similar hack. This way
someone could write a plugin for tgtd for example, or in my case the
library I'm working with. I think this would also help others with
writing plugins for more storage backends. How difficult do you think
this would be? I'm willing to do a reasonable amount of work to get
this implemented, but I want to know what the experts think!
Best,
Patrick Dignan
--- libvirt-0.8.2.orig/src/storage/storage_backend.h 2010-06-16
17:27:22.000000000 -0500
+++ libvirt-0.8.2.work/src/storage/storage_backend.h 2010-07-27
16:36:08.321439851 -0500
@@ -43,6 +43,13 @@
typedef int (*virStorageBackendBuildVolFrom)(virConnectPtr conn,
virStoragePoolObjPtr pool,
virStorageVolDefPtr
origvol, virStorageVolDefPtr newvol,
unsigned int flags);
+typedef int (*virStorageBackendGrowVol)(virConnectPtr conn,
virStoragePoolObjPtr pool, virStorageVolDefPtr vol, unsigned long long
newsize);
+typedef bool (*virStorageBackendThinProvisionShow)(virConnectPtr conn,
virStoragePoolObjPtr pool, virStorageVolDefPtr vol);
+typedef int (*virStorageBackendThinProvisionEnable)(virConnectPtr conn,
virStoragePoolObjPtr pool, virStorageVolDefPtr vol);
+typedef int (*virStorageBackendThinProvisionDisable)(virConnectPtr
conn, virStoragePoolObjPtr pool, virStorageVolDefPtr vol);
+
+typedef int (virStorageBackendCreateSnapshot)(virConnectPtr conn,
virStoragePoolObjPtr pool, virStorageVolDefPtr vol,
virStorageSnapshotDefPtr snapshot);
+typedef int (virStorageBackendDeleteSnapshot)(virConnectPtr conn,
virStoragePoolObjPtr pool, virStorageVolDefPtr vol,
virStorageSnapshotDefPtr snapshot);
/* File creation/cloning functions used for cloning between backends */
int virStorageBackendCreateRaw(virConnectPtr conn,
@@ -76,6 +83,12 @@
virStorageBackendCreateVol createVol;
virStorageBackendRefreshVol refreshVol;
virStorageBackendDeleteVol deleteVol;
+ virStorageBackendGrowVol growVol;
+ virStorageBackendThinProvisionShow thinProvisionShow;
+ virStorageBackendThinProvisionEnable thinProvisionEnable;
+ virStorageBackendThinProvisionDisable thinProvisionDisable;
+ virStorageBackendCreateSnapshot createSnapshot;
+ virStorageBackendDeleteSnapshot deleteSnapshot;
};
virStorageBackendPtr virStorageBackendForType(int type);
2
4
[libvirt] [PATCH] esx: Add vpx:// scheme to allow direct connection to a vCenter
by Matthias Bolte 29 Jul '10
by Matthias Bolte 29 Jul '10
29 Jul '10
Add a pointer to the primary context of a connection and use it in all
driver functions that don't dependent on the context type. This includes
almost all functions that deal with a virDomianPtr. Therefore, using
a vpx:// connection allows you to perform all the usual domain related
actions like start, destroy, suspend, resume, dumpxml etc.
Some functions that require an explicitly specified ESX server don't work
yet. This includes the host UUID, the hostname, the general node info, the
max vCPU count and the free memory. Also not working yet are migration and
defining new domains.
---
docs/drvesx.html.in | 21 +-
src/esx/esx_driver.c | 931 ++++++++++++++++++++++++------------------
src/esx/esx_private.h | 1 +
src/esx/esx_storage_driver.c | 33 +-
src/esx/esx_vmx.c | 2 +
src/libvirt.c | 1 +
6 files changed, 562 insertions(+), 427 deletions(-)
diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in
index e8cee77..1f2ae4e 100644
--- a/docs/drvesx.html.in
+++ b/docs/drvesx.html.in
@@ -4,13 +4,14 @@
<p>
The libvirt VMware ESX driver can manage VMware ESX/ESXi 3.5/4.0 and
VMware GSX 2.0, also called VMware Server 2.0, and possibly later
- versions.
+ versions. <span class="since">Since 0.8.3</span> the driver can also
+ connect to a VMware vCenter 2.5/4.0 (VPX).
</p>
<h2><a name="prereq">Deployment pre-requisites</a></h2>
<p>
- None. Any out-of-the-box installation of ESX/GSX should work. No
+ None. Any out-of-the-box installation of VPX/ESX(i)/GSX should work. No
preparations are required on the server side, no libvirtd must be
installed on the ESX server. The driver uses version 2.5 of the remote,
SOAP based
@@ -27,10 +28,11 @@
Some example remote connection URIs for the driver are:
</p>
<pre>
-esx://example.com (ESX over HTTPS)
-gsx://example.com (GSX over HTTPS)
-esx://example.com/?transport=http (ESX over HTTP)
-esx://example.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the server's SSL certificate)
+vpx://example-vcenter.com (VPX over HTTPS)
+esx://example-esx.com (ESX over HTTPS)
+gsx://example-gsx.com (GSX over HTTPS)
+esx://example-esx.com/?transport=http (ESX over HTTP)
+esx://example-esx.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the server's SSL certificate)
</pre>
<p>
<strong>Note</strong>: In contrast to other drivers, the ESX driver is
@@ -49,9 +51,9 @@ esx://example.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the serve
type://[username@]hostname[:port]/[?extraparameters]
</pre>
<p>
- The <code>type://</code> is either <code>esx://</code> or
+ The <code>type://</code> is either <code>vpx://</code> or <code>esx://</code> or
<code>gsx://</code> and the driver selects the default port depending
- on it. For ESX the default HTTPS port is 443, for GSX it is 8333. If
+ on it. For VPX and ESX the default HTTPS port is 443, for GSX it is 8333. If
the port parameter is given, it overrides the default port.
</p>
@@ -76,7 +78,7 @@ type://[username@]hostname[:port]/[?extraparameters]
<code>http</code> or <code>https</code>
</td>
<td>
- Overrides the default HTTPS transport. For ESX the default
+ Overrides the default HTTPS transport. For VPX and ESX the default
HTTP port is 80, for GSX it is 8222.
</td>
</tr>
@@ -91,6 +93,7 @@ type://[username@]hostname[:port]/[?extraparameters]
In order to perform a migration the driver needs to know the
VMware vCenter for the ESX server. If set to <code>*</code>,
the driver connects to the vCenter known to the ESX server.
+ This paramater in useful when connecting to an ESX server only.
</td>
</tr>
<tr>
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 33f421d..5922cb6 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -67,6 +67,11 @@ esxSupportsLongMode(esxPrivate *priv)
return priv->supportsLongMode;
}
+ if (priv->host == NULL) {
+ /* FIXME: Currently no host for a vpx:// connection */
+ return esxVI_Boolean_False;
+ }
+
if (esxVI_EnsureSession(priv->host) < 0) {
return esxVI_Boolean_Undefined;
}
@@ -148,6 +153,11 @@ esxLookupHostSystemBiosUuid(esxPrivate *priv, unsigned char *uuid)
esxVI_ObjectContent *hostSystem = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL;
+ if (priv->host == NULL) {
+ /* FIXME: Currently no host for a vpx:// connection */
+ return 0;
+ }
+
if (esxVI_EnsureSession(priv->host) < 0) {
return -1;
}
@@ -280,11 +290,204 @@ esxCapsInit(esxPrivate *priv)
+static int
+esxConnectToHost(esxPrivate *priv, virConnectAuthPtr auth,
+ const char *hostname, int port,
+ const char *predefinedUsername,
+ esxUtil_ParsedQuery *parsedQuery,
+ esxVI_ProductVersion expectedProductVersion,
+ char **vCenterIpAddress)
+{
+ int result = -1;
+ char ipAddress[NI_MAXHOST] = "";
+ char *username = NULL;
+ char *password = NULL;
+ char *url = NULL;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *hostSystem = NULL;
+ esxVI_Boolean inMaintenanceMode = esxVI_Boolean_Undefined;
+
+ if (vCenterIpAddress == NULL || *vCenterIpAddress != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ if (esxUtil_ResolveHostname(hostname, ipAddress, NI_MAXHOST) < 0) {
+ return -1;
+ }
+
+ if (predefinedUsername != NULL) {
+ username = strdup(predefinedUsername);
+
+ if (username == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else {
+ username = virRequestUsername(auth, "root", hostname);
+
+ if (username == NULL) {
+ ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
+ goto cleanup;
+ }
+ }
+
+ password = virRequestPassword(auth, username, hostname);
+
+ if (password == NULL) {
+ ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
+ goto cleanup;
+ }
+
+ if (virAsprintf(&url, "%s://%s:%d/sdk", priv->transport, hostname,
+ port) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (esxVI_Context_Alloc(&priv->host) < 0 ||
+ esxVI_Context_Connect(priv->host, url, ipAddress, username, password,
+ parsedQuery) < 0) {
+ goto cleanup;
+ }
+
+ if (expectedProductVersion == esxVI_ProductVersion_ESX) {
+ if (priv->host->productVersion != esxVI_ProductVersion_ESX35 &&
+ priv->host->productVersion != esxVI_ProductVersion_ESX40) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("%s is neither an ESX 3.5 host nor an ESX 4.0 host"),
+ hostname);
+ goto cleanup;
+ }
+ } else { /* GSX */
+ if (priv->host->productVersion != esxVI_ProductVersion_GSX20) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("%s isn't a GSX 2.0 host"), hostname);
+ goto cleanup;
+ }
+ }
+
+ /* Query the host for maintenance mode and vCenter IP address */
+ if (esxVI_String_AppendValueListToList(&propertyNameList,
+ "runtime.inMaintenanceMode\0"
+ "summary.managementServerIp\0") < 0 ||
+ esxVI_LookupHostSystemByIp(priv->host, ipAddress, propertyNameList,
+ &hostSystem) < 0 ||
+ esxVI_GetBoolean(hostSystem, "runtime.inMaintenanceMode",
+ &inMaintenanceMode,
+ esxVI_Occurrence_RequiredItem) < 0 ||
+ esxVI_GetStringValue(hostSystem, "summary.managementServerIp",
+ vCenterIpAddress,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+
+ /* Warn if host is in maintenance mode */
+ if (inMaintenanceMode == esxVI_Boolean_True) {
+ VIR_WARN0("The server is in maintenance mode");
+ }
+
+ if (*vCenterIpAddress != NULL) {
+ *vCenterIpAddress = strdup(*vCenterIpAddress);
+
+ if (*vCenterIpAddress == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ }
+
+ result = 0;
+
+ cleanup:
+ VIR_FREE(password);
+ VIR_FREE(username);
+ VIR_FREE(url);
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&hostSystem);
+
+ return result;
+}
+
+
+
+static int
+esxConnectToVCenter(esxPrivate *priv, virConnectAuthPtr auth,
+ const char *hostname, int port,
+ const char *predefinedUsername,
+ esxUtil_ParsedQuery *parsedQuery)
+{
+ int result = -1;
+ char ipAddress[NI_MAXHOST] = "";
+ char *username = NULL;
+ char *password = NULL;
+ char *url = NULL;
+
+ if (esxUtil_ResolveHostname(hostname, ipAddress, NI_MAXHOST) < 0) {
+ return -1;
+ }
+
+ if (predefinedUsername != NULL) {
+ username = strdup(predefinedUsername);
+
+ if (username == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else {
+ username = virRequestUsername(auth, "administrator", hostname);
+
+ if (username == NULL) {
+ ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
+ goto cleanup;
+ }
+ }
+
+ password = virRequestPassword(auth, username, hostname);
+
+ if (password == NULL) {
+ ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
+ goto cleanup;
+ }
+
+ if (virAsprintf(&url, "%s://%s:%d/sdk", priv->transport, hostname,
+ port) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (esxVI_Context_Alloc(&priv->vCenter) < 0 ||
+ esxVI_Context_Connect(priv->vCenter, url, ipAddress, username,
+ password, parsedQuery) < 0) {
+ goto cleanup;
+ }
+
+ if (priv->vCenter->productVersion != esxVI_ProductVersion_VPX25 &&
+ priv->vCenter->productVersion != esxVI_ProductVersion_VPX40) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("%s is neither a vCenter 2.5 server nor a vCenter "
+ "4.0 server"), hostname);
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ VIR_FREE(password);
+ VIR_FREE(username);
+ VIR_FREE(url);
+
+ return result;
+}
+
+
+
/*
- * URI format: {esx|gsx}://[<username>@]<hostname>[:<port>]/[<query parameter> ...]
+ * URI format: {vpx|esx|gsx}://[<username>@]<hostname>[:<port>]/[<query parameter> ...]
*
* If no port is specified the default port is set dependent on the scheme and
* transport parameter:
+ * - vpx+http 80
+ * - vpx+https 443
* - esx+http 80
* - esx+https 443
* - gsx+http 8222
@@ -292,7 +495,7 @@ esxCapsInit(esxPrivate *priv)
*
* Optional query parameters:
* - transport={http|https}
- * - vcenter={<vcenter>|*}
+ * - vcenter={<vcenter>|*} only useful for an esx:// connection
* - no_verify={0|1}
* - auto_answer={0|1}
* - proxy=[{http|socks|socks4|socks4a|socks5}://]<hostname>[:<port>]
@@ -322,19 +525,13 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
virDrvOpenStatus result = VIR_DRV_OPEN_ERROR;
esxPrivate *priv = NULL;
esxUtil_ParsedQuery *parsedQuery = NULL;
- char hostIpAddress[NI_MAXHOST] = "";
+ char *potentialVCenterIpAddress = NULL;
char vCenterIpAddress[NI_MAXHOST] = "";
- char *url = NULL;
- char *vCenter = NULL;
- char *username = NULL;
- char *password = NULL;
- esxVI_String *propertyNameList = NULL;
- esxVI_ObjectContent *hostSystem = NULL;
- esxVI_DynamicProperty *dynamicProperty = NULL;
- /* Decline if the URI is NULL or the scheme is neither 'esx' nor 'gsx' */
+ /* Decline if the URI is NULL or the scheme is not one of {vpx|esx|gsx} */
if (conn->uri == NULL || conn->uri->scheme == NULL ||
- (STRCASENEQ(conn->uri->scheme, "esx") &&
+ (STRCASENEQ(conn->uri->scheme, "vpx") &&
+ STRCASENEQ(conn->uri->scheme, "esx") &&
STRCASENEQ(conn->uri->scheme, "gsx"))) {
return VIR_DRV_OPEN_DECLINED;
}
@@ -376,7 +573,8 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
* distinguish between the situations port == 0 and port != 0
*/
if (conn->uri->port == 0) {
- if (STRCASEEQ(conn->uri->scheme, "esx")) {
+ if (STRCASEEQ(conn->uri->scheme, "vpx") ||
+ STRCASEEQ(conn->uri->scheme, "esx")) {
if (STRCASEEQ(priv->transport, "https")) {
conn->uri->port = 443;
} else {
@@ -391,194 +589,67 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
}
}
- /* Login to host */
- if (esxUtil_ResolveHostname(conn->uri->server, hostIpAddress,
- NI_MAXHOST) < 0) {
- goto cleanup;
- }
-
- if (virAsprintf(&url, "%s://%s:%d/sdk", priv->transport,
- conn->uri->server, conn->uri->port) < 0) {
- virReportOOMError();
- goto cleanup;
- }
-
- if (conn->uri->user != NULL) {
- username = strdup(conn->uri->user);
-
- if (username == NULL) {
- virReportOOMError();
- goto cleanup;
- }
- } else {
- username = virRequestUsername(auth, "root", conn->uri->server);
-
- if (username == NULL) {
- ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
- goto cleanup;
- }
- }
-
- password = virRequestPassword(auth, username, conn->uri->server);
-
- if (password == NULL) {
- ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
- goto cleanup;
- }
-
- if (esxVI_Context_Alloc(&priv->host) < 0 ||
- esxVI_Context_Connect(priv->host, url, hostIpAddress, username,
- password, parsedQuery) < 0) {
- goto cleanup;
- }
-
- if (STRCASEEQ(conn->uri->scheme, "esx")) {
- if (priv->host->productVersion != esxVI_ProductVersion_ESX35 &&
- priv->host->productVersion != esxVI_ProductVersion_ESX40) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("%s is neither an ESX 3.5 host nor an ESX 4.0 host"),
- conn->uri->server);
+ if (STRCASEEQ(conn->uri->scheme, "esx") ||
+ STRCASEEQ(conn->uri->scheme, "gsx")) {
+ /* Connect to host */
+ if (esxConnectToHost(priv, auth, conn->uri->server, conn->uri->port,
+ conn->uri->user, parsedQuery,
+ STRCASEEQ(conn->uri->scheme, "esx")
+ ? esxVI_ProductVersion_ESX
+ : esxVI_ProductVersion_GSX,
+ &potentialVCenterIpAddress) < 0) {
goto cleanup;
}
- } else { /* GSX */
- if (priv->host->productVersion != esxVI_ProductVersion_GSX20) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("%s isn't a GSX 2.0 host"), conn->uri->server);
- goto cleanup;
- }
- }
-
- /* Query the host for maintenance mode and vCenter IP address */
- if (esxVI_String_AppendValueListToList(&propertyNameList,
- "runtime.inMaintenanceMode\0"
- "summary.managementServerIp\0") < 0 ||
- esxVI_LookupHostSystemByIp(priv->host, hostIpAddress, propertyNameList,
- &hostSystem) < 0) {
- goto cleanup;
- }
- /* Warn if host is in maintenance mode */
- for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
- dynamicProperty = dynamicProperty->_next) {
- if (STREQ(dynamicProperty->name, "runtime.inMaintenanceMode")) {
- if (esxVI_AnyType_ExpectType(dynamicProperty->val,
- esxVI_Type_Boolean) < 0) {
- goto cleanup;
- }
-
- if (dynamicProperty->val->boolean == esxVI_Boolean_True) {
- VIR_WARN0("The server is in maintenance mode");
- }
-
- break;
- }
- }
-
- /* Login to vCenter */
- if (parsedQuery->vCenter != NULL) {
- VIR_FREE(url);
- VIR_FREE(password);
- VIR_FREE(username);
-
- vCenter = strdup(parsedQuery->vCenter);
-
- if (vCenter == NULL) {
- virReportOOMError();
- goto cleanup;
- }
-
- /* If a vCenter is specified resolve the hostname */
- if (STRNEQ(vCenter, "*") &&
- esxUtil_ResolveHostname(vCenter, vCenterIpAddress,
- NI_MAXHOST) < 0) {
- goto cleanup;
- }
-
- /* Lookup the vCenter from the ESX host */
- for (dynamicProperty = hostSystem->propSet; dynamicProperty != NULL;
- dynamicProperty = dynamicProperty->_next) {
- if (STREQ(dynamicProperty->name, "summary.managementServerIp")) {
- if (esxVI_AnyType_ExpectType(dynamicProperty->val,
- esxVI_Type_String) < 0) {
+ /* Connect to vCenter */
+ if (parsedQuery->vCenter != NULL) {
+ if (STREQ(parsedQuery->vCenter, "*")) {
+ if (potentialVCenterIpAddress == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("This host is not managed by a vCenter"));
goto cleanup;
}
- /* Get the vCenter IP address or verify the specified one */
- if (STREQ(vCenter, "*")) {
- VIR_FREE(vCenter);
-
- vCenter = strdup(dynamicProperty->val->string);
-
- if (vCenter == NULL) {
- virReportOOMError();
- goto cleanup;
- }
+ if (virStrcpyStatic(vCenterIpAddress,
+ potentialVCenterIpAddress) == NULL) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("vCenter IP address %s too big for destination"),
+ potentialVCenterIpAddress);
+ goto cleanup;
+ }
+ } else {
+ if (esxUtil_ResolveHostname(parsedQuery->vCenter,
+ vCenterIpAddress, NI_MAXHOST) < 0) {
+ goto cleanup;
+ }
- if (virStrcpyStatic(vCenterIpAddress,
- dynamicProperty->val->string) == NULL) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("vCenter IP address %s too big for "
- "destination"),
- dynamicProperty->val->string);
- goto cleanup;
- }
- } else if (STRNEQ(vCenterIpAddress,
- dynamicProperty->val->string)) {
+ if (potentialVCenterIpAddress != NULL &&
+ STRNEQ(vCenterIpAddress, potentialVCenterIpAddress)) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("This host is managed by a vCenter with IP "
"address %s, but a mismachting vCenter '%s' "
"(%s) has been specified"),
- dynamicProperty->val->string, vCenter,
+ potentialVCenterIpAddress, parsedQuery->vCenter,
vCenterIpAddress);
goto cleanup;
}
-
- break;
}
- }
-
- if (STREQ(vCenter, "*")) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("This host is not managed by a vCenter"));
- goto cleanup;
- }
-
- if (virAsprintf(&url, "%s://%s/sdk", priv->transport,
- vCenter) < 0) {
- virReportOOMError();
- goto cleanup;
- }
-
- if (esxVI_Context_Alloc(&priv->vCenter) < 0) {
- goto cleanup;
- }
- username = virRequestUsername(auth, "administrator", vCenter);
-
- if (username == NULL) {
- ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Username request failed"));
- goto cleanup;
- }
-
- password = virRequestPassword(auth, username, vCenter);
-
- if (password == NULL) {
- ESX_ERROR(VIR_ERR_AUTH_FAILED, "%s", _("Password request failed"));
- goto cleanup;
+ if (esxConnectToVCenter(priv, auth, vCenterIpAddress,
+ conn->uri->port, NULL, parsedQuery) < 0) {
+ goto cleanup;
+ }
}
- if (esxVI_Context_Connect(priv->vCenter, url, vCenterIpAddress,
- username, password, parsedQuery) < 0) {
+ priv->primary = priv->host;
+ } else { /* VPX */
+ /* Connect to vCenter */
+ if (esxConnectToVCenter(priv, auth, conn->uri->server, conn->uri->port,
+ conn->uri->user, parsedQuery) < 0) {
goto cleanup;
}
- if (priv->vCenter->productVersion != esxVI_ProductVersion_VPX25 &&
- priv->vCenter->productVersion != esxVI_ProductVersion_VPX40) {
- ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("%s is neither a vCenter 2.5 server nor a vCenter "
- "4.0 server"), conn->uri->server);
- goto cleanup;
- }
+ priv->primary = priv->vCenter;
}
conn->privateData = priv;
@@ -604,12 +675,7 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth, int flags ATTRIBUTE_UNUSED)
}
esxUtil_FreeParsedQuery(&parsedQuery);
- VIR_FREE(url);
- VIR_FREE(vCenter);
- VIR_FREE(password);
- VIR_FREE(username);
- esxVI_String_Free(&propertyNameList);
- esxVI_ObjectContent_Free(&hostSystem);
+ VIR_FREE(potentialVCenterIpAddress);
return result;
}
@@ -622,12 +688,14 @@ esxClose(virConnectPtr conn)
esxPrivate *priv = conn->privateData;
int result = 0;
- if (esxVI_EnsureSession(priv->host) < 0 ||
- esxVI_Logout(priv->host) < 0) {
- result = -1;
- }
+ if (priv->host != NULL) {
+ if (esxVI_EnsureSession(priv->host) < 0 ||
+ esxVI_Logout(priv->host) < 0) {
+ result = -1;
+ }
- esxVI_Context_Free(&priv->host);
+ esxVI_Context_Free(&priv->host);
+ }
if (priv->vCenter != NULL) {
if (esxVI_EnsureSession(priv->vCenter) < 0 ||
@@ -661,6 +729,11 @@ esxSupportsVMotion(esxPrivate *priv)
return priv->supportsVMotion;
}
+ if (priv->host == NULL) {
+ /* FIXME: Currently no host for a vpx:// connection */
+ return esxVI_Boolean_False;
+ }
+
if (esxVI_EnsureSession(priv->host) < 0) {
return esxVI_Boolean_Undefined;
}
@@ -745,11 +818,11 @@ esxGetVersion(virConnectPtr conn, unsigned long *version)
{
esxPrivate *priv = conn->privateData;
- if (virParseVersionString(priv->host->service->about->version,
+ if (virParseVersionString(priv->primary->service->about->version,
version) < 0) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Could not parse version number from '%s'"),
- priv->host->service->about->version);
+ priv->primary->service->about->version);
return -1;
}
@@ -770,6 +843,13 @@ esxGetHostname(virConnectPtr conn)
const char *domainName = NULL;
char *complete = NULL;
+ if (priv->host == NULL) {
+ /* FIXME: Currently no host for a vpx:// connection */
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve the hostname for a vpx:// connection"));
+ return NULL;
+ }
+
if (esxVI_EnsureSession(priv->host) < 0) {
return NULL;
}
@@ -865,6 +945,13 @@ esxNodeGetInfo(virConnectPtr conn, virNodeInfoPtr nodeinfo)
memset(nodeinfo, 0, sizeof (*nodeinfo));
+ if (priv->host == NULL) {
+ /* FIXME: Currently no host for a vpx:// connection */
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Nodeinfo is not available for a vpx:// connection"));
+ return -1;
+ }
+
if (esxVI_EnsureSession(priv->host) < 0) {
return -1;
}
@@ -1034,13 +1121,13 @@ esxListDomains(virConnectPtr conn, int *ids, int maxids)
return 0;
}
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"runtime.powerState") < 0 ||
- esxVI_LookupObjectContentByType(priv->host, priv->host->vmFolder,
+ esxVI_LookupObjectContentByType(priv->primary, priv->primary->vmFolder,
"VirtualMachine", propertyNameList,
esxVI_Boolean_True,
&virtualMachineList) < 0) {
@@ -1090,12 +1177,12 @@ esxNumberOfDomains(virConnectPtr conn)
{
esxPrivate *priv = conn->privateData;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
return esxVI_LookupNumberOfDomainsByPowerState
- (priv->host, esxVI_VirtualMachinePowerState_PoweredOn,
+ (priv->primary, esxVI_VirtualMachinePowerState_PoweredOn,
esxVI_Boolean_False);
}
@@ -1114,7 +1201,7 @@ esxDomainLookupByID(virConnectPtr conn, int id)
unsigned char uuid_candidate[VIR_UUID_BUFLEN];
virDomainPtr domain = NULL;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
@@ -1123,7 +1210,7 @@ esxDomainLookupByID(virConnectPtr conn, int id)
"name\0"
"runtime.powerState\0"
"config.uuid\0") < 0 ||
- esxVI_LookupObjectContentByType(priv->host, priv->host->vmFolder,
+ esxVI_LookupObjectContentByType(priv->primary, priv->primary->vmFolder,
"VirtualMachine", propertyNameList,
esxVI_Boolean_True,
&virtualMachineList) < 0) {
@@ -1190,14 +1277,14 @@ esxDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
char *name = NULL;
virDomainPtr domain = NULL;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
if (esxVI_String_AppendValueListToList(&propertyNameList,
"name\0"
"runtime.powerState\0") < 0 ||
- esxVI_LookupVirtualMachineByUuid(priv->host, uuid, propertyNameList,
+ esxVI_LookupVirtualMachineByUuid(priv->primary, uuid, propertyNameList,
&virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachineIdentity(virtualMachine, &id, &name, NULL) < 0 ||
@@ -1239,7 +1326,7 @@ esxDomainLookupByName(virConnectPtr conn, const char *name)
unsigned char uuid[VIR_UUID_BUFLEN];
virDomainPtr domain = NULL;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
@@ -1247,7 +1334,7 @@ esxDomainLookupByName(virConnectPtr conn, const char *name)
"configStatus\0"
"runtime.powerState\0"
"config.uuid\0") < 0 ||
- esxVI_LookupVirtualMachineByName(priv->host, name, propertyNameList,
+ esxVI_LookupVirtualMachineByName(priv->primary, name, propertyNameList,
&virtualMachine,
esxVI_Occurrence_OptionalItem) < 0) {
goto cleanup;
@@ -1297,14 +1384,14 @@ esxDomainSuspend(virDomainPtr domain)
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"runtime.powerState") < 0 ||
esxVI_LookupVirtualMachineByUuidAndPrepareForTask
- (priv->host, domain->uuid, propertyNameList, &virtualMachine,
+ (priv->primary, domain->uuid, propertyNameList, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
goto cleanup;
@@ -1316,8 +1403,8 @@ esxDomainSuspend(virDomainPtr domain)
goto cleanup;
}
- if (esxVI_SuspendVM_Task(priv->host, virtualMachine->obj, &task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
+ if (esxVI_SuspendVM_Task(priv->primary, virtualMachine->obj, &task) < 0 ||
+ esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
@@ -1350,14 +1437,14 @@ esxDomainResume(virDomainPtr domain)
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"runtime.powerState") < 0 ||
esxVI_LookupVirtualMachineByUuidAndPrepareForTask
- (priv->host, domain->uuid, propertyNameList, &virtualMachine,
+ (priv->primary, domain->uuid, propertyNameList, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
goto cleanup;
@@ -1368,9 +1455,9 @@ esxDomainResume(virDomainPtr domain)
goto cleanup;
}
- if (esxVI_PowerOnVM_Task(priv->host, virtualMachine->obj, NULL,
+ if (esxVI_PowerOnVM_Task(priv->primary, virtualMachine->obj, NULL,
&task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
+ esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
@@ -1401,13 +1488,13 @@ esxDomainShutdown(virDomainPtr domain)
esxVI_String *propertyNameList = NULL;
esxVI_VirtualMachinePowerState powerState;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"runtime.powerState") < 0 ||
- esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
@@ -1420,7 +1507,7 @@ esxDomainShutdown(virDomainPtr domain)
goto cleanup;
}
- if (esxVI_ShutdownGuest(priv->host, virtualMachine->obj) < 0) {
+ if (esxVI_ShutdownGuest(priv->primary, virtualMachine->obj) < 0) {
goto cleanup;
}
@@ -1444,13 +1531,13 @@ esxDomainReboot(virDomainPtr domain, unsigned int flags ATTRIBUTE_UNUSED)
esxVI_String *propertyNameList = NULL;
esxVI_VirtualMachinePowerState powerState;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"runtime.powerState") < 0 ||
- esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
@@ -1463,7 +1550,7 @@ esxDomainReboot(virDomainPtr domain, unsigned int flags ATTRIBUTE_UNUSED)
goto cleanup;
}
- if (esxVI_RebootGuest(priv->host, virtualMachine->obj) < 0) {
+ if (esxVI_RebootGuest(priv->primary, virtualMachine->obj) < 0) {
goto cleanup;
}
@@ -1562,13 +1649,13 @@ esxDomainGetMaxMemory(virDomainPtr domain)
esxVI_DynamicProperty *dynamicProperty = NULL;
unsigned long memoryMB = 0;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return 0;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"config.hardware.memoryMB") < 0 ||
- esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
@@ -1615,12 +1702,12 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
- (priv->host, domain->uuid, NULL, &virtualMachine,
+ (priv->primary, domain->uuid, NULL, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 ||
esxVI_Long_Alloc(&spec->memoryMB) < 0) {
@@ -1630,9 +1717,9 @@ esxDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
spec->memoryMB->value =
memory / 1024; /* Scale from kilobytes to megabytes */
- if (esxVI_ReconfigVM_Task(priv->host, virtualMachine->obj, spec,
+ if (esxVI_ReconfigVM_Task(priv->primary, virtualMachine->obj, spec,
&task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
+ esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
@@ -1665,12 +1752,12 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
- (priv->host, domain->uuid, NULL, &virtualMachine,
+ (priv->primary, domain->uuid, NULL, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 ||
esxVI_ResourceAllocationInfo_Alloc(&spec->memoryAllocation) < 0 ||
@@ -1681,9 +1768,9 @@ esxDomainSetMemory(virDomainPtr domain, unsigned long memory)
spec->memoryAllocation->limit->value =
memory / 1024; /* Scale from kilobytes to megabytes */
- if (esxVI_ReconfigVM_Task(priv->host, virtualMachine->obj, spec,
+ if (esxVI_ReconfigVM_Task(priv->primary, virtualMachine->obj, spec,
&task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
+ esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
@@ -1731,7 +1818,7 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
memset(info, 0, sizeof (*info));
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
@@ -1740,7 +1827,7 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
"config.hardware.memoryMB\0"
"config.hardware.numCPU\0"
"config.memoryAllocation.limit\0") < 0 ||
- esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
@@ -1793,157 +1880,160 @@ esxDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
info->memory = memory_limit < 0 ? info->maxMem : memory_limit;
/* Verify the cached 'used CPU time' performance counter ID */
- if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId >= 0) {
- if (esxVI_Int_Alloc(&counterId) < 0) {
- goto cleanup;
- }
+ /* FIXME: Currently no host for a vpx:// connection */
+ if (priv->host != NULL) {
+ if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId >= 0) {
+ if (esxVI_Int_Alloc(&counterId) < 0) {
+ goto cleanup;
+ }
- counterId->value = priv->usedCpuTimeCounterId;
+ counterId->value = priv->usedCpuTimeCounterId;
- if (esxVI_Int_AppendToList(&counterIdList, counterId) < 0) {
- goto cleanup;
- }
+ if (esxVI_Int_AppendToList(&counterIdList, counterId) < 0) {
+ goto cleanup;
+ }
- if (esxVI_QueryPerfCounter(priv->host, counterIdList,
- &perfCounterInfo) < 0) {
- goto cleanup;
- }
+ if (esxVI_QueryPerfCounter(priv->host, counterIdList,
+ &perfCounterInfo) < 0) {
+ goto cleanup;
+ }
- if (STRNEQ(perfCounterInfo->groupInfo->key, "cpu") ||
- STRNEQ(perfCounterInfo->nameInfo->key, "used") ||
- STRNEQ(perfCounterInfo->unitInfo->key, "millisecond")) {
- VIR_DEBUG("Cached usedCpuTimeCounterId %d is invalid",
- priv->usedCpuTimeCounterId);
+ if (STRNEQ(perfCounterInfo->groupInfo->key, "cpu") ||
+ STRNEQ(perfCounterInfo->nameInfo->key, "used") ||
+ STRNEQ(perfCounterInfo->unitInfo->key, "millisecond")) {
+ VIR_DEBUG("Cached usedCpuTimeCounterId %d is invalid",
+ priv->usedCpuTimeCounterId);
- priv->usedCpuTimeCounterId = -1;
+ priv->usedCpuTimeCounterId = -1;
+ }
+
+ esxVI_Int_Free(&counterIdList);
+ esxVI_PerfCounterInfo_Free(&perfCounterInfo);
}
- esxVI_Int_Free(&counterIdList);
- esxVI_PerfCounterInfo_Free(&perfCounterInfo);
- }
+ /*
+ * Query the PerformanceManager for the 'used CPU time' performance
+ * counter ID and cache it, if it's not already cached.
+ */
+ if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId < 0) {
+ if (esxVI_QueryAvailablePerfMetric(priv->host, virtualMachine->obj,
+ NULL, NULL, NULL,
+ &perfMetricIdList) < 0) {
+ goto cleanup;
+ }
- /*
- * Query the PerformanceManager for the 'used CPU time' performance
- * counter ID and cache it, if it's not already cached.
- */
- if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId < 0) {
- if (esxVI_QueryAvailablePerfMetric(priv->host, virtualMachine->obj,
- NULL, NULL, NULL,
- &perfMetricIdList) < 0) {
- goto cleanup;
- }
+ for (perfMetricId = perfMetricIdList; perfMetricId != NULL;
+ perfMetricId = perfMetricId->_next) {
+ VIR_DEBUG("perfMetricId counterId %d, instance '%s'",
+ perfMetricId->counterId->value, perfMetricId->instance);
- for (perfMetricId = perfMetricIdList; perfMetricId != NULL;
- perfMetricId = perfMetricId->_next) {
- VIR_DEBUG("perfMetricId counterId %d, instance '%s'",
- perfMetricId->counterId->value, perfMetricId->instance);
+ counterId = NULL;
- counterId = NULL;
+ if (esxVI_Int_DeepCopy(&counterId, perfMetricId->counterId) < 0 ||
+ esxVI_Int_AppendToList(&counterIdList, counterId) < 0) {
+ goto cleanup;
+ }
+ }
- if (esxVI_Int_DeepCopy(&counterId, perfMetricId->counterId) < 0 ||
- esxVI_Int_AppendToList(&counterIdList, counterId) < 0) {
+ if (esxVI_QueryPerfCounter(priv->host, counterIdList,
+ &perfCounterInfoList) < 0) {
goto cleanup;
}
- }
- if (esxVI_QueryPerfCounter(priv->host, counterIdList,
- &perfCounterInfoList) < 0) {
- goto cleanup;
- }
-
- for (perfCounterInfo = perfCounterInfoList; perfCounterInfo != NULL;
- perfCounterInfo = perfCounterInfo->_next) {
- VIR_DEBUG("perfCounterInfo key %d, nameInfo '%s', groupInfo '%s', "
- "unitInfo '%s', rollupType %d, statsType %d",
- perfCounterInfo->key->value,
- perfCounterInfo->nameInfo->key,
- perfCounterInfo->groupInfo->key,
- perfCounterInfo->unitInfo->key,
- perfCounterInfo->rollupType,
- perfCounterInfo->statsType);
-
- if (STREQ(perfCounterInfo->groupInfo->key, "cpu") &&
- STREQ(perfCounterInfo->nameInfo->key, "used") &&
- STREQ(perfCounterInfo->unitInfo->key, "millisecond")) {
- priv->usedCpuTimeCounterId = perfCounterInfo->key->value;
- break;
+ for (perfCounterInfo = perfCounterInfoList; perfCounterInfo != NULL;
+ perfCounterInfo = perfCounterInfo->_next) {
+ VIR_DEBUG("perfCounterInfo key %d, nameInfo '%s', groupInfo '%s', "
+ "unitInfo '%s', rollupType %d, statsType %d",
+ perfCounterInfo->key->value,
+ perfCounterInfo->nameInfo->key,
+ perfCounterInfo->groupInfo->key,
+ perfCounterInfo->unitInfo->key,
+ perfCounterInfo->rollupType,
+ perfCounterInfo->statsType);
+
+ if (STREQ(perfCounterInfo->groupInfo->key, "cpu") &&
+ STREQ(perfCounterInfo->nameInfo->key, "used") &&
+ STREQ(perfCounterInfo->unitInfo->key, "millisecond")) {
+ priv->usedCpuTimeCounterId = perfCounterInfo->key->value;
+ break;
+ }
}
- }
- if (priv->usedCpuTimeCounterId < 0) {
- VIR_WARN0("Could not find 'used CPU time' performance counter");
+ if (priv->usedCpuTimeCounterId < 0) {
+ VIR_WARN0("Could not find 'used CPU time' performance counter");
+ }
}
- }
-
- /*
- * Query the PerformanceManager for the 'used CPU time' performance
- * counter value.
- */
- if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId >= 0) {
- VIR_DEBUG("usedCpuTimeCounterId %d BEGIN", priv->usedCpuTimeCounterId);
- if (esxVI_PerfQuerySpec_Alloc(&querySpec) < 0 ||
- esxVI_Int_Alloc(&querySpec->maxSample) < 0 ||
- esxVI_PerfMetricId_Alloc(&querySpec->metricId) < 0 ||
- esxVI_Int_Alloc(&querySpec->metricId->counterId) < 0) {
- goto cleanup;
- }
+ /*
+ * Query the PerformanceManager for the 'used CPU time' performance
+ * counter value.
+ */
+ if (info->state == VIR_DOMAIN_RUNNING && priv->usedCpuTimeCounterId >= 0) {
+ VIR_DEBUG("usedCpuTimeCounterId %d BEGIN", priv->usedCpuTimeCounterId);
- querySpec->entity = virtualMachine->obj;
- querySpec->maxSample->value = 1;
- querySpec->metricId->counterId->value = priv->usedCpuTimeCounterId;
- querySpec->metricId->instance = (char *)"";
- querySpec->format = (char *)"normal";
+ if (esxVI_PerfQuerySpec_Alloc(&querySpec) < 0 ||
+ esxVI_Int_Alloc(&querySpec->maxSample) < 0 ||
+ esxVI_PerfMetricId_Alloc(&querySpec->metricId) < 0 ||
+ esxVI_Int_Alloc(&querySpec->metricId->counterId) < 0) {
+ goto cleanup;
+ }
- if (esxVI_QueryPerf(priv->host, querySpec,
- &perfEntityMetricBaseList) < 0) {
- querySpec->entity = NULL;
- querySpec->metricId->instance = NULL;
- querySpec->format = NULL;
- goto cleanup;
- }
+ querySpec->entity = virtualMachine->obj;
+ querySpec->maxSample->value = 1;
+ querySpec->metricId->counterId->value = priv->usedCpuTimeCounterId;
+ querySpec->metricId->instance = (char *)"";
+ querySpec->format = (char *)"normal";
+
+ if (esxVI_QueryPerf(priv->host, querySpec,
+ &perfEntityMetricBaseList) < 0) {
+ querySpec->entity = NULL;
+ querySpec->metricId->instance = NULL;
+ querySpec->format = NULL;
+ goto cleanup;
+ }
- for (perfEntityMetricBase = perfEntityMetricBaseList;
- perfEntityMetricBase != NULL;
- perfEntityMetricBase = perfEntityMetricBase->_next) {
- VIR_DEBUG0("perfEntityMetric ...");
+ for (perfEntityMetricBase = perfEntityMetricBaseList;
+ perfEntityMetricBase != NULL;
+ perfEntityMetricBase = perfEntityMetricBase->_next) {
+ VIR_DEBUG0("perfEntityMetric ...");
- perfEntityMetric =
- esxVI_PerfEntityMetric_DynamicCast(perfEntityMetricBase);
+ perfEntityMetric =
+ esxVI_PerfEntityMetric_DynamicCast(perfEntityMetricBase);
- if (perfMetricIntSeries == NULL) {
- VIR_ERROR0(_("QueryPerf returned object with unexpected type"));
- }
+ if (perfMetricIntSeries == NULL) {
+ VIR_ERROR0(_("QueryPerf returned object with unexpected type"));
+ }
- perfMetricIntSeries =
- esxVI_PerfMetricIntSeries_DynamicCast(perfEntityMetric->value);
+ perfMetricIntSeries =
+ esxVI_PerfMetricIntSeries_DynamicCast(perfEntityMetric->value);
- if (perfMetricIntSeries == NULL) {
- VIR_ERROR0(_("QueryPerf returned object with unexpected type"));
- }
+ if (perfMetricIntSeries == NULL) {
+ VIR_ERROR0(_("QueryPerf returned object with unexpected type"));
+ }
- for (; perfMetricIntSeries != NULL;
- perfMetricIntSeries = perfMetricIntSeries->_next) {
- VIR_DEBUG0("perfMetricIntSeries ...");
+ for (; perfMetricIntSeries != NULL;
+ perfMetricIntSeries = perfMetricIntSeries->_next) {
+ VIR_DEBUG0("perfMetricIntSeries ...");
- for (value = perfMetricIntSeries->value;
- value != NULL;
- value = value->_next) {
- VIR_DEBUG("value %lld", (long long int)value->value);
+ for (value = perfMetricIntSeries->value;
+ value != NULL;
+ value = value->_next) {
+ VIR_DEBUG("value %lld", (long long int)value->value);
+ }
}
}
- }
- querySpec->entity = NULL;
- querySpec->metricId->instance = NULL;
- querySpec->format = NULL;
+ querySpec->entity = NULL;
+ querySpec->metricId->instance = NULL;
+ querySpec->format = NULL;
- VIR_DEBUG("usedCpuTimeCounterId %d END", priv->usedCpuTimeCounterId);
+ VIR_DEBUG("usedCpuTimeCounterId %d END", priv->usedCpuTimeCounterId);
- /*
- * FIXME: Cannot map between realtive used-cpu-time and absolute
- * info->cpuTime
- */
+ /*
+ * FIXME: Cannot map between realtive used-cpu-time and absolute
+ * info->cpuTime
+ */
+ }
}
result = 0;
@@ -1979,7 +2069,7 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
return -1;
}
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
@@ -1998,7 +2088,7 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
- (priv->host, domain->uuid, NULL, &virtualMachine,
+ (priv->primary, domain->uuid, NULL, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 ||
esxVI_Int_Alloc(&spec->numCPUs) < 0) {
@@ -2007,9 +2097,9 @@ esxDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
spec->numCPUs->value = nvcpus;
- if (esxVI_ReconfigVM_Task(priv->host, virtualMachine->obj, spec,
+ if (esxVI_ReconfigVM_Task(priv->primary, virtualMachine->obj, spec,
&task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
+ esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
@@ -2046,6 +2136,13 @@ esxDomainGetMaxVcpus(virDomainPtr domain)
priv->maxVcpus = -1;
+ if (priv->host == NULL) {
+ /* FIXME: Currently no host for a vpx:// connection */
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("MaxVCPUs value is not available for a vpx:// connection"));
+ return -1;
+ }
+
if (esxVI_EnsureSession(priv->host) < 0) {
return -1;
}
@@ -2093,9 +2190,11 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
{
esxPrivate *priv = domain->conn->privateData;
esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *datacenter = NULL;
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL;
const char *vmPathName = NULL;
+ char *datacenterName = NULL;
char *datastoreName = NULL;
char *directoryName = NULL;
char *fileName = NULL;
@@ -2105,13 +2204,24 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
virDomainDefPtr def = NULL;
char *xml = NULL;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
+ if (esxVI_String_AppendValueToList(&propertyNameList, "name") < 0 ||
+ esxVI_LookupObjectContentByType(priv->primary, priv->primary->datacenter,
+ "Datacenter", propertyNameList,
+ esxVI_Boolean_False, &datacenter) < 0 ||
+ esxVI_GetStringValue(datacenter, "name", &datacenterName,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto cleanup;
+ }
+
+ esxVI_String_Free(&propertyNameList);
+
if (esxVI_String_AppendValueToList(&propertyNameList,
"config.files.vmPathName") < 0 ||
- esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
@@ -2145,7 +2255,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
virBufferURIEncodeString(&buffer, fileName);
virBufferAddLit(&buffer, "?dcPath=");
- virBufferURIEncodeString(&buffer, priv->host->datacenter->value);
+ virBufferURIEncodeString(&buffer, datacenterName);
virBufferAddLit(&buffer, "&dsName=");
virBufferURIEncodeString(&buffer, datastoreName);
@@ -2156,12 +2266,12 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
url = virBufferContentAndReset(&buffer);
- if (esxVI_Context_DownloadFile(priv->host, url, &vmx) < 0) {
+ if (esxVI_Context_DownloadFile(priv->primary, url, &vmx) < 0) {
goto cleanup;
}
- def = esxVMX_ParseConfig(priv->host, priv->caps, vmx, datastoreName,
- directoryName, priv->host->productVersion);
+ def = esxVMX_ParseConfig(priv->primary, priv->caps, vmx, datastoreName,
+ directoryName, priv->primary->productVersion);
if (def != NULL) {
xml = virDomainDefFormat(def, flags);
@@ -2173,6 +2283,7 @@ esxDomainDumpXML(virDomainPtr domain, int flags)
}
esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&datacenter);
esxVI_ObjectContent_Free(&virtualMachine);
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
@@ -2201,8 +2312,8 @@ esxDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
return NULL;
}
- def = esxVMX_ParseConfig(priv->host, priv->caps, nativeConfig, "?", "?",
- priv->host->productVersion);
+ def = esxVMX_ParseConfig(priv->primary, priv->caps, nativeConfig, "?", "?",
+ priv->primary->productVersion);
if (def != NULL) {
xml = virDomainDefFormat(def, VIR_DOMAIN_XML_INACTIVE);
@@ -2236,8 +2347,8 @@ esxDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
return NULL;
}
- vmx = esxVMX_FormatConfig(priv->host, priv->caps, def,
- priv->host->productVersion);
+ vmx = esxVMX_FormatConfig(priv->primary, priv->caps, def,
+ priv->primary->productVersion);
virDomainDefFree(def);
@@ -2268,14 +2379,14 @@ esxListDefinedDomains(virConnectPtr conn, char **const names, int maxnames)
return 0;
}
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_String_AppendValueListToList(&propertyNameList,
"name\0"
"runtime.powerState\0") < 0 ||
- esxVI_LookupObjectContentByType(priv->host, priv->host->vmFolder,
+ esxVI_LookupObjectContentByType(priv->primary, priv->primary->vmFolder,
"VirtualMachine", propertyNameList,
esxVI_Boolean_True,
&virtualMachineList) < 0) {
@@ -2343,12 +2454,12 @@ esxNumberOfDefinedDomains(virConnectPtr conn)
{
esxPrivate *priv = conn->privateData;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
return esxVI_LookupNumberOfDomainsByPowerState
- (priv->host, esxVI_VirtualMachinePowerState_PoweredOn,
+ (priv->primary, esxVI_VirtualMachinePowerState_PoweredOn,
esxVI_Boolean_True);
}
@@ -2367,14 +2478,14 @@ esxDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
virCheckFlags(0, -1);
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"runtime.powerState") < 0 ||
esxVI_LookupVirtualMachineByUuidAndPrepareForTask
- (priv->host, domain->uuid, propertyNameList, &virtualMachine,
+ (priv->primary, domain->uuid, propertyNameList, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine,
&powerState) < 0) {
@@ -2387,9 +2498,9 @@ esxDomainCreateWithFlags(virDomainPtr domain, unsigned int flags)
goto cleanup;
}
- if (esxVI_PowerOnVM_Task(priv->host, virtualMachine->obj, NULL,
+ if (esxVI_PowerOnVM_Task(priv->primary, virtualMachine->obj, NULL,
&task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
+ esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
@@ -2437,6 +2548,13 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml ATTRIBUTE_UNUSED)
esxVI_TaskInfoState taskInfoState;
virDomainPtr domain = NULL;
+ if (priv->host == NULL) {
+ /* FIXME: Currently no host for a vpx:// connection */
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not define domain with a vpx:// connection"));
+ return NULL;
+ }
+
if (esxVI_EnsureSession(priv->host) < 0) {
return NULL;
}
@@ -2737,7 +2855,7 @@ esxDomainGetSchedulerParameters(virDomainPtr domain,
return -1;
}
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
@@ -2745,7 +2863,7 @@ esxDomainGetSchedulerParameters(virDomainPtr domain,
"config.cpuAllocation.reservation\0"
"config.cpuAllocation.limit\0"
"config.cpuAllocation.shares\0") < 0 ||
- esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
@@ -2856,12 +2974,12 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
esxVI_TaskInfoState taskInfoState;
int i;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
- (priv->host, domain->uuid, NULL, &virtualMachine,
+ (priv->primary, domain->uuid, NULL, &virtualMachine,
priv->autoAnswer) < 0 ||
esxVI_VirtualMachineConfigSpec_Alloc(&spec) < 0 ||
esxVI_ResourceAllocationInfo_Alloc(&spec->cpuAllocation) < 0) {
@@ -2944,9 +3062,9 @@ esxDomainSetSchedulerParameters(virDomainPtr domain,
}
}
- if (esxVI_ReconfigVM_Task(priv->host, virtualMachine->obj, spec,
+ if (esxVI_ReconfigVM_Task(priv->primary, virtualMachine->obj, spec,
&task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
+ esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
@@ -3152,6 +3270,13 @@ esxNodeGetFreeMemory(virConnectPtr conn)
esxVI_DynamicProperty *dynamicProperty = NULL;
esxVI_ResourcePoolResourceUsage *resourcePoolResourceUsage = NULL;
+ if (priv->host == NULL) {
+ /* FIXME: Currently no host for a vpx:// connection */
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve free memory for a vpx:// connection"));
+ return 0;
+ }
+
if (esxVI_EnsureSession(priv->host) < 0) {
return 0;
}
@@ -3251,13 +3376,13 @@ esxDomainIsActive(virDomainPtr domain)
esxVI_String *propertyNameList = NULL;
esxVI_VirtualMachinePowerState powerState;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"runtime.powerState") < 0 ||
- esxVI_LookupVirtualMachineByUuid(priv->host, domain->uuid,
+ esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0) {
@@ -3304,7 +3429,7 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
virCheckFlags(0, NULL);
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
@@ -3315,9 +3440,9 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
}
if (esxVI_LookupVirtualMachineByUuidAndPrepareForTask
- (priv->host, domain->uuid, NULL, &virtualMachine,
+ (priv->primary, domain->uuid, NULL, &virtualMachine,
priv->autoAnswer) < 0 ||
- esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
+ esxVI_LookupRootSnapshotTreeList(priv->primary, domain->uuid,
&rootSnapshotList) < 0 ||
esxVI_GetSnapshotTreeByName(rootSnapshotList, def->name,
&snapshotTree, &snapshotTreeParent,
@@ -3331,11 +3456,11 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
goto cleanup;
}
- if (esxVI_CreateSnapshot_Task(priv->host, virtualMachine->obj,
+ if (esxVI_CreateSnapshot_Task(priv->primary, virtualMachine->obj,
def->name, def->description,
esxVI_Boolean_True,
esxVI_Boolean_False, &task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, domain->uuid,
+ esxVI_WaitForTaskCompletion(priv->primary, task, domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
@@ -3374,11 +3499,11 @@ esxDomainSnapshotDumpXML(virDomainSnapshotPtr snapshot,
memset(&def, 0, sizeof (def));
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
- if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid,
+ if (esxVI_LookupRootSnapshotTreeList(priv->primary, snapshot->domain->uuid,
&rootSnapshotList) < 0 ||
esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
&snapshotTree, &snapshotTreeParent,
@@ -3419,11 +3544,11 @@ esxDomainSnapshotNum(virDomainPtr domain, unsigned int flags)
virCheckFlags(0, -1);
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
- if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
+ if (esxVI_LookupRootSnapshotTreeList(priv->primary, domain->uuid,
&rootSnapshotTreeList) < 0) {
return -1;
}
@@ -3456,11 +3581,11 @@ esxDomainSnapshotListNames(virDomainPtr domain, char **names, int nameslen,
return 0;
}
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
- if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
+ if (esxVI_LookupRootSnapshotTreeList(priv->primary, domain->uuid,
&rootSnapshotTreeList) < 0) {
return -1;
}
@@ -3486,11 +3611,11 @@ esxDomainSnapshotLookupByName(virDomainPtr domain, const char *name,
virCheckFlags(0, NULL);
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
- if (esxVI_LookupRootSnapshotTreeList(priv->host, domain->uuid,
+ if (esxVI_LookupRootSnapshotTreeList(priv->primary, domain->uuid,
&rootSnapshotTreeList) < 0 ||
esxVI_GetSnapshotTreeByName(rootSnapshotTreeList, name, &snapshotTree,
&snapshotTreeParent,
@@ -3516,11 +3641,11 @@ esxDomainHasCurrentSnapshot(virDomainPtr domain, unsigned int flags)
virCheckFlags(0, -1);
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
- if (esxVI_LookupCurrentSnapshotTree(priv->host, domain->uuid,
+ if (esxVI_LookupCurrentSnapshotTree(priv->primary, domain->uuid,
¤tSnapshotTree,
esxVI_Occurrence_OptionalItem) < 0) {
return -1;
@@ -3545,11 +3670,11 @@ esxDomainSnapshotCurrent(virDomainPtr domain, unsigned int flags)
virCheckFlags(0, NULL);
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
- if (esxVI_LookupCurrentSnapshotTree(priv->host, domain->uuid,
+ if (esxVI_LookupCurrentSnapshotTree(priv->primary, domain->uuid,
¤tSnapshotTree,
esxVI_Occurrence_RequiredItem) < 0) {
return NULL;
@@ -3577,11 +3702,11 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
virCheckFlags(0, -1);
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
- if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid,
+ if (esxVI_LookupRootSnapshotTreeList(priv->primary, snapshot->domain->uuid,
&rootSnapshotList) < 0 ||
esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
&snapshotTree, &snapshotTreeParent,
@@ -3589,9 +3714,9 @@ esxDomainRevertToSnapshot(virDomainSnapshotPtr snapshot, unsigned int flags)
goto cleanup;
}
- if (esxVI_RevertToSnapshot_Task(priv->host, snapshotTree->snapshot, NULL,
+ if (esxVI_RevertToSnapshot_Task(priv->primary, snapshotTree->snapshot, NULL,
&task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, snapshot->domain->uuid,
+ esxVI_WaitForTaskCompletion(priv->primary, task, snapshot->domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
@@ -3627,7 +3752,7 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
virCheckFlags(VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, -1);
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
@@ -3635,7 +3760,7 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
removeChildren = esxVI_Boolean_True;
}
- if (esxVI_LookupRootSnapshotTreeList(priv->host, snapshot->domain->uuid,
+ if (esxVI_LookupRootSnapshotTreeList(priv->primary, snapshot->domain->uuid,
&rootSnapshotList) < 0 ||
esxVI_GetSnapshotTreeByName(rootSnapshotList, snapshot->name,
&snapshotTree, &snapshotTreeParent,
@@ -3643,9 +3768,9 @@ esxDomainSnapshotDelete(virDomainSnapshotPtr snapshot, unsigned int flags)
goto cleanup;
}
- if (esxVI_RemoveSnapshot_Task(priv->host, snapshotTree->snapshot,
+ if (esxVI_RemoveSnapshot_Task(priv->primary, snapshotTree->snapshot,
removeChildren, &task) < 0 ||
- esxVI_WaitForTaskCompletion(priv->host, task, snapshot->domain->uuid,
+ esxVI_WaitForTaskCompletion(priv->primary, task, snapshot->domain->uuid,
priv->autoAnswer, &taskInfoState) < 0) {
goto cleanup;
}
diff --git a/src/esx/esx_private.h b/src/esx/esx_private.h
index 19955a5..6c7edb1 100644
--- a/src/esx/esx_private.h
+++ b/src/esx/esx_private.h
@@ -33,6 +33,7 @@
__LINE__, __VA_ARGS__)
typedef struct _esxPrivate {
+ esxVI_Context *primary; /* points to host or vCenter */
esxVI_Context *host;
esxVI_Context *vCenter;
virCapsPtr caps;
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index 98e7137..44d7d85 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -74,11 +74,11 @@ esxNumberOfStoragePools(virConnectPtr conn)
esxVI_ObjectContent *datastoreList = NULL;
esxVI_ObjectContent *datastore = NULL;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
- if (esxVI_LookupObjectContentByType(priv->host, priv->host->datacenter,
+ if (esxVI_LookupObjectContentByType(priv->primary, priv->primary->datacenter,
"Datastore", NULL, esxVI_Boolean_True,
&datastoreList) < 0) {
return -1;
@@ -117,13 +117,13 @@ esxListStoragePools(virConnectPtr conn, char **const names, int maxnames)
return 0;
}
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
if (esxVI_String_AppendValueToList(&propertyNameList,
"summary.name") < 0 ||
- esxVI_LookupObjectContentByType(priv->host, priv->host->datacenter,
+ esxVI_LookupObjectContentByType(priv->primary, priv->primary->datacenter,
"Datastore", propertyNameList,
esxVI_Boolean_True,
&datastoreList) < 0) {
@@ -209,7 +209,7 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name)
char *realName = NULL;
virStoragePoolPtr pool = NULL;
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
@@ -217,7 +217,7 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name)
"summary.accessible\0"
"summary.name\0"
"summary.url\0") < 0 ||
- esxVI_LookupDatastoreByName(priv->host, name,
+ esxVI_LookupDatastoreByName(priv->primary, name,
propertyNameList, &datastore,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetBoolean(datastore, "summary.accessible",
@@ -242,7 +242,8 @@ esxStoragePoolLookupByName(virConnectPtr conn, const char *name)
*
* The 'summary.url' property of an inaccessible datastore is invalid.
*/
- if (accessible == esxVI_Boolean_True &&
+ /* FIXME: Need to handle this for a vpx:// connection */
+ if (accessible == esxVI_Boolean_True && priv->host != NULL &&
priv->host->productVersion & esxVI_ProductVersion_ESX) {
if (esxVI_GetStringValue(datastore, "summary.url", &summaryUrl,
esxVI_Occurrence_RequiredItem) < 0) {
@@ -307,7 +308,9 @@ esxStoragePoolLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
char *name = NULL;
virStoragePoolPtr pool = NULL;
- if (! (priv->host->productVersion & esxVI_ProductVersion_ESX)) {
+ /* FIXME: Need to handle this for a vpx:// connection */
+ if (priv->host == NULL ||
+ ! (priv->host->productVersion & esxVI_ProductVersion_ESX)) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Lookup by UUID is supported on ESX only"));
return NULL;
@@ -389,13 +392,13 @@ esxStoragePoolRefresh(virStoragePoolPtr pool, unsigned int flags)
virCheckFlags(0, -1);
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
- if (esxVI_LookupDatastoreByName(priv->host, pool->name, NULL, &datastore,
+ if (esxVI_LookupDatastoreByName(priv->primary, pool->name, NULL, &datastore,
esxVI_Occurrence_RequiredItem) < 0 ||
- esxVI_RefreshDatastore(priv->host, datastore->obj) < 0) {
+ esxVI_RefreshDatastore(priv->primary, datastore->obj) < 0) {
goto cleanup;
}
@@ -421,7 +424,7 @@ esxStoragePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr info)
memset(info, 0, sizeof (*info));
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return -1;
}
@@ -429,7 +432,7 @@ esxStoragePoolGetInfo(virStoragePoolPtr pool, virStoragePoolInfoPtr info)
"summary.accessible\0"
"summary.capacity\0"
"summary.freeSpace\0") < 0 ||
- esxVI_LookupDatastoreByName(priv->host, pool->name,
+ esxVI_LookupDatastoreByName(priv->primary, pool->name,
propertyNameList, &datastore,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetBoolean(datastore, "summary.accessible",
@@ -494,7 +497,7 @@ esxStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags)
memset(&def, 0, sizeof (def));
- if (esxVI_EnsureSession(priv->host) < 0) {
+ if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
@@ -503,7 +506,7 @@ esxStoragePoolGetXMLDesc(virStoragePoolPtr pool, unsigned int flags)
"summary.capacity\0"
"summary.freeSpace\0"
"info\0") < 0 ||
- esxVI_LookupDatastoreByName(priv->host, pool->name,
+ esxVI_LookupDatastoreByName(priv->primary, pool->name,
propertyNameList, &datastore,
esxVI_Occurrence_RequiredItem) < 0 ||
esxVI_GetBoolean(datastore, "summary.accessible",
diff --git a/src/esx/esx_vmx.c b/src/esx/esx_vmx.c
index 9035233..e075149 100644
--- a/src/esx/esx_vmx.c
+++ b/src/esx/esx_vmx.c
@@ -1188,6 +1188,7 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
*/
switch (productVersion) {
case esxVI_ProductVersion_ESX35:
+ case esxVI_ProductVersion_VPX25:
if (virtualHW_version != 4) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Expecting VMX entry 'virtualHW.version' to be 4 "
@@ -1200,6 +1201,7 @@ esxVMX_ParseConfig(esxVI_Context *ctx, virCapsPtr caps, const char *vmx,
case esxVI_ProductVersion_GSX20:
case esxVI_ProductVersion_ESX40:
+ case esxVI_ProductVersion_VPX40:
if (virtualHW_version != 4 && virtualHW_version != 7) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Expecting VMX entry 'virtualHW.version' to be 4 or 7 "
diff --git a/src/libvirt.c b/src/libvirt.c
index d1b210d..3ec5724 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -1224,6 +1224,7 @@ do_open (const char *name,
STRCASEEQ(ret->uri->scheme, "phyp") ||
#endif
#ifndef WITH_ESX
+ STRCASEEQ(ret->uri->scheme, "vpx") ||
STRCASEEQ(ret->uri->scheme, "esx") ||
STRCASEEQ(ret->uri->scheme, "gsx") ||
#endif
--
1.7.0.4
3
9
Hello,
I'd like to be able to add interfaces to OpenVZ guests like the following
vzctl command does : vzctl set 100 --netif_add eth0,00:11:22:33:44:55,tap0
Here, eth0 is the guest interface name, and tap0 the host interface name.
This is currently not supported by libvirt so I'd like to implement it.
In terms of domain XML I think it would be something like:
<interface type='ethernet'>
<mac address='00:11:22:33:44:55'/>
<source dev='eth0'/>
<target dev='tap0'/>
</interface>
Currently the OpenVZ driver calls "vzctl set 100 --ipadd" when the interface
type is "ethernet" and the ip address attribute isn't empty.
Does it seem ok to use --netif_add for ethernet interfaces when there is no ip
defined ?
Regards,
Jean-Baptiste Rouault
1
0
[libvirt] [PATCH] fix handling of PORT_PROFILE_RESPONSE_INPROGRESS netlink message
by Gerhard Stenzel 28 Jul '10
by Gerhard Stenzel 28 Jul '10
28 Jul '10
During function test of the 802.1Qbg implementation in lldpad we came
across a small problem in the handling of the netlink message
corresponding to PORT_PROFILE_RESPONSE_INPROGRESS. This should not
result in returning the default rc=1.
Signed-off-by: Gerhard Stenzel <gerhard.stenzel(a)de.ibm.com>
diff --git a/src/util/macvtap.c b/src/util/macvtap.c
index 635458d..a6d9a57 100644
--- a/src/util/macvtap.c
+++ b/src/util/macvtap.c
@@ -1025,6 +1025,7 @@ getPortProfileStatus(struct nlattr **tb, int32_t
vf,
if (is8021Qbg) {
/* no in-progress here; may be missing */
*status = PORT_PROFILE_RESPONSE_INPROGRESS;
+ rc = 0;
} else {
msg = _("no IFLA_PORT_RESPONSE found in netlink message");
goto err_exit;
--
Best regards,
Gerhard Stenzel,
-----------------------------------------------------------------------------------------------------------------------------------
IBM Deutschland Research & Development GmbH
Vorsitzender des Aufsichtsrats: Martin Jetter
Geschäftsführung: Dirk Wittkopp
Sitz der Gesellschaft: Böblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294
2
1
* src/network/bridge_driver.c
(networkAddMasqueradingIptablesRules): Fix spelling and grammar.
---
Pushing under the trivial change rule.
src/network/bridge_driver.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 80ed57a..d6c7ae1 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -643,12 +643,12 @@ networkAddMasqueradingIptablesRules(struct network_driver *driver,
*
* We need to end up with 3 rules in the table in this order
*
- * 1. protocol=tcp with sport mapping restricton
- * 2. protocol=udp with sport mapping restricton
+ * 1. protocol=tcp with sport mapping restriction
+ * 2. protocol=udp with sport mapping restriction
* 3. generic any protocol
*
* The sport mappings are required, because default IPtables
- * MASQUERADE is maintain port number unchanged where possible.
+ * MASQUERADE maintain port numbers unchanged where possible.
*
* NFS can be configured to only "trust" port numbers < 1023.
*
--
1.7.2
1
0
Hello,
I've pushed the attached patch under the trivial rules.
Thanks,
--
Chris Lalancette
1
0
28 Jul '10
Today libvirt parses -help output to attempt to enumerate capabilities. This
is very broken and has led to multiple failures. Since libvirt is an important
management interface to QEMU, we need to do a better job giving them the ability
to detect what a QEMU executable supports. Right now, we keep fixing up help
output to appease it's parsing code but this is undesirable.
The Right Solution is to introduce a robust capabilities advertisement that
enumerates every feature we have. As with most Right Solutions, we don't have
mergable code today and it's unclear that we'll get there by the next release.
This patch introduces an incremental solution of just spitting out the handful
of capabilities libvirt is probing for today. This interface will need to
remain forever but can stop being updated once we have a Right Solution.
Signed-off-by: Anthony Liguori <aliguori(a)us.ibm.com>
diff --git a/qemu-options.hx b/qemu-options.hx
index 40cee70..a618914 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2235,7 +2235,26 @@ Normally QEMU loads a configuration file from @var{sysconfdir}/qemu.conf and
option will prevent QEMU from loading these configuration files at startup.
ETEXI
+DEF("libvirt-caps", 0, QEMU_OPTION_libvirt_caps,
+ "-libvirt-caps output libvirt-specific capabilities\n",
+ QEMU_ARCH_ALL)
+STEXI
+@item -libvirt-caps
+@findex -libvirt-caps
+Output a common separate list of capabilities that this version of QEMU
+supports and exit. This interface specifically exists for libvirt's use as an
+intermediate solution until we support a full capabilities system. One this
+capabilities system exist, this option's output should never change.
+
+The format out this command is:
+
+version: VERSION
+package: PACKAGE
+caps: CAP1[,CAP2...]
+ETEXI
+
HXCOMM This is the last statement. Insert new options before this line!
STEXI
@end table
ETEXI
+
diff --git a/vl.c b/vl.c
index ba6ee11..8fe354d 100644
--- a/vl.c
+++ b/vl.c
@@ -2616,6 +2616,14 @@ int main(int argc, char **argv, char **envp)
fclose(fp);
break;
}
+ case QEMU_OPTION_libvirt_caps:
+ printf("version: " QEMU_VERSION "\n"
+ "package: " QEMU_PKGVERSION "\n"
+ "caps: name,enable-kvm,no-reboot,uuid,xen-domid,drive"
+ ",cache-v2,format,vga,serial,mem-path,chardev,balloon"
+ ",device,rtc,netdev,sdl,topology\n");
+ exit(0);
+ break;
default:
os_parse_cmd_args(popt->index, optarg);
}
--
1.7.0.4
7
10
28 Jul '10
https://bugzilla.redhat.com/show_bug.cgi?id=617300 documents
several shortcoming in our libvirt-guests init script, in
relation to Fedora init script standards. For easier review,
I've split it into three simpler patches.
Eric Blake (3):
libvirt-guests: detect invalid arguments
libvirt-guests: enhance status
libvirt-guests: add reload, condrestart
daemon/libvirt-guests.init.in | 46 +++++++++++++++++++++++++++++++++-------
1 files changed, 38 insertions(+), 8 deletions(-)
--
1.7.2
3
6
Add a new element to the <os> block:
<bootmenu enable="yes|no"/>
Which maps to -boot,menu=on|off on the QEMU command line.
I decided to use an explicit 'enable' attribute rather than just make the
bootmenu element boolean. This allows us to treat lack of a bootmenu element
as 'use hypervisor default'.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
docs/formatdomain.html.in | 8 +++++
docs/schemas/domain.rng | 10 ++++++
src/conf/domain_conf.c | 18 ++++++++++++
src/conf/domain_conf.h | 8 ++++-
src/qemu/qemu_conf.c | 27 ++++++++++++++++-
src/qemu/qemu_conf.h | 1 +
tests/qemuhelptest.c | 9 ++++--
.../qemuxml2argv-boot-menu-disable.args | 1 +
.../qemuxml2argv-boot-menu-disable.xml | 27 ++++++++++++++++++
.../qemuxml2argvdata/qemuxml2argv-boot-multi.args | 1 +
tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml | 30 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 2 +
tests/qemuxml2xmltest.c | 2 +
13 files changed, 138 insertions(+), 6 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-boot-multi.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 3e80312..c79b606 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -79,6 +79,8 @@
<type>hvm</type>
<loader>/usr/lib/xen/boot/hvmloader</loader>
<boot dev='hd'/>
+ <boot dev='cdrom'/>
+ <bootmenu enable='yes'/>
</os>
...</pre>
@@ -104,6 +106,12 @@
times to setup a priority list of boot devices to try in turn.
<span class="since">Since 0.1.3</span>
</dd>
+ <dt><code>bootmenu</code></dt>
+ <dd> Whether or not to enable an interactive boot menu prompt on guest
+ startup. The <code>enable</code> attribute can be either "yes" or "no".
+ If not specified, the hypervisor default is used. <span class="since">
+ Since 0.8.3</span>
+ </dd>
</dl>
<h4><a name="elementsOSBootloader">Host bootloader</a></h4>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 2d22ce4..f36bb1f 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -122,6 +122,16 @@
<ref name="osbootdev"/>
</oneOrMore>
</choice>
+ <optional>
+ <element name="bootmenu">
+ <attribute name="enable">
+ <choice>
+ <value>yes</value>
+ <value>no</value>
+ </choice>
+ </attribute>
+ </element>
+ </optional>
</interleave>
</element>
</define>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5b59c01..dc775e8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4300,6 +4300,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
}
if (STREQ(def->os.type, "hvm")) {
+ char *bootstr;
+
/* analysis of the boot devices */
if ((n = virXPathNodeSet("./os/boot", ctxt, &nodes)) < 0) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -4329,6 +4331,15 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
def->os.bootDevs[0] = VIR_DOMAIN_BOOT_DISK;
}
VIR_FREE(nodes);
+
+ bootstr = virXPathString("string(./os/bootmenu[1]/@enable)", ctxt);
+ if (bootstr) {
+ if (STREQ(bootstr, "yes"))
+ def->os.bootmenu = VIR_DOMAIN_BOOT_MENU_ENABLED;
+ else
+ def->os.bootmenu = VIR_DOMAIN_BOOT_MENU_DISABLED;
+ VIR_FREE(bootstr);
+ }
}
def->emulator = virXPathString("string(./devices/emulator[1])", ctxt);
@@ -6275,6 +6286,13 @@ char *virDomainDefFormat(virDomainDefPtr def,
}
virBufferVSprintf(&buf, " <boot dev='%s'/>\n", boottype);
}
+
+ if (def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_DEFAULT) {
+ const char *enabled = (def->os.bootmenu ==
+ VIR_DOMAIN_BOOT_MENU_ENABLED ? "yes"
+ : "no");
+ virBufferVSprintf(&buf, " <bootmenu enable='%s'/>\n", enabled);
+ }
}
virBufferAddLit(&buf, " </os>\n");
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9ef687b..afd172f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -615,7 +615,6 @@ struct _virDomainDeviceDef {
# define VIR_DOMAIN_MAX_BOOT_DEVS 4
-/* 3 possible boot devices */
enum virDomainBootOrder {
VIR_DOMAIN_BOOT_FLOPPY,
VIR_DOMAIN_BOOT_CDROM,
@@ -625,6 +624,12 @@ enum virDomainBootOrder {
VIR_DOMAIN_BOOT_LAST,
};
+enum virDomainBootMenu {
+ VIR_DOMAIN_BOOT_MENU_DEFAULT = 0,
+ VIR_DOMAIN_BOOT_MENU_ENABLED,
+ VIR_DOMAIN_BOOT_MENU_DISABLED,
+};
+
enum virDomainFeature {
VIR_DOMAIN_FEATURE_ACPI,
VIR_DOMAIN_FEATURE_APIC,
@@ -651,6 +656,7 @@ struct _virDomainOSDef {
char *machine;
int nBootDevs;
int bootDevs[VIR_DOMAIN_BOOT_LAST];
+ int bootmenu;
char *init;
char *kernel;
char *initrd;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 05ad67d..1db504d 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1205,6 +1205,8 @@ static unsigned long long qemudComputeCmdFlags(const char *help,
flags |= QEMUD_CMD_FLAG_NO_KVM_PIT;
if (strstr(help, "-tdf"))
flags |= QEMUD_CMD_FLAG_TDF;
+ if (strstr(help, ",menu=on"))
+ flags |= QEMUD_CMD_FLAG_BOOT_MENU;
/* Keep disabled till we're actually ready to turn on netdev mode
* The plan is todo it in 0.13.0 QEMU, but lets wait & see... */
@@ -4078,9 +4080,25 @@ int qemudBuildCommandLine(virConnectPtr conn,
}
}
if (def->os.nBootDevs) {
+ virBuffer boot_buf = VIR_BUFFER_INITIALIZER;
+
boot[def->os.nBootDevs] = '\0';
- ADD_ARG_LIT("-boot");
- ADD_ARG_LIT(boot);
+ virBufferVSprintf(&boot_buf, "-boot %s", boot);
+
+ if (qemuCmdFlags & QEMUD_CMD_FLAG_BOOT_MENU &&
+ def->os.bootmenu != VIR_DOMAIN_BOOT_MENU_DEFAULT) {
+ if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_ENABLED)
+ virBufferAddLit(&boot_buf, ",menu=on");
+ else if (def->os.bootmenu == VIR_DOMAIN_BOOT_MENU_DISABLED)
+ virBufferAddLit(&boot_buf, ",menu=off");
+ }
+
+ if (virBufferError(&boot_buf)) {
+ virReportOOMError();
+ goto error;
+ }
+
+ ADD_ARG_LIT(virBufferContentAndReset(&boot_buf));
}
if (def->os.kernel) {
@@ -6207,8 +6225,13 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_CDROM;
else if (val[n] == 'n')
def->os.bootDevs[b++] = VIR_DOMAIN_BOOT_NET;
+ else if (val[n] == ',')
+ break;
}
def->os.nBootDevs = b;
+
+ if (strstr(val, "menu=on"))
+ def->os.bootmenu = 1;
} else if (STREQ(arg, "-name")) {
WANT_VALUE();
if (!(def->name = strdup(val)))
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 8c17e26..1aa9d2e 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -91,6 +91,7 @@ enum qemud_cmd_flags {
QEMUD_CMD_FLAG_TDF = (1LL << 35), /* -tdf flag (user-mode pit catchup) */
QEMUD_CMD_FLAG_PCI_CONFIGFD = (1LL << 36), /* pci-assign.configfd */
QEMUD_CMD_FLAG_NODEFCONFIG = (1LL << 37), /* -nodefconfig */
+ QEMUD_CMD_FLAG_BOOT_MENU = (1LL << 38), /* -boot menu=on support */
};
/* Main driver state */
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index 517a8fe..56a49fd 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -220,7 +220,8 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_RTC_TD_HACK |
QEMUD_CMD_FLAG_NO_HPET |
QEMUD_CMD_FLAG_NO_KVM_PIT |
- QEMUD_CMD_FLAG_TDF,
+ QEMUD_CMD_FLAG_TDF |
+ QEMUD_CMD_FLAG_BOOT_MENU,
10092, 1, 0);
DO_TEST("qemu-0.12.1",
QEMUD_CMD_FLAG_VNC_COLON |
@@ -244,7 +245,8 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_DEVICE |
QEMUD_CMD_FLAG_SMP_TOPOLOGY |
QEMUD_CMD_FLAG_RTC |
- QEMUD_CMD_FLAG_NO_HPET,
+ QEMUD_CMD_FLAG_NO_HPET |
+ QEMUD_CMD_FLAG_BOOT_MENU,
12001, 0, 0);
DO_TEST("qemu-kvm-0.12.3",
QEMUD_CMD_FLAG_VNC_COLON |
@@ -274,7 +276,8 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_VNET_HOST |
QEMUD_CMD_FLAG_NO_HPET |
QEMUD_CMD_FLAG_NO_KVM_PIT |
- QEMUD_CMD_FLAG_TDF,
+ QEMUD_CMD_FLAG_TDF |
+ QEMUD_CMD_FLAG_BOOT_MENU,
12003, 1, 0);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.args
new file mode 100644
index 0000000..1c773fd
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot d,menu=off -cdrom /dev/cdrom -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml
new file mode 100644
index 0000000..ceb109c
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-menu-disable.xml
@@ -0,0 +1,27 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='cdrom'/>
+ <bootmenu enable='no'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='cdrom'>
+ <source dev='/dev/cdrom'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <address type='drive' controller='0' bus='1' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.args b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.args
new file mode 100644
index 0000000..85b74d1
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.args
@@ -0,0 +1 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot dcna,menu=on -cdrom /dev/cdrom -net none -serial none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml
new file mode 100644
index 0000000..48f27aa
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-multi.xml
@@ -0,0 +1,30 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219200</memory>
+ <currentMemory>219200</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='cdrom'/>
+ <boot dev='hd'/>
+ <boot dev='network'/>
+ <boot dev='fd'/>
+ <bootmenu enable='yes'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='cdrom'>
+ <source dev='/dev/cdrom'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <address type='drive' controller='0' bus='1' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 3d6c583..0ca9804 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -223,6 +223,8 @@ mymain(int argc, char **argv)
DO_TEST("boot-cdrom", 0);
DO_TEST("boot-network", 0);
DO_TEST("boot-floppy", 0);
+ DO_TEST("boot-multi", QEMUD_CMD_FLAG_BOOT_MENU);
+ DO_TEST("boot-menu-disable", QEMUD_CMD_FLAG_BOOT_MENU);
DO_TEST("bootloader", QEMUD_CMD_FLAG_DOMID);
DO_TEST("clock-utc", 0);
DO_TEST("clock-localtime", 0);
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 69829b1..00b3a1b 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -89,6 +89,8 @@ mymain(int argc, char **argv)
DO_TEST("boot-cdrom");
DO_TEST("boot-network");
DO_TEST("boot-floppy");
+ DO_TEST("boot-multi");
+ DO_TEST("boot-menu-disable");
DO_TEST("bootloader");
DO_TEST("clock-utc");
DO_TEST("clock-localtime");
--
1.7.1.1
3
4
Since DV recommended keeping the build instructions distributed with the
source, move them from the old FAQ to the downloads page.
Signed-off-by: Cole Robinson <crobinso(a)redhat.com>
---
docs/FAQ.html.in | 144 ------------------------------------------------
docs/Makefile.am | 3 +-
docs/downloads.html.in | 29 ++++++++++
docs/search.php | 2 +-
docs/sitemap.html.in | 2 +-
5 files changed, 32 insertions(+), 148 deletions(-)
delete mode 100644 docs/FAQ.html.in
diff --git a/docs/FAQ.html.in b/docs/FAQ.html.in
deleted file mode 100644
index 50f798d..0000000
--- a/docs/FAQ.html.in
+++ /dev/null
@@ -1,144 +0,0 @@
-<?xml version="1.0"?>
-<html>
- <body>
- <h1 >FAQ</h1>
- <p>Table of Contents:</p>
- <ul>
- <li>
- <a href="FAQ.html#License">License(s)</a>
- </li>
- <li>
- <a href="FAQ.html#Installati">Installation</a>
- </li>
- <li>
- <a href="FAQ.html#Compilatio">Compilation</a>
- </li>
- <li>
- <a href="FAQ.html#Developer">Developer corner</a>
- </li>
- </ul>
- <h3><a name="License" id="License">License</a>(s)</h3>
- <ol>
- <li>
- <em>Licensing Terms for libvirt</em>
- <p>libvirt is released under the <a href="http://www.opensource.org/licenses/lgpl-license.html">GNU Lesser
- General Public License</a>, see the file COPYING.LIB in the distribution
- for the precise wording. The only library that libvirt depends upon is
- the Xen store access library which is also licenced under the LGPL.</p>
- </li>
- <li>
- <em>Can I embed libvirt in a proprietary application ?</em>
- <p>Yes. The LGPL allows you to embed libvirt into a proprietary
- application. It would be graceful to send-back bug fixes and improvements
- as patches for possible incorporation in the main development tree. It
- will decrease your maintenance costs anyway if you do so.</p>
- </li>
- </ol>
- <h3>
- <a name="Installati" id="Installati">Installation</a>
- </h3>
- <ol>
- <li><em>Where can I get libvirt</em> ?
- <p>The original distribution comes from <a href="ftp://libvirt.org/libvirt/">ftp://libvirt.org/libvirt/</a>.</p>
- </li>
- <li>
- <em>I can't install the libvirt/libvirt-devel RPM packages due to
- failed dependencies</em>
- <p>The most generic solution is to re-fetch the latest src.rpm , and
- rebuild it locally with</p>
- <p><code>rpm --rebuild libvirt-xxx.src.rpm</code>.</p>
- <p>If everything goes well it will generate two binary rpm packages (one
- providing the shared libs and virsh, and the other one, the -devel
- package, providing includes, static libraries and scripts needed to build
- applications with libvirt that you can install locally.</p>
- <p>One can also rebuild the RPMs from a tarball:</p>
- <p>
- <code>rpmbuild -ta libdir-xxx.tar.gz</code>
- </p>
- <p>Or from a configured tree with:</p>
- <p>
- <code>make rpm</code>
- </p>
- </li>
- <li>
- <em>Failure to use the API for non-root users</em>
- <p>Large parts of the API may only be accessible with root privileges,
- however the read only access to the xenstore data doesnot have to be
- forbidden to user, at least for monitoring purposes. If "virsh dominfo"
- fails to run as an user, change the mode of the xenstore read-only socket
- with:</p>
- <p>
- <code>chmod 666 /var/run/xenstored/socket_ro</code>
- </p>
- <p>and also make sure that the Xen Daemon is running correctly with local
- HTTP server enabled, this is defined in
- <code>/etc/xen/xend-config.sxp</code> which need the following line to be
- enabled:</p>
- <p>
- <code>(xend-http-server yes)</code>
- </p>
- <p>If needed restart the xend daemon after making the change with the
- following command run as root:</p>
- <p>
- <code>service xend restart</code>
- </p>
- </li>
- </ol>
- <h3>
- <a name="Compilatio" id="Compilatio">Compilation</a>
- </h3>
- <ol>
- <li>
- <em>What is the process to compile libvirt ?</em>
- <p>As most UNIX libraries libvirt follows the "standard":</p>
- <p>
- <code>gunzip -c libvirt-xxx.tar.gz | tar xvf -</code>
- </p>
- <p>
- <code>cd libvirt-xxxx</code>
- </p>
- <p>
- <code>./configure --help</code>
- </p>
- <p>to see the options, then the compilation/installation proper</p>
- <p>
- <code>./configure [possible options]</code>
- </p>
- <p>
- <code>make</code>
- </p>
- <p>
- <code>make install</code>
- </p>
- <p>At that point you may have to rerun ldconfig or a similar utility to
- update your list of installed shared libs.</p>
- </li>
- <li>
- <em>What other libraries are needed to compile/install libvirt ?</em>
- <p>Libvirt requires libxenstore, which is usually provided by the xen
- packages as well as the public headers to compile against libxenstore.</p>
- </li>
- <li>
- <em>I use the GIT version and there is no configure script</em>
- <p>The configure script (and other Makefiles) are generated. Use the
- autogen.sh script to regenerate the configure script and Makefiles,
- like:</p>
- <p>
- <code>./autogen.sh --prefix=/usr --disable-shared</code>
- </p>
- </li>
- </ol>
- <h3><a name="Developer" id="Developer">Developer</a> corner</h3>
- <ol>
- <li>
- <em>Troubles compiling or linking programs using libvirt</em>
- <p>To simplify the process of reusing the library, libvirt comes with
- pkgconfig support, which can be used directly from autoconf support or
- via the pkg-config command line tool, like:</p>
- <p>
- <code>pkg-config libvirt --libs</code>
- </p>
- </li>
- </ol>
- </body>
-</html>
diff --git a/docs/Makefile.am b/docs/Makefile.am
index a6a6d07..114ea1f 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -159,8 +159,7 @@ rebuild: api all
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)
- -$(INSTALL) -m 0644 $(srcdir)/FAQ.html \
- $(srcdir)/Libxml2-Logo-90x34.gif $(DESTDIR)$(HTML_DIR)
+ -$(INSTALL) -m 0644 $(srcdir)/Libxml2-Logo-90x34.gif $(DESTDIR)$(HTML_DIR)
$(mkinstalldirs) $(DESTDIR)$(HTML_DIR)/html
for h in $(apihtml); do \
$(INSTALL) -m 0644 $(srcdir)/$$h $(DESTDIR)$(HTML_DIR)/html; done
diff --git a/docs/downloads.html.in b/docs/downloads.html.in
index a0cb6fc..04fd16c 100644
--- a/docs/downloads.html.in
+++ b/docs/downloads.html.in
@@ -43,6 +43,35 @@
<a href="http://libvirt.org/git/?p=libvirt.git;a=summary">http://libvirt.org/git/?p=libvirt.git;a=summary</a>
</pre>
+
+ <h1>Installation</h1>
+ <h2>
+ <a name="Compilatio" id="Compilatio">Compilation</a>
+ </h2>
+ <p>As most UNIX libraries libvirt follows the "standard":</p>
+ <p>
+ <code>gunzip -c libvirt-xxx.tar.gz | tar xvf -</code>
+ </p>
+ <p>
+ <code>cd libvirt-xxxx</code>
+ </p>
+ <p>
+ <code>./configure --help</code>
+ </p>
+ <p>to see the options, then the compilation/installation proper</p>
+ <p>
+ <code>./configure [possible options]</code>
+ </p>
+ <p>
+ <code>make</code>
+ </p>
+ <p>
+ <code>make install</code>
+ </p>
+ <p>At that point you may have to rerun ldconfig or a similar utility to
+ update your list of installed shared libs.</p>
+ </p>
+
<h2>Building from a source code checkout</h2>
<p> The libvirt build process uses GNU autotools, so after obtaining a
checkout it is necessary to generate the configure script and Makefile.in
diff --git a/docs/search.php b/docs/search.php
index a6c1def..bbd652a 100644
--- a/docs/search.php
+++ b/docs/search.php
@@ -258,7 +258,7 @@
</li><li>
<a title="User contributed content" class="inactive" href="http://wiki.libvirt.org">Wiki</a>
</li><li>
- <a title="Frequently asked questions" class="inactive" href="FAQ.html">FAQ</a>
+ <a title="Frequently asked questions" class="inactive" href="http://wiki.libvirt.org/page/FAQ">FAQ</a>
</li><li>
<a title="How and where to report bugs and request features" class="inactive" href="bugs.html">Bug reports</a>
</li><li>
diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in
index 404ce5a..e9ab591 100644
--- a/docs/sitemap.html.in
+++ b/docs/sitemap.html.in
@@ -265,7 +265,7 @@
<span>User contributed content</span>
</li>
<li>
- <a href="FAQ.html">FAQ</a>
+ <a href="http://wiki.libvirt.org/page/FAQ">FAQ</a>
<span>Frequently asked questions</span>
</li>
<li>
--
1.7.1.1
2
2