[libvirt] [PATCH] Add missing param initialization in qemuDomainBlockStatsFlags
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
* src/qemu/qemu_driver.c: Fix use of uninitialized 'params'
---
src/qemu/qemu_driver.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f81cb88..3194e6b 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7236,6 +7236,7 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
}
if (tmp < *nparams && wr_req != -1) {
+ param = ¶ms[tmp];
if (virStrcpyStatic(param->field,
VIR_DOMAIN_BLOCK_STATS_WRITE_REQ) == NULL) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -7249,6 +7250,7 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
}
if (tmp < *nparams && rd_bytes != -1) {
+ param = ¶ms[tmp];
if (virStrcpyStatic(param->field,
VIR_DOMAIN_BLOCK_STATS_READ_BYTES) == NULL) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -7262,6 +7264,7 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
}
if (tmp < *nparams && rd_req != -1) {
+ param = ¶ms[tmp];
if (virStrcpyStatic(param->field,
VIR_DOMAIN_BLOCK_STATS_READ_REQ) == NULL) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -7275,6 +7278,7 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
}
if (tmp < *nparams && flush_req != -1) {
+ param = ¶ms[tmp];
if (virStrcpyStatic(param->field,
VIR_DOMAIN_BLOCK_STATS_FLUSH_REQ) == NULL) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -7288,6 +7292,7 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
}
if (tmp < *nparams && wr_total_times != -1) {
+ param = ¶ms[tmp];
if (virStrcpyStatic(param->field,
VIR_DOMAIN_BLOCK_STATS_WRITE_TOTAL_TIMES) == NULL) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -7301,6 +7306,7 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
}
if (tmp < *nparams && rd_total_times != -1) {
+ param = ¶ms[tmp];
if (virStrcpyStatic(param->field,
VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES) == NULL) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
@@ -7314,6 +7320,7 @@ qemuDomainBlockStatsFlags(virDomainPtr dom,
}
if (tmp < *nparams && flush_total_times != -1) {
+ param = ¶ms[tmp];
if (virStrcpyStatic(param->field,
VIR_DOMAIN_BLOCK_STATS_READ_TOTAL_TIMES) == NULL) {
qemuReportError(VIR_ERR_INTERNAL_ERROR,
--
1.7.6.4
13 years
[libvirt] Coverity automatic detection
by Alex Jia
This email is automatically generated.
The test result is based on the following git commit:
9765653 qemu: allow getting < max typed parameters
For details, please see attachment.
Regards,
Alex
13 years
[libvirt] RFC decoupling VM NIC provisioning from VM NIC connection to backend networks
by Sumit Naiksatam (snaiksat)
Hi,
In its current implementation Libvirt makes sure that the network
interfaces that it passes/provision to a VM (for example to qemu[-kvm])
are already connected to its backend (interfaces/networks) by the time
the VM starts its boot process. In a non virtualized setup it would be
like booting a machine with the Ethernet cable already plugged into a
router/switch port. While in a non virtualized setup you can boot a
machine first (with no physical connection to a router/switch) and later
connect its NIC/s to the switch/router, when you boot a VM via Libvirt
it is not possible to decouple the two actions (VM boot, cable
plug/unplug).
An example of case where the capability of decoupling the two actions
mentioned above is a requirement in Quantum/NetStack which is the
network service leveraged by OpenStack. The modular design of OpenStack
allows you to:
- provision VMs with NIC/s
- create networks
- create ports on networks
- plug/unplug a VM NIC into/from a given port on a network (at runtime)
Note that this runtime plug/unplug requirement has nothing to do with
hot plug/unplug of NICs.
The idea is more that of decoupling the provisioning of a VM from the
connection of the VM to the network/s.
This would make it possible to change (at run-time too) the networks the
NIC/s of a given VM are connected to.
For example, when a VM boots, its interfaces should be in link down
state if the network admin has not connected the VM NIC/s to any
"network" yet.
Even though libvirt already provides a way to change the link state of
an a VM NIC, link state and physical connection are two different things
and should be manageable independently.
Ideally the configuration syntax should be interface type and hypervisor
type agnostic.
Let's take QEMU[-kvm] as an example - when Libvirt starts a QEMU VM, it
passes to QEMU a number of file descriptors that map to host backend
interfaces (for example macvtap interfaces).
In order to introduce this runtime plug/unplug capability, we need a
mechanism that permits to delay the binding between the host macvtap
interfaces and the guest taps (because you cannot know the fd of the
macvtap interfaces before you create them). This means you need a
mechanism that allows you to change such fd/s at runtime:
- you can close/reset an fd (ie, when you disconnect a VM NIC from its
network)
- you can open/set an fd (ie, when you connect a VM NIC to a network)
This could probably be a libvirt command that translates to a QEMU
monitor command.
Can the runtime plug/unplug capability described above be achieved
(cleanly) with another mechanism?
Is anybody working on implementing something similar?
[For more information on OpenStack/NetStack/Quantum and the above
requirements please refer to the network model used therein:
http://docs.openstack.org/incubation/openstack-network/admin/content/Wha
tIsQuantum.html (information on network, port, and attachment
abstractions)
http://www.slideshare.net/danwent/quantum-diablo-summary (slides 7 & 8)]
Thanks,
~Sumit Naiksatam.
(On behalf of OpenStack/Quantum team)
13 years
[libvirt] [PATCHv2] esx: Support folders in the path of vpx:// connection URIs
by Matthias Bolte
Allow the datacenter and compute resource parts of the path
to be prefixed with folders. Therefore, the way the path is
parsed has changed. Before, it was split in 2 or 3 items and
the items' meanings were determined by their positions. Now
the path can have 2 or more items and the the vCenter server
is asked whether a folder, datacenter of compute resource
with the specified name exists at the current hierarchy level.
Before the datacenter and compute resource lookup automatically
traversed folders during lookup. This is logic got removed
and folders have to be specified explicitly.
The proper datacenter path including folders is now used when
accessing a datastore over HTTPS. This makes virsh dumpxml
and define work for datacenters in folders.
https://bugzilla.redhat.com/show_bug.cgi?id=732676
---
v1:
https://www.redhat.com/archives/libvir-list/2011-September/msg00345.html
v2:
- Fix managed object lookup for esx:// connections that was broken by the
changes to esxVI_Context_LookupManagedObjectsByPath in v1
- Store parsed/generated path parts in the context
docs/drvesx.html.in | 10 ++-
src/esx/esx_driver.c | 30 +++--
src/esx/esx_util.c | 22 +---
src/esx/esx_util.h | 4 +-
src/esx/esx_vi.c | 267 +++++++++++++++++++++++++++++++++++-----
src/esx/esx_vi.h | 11 +-
src/esx/esx_vi_generator.input | 4 +
7 files changed, 280 insertions(+), 68 deletions(-)
diff --git a/docs/drvesx.html.in b/docs/drvesx.html.in
index da9d2a1..7d323b3 100644
--- a/docs/drvesx.html.in
+++ b/docs/drvesx.html.in
@@ -56,7 +56,7 @@ esx://example-esx.com/?no_verify=1 (ESX over HTTPS, but doesn't verify the s
URIs have this general form (<code>[...]</code> marks an optional part).
</p>
<pre>
-type://[username@]hostname[:port]/[datacenter[/cluster]/server][?extraparameters]
+type://[username@]hostname[:port]/[[folder/...]datacenter/[folder/...][cluster/]server][?extraparameters]
</pre>
<p>
The <code>type://</code> is either <code>esx://</code> or
@@ -80,6 +80,14 @@ type://[username@]hostname[:port]/[datacenter[/cluster]/server][?extraparameters
<pre>
vpx://example-vcenter.com/dc1/cluster1/example-esx.com
</pre>
+ <p>
+ Datacenters and clusters can be organized in folders, those have to be
+ specified as well. The driver can handle folders
+ <span class="since">since 0.9.7</span>.
+ </p>
+<pre>
+vpx://example-vcenter.com/folder1/dc1/folder2/example-esx.com
+</pre>
<h4><a name="extraparams">Extra parameters</a></h4>
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index c5e4974..109d9f1 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -722,7 +722,7 @@ esxConnectToHost(esxPrivate *priv, virConnectAuthPtr auth,
if (esxVI_Context_Alloc(&priv->host) < 0 ||
esxVI_Context_Connect(priv->host, url, ipAddress, username, password,
priv->parsedUri) < 0 ||
- esxVI_Context_LookupObjectsByPath(priv->host, priv->parsedUri) < 0) {
+ esxVI_Context_LookupManagedObjects(priv->host) < 0) {
goto cleanup;
}
@@ -799,8 +799,7 @@ esxConnectToVCenter(esxPrivate *priv, virConnectAuthPtr auth,
char *url = NULL;
if (hostSystemIpAddress == NULL &&
- (priv->parsedUri->path_datacenter == NULL ||
- priv->parsedUri->path_computeResource == NULL)) {
+ (priv->parsedUri->path == NULL || STREQ(priv->parsedUri->path, "/"))) {
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
_("Path has to specify the datacenter and compute resource"));
return -1;
@@ -859,13 +858,13 @@ esxConnectToVCenter(esxPrivate *priv, virConnectAuthPtr auth,
}
if (hostSystemIpAddress != NULL) {
- if (esxVI_Context_LookupObjectsByHostSystemIp(priv->vCenter,
- hostSystemIpAddress) < 0) {
+ if (esxVI_Context_LookupManagedObjectsByHostSystemIp
+ (priv->vCenter, hostSystemIpAddress) < 0) {
goto cleanup;
}
} else {
- if (esxVI_Context_LookupObjectsByPath(priv->vCenter,
- priv->parsedUri) < 0) {
+ if (esxVI_Context_LookupManagedObjectsByPath(priv->vCenter,
+ priv->parsedUri->path) < 0) {
goto cleanup;
}
}
@@ -884,8 +883,8 @@ esxConnectToVCenter(esxPrivate *priv, virConnectAuthPtr auth,
/*
- * URI format: {vpx|esx|gsx}://[<username>@]<hostname>[:<port>]/[<path>][?<query parameter> ...]
- * <path> = <datacenter>/<computeresource>[/<hostsystem>]
+ * URI format: {vpx|esx|gsx}://[<username>@]<hostname>[:<port>]/[<path>][?<query parameter>...]
+ * <path> = [<folder>/...]<datacenter>/[<folder>/...]<computeresource>[/<hostsystem>]
*
* If no port is specified the default port is set dependent on the scheme and
* transport parameter:
@@ -899,7 +898,8 @@ esxConnectToVCenter(esxPrivate *priv, virConnectAuthPtr auth,
* For a vpx:// connection <path> references a host managed by the vCenter.
* In case the host is part of a cluster then <computeresource> is the cluster
* name. Otherwise <computeresource> and <hostsystem> are equal and the later
- * can be omitted.
+ * can be omitted. As datacenters and computeresources can be organized in
+ * folders those have to be included in <path>.
*
* Optional query parameters:
* - transport={http|https}
@@ -967,6 +967,12 @@ esxOpen(virConnectPtr conn, virConnectAuthPtr auth,
return VIR_DRV_OPEN_ERROR;
}
+ if (STRCASENEQ(conn->uri->scheme, "vpx") &&
+ conn->uri->path != NULL && STRNEQ(conn->uri->path, "/")) {
+ VIR_WARN("Ignoring unexpected path '%s' for non-vpx scheme '%s'",
+ conn->uri->path, conn->uri->scheme);
+ }
+
/* Require server part */
if (conn->uri->server == NULL) {
ESX_ERROR(VIR_ERR_INVALID_ARG, "%s",
@@ -2759,7 +2765,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
domain->conn->uri->server, domain->conn->uri->port);
virBufferURIEncodeString(&buffer, directoryAndFileName);
virBufferAddLit(&buffer, "?dcPath=");
- virBufferURIEncodeString(&buffer, priv->primary->datacenter->name);
+ virBufferURIEncodeString(&buffer, priv->primary->datacenterPath);
virBufferAddLit(&buffer, "&dsName=");
virBufferURIEncodeString(&buffer, datastoreName);
@@ -3227,7 +3233,7 @@ esxDomainDefineXML(virConnectPtr conn, const char *xml)
virBufferURIEncodeString(&buffer, escapedName);
virBufferAddLit(&buffer, ".vmx?dcPath=");
- virBufferURIEncodeString(&buffer, priv->primary->datacenter->name);
+ virBufferURIEncodeString(&buffer, priv->primary->datacenterPath);
virBufferAddLit(&buffer, "&dsName=");
virBufferURIEncodeString(&buffer, datastoreName);
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index c14179d..1925802 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -51,7 +51,6 @@ esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, xmlURIPtr uri)
int noVerify;
int autoAnswer;
char *tmp;
- char *saveptr;
if (parsedUri == NULL || *parsedUri != NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
@@ -184,26 +183,13 @@ esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, xmlURIPtr uri)
}
}
- /* Expected format: [/]<datacenter>/<computeresource>[/<hostsystem>] */
if (uri->path != NULL) {
- tmp = strdup(uri->path);
+ (*parsedUri)->path = strdup(uri->path);
- if (tmp == NULL) {
+ if ((*parsedUri)->path == NULL) {
virReportOOMError();
goto cleanup;
}
-
- if (esxVI_String_DeepCopyValue(&(*parsedUri)->path_datacenter,
- strtok_r(tmp, "/", &saveptr)) < 0 ||
- esxVI_String_DeepCopyValue(&(*parsedUri)->path_computeResource,
- strtok_r(NULL, "/", &saveptr)) < 0 ||
- esxVI_String_DeepCopyValue(&(*parsedUri)->path_hostSystem,
- strtok_r(NULL, "", &saveptr)) < 0) {
- VIR_FREE(tmp);
- goto cleanup;
- }
-
- VIR_FREE(tmp);
}
if ((*parsedUri)->transport == NULL) {
@@ -242,9 +228,7 @@ esxUtil_FreeParsedUri(esxUtil_ParsedUri **parsedUri)
VIR_FREE((*parsedUri)->transport);
VIR_FREE((*parsedUri)->vCenter);
VIR_FREE((*parsedUri)->proxy_hostname);
- VIR_FREE((*parsedUri)->path_datacenter);
- VIR_FREE((*parsedUri)->path_computeResource);
- VIR_FREE((*parsedUri)->path_hostSystem);
+ VIR_FREE((*parsedUri)->path);
VIR_FREE(*parsedUri);
}
diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h
index 39fdb6d..8d172e1 100644
--- a/src/esx/esx_util.h
+++ b/src/esx/esx_util.h
@@ -37,9 +37,7 @@ struct _esxUtil_ParsedUri {
int proxy_type;
char *proxy_hostname;
int proxy_port;
- char *path_datacenter;
- char *path_computeResource;
- char *path_hostSystem;
+ char *path;
};
int esxUtil_ParseUri(esxUtil_ParsedUri **parsedUri, xmlURIPtr uri);
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 87ae802..314f322 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -616,8 +616,11 @@ ESX_VI__TEMPLATE__FREE(Context,
esxVI_UserSession_Free(&item->session);
VIR_FREE(item->sessionLock);
esxVI_Datacenter_Free(&item->datacenter);
+ VIR_FREE(item->datacenterPath);
esxVI_ComputeResource_Free(&item->computeResource);
+ VIR_FREE(item->computeResourcePath);
esxVI_HostSystem_Free(&item->hostSystem);
+ VIR_FREE(item->hostSystemName);
esxVI_SelectionSpec_Free(&item->selectSet_folderToChildEntity);
esxVI_SelectionSpec_Free(&item->selectSet_hostSystemToParent);
esxVI_SelectionSpec_Free(&item->selectSet_hostSystemToVm);
@@ -789,21 +792,25 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
}
int
-esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
- esxUtil_ParsedUri *parsedUri)
+esxVI_Context_LookupManagedObjects(esxVI_Context *ctx)
{
- char *hostSystemName = NULL;
/* Lookup Datacenter */
- if (esxVI_LookupDatacenter(ctx, parsedUri->path_datacenter,
- ctx->service->rootFolder, NULL, &ctx->datacenter,
+ if (esxVI_LookupDatacenter(ctx, NULL, ctx->service->rootFolder, NULL,
+ &ctx->datacenter,
esxVI_Occurrence_RequiredItem) < 0) {
return -1;
}
+ ctx->datacenterPath = strdup(ctx->datacenter->name);
+
+ if (ctx->datacenterPath == NULL) {
+ virReportOOMError();
+ return -1;
+ }
+
/* Lookup (Cluster)ComputeResource */
- if (esxVI_LookupComputeResource(ctx, parsedUri->path_computeResource,
- ctx->datacenter->hostFolder, NULL,
- &ctx->computeResource,
+ if (esxVI_LookupComputeResource(ctx, NULL, ctx->datacenter->hostFolder,
+ NULL, &ctx->computeResource,
esxVI_Occurrence_RequiredItem) < 0) {
return -1;
}
@@ -814,38 +821,240 @@ esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
return -1;
}
+ ctx->computeResourcePath = strdup(ctx->computeResource->name);
+
+ if (ctx->computeResourcePath == NULL) {
+ virReportOOMError();
+ return -1;
+ }
+
/* Lookup HostSystem */
- if (parsedUri->path_hostSystem == NULL &&
- STREQ(ctx->computeResource->_reference->type,
- "ClusterComputeResource")) {
- ESX_VI_ERROR(VIR_ERR_INVALID_ARG, "%s",
- _("Path has to specify the host system"));
+ if (esxVI_LookupHostSystem(ctx, NULL, ctx->computeResource->_reference,
+ NULL, &ctx->hostSystem,
+ esxVI_Occurrence_RequiredItem) < 0) {
return -1;
}
- if (parsedUri->path_hostSystem != NULL ||
- (parsedUri->path_computeResource != NULL &&
- parsedUri->path_hostSystem == NULL)) {
- if (parsedUri->path_hostSystem != NULL) {
- hostSystemName = parsedUri->path_hostSystem;
+ ctx->hostSystemName = strdup(ctx->hostSystem->name);
+
+ if (ctx->hostSystemName == NULL) {
+ virReportOOMError();
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path)
+{
+ int result = -1;
+ char *tmp = NULL;
+ char *saveptr = NULL;
+ char *previousItem = NULL;
+ char *item = NULL;
+ virBuffer buffer = VIR_BUFFER_INITIALIZER;
+ esxVI_ManagedObjectReference *root = NULL;
+ esxVI_Folder *folder = NULL;
+
+ tmp = strdup(path);
+
+ if (tmp == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ /* Lookup Datacenter */
+ item = strtok_r(tmp, "/", &saveptr);
+
+ if (item == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INVALID_ARG,
+ _("Path '%s' does not specify a datacenter"), path);
+ goto cleanup;
+ }
+
+ root = ctx->service->rootFolder;
+
+ while (ctx->datacenter == NULL && item != NULL) {
+ esxVI_Folder_Free(&folder);
+
+ /* Try to lookup item as a folder */
+ if (esxVI_LookupFolder(ctx, item, root, NULL, &folder,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+
+ if (folder != NULL) {
+ /* It's a folder, use it as new lookup root */
+ if (root != ctx->service->rootFolder) {
+ esxVI_ManagedObjectReference_Free(&root);
+ }
+
+ root = folder->_reference;
+ folder->_reference = NULL;
+ } else {
+ /* Try to lookup item as a datacenter */
+ if (esxVI_LookupDatacenter(ctx, item, root, NULL, &ctx->datacenter,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+ }
+
+ /* Build path_datacenter */
+ if (virBufferUse(&buffer) > 0) {
+ virBufferAddChar(&buffer, '/');
+ }
+
+ virBufferAdd(&buffer, item, -1);
+
+ previousItem = item;
+ item = strtok_r(NULL, "/", &saveptr);
+ }
+
+ if (ctx->datacenter == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not find datacenter specified in '%s'"), path);
+ goto cleanup;
+ }
+
+ if (virBufferError(&buffer)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ ctx->datacenterPath = virBufferContentAndReset(&buffer);
+
+ /* Lookup (Cluster)ComputeResource */
+ if (item == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INVALID_ARG,
+ _("Path '%s' does not specify a compute resource"), path);
+ goto cleanup;
+ }
+
+ if (root != ctx->service->rootFolder) {
+ esxVI_ManagedObjectReference_Free(&root);
+ }
+
+ root = ctx->datacenter->hostFolder;
+
+ while (ctx->computeResource == NULL && item != NULL) {
+ esxVI_Folder_Free(&folder);
+
+ /* Try to lookup item as a folder */
+ if (esxVI_LookupFolder(ctx, item, root, NULL, &folder,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+
+ if (folder != NULL) {
+ /* It's a folder, use it as new lookup root */
+ if (root != ctx->datacenter->hostFolder) {
+ esxVI_ManagedObjectReference_Free(&root);
+ }
+
+ root = folder->_reference;
+ folder->_reference = NULL;
} else {
- hostSystemName = parsedUri->path_computeResource;
+ /* Try to lookup item as a compute resource */
+ if (esxVI_LookupComputeResource(ctx, item, root, NULL,
+ &ctx->computeResource,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+ }
+
+ /* Build path_computeResource */
+ if (virBufferUse(&buffer) > 0) {
+ virBufferAddChar(&buffer, '/');
+ }
+
+ virBufferAdd(&buffer, item, -1);
+
+ previousItem = item;
+ item = strtok_r(NULL, "/", &saveptr);
+ }
+
+ if (ctx->computeResource == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not find compute resource specified in '%s'"),
+ path);
+ goto cleanup;
+ }
+
+ if (ctx->computeResource->resourcePool == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not retrieve resource pool"));
+ goto cleanup;
+ }
+
+ if (virBufferError(&buffer)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ ctx->computeResourcePath = virBufferContentAndReset(&buffer);
+
+ /* Lookup HostSystem */
+ if (STREQ(ctx->computeResource->_reference->type,
+ "ClusterComputeResource")) {
+ if (item == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INVALID_ARG,
+ _("Path '%s' does not specify a host system"), path);
+ goto cleanup;
}
+
+ /* The path specified a cluster, it has to specify a host system too */
+ previousItem = item;
+ item = strtok_r(NULL, "/", &saveptr);
+ }
+
+ if (item != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INVALID_ARG,
+ _("Path '%s' ends with an excess item"), path);
+ goto cleanup;
}
- if (esxVI_LookupHostSystem(ctx, hostSystemName,
+ ctx->hostSystemName = strdup(previousItem);
+
+ if (ctx->hostSystemName == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (esxVI_LookupHostSystem(ctx, ctx->hostSystemName,
ctx->computeResource->_reference, NULL,
&ctx->hostSystem,
- esxVI_Occurrence_RequiredItem) < 0) {
- return -1;
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
}
- return 0;
+ if (ctx->hostSystem == NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not find host system specified in '%s'"), path);
+ goto cleanup;
+ }
+
+ result = 0;
+
+ cleanup:
+ if (result < 0) {
+ virBufferFreeAndReset(&buffer);
+ }
+
+ if (root != ctx->service->rootFolder &&
+ (ctx->datacenter == NULL || root != ctx->datacenter->hostFolder)) {
+ esxVI_ManagedObjectReference_Free(&root);
+ }
+
+ VIR_FREE(tmp);
+ esxVI_Folder_Free(&folder);
+
+ return result;
}
int
-esxVI_Context_LookupObjectsByHostSystemIp(esxVI_Context *ctx,
- const char *hostSystemIpAddress)
+esxVI_Context_LookupManagedObjectsByHostSystemIp(esxVI_Context *ctx,
+ const char *hostSystemIpAddress)
{
int result = -1;
esxVI_ManagedObjectReference *managedObjectReference = NULL;
@@ -1491,8 +1700,7 @@ esxVI_BuildSelectSetCollection(esxVI_Context *ctx)
/* Folder -> childEntity (ManagedEntity) */
if (esxVI_BuildSelectSet(&ctx->selectSet_folderToChildEntity,
"folderToChildEntity",
- "Folder", "childEntity",
- "folderToChildEntity\0") < 0) {
+ "Folder", "childEntity", NULL) < 0) {
return -1;
}
@@ -1689,9 +1897,10 @@ esxVI_LookupObjectContentByType(esxVI_Context *ctx,
objectSpec->obj = root;
objectSpec->skip = esxVI_Boolean_False;
- if (STRNEQ(root->type, type)) {
+ if (STRNEQ(root->type, type) || STREQ(root->type, "Folder")) {
if (STREQ(root->type, "Folder")) {
- if (STREQ(type, "Datacenter") || STREQ(type, "ComputeResource") ||
+ if (STREQ(type, "Folder") || STREQ(type, "Datacenter") ||
+ STREQ(type, "ComputeResource") ||
STREQ(type, "ClusterComputeResource")) {
objectSpec->selectSet = ctx->selectSet_folderToChildEntity;
} else {
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 0b3f889..78d3986 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -204,8 +204,11 @@ struct _esxVI_Context {
esxVI_UserSession *session; /* ... except the session ... */
virMutexPtr sessionLock; /* ... that is protected by this mutex */
esxVI_Datacenter *datacenter;
+ char *datacenterPath; /* including folders */
esxVI_ComputeResource *computeResource;
+ char *computeResourcePath; /* including folders */
esxVI_HostSystem *hostSystem;
+ char *hostSystemName;
esxVI_SelectionSpec *selectSet_folderToChildEntity;
esxVI_SelectionSpec *selectSet_hostSystemToParent;
esxVI_SelectionSpec *selectSet_hostSystemToVm;
@@ -221,10 +224,10 @@ void esxVI_Context_Free(esxVI_Context **ctx);
int esxVI_Context_Connect(esxVI_Context *ctx, const char *ipAddress,
const char *url, const char *username,
const char *password, esxUtil_ParsedUri *parsedUri);
-int esxVI_Context_LookupObjectsByPath(esxVI_Context *ctx,
- esxUtil_ParsedUri *parsedUri);
-int esxVI_Context_LookupObjectsByHostSystemIp(esxVI_Context *ctx,
- const char *hostSystemIpAddress);
+int esxVI_Context_LookupManagedObjects(esxVI_Context *ctx);
+int esxVI_Context_LookupManagedObjectsByPath(esxVI_Context *ctx, const char *path);
+int esxVI_Context_LookupManagedObjectsByHostSystemIp(esxVI_Context *ctx,
+ const char *hostSystemIpAddress);
int esxVI_Context_Execute(esxVI_Context *ctx, const char *methodName,
const char *request, esxVI_Response **response,
esxVI_Occurrence occurrence);
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index 361a6e7..1a67a8c 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -755,6 +755,10 @@ managed object Datacenter extends ManagedEntity
end
+managed object Folder extends ManagedEntity
+end
+
+
managed object HostSystem extends ManagedEntity
HostConfigManager configManager r
end
--
1.7.4.1
13 years
[libvirt] [PATCH] esx: Support vSphere 5.x
by Patrice LACHANCE
Hello
Based on http://www.redhat.com/archives/libvir-list/2010-July/msg00480.html,
I created this quick patch to accept connection to vSphere 5.x
Notes:
- I had to remove the warnings for version > 4.1 & 5 because they were
generating errors when running scripts encapsulating virsh commands with
opennebula. A better option might be to relie on an environment variable
(for example DONT_BLAME_LIBVIRT!) to toggle warnings on/off
- Ran only a few tests but it works as expected.
- Next steps should be to work on VMware API 5. integration
Patrice
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 41086ef..78872d4 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -730,9 +730,11 @@ esxConnectToHost(esxPrivate *priv, virConnectAuthPtr
auth,
if (priv->host->productVersion != esxVI_ProductVersion_ESX35 &&
priv->host->productVersion != esxVI_ProductVersion_ESX40 &&
priv->host->productVersion != esxVI_ProductVersion_ESX41 &&
- priv->host->productVersion != esxVI_ProductVersion_ESX4x) {
+ priv->host->productVersion != esxVI_ProductVersion_ESX4x &&
+ priv->host->productVersion != esxVI_ProductVersion_ESX50 &&
+ priv->host->productVersion != esxVI_ProductVersion_ESX5x) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("%s is neither an ESX 3.5 host nor an ESX 4.x
host"),
+ _("%s is neither an ESX 3.5, 4.x nor 5.x host"),
hostname);
goto cleanup;
}
@@ -857,10 +859,11 @@ esxConnectToVCenter(esxPrivate *priv,
virConnectAuthPtr auth,
if (priv->vCenter->productVersion != esxVI_ProductVersion_VPX25 &&
priv->vCenter->productVersion != esxVI_ProductVersion_VPX40 &&
priv->vCenter->productVersion != esxVI_ProductVersion_VPX41 &&
- priv->vCenter->productVersion != esxVI_ProductVersion_VPX4x) {
+ priv->vCenter->productVersion != esxVI_ProductVersion_VPX4x &&
+ priv->vCenter->productVersion != esxVI_ProductVersion_VPX50 &&
+ priv->vCenter->productVersion != esxVI_ProductVersion_VPX5x) {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("%s is neither a vCenter 2.5 server nor a vCenter "
- "4.x server"), hostname);
+ _("%s is neither a vCenter 2.5, 4.x nor 5.x server"),
hostname);
goto cleanup;
}
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 325157c..3a11116 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -675,9 +675,23 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char
*url,
VIR_WARN("Found untested VI API major/minor version '%s'",
ctx->service->about->apiVersion);
+ } else if (STRPREFIX(ctx->service->about->apiVersion, "5.0")) {
+ ctx->apiVersion = esxVI_APIVersion_50;
+
+ /*
+ VIR_WARN("Found untested VI API major/minor version '%s'",
+ ctx->service->about->apiVersion);
+ */
+ } else if (STRPREFIX(ctx->service->about->apiVersion, "5.")) {
+ ctx->apiVersion = esxVI_APIVersion_5x;
+
+ /*
+ VIR_WARN("Found untested VI API major/minor version '%s'",
+ ctx->service->about->apiVersion);
+ */
} else {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Expecting VI API major/minor version '2.5' or
'4.x' "
+ _("Expecting VI API major/minor version '2.5',
'4.x' or '5.x' "
"but found '%s'"),
ctx->service->about->apiVersion);
return -1;
}
@@ -704,10 +718,24 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char
*url,
VIR_WARN("Found untested ESX major/minor version '%s'",
ctx->service->about->version);
+ } else if (STRPREFIX(ctx->service->about->version, "5.0")) {
+ ctx->productVersion = esxVI_ProductVersion_ESX50;
+
+ /*
+ VIR_WARN("Found untested ESX major/minor version '%s'",
+ ctx->service->about->version);
+ */
+ } else if (STRPREFIX(ctx->service->about->version, "5.")) {
+ ctx->productVersion = esxVI_ProductVersion_ESX5x;
+
+ /*
+ VIR_WARN("Found untested ESX major/minor version '%s'",
+ ctx->service->about->version);
+ */
} else {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Expecting ESX major/minor version '3.5' or
"
- "'4.x' but found '%s'"),
+ _("Expecting ESX major/minor version '3.5',
'4.x' or "
+ "'5.x' but found '%s'"),
ctx->service->about->version);
return -1;
}
@@ -723,9 +751,23 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char
*url,
VIR_WARN("Found untested VPX major/minor version '%s'",
ctx->service->about->version);
+ } else if (STRPREFIX(ctx->service->about->version, "5.0")) {
+ ctx->productVersion = esxVI_ProductVersion_VPX50;
+
+ /*
+ VIR_WARN("Found untested VPX major/minor version '%s'",
+ ctx->service->about->version);
+ */
+ } else if (STRPREFIX(ctx->service->about->version, "5.")) {
+ ctx->productVersion = esxVI_ProductVersion_VPX5x;
+
+ /*
+ VIR_WARN("Found untested VPX major/minor version '%s'",
+ ctx->service->about->version);
+ */
} else {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
- _("Expecting VPX major/minor version '2.5' or
'4.x' "
+ _("Expecting VPX major/minor version '2.5',
'4.x' or '5.x' "
"but found '%s'"),
ctx->service->about->version);
return -1;
}
@@ -3919,6 +3961,12 @@
esxVI_ProductVersionToDefaultVirtualHWVersion(esxVI_ProductVersion
productVersio
case esxVI_ProductVersion_VPX4x:
return 7;
+ case esxVI_ProductVersion_ESX50:
+ case esxVI_ProductVersion_VPX50:
+ case esxVI_ProductVersion_ESX5x:
+ case esxVI_ProductVersion_VPX5x:
+ return 8;
+
default:
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unexpected product version"));
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index b8e921f..fbf3fb2 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -99,7 +99,9 @@ enum _esxVI_APIVersion {
esxVI_APIVersion_25,
esxVI_APIVersion_40,
esxVI_APIVersion_41,
- esxVI_APIVersion_4x /* > 4.1 */
+ esxVI_APIVersion_4x,
+ esxVI_APIVersion_50,
+ esxVI_APIVersion_5x /* > 5.0 */
};
/*
@@ -116,13 +118,17 @@ enum _esxVI_ProductVersion {
esxVI_ProductVersion_ESX35 = esxVI_ProductVersion_ESX | 1,
esxVI_ProductVersion_ESX40 = esxVI_ProductVersion_ESX | 2,
esxVI_ProductVersion_ESX41 = esxVI_ProductVersion_ESX | 3,
- esxVI_ProductVersion_ESX4x = esxVI_ProductVersion_ESX | 4, /* > 4.1 */
+ esxVI_ProductVersion_ESX4x = esxVI_ProductVersion_ESX | 4,
+ esxVI_ProductVersion_ESX50 = esxVI_ProductVersion_ESX | 5,
+ esxVI_ProductVersion_ESX5x = esxVI_ProductVersion_ESX | 6, /* > 5.0 */
esxVI_ProductVersion_VPX = (1 << 2) << 16,
esxVI_ProductVersion_VPX25 = esxVI_ProductVersion_VPX | 1,
esxVI_ProductVersion_VPX40 = esxVI_ProductVersion_VPX | 2,
esxVI_ProductVersion_VPX41 = esxVI_ProductVersion_VPX | 3,
- esxVI_ProductVersion_VPX4x = esxVI_ProductVersion_VPX | 4 /* > 4.1 */
+ esxVI_ProductVersion_VPX4x = esxVI_ProductVersion_VPX | 4,
+ esxVI_ProductVersion_VPX50 = esxVI_ProductVersion_VPX | 5,
+ esxVI_ProductVersion_VPX5x = esxVI_ProductVersion_VPX | 6 /* > 5.0 */
};
enum _esxVI_Occurrence {
13 years
[libvirt] [PATCH v3] Fix URI alias prefix matching
by Wen Ruo Lv
with /etc/libvirt/libvirt.conf below:
uri_aliases = [
"hail=qemu:///system",
"sleet=qemu+ssh://root 9 115 122 57/system",
"sam=qemu+unix:///system?socket=/var/run/libvirt/libvirt-sock",
]
Neither "virsh -c hailly" nor "hai" should result in matching "hail=qemu:///system"
Fix URI alias prefix matching when connecting
Signed-off-by: Wen Ruo Lv <lvroyce(a)linux.vnet.ibm.com>
---
src/libvirt.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index e9d1a29..6f8a76f 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -990,6 +990,8 @@ static int
virConnectOpenFindURIAliasMatch(virConfValuePtr value, const char *alias, char **uri)
{
virConfValuePtr entry;
+ size_t alias_len;
+
if (value->type != VIR_CONF_LIST) {
virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Expected a list for 'uri_aliases' config parameter"));
@@ -997,6 +999,7 @@ virConnectOpenFindURIAliasMatch(virConfValuePtr value, const char *alias, char *
}
entry = value->list;
+ alias_len = strlen(alias);
while (entry) {
char *offset;
size_t safe;
@@ -1022,7 +1025,8 @@ virConnectOpenFindURIAliasMatch(virConfValuePtr value, const char *alias, char *
return -1;
}
- if (STREQLEN(entry->str, alias, offset-entry->str)) {
+ if (alias_len == (offset - entry->str) &&
+ STREQLEN(entry->str, alias, alias_len)) {
VIR_DEBUG("Resolved alias '%s' to '%s'",
alias, offset+1);
if (!(*uri = strdup(offset+1))) {
--
1.7.4.1
13 years
Re: [libvirt] [libvirt-users] Error on the site
by Eric Blake
On 11/01/2011 01:15 AM, Alexander Biryukov wrote:
> Good afternoon.
> I apologize for my English.
>
> Error on page: http://libvirt.org/formatdomain.html
> To be more precise in the line "<target *def*='hdc' bus='ide'/>"
Thanks; I'm pushing this as the trivial fix:
diff --git i/docs/formatdomain.html.in w/docs/formatdomain.html.in
index 4fb5829..c3e7752 100644
--- i/docs/formatdomain.html.in
+++ w/docs/formatdomain.html.in
@@ -925,7 +925,7 @@
</disk>
<disk type='block' device='cdrom'>
<driver name='qemu' type='raw'/>
- <target def='hdc' bus='ide'/>
+ <target dev='hdc' bus='ide'/>
<readonly/>
</disk>
</devices>
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
13 years
[libvirt] [PATCH] Don't overwrite error message during VM cleanup
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
If an LXC VM fails to start, quite a few cleanup paths will
result in the original error message being overwritten. Some
other cleanup paths also forgot to actually terminate the VM.
* src/lxc/lxc_driver.c: Ensure VM is terminated on startup
failure and preserve original error
---
src/lxc/lxc_driver.c | 29 +++++++++++++++++++++--------
1 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 23efe1e..eabc1fb 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -1622,6 +1622,7 @@ static int lxcVmStart(virConnectPtr conn,
char *timestamp;
virCommandPtr cmd = NULL;
lxcDomainObjPrivatePtr priv = vm->privateData;
+ virErrorPtr err = NULL;
if (!lxc_driver->cgroup) {
lxcError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1753,8 +1754,7 @@ static int lxcVmStart(virConnectPtr conn,
_("guest failed to start: %s"), out);
}
- lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
- goto cleanup;
+ goto error;
}
if ((priv->monitorWatch = virEventAddHandle(
@@ -1762,31 +1762,33 @@ static int lxcVmStart(virConnectPtr conn,
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_HANGUP,
lxcMonitorEvent,
vm, NULL)) < 0) {
- lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
- goto cleanup;
+ goto error;
}
if (autoDestroy &&
lxcProcessAutoDestroyAdd(driver, vm, conn) < 0)
- goto cleanup;
+ goto error;
/*
* Again, need to save the live configuration, because the function
* requires vm->def->id != -1 to save tty info surely.
*/
if (virDomainSaveConfig(driver->stateDir, vm->def) < 0)
- goto cleanup;
+ goto error;
if (virDomainObjSetDefTransient(driver->caps, vm, false) < 0)
- goto cleanup;
+ goto error;
/* Write domain status to disk. */
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
- goto cleanup;
+ goto error;
rc = 0;
cleanup:
+ if (rc != 0 && !err)
+ err = virSaveLastError();
+ VIR_WARN("Cleanup %s" , err && err->message ? err->message : NULL);
virCommandFree(cmd);
if (VIR_CLOSE(logfd) < 0) {
virReportSystemError(errno, "%s", _("could not close logfile"));
@@ -1805,7 +1807,18 @@ cleanup:
VIR_FORCE_CLOSE(handshakefds[0]);
VIR_FORCE_CLOSE(handshakefds[1]);
VIR_FREE(logfile);
+
+ if (err) {
+ virSetError(err);
+ virResetError(err);
+ }
+
return rc;
+
+error:
+ err = virSaveLastError();
+ lxcVmTerminate(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED);
+ goto cleanup;
}
/**
--
1.7.6.4
13 years
[libvirt] [PATCH] Add support for probing filesystem with libblkid
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The LXC code for mounting container filesystems from block devices
tries all filesystems in /etc/filesystems and possibly those in
/proc/filesystems. The regular mount binary, however, first tries
using libblkid to detect the format. Add support for doing the same
in libvirt, since Fedora's /etc/filesystems is missing many formats,
most notably ext4 which is the default filesystem Fedora uses!
* src/Makefile.am: Link libvirt_lxc to libblkid
* src/lxc/lxc_container.c: Probe filesystem format with liblkid
---
src/Makefile.am | 4 ++
src/lxc/lxc_container.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 105 insertions(+), 1 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index c36664b..bf26b19 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1495,6 +1495,10 @@ libvirt_lxc_CFLAGS = \
$(AUDIT_CFLAGS) \
-I@top_srcdir@/src/conf \
$(AM_CFLAGS)
+if HAVE_LIBBLKID
+libvirt_lxc_CFLAGS += $(BLKID_CFLAGS)
+libvirt_lxc_LDADD += $(BLKID_LIBS)
+endif
endif
endif
EXTRA_DIST += $(LXC_CONTROLLER_SOURCES)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 36ac3a9..647aaea 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -47,6 +47,10 @@
# include <cap-ng.h>
#endif
+#if HAVE_LIBBLKID
+# include <blkid/blkid.h>
+#endif
+
#include "virterror_internal.h"
#include "logging.h"
#include "lxc_container.h"
@@ -627,6 +631,86 @@ cleanup:
}
+#ifdef HAVE_LIBBLKID
+static int
+lxcContainerMountDetectFilesystem(const char *src, char **type)
+{
+ int fd;
+ int ret = -1;
+ int rc;
+ const char *data = NULL;
+ blkid_probe blkid = NULL;
+
+ *type = NULL;
+
+ if ((fd = open(src, O_RDONLY)) < 0) {
+ virReportSystemError(errno,
+ _("Unable to open filesystem %s"), src);
+ return -1;
+ }
+
+ if (!(blkid = blkid_new_probe())) {
+ virReportSystemError(errno, "%s",
+ _("Unable to create blkid library handle"));
+ goto cleanup;
+ }
+ if (blkid_probe_set_device(blkid, fd, 0, 0) < 0) {
+ virReportSystemError(EINVAL,
+ _("Unable to associated device %s with blkid library"),
+ src);
+ goto cleanup;
+ }
+
+ blkid_probe_enable_superblocks(blkid, 1);
+
+ blkid_probe_set_superblocks_flags(blkid, BLKID_SUBLKS_TYPE);
+
+ rc = blkid_do_safeprobe(blkid);
+ if (rc != 0) {
+ if (rc == 1) /* Nothing found, return success with *type == NULL */
+ goto done;
+
+ if (rc == -2) {
+ virReportSystemError(EINVAL,
+ _("Too many filesystems detected for %s"),
+ src);
+ } else {
+ virReportSystemError(errno,
+ _("Unable to detect filesystem for %s"),
+ src);
+ }
+ goto cleanup;
+ }
+
+ if (blkid_probe_lookup_value(blkid, "TYPE", &data, NULL) < 0) {
+ virReportSystemError(ENOENT,
+ _("Unable to find filesystem type for %s"),
+ src);
+ goto cleanup;
+ }
+
+ if (!(*type = strdup(data))) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+done:
+ ret = 0;
+cleanup:
+ VIR_FORCE_CLOSE(fd);
+ blkid_free_probe(blkid);
+ return ret;
+}
+#else /* ! HAVE_LIBBLKID */
+static int
+lxcContainerMountDetectFilesystem(const char *src ATTRIBUTE_UNUSED,
+ char **type)
+{
+ /* No libblkid, so just return success with no detected type */
+ *type = NULL;
+ return 0;
+}
+#endif /* ! HAVE_LIBBLKID */
/*
* This functions attempts to do automatic detection of filesystem
@@ -771,6 +855,8 @@ static int lxcContainerMountFSBlockHelper(virDomainFSDefPtr fs,
{
int fsflags = 0;
int ret = -1;
+ char *format = NULL;
+
if (fs->readonly)
fsflags |= MS_RDONLY;
@@ -781,7 +867,21 @@ static int lxcContainerMountFSBlockHelper(virDomainFSDefPtr fs,
goto cleanup;
}
- ret = lxcContainerMountFSBlockAuto(fs, fsflags, src, srcprefix);
+ if (lxcContainerMountDetectFilesystem(src, &format) < 0)
+ goto cleanup;
+
+ if (format) {
+ VIR_DEBUG("Mount %s with detected format %s", src, format);
+ if (mount(src, fs->dst, format, fsflags, NULL) < 0) {
+ virReportSystemError(errno,
+ _("Failed to mount device %s to %s as %s"),
+ src, fs->dst, format);
+ goto cleanup;
+ }
+ ret = 0;
+ } else {
+ ret = lxcContainerMountFSBlockAuto(fs, fsflags, src, srcprefix);
+ }
cleanup:
return ret;
--
1.7.6.4
13 years
[libvirt] [PATCH] Fix error message when failing to detect filesystem
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
If we looped through /etc/filesystems trying to mount with each
type and failed all options, we forget to actually raise an
error message.
* src/lxc/lxc_container.c: Raise error if unable to detect
the filesystems. Also fix existing error message
---
src/lxc/lxc_container.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index fbd5267..36ac3a9 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -725,7 +725,7 @@ retry:
continue;
virReportSystemError(errno,
- _("Failed to bind mount directory %s to %s"),
+ _("Failed to mount device %s to %s"),
src, fs->dst);
goto cleanup;
}
@@ -746,6 +746,12 @@ retry:
goto retry;
}
+ if (ret != 0) {
+ virReportSystemError(ENODEV,
+ _("Failed to mount device %s to %s, unable to detect filesystem"),
+ src, fs->dst);
+ }
+
VIR_DEBUG("Done mounting filesystem ret=%d tryProc=%d", ret, tryProc);
cleanup:
--
1.7.6.4
13 years