[libvirt] [PATCH] esx: Use SessionIsActive when available
by Matthias Bolte
---
src/esx/esx_vi.c | 122 +++++++++++++++++++++++++++---------------------------
src/esx/esx_vi.h | 1 +
2 files changed, 62 insertions(+), 61 deletions(-)
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 78cfdfd..d361f01 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -464,6 +464,10 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
ctx->hasQueryVirtualDiskUuid = true;
}
+ if (ctx->productVersion & esxVI_ProductVersion_VPX) {
+ ctx->hasSessionIsActive = true;
+ }
+
if (esxVI_Login(ctx, username, password, NULL, &ctx->session) < 0 ||
esxVI_BuildSelectSetCollection(ctx) < 0) {
return -1;
@@ -1452,6 +1456,7 @@ esxVI_BuildSelectSet(esxVI_SelectionSpec **selectSet,
}
+
int
esxVI_BuildSelectSetCollection(esxVI_Context *ctx)
{
@@ -1533,97 +1538,92 @@ esxVI_BuildSelectSetCollection(esxVI_Context *ctx)
}
-/*
- * Can't use the SessionIsActive() function here, because at least
- * 'ESX Server 3.5.0 build-64607' returns an 'method not implemented' fault if
- * you try to call it. Query the session manager for the current session of
- * this connection instead and re-login if there is no current session for this
- * connection.
- *
- * Update: 'ESX 4.0.0 build-171294' doesn't implement this method.
- */
-#define ESX_VI_USE_SESSION_IS_ACTIVE 0
int
esxVI_EnsureSession(esxVI_Context *ctx)
{
-#if ESX_VI_USE_SESSION_IS_ACTIVE
- esxVI_Boolean active = esxVI_Boolean_Undefined;
-#else
int result = -1;
+ esxVI_Boolean active = esxVI_Boolean_Undefined;
esxVI_String *propertyNameList = NULL;
esxVI_ObjectContent *sessionManager = NULL;
esxVI_DynamicProperty *dynamicProperty = NULL;
esxVI_UserSession *currentSession = NULL;
-#endif
if (ctx->session == NULL) {
ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid call"));
return -1;
}
-#if ESX_VI_USE_SESSION_IS_ACTIVE
- if (esxVI_SessionIsActive(ctx, ctx->session->key, ctx->session->userName,
- &active) < 0) {
- return -1;
- }
-
- if (active != esxVI_Boolean_True) {
- esxVI_UserSession_Free(&ctx->session);
-
- if (esxVI_Login(ctx, ctx->username, ctx->password, NULL,
- &ctx->session) < 0) {
+ if (ctx->hasSessionIsActive) {
+ /*
+ * Use SessionIsActive to check if there is an active session for this
+ * connection an re-login in there isn't.
+ */
+ if (esxVI_SessionIsActive(ctx, ctx->session->key,
+ ctx->session->userName, &active) < 0) {
return -1;
}
- }
- return 0;
-#else
- if (esxVI_String_AppendValueToList(&propertyNameList,
- "currentSession") < 0 ||
- esxVI_LookupObjectContentByType(ctx, ctx->service->sessionManager,
- "SessionManager", propertyNameList,
- &sessionManager) < 0) {
- goto cleanup;
- }
+ if (active != esxVI_Boolean_True) {
+ esxVI_UserSession_Free(&ctx->session);
- for (dynamicProperty = sessionManager->propSet; dynamicProperty != NULL;
- dynamicProperty = dynamicProperty->_next) {
- if (STREQ(dynamicProperty->name, "currentSession")) {
- if (esxVI_UserSession_CastFromAnyType(dynamicProperty->val,
- ¤tSession) < 0) {
- goto cleanup;
+ if (esxVI_Login(ctx, ctx->username, ctx->password, NULL,
+ &ctx->session) < 0) {
+ return -1;
}
+ }
- break;
- } else {
- VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+ return 0;
+ } else {
+ /*
+ * Query the session manager for the current session of this connection
+ * and re-login if there is no current session for this connection.
+ */
+ if (esxVI_String_AppendValueToList(&propertyNameList,
+ "currentSession") < 0 ||
+ esxVI_LookupObjectContentByType(ctx, ctx->service->sessionManager,
+ "SessionManager", propertyNameList,
+ &sessionManager) < 0) {
+ goto cleanup;
+ }
+
+ for (dynamicProperty = sessionManager->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "currentSession")) {
+ if (esxVI_UserSession_CastFromAnyType(dynamicProperty->val,
+ ¤tSession) < 0) {
+ goto cleanup;
+ }
+
+ break;
+ } else {
+ VIR_WARN("Unexpected '%s' property", dynamicProperty->name);
+ }
}
- }
- if (currentSession == NULL) {
- esxVI_UserSession_Free(&ctx->session);
+ if (currentSession == NULL) {
+ esxVI_UserSession_Free(&ctx->session);
- if (esxVI_Login(ctx, ctx->username, ctx->password, NULL,
- &ctx->session) < 0) {
+ if (esxVI_Login(ctx, ctx->username, ctx->password, NULL,
+ &ctx->session) < 0) {
+ goto cleanup;
+ }
+ } else if (STRNEQ(ctx->session->key, currentSession->key)) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Key of the current session differs from the key at "
+ "last login"));
goto cleanup;
}
- } else if (STRNEQ(ctx->session->key, currentSession->key)) {
- ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Key of the current session differs from the key at "
- "last login"));
- goto cleanup;
- }
- result = 0;
+ result = 0;
cleanup:
- esxVI_String_Free(&propertyNameList);
- esxVI_ObjectContent_Free(&sessionManager);
- esxVI_UserSession_Free(¤tSession);
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&sessionManager);
+ esxVI_UserSession_Free(¤tSession);
- return result;
-#endif
+ return result;
+ }
}
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index b205b8c..aa47e87 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -168,6 +168,7 @@ struct _esxVI_Context {
esxVI_SelectionSpec *selectSet_computeResourceToHost;
esxVI_SelectionSpec *selectSet_computeResourceToParentToParent;
bool hasQueryVirtualDiskUuid;
+ bool hasSessionIsActive;
};
int esxVI_Context_Alloc(esxVI_Context **ctx);
--
1.7.0.4
14 years, 7 months
[libvirt] [PATCH] esx: Fall back to path as key when QueryVirtualDiskUuid isn't available
by Matthias Bolte
QueryVirtualDiskUuid is only available on an ESX(i) server. vCenter
returns an NotImplemented fault and a GSX server is missing the
VirtualDiskManager completely. Therefore only use QueryVirtualDiskUuid
with an ESX(i) server and fall back to path as storage volume key for
vCenter and GSX server.
---
src/esx/esx_storage_driver.c | 36 +++++++++++++++++++++++------
src/esx/esx_vi.c | 50 +++++++++++++++++++++++++++--------------
src/esx/esx_vi.h | 1 +
3 files changed, 62 insertions(+), 25 deletions(-)
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index 76f8769..329020b 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -783,6 +783,13 @@ esxStorageVolumeLookupByKey(virConnectPtr conn, const char *key)
return esxStorageVolumeLookupByPath(conn, key);
}
+ if (!priv->primary->hasQueryVirtualDiskUuid) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("QueryVirtualDiskUuid not avialable, cannot lookup storage "
+ "volume by UUID"));
+ return NULL;
+ }
+
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
@@ -916,7 +923,7 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
char *uuid_string = NULL;
- char key[VIR_UUID_STRING_BUFLEN] = "";
+ char *key = NULL;
virCheckFlags(0, NULL);
@@ -1068,14 +1075,26 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
goto cleanup;
}
- if (esxVI_QueryVirtualDiskUuid(priv->primary, datastorePath,
- priv->primary->datacenter->_reference,
- &uuid_string) < 0) {
- goto cleanup;
- }
+ if (priv->primary->hasQueryVirtualDiskUuid) {
+ if (VIR_ALLOC_N(key, VIR_UUID_STRING_BUFLEN) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
- if (esxUtil_ReformatUuid(uuid_string, key) < 0) {
- goto cleanup;
+ if (esxVI_QueryVirtualDiskUuid(priv->primary, datastorePath,
+ priv->primary->datacenter->_reference,
+ &uuid_string) < 0) {
+ goto cleanup;
+ }
+
+ if (esxUtil_ReformatUuid(uuid_string, key) < 0) {
+ goto cleanup;
+ }
+ } else {
+ /* Fall back to the path as key */
+ if (esxVI_String_DeepCopyValue(&key, datastorePath) < 0) {
+ goto cleanup;
+ }
}
} else {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
@@ -1103,6 +1122,7 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
esxVI_FileBackedVirtualDiskSpec_Free(&virtualDiskSpec);
esxVI_ManagedObjectReference_Free(&task);
VIR_FREE(uuid_string);
+ VIR_FREE(key);
return volume;
}
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 00e15f0..78cfdfd 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -453,6 +453,17 @@ esxVI_Context_Connect(esxVI_Context *ctx, const char *url,
return -1;
}
+ if (ctx->productVersion & esxVI_ProductVersion_ESX) {
+ /*
+ * FIXME: Actually this should be detected by really calling
+ * QueryVirtualDiskUuid and checking if a NotImplemented fault is
+ * returned. But currently we don't deserialized the details of a
+ * possbile fault and therefore we don't know if the fault was a
+ * NotImplemented fault or not.
+ */
+ ctx->hasQueryVirtualDiskUuid = true;
+ }
+
if (esxVI_Login(ctx, username, password, NULL, &ctx->session) < 0 ||
esxVI_BuildSelectSetCollection(ctx) < 0) {
return -1;
@@ -3267,28 +3278,33 @@ esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx,
return -1;
}
- if (esxVI_LookupFileInfoByDatastorePath(ctx, datastorePath, false, &fileInfo,
- esxVI_Occurrence_RequiredItem) < 0) {
- goto cleanup;
- }
-
- if (esxVI_VmDiskFileInfo_DynamicCast(fileInfo) != NULL) {
- /* VirtualDisks have a UUID, use it as key */
- if (esxVI_QueryVirtualDiskUuid(ctx, datastorePath,
- ctx->datacenter->_reference,
- &uuid_string) < 0) {
+ if (ctx->hasQueryVirtualDiskUuid) {
+ if (esxVI_LookupFileInfoByDatastorePath
+ (ctx, datastorePath, false, &fileInfo,
+ esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
- if (VIR_ALLOC_N(*key, VIR_UUID_STRING_BUFLEN) < 0) {
- virReportOOMError();
- goto cleanup;
- }
+ if (esxVI_VmDiskFileInfo_DynamicCast(fileInfo) != NULL) {
+ /* VirtualDisks have a UUID, use it as key */
+ if (esxVI_QueryVirtualDiskUuid(ctx, datastorePath,
+ ctx->datacenter->_reference,
+ &uuid_string) < 0) {
+ goto cleanup;
+ }
- if (esxUtil_ReformatUuid(uuid_string, *key) < 0) {
- goto cleanup;
+ if (VIR_ALLOC_N(*key, VIR_UUID_STRING_BUFLEN) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (esxUtil_ReformatUuid(uuid_string, *key) < 0) {
+ goto cleanup;
+ }
}
- } else {
+ }
+
+ if (*key == NULL) {
/* Other files don't have a UUID, fall back to the path as key */
if (esxVI_String_DeepCopyValue(key, datastorePath) < 0) {
goto cleanup;
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index bd37b05..b205b8c 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -167,6 +167,7 @@ struct _esxVI_Context {
esxVI_SelectionSpec *selectSet_hostSystemToDatastore;
esxVI_SelectionSpec *selectSet_computeResourceToHost;
esxVI_SelectionSpec *selectSet_computeResourceToParentToParent;
+ bool hasQueryVirtualDiskUuid;
};
int esxVI_Context_Alloc(esxVI_Context **ctx);
--
1.7.0.4
14 years, 7 months
[libvirt] [PATCH] mingw: match recent changes in spec file
by Eric Blake
These changes allow './autobuild.sh' to complete again, when a full
mingw cross-compilation is available on Fedora.
* libvirt.spec.in (%file): List new installed files.
* configure.ac (with_init_script): Assume default of none when
cross-compiling.
---
configure.ac | 6 +++---
mingw32-libvirt.spec.in | 5 +++++
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index d42d9e6..6c0fc69 100644
--- a/configure.ac
+++ b/configure.ac
@@ -276,10 +276,10 @@ AC_ARG_WITH([init-script],
[AC_HELP_STRING([--with-init-script=@<:@redhat|auto|none@:>@],
[Style of init script to install @<:@default=auto@:>@])])
if test "x$with_init_script" = "x" || test "x$with_init_script" = "xauto"; then
- if test -f /etc/redhat-release ; then
- with_init_script=redhat
- else
+ if test "$cross_compiling" = yes || test ! -f /etc/redhat-release; then
with_init_script=none
+ else
+ with_init_script=redhat
fi
fi
AM_CONDITIONAL([LIBVIRT_INIT_SCRIPT_RED_HAT], test x$with_init_script = xredhat)
diff --git a/mingw32-libvirt.spec.in b/mingw32-libvirt.spec.in
index 6b2b5c6..4bbbc3b 100644
--- a/mingw32-libvirt.spec.in
+++ b/mingw32-libvirt.spec.in
@@ -71,6 +71,7 @@ rm -rf $RPM_BUILD_ROOT%{_mingw32_datadir}/doc/*
rm -rf $RPM_BUILD_ROOT%{_mingw32_datadir}/gtk-doc/*
rm $RPM_BUILD_ROOT%{_mingw32_libdir}/libvirt.a
+rm $RPM_BUILD_ROOT%{_mingw32_libdir}/libvirt-qemu.a
%clean
@@ -83,10 +84,13 @@ rm -rf $RPM_BUILD_ROOT
%{_mingw32_bindir}/virsh.exe
%{_mingw32_bindir}/virt-xml-validate
%{_mingw32_bindir}/virt-pki-validate
+%{_mingw32_bindir}/libvirt-qemu-0.dll
%{_mingw32_libdir}/libvirt.dll.a
%{_mingw32_libdir}/libvirt.la
%{_mingw32_libdir}/pkgconfig/libvirt.pc
+%{_mingw32_libdir}/libvirt-qemu.dll.a
+%{_mingw32_libdir}/libvirt-qemu.la
%dir %{_mingw32_datadir}/libvirt/
%dir %{_mingw32_datadir}/libvirt/schemas/
@@ -109,6 +113,7 @@ rm -rf $RPM_BUILD_ROOT
%dir %{_mingw32_includedir}/libvirt
%{_mingw32_includedir}/libvirt/libvirt.h
%{_mingw32_includedir}/libvirt/virterror.h
+%{_mingw32_includedir}/libvirt/libvirt-qemu.h
%{_mingw32_mandir}/man1/virsh.1*
%{_mingw32_mandir}/man1/virt-xml-validate.1*
--
1.7.2.2
14 years, 7 months
Re: [libvirt] ruby-libvirt / rubygems
by Chris Lalancette
On 09/03/10 - 09:23:48PM, Roland Moriz wrote:
> Hello Chris,
>
> could you publish the updated ruby-libvirt bindings to rubygems.org?
> There is still only version 0.1.0 of 2008 available:
>
> http://rubygems.org/gems/ruby-libvirt
>
> Thank you!
Hello,
I'd be happy to update the gem on rubygems.org. Unfortunately I don't
have permission to do so, so I can't right at the moment. I've written to
the previous maintainer of ruby-libvirt to see if he can give me access to
update the gems there. As soon as I get that access, I'll push a new version
of the gem and let you know.
Thanks,
--
Chris Lalancette
14 years, 7 months
[libvirt] [PATCH] build: Fix permissions of sysconfig files
by Jiri Denemark
---
daemon/Makefile.am | 2 +-
libvirt.spec.in | 4 ----
tools/Makefile.am | 2 +-
3 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 53133d2..45c30a9 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -261,7 +261,7 @@ install-init: libvirtd.init
$(INSTALL_SCRIPT) libvirtd.init \
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirtd
mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig
- $(INSTALL_SCRIPT) $(srcdir)/libvirtd.sysconf \
+ $(INSTALL_DATA) $(srcdir)/libvirtd.sysconf \
$(DESTDIR)$(sysconfdir)/sysconfig/libvirtd
uninstall-init:
diff --git a/libvirt.spec.in b/libvirt.spec.in
index e530b1a..3cb38cc 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -646,10 +646,6 @@ rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.lxc
rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.uml
%endif
-%if %{with_libvirtd}
-chmod 0644 $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/libvirtd
-%endif
-
%clean
rm -fr %{buildroot}
diff --git a/tools/Makefile.am b/tools/Makefile.am
index ac26cae..bfe4455 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -134,7 +134,7 @@ install-init: libvirt-guests.init
$(INSTALL_SCRIPT) libvirt-guests.init \
$(DESTDIR)$(sysconfdir)/rc.d/init.d/libvirt-guests
mkdir -p $(DESTDIR)$(sysconfdir)/sysconfig
- $(INSTALL_SCRIPT) $(srcdir)/libvirt-guests.sysconf \
+ $(INSTALL_DATA) $(srcdir)/libvirt-guests.sysconf \
$(DESTDIR)$(sysconfdir)/sysconfig/libvirt-guests
uninstall-init:
--
1.7.2.2
14 years, 7 months
Re: [libvirt] virt-top version bump in EPEL5
by Richard W.M. Jones
On Mon, Sep 06, 2010 at 05:46:03PM +0200, Wolfram Schlich wrote:
> * Richard W.M. Jones <rjones(a)redhat.com> [2010-09-06 17:23]:
> > On Mon, Sep 06, 2010 at 05:06:55PM +0200, Wolfram Schlich wrote:
> > > We are experiencing a problem with virt-top on our RHEL5 virthosts.
> > >
> > > On a heavily loaded virthost, virt-top is damn slow -- it takes 4-5s
> > > to update and imposes a noticeable load on the dom0 as well
> > > (xenstored shows up in top eating all CPU for some seconds).
> > > xentop seems to impose *much* less load on the dom0.
> > > Is there something I can do about it?
> > >
> > > Another problem: 0.3.3.1 shows RDRQ/WRRQ/RXBY/TXBY after some seconds
> > > whereas 1.0.4 does not...?
> >
> > I bet both of these will be libvirt issues.
> >
> > Try running:
> >
> > virsh list --all
>
> Takes around 2-4s depending on dom0 load.
CC-ing to libvir-list. There may be a better way now for virt-top to
get the list of domains, but if 'virsh list --all' is also slow, then
it's probably a generic libvirt problem.
> > virsh domblkstat DomainName hda
>
> s/hda/xvda/ I guess :)
> This one is quite fast, below 0.2s.
>
> > virsh domifstat DomainName vnet0
>
> This takes around 0.1s most of the time, but sometimes around 1.0s.
>
> > etc.
> >
> > If those commands (done in a suitable loop) also cause load on the
> > dom0, and if domblkstat/domifstat don't show stats, then it's down to
> > libvirt.
> >
> > virt-top is a simple little program that just exercises those libvirt
> > APIs ...
>
> Hmm :/ So I guess we're better off with xentop...
We should be able to have performance very close to xentop. After
all, libvirt makes exactly the same direct hypervisor calls.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming blog: http://rwmj.wordpress.com
Fedora now supports 80 OCaml packages (the OPEN alternative to F#)
http://cocan.org/getting_started_with_ocaml_on_red_hat_and_fedora
14 years, 7 months
[libvirt] [PATCH] Default to qemu:///system if accessible
by Soren Hansen
If no uri is passed to one of the virConnectOpen-ish calls, libvirt
attempts to autoprobe a sensible URI. Part of the current logic checks
for getuid() > 0, and if that check is succesful, a libvirtd daemon is
spawned. This patch replaces this check with a call to
access(LIBVIRTD_PRIV_UNIX_SOCKET, W_OK) so that users with access to the
qemu:///system UNIX socket connect to that one by default instead of
spawning a new libvirtd daemon.
Signed-off-by: Soren Hansen <soren(a)linux2go.dk>
---
src/remote/remote_driver.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index a945710..17e6ead 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1086,7 +1086,7 @@ remoteOpen (virConnectPtr conn,
if (!conn->uri) {
DEBUG0("Auto-probe remote URI");
#ifndef __sun
- if (getuid() > 0) {
+ if (access(LIBVIRTD_PRIV_UNIX_SOCKET, W_OK)) {
DEBUG0("Auto-spawn user daemon instance");
rflags |= VIR_DRV_OPEN_REMOTE_USER;
if (!autostart ||
--
1.7.1
14 years, 7 months
[libvirt] [PATCH] esx: Use the VirtualDisk UUID as storage volume key
by Matthias Bolte
VirtualDisks are .vmdk file based. Other files in a datastore
like .iso or .flp files don't have a UUID attached, fall back
to the path as key for them.
---
src/esx/esx_storage_driver.c | 190 ++++++++++++++++++++++++++++++++++++----
src/esx/esx_util.c | 19 ++++
src/esx/esx_util.h | 2 +
src/esx/esx_vi.c | 53 +++++++++++
src/esx/esx_vi.h | 4 +
src/esx/esx_vi_generator.input | 7 ++
6 files changed, 256 insertions(+), 19 deletions(-)
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index 3b959c2..a9a5633 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -697,7 +697,7 @@ esxStorageVolumeLookupByName(virStoragePoolPtr pool, const char *name)
virStorageVolPtr volume = NULL;
esxPrivate *priv = pool->conn->storagePrivateData;
char *datastorePath = NULL;
- esxVI_FileInfo *fileInfo = NULL;
+ char *key = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
@@ -708,17 +708,16 @@ esxStorageVolumeLookupByName(virStoragePoolPtr pool, const char *name)
goto cleanup;
}
- if (esxVI_LookupFileInfoByDatastorePath(priv->primary, datastorePath,
- false, &fileInfo,
- esxVI_Occurrence_RequiredItem) < 0) {
+ if (esxVI_LookupStorageVolumeKeyByDatastorePath(priv->primary,
+ datastorePath, &key) < 0) {
goto cleanup;
}
- volume = virGetStorageVol(pool->conn, pool->name, name, datastorePath);
+ volume = virGetStorageVol(pool->conn, pool->name, name, key);
cleanup:
VIR_FREE(datastorePath);
- esxVI_FileInfo_Free(&fileInfo);
+ VIR_FREE(key);
return volume;
}
@@ -726,36 +725,170 @@ esxStorageVolumeLookupByName(virStoragePoolPtr pool, const char *name)
static virStorageVolPtr
-esxStorageVolumeLookupByKeyOrPath(virConnectPtr conn, const char *keyOrPath)
+esxStorageVolumeLookupByPath(virConnectPtr conn, const char *path)
{
virStorageVolPtr volume = NULL;
esxPrivate *priv = conn->storagePrivateData;
char *datastoreName = NULL;
char *directoryAndFileName = NULL;
- esxVI_FileInfo *fileInfo = NULL;
+ char *key = NULL;
if (esxVI_EnsureSession(priv->primary) < 0) {
return NULL;
}
- if (esxUtil_ParseDatastorePath(keyOrPath, &datastoreName, NULL,
+ if (esxUtil_ParseDatastorePath(path, &datastoreName, NULL,
&directoryAndFileName) < 0) {
goto cleanup;
}
- if (esxVI_LookupFileInfoByDatastorePath(priv->primary, keyOrPath,
- false, &fileInfo,
- esxVI_Occurrence_RequiredItem) < 0) {
+ if (esxVI_LookupStorageVolumeKeyByDatastorePath(priv->primary, path,
+ &key) < 0) {
goto cleanup;
}
- volume = virGetStorageVol(conn, datastoreName, directoryAndFileName,
- keyOrPath);
+ volume = virGetStorageVol(conn, datastoreName, directoryAndFileName, key);
cleanup:
VIR_FREE(datastoreName);
VIR_FREE(directoryAndFileName);
- esxVI_FileInfo_Free(&fileInfo);
+ VIR_FREE(key);
+
+ return volume;
+}
+
+
+
+static virStorageVolPtr
+esxStorageVolumeLookupByKey(virConnectPtr conn, const char *key)
+{
+ virStorageVolPtr volume = NULL;
+ esxPrivate *priv = conn->storagePrivateData;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *datastoreList = NULL;
+ esxVI_ObjectContent *datastore = NULL;
+ char *datastoreName = NULL;
+ esxVI_HostDatastoreBrowserSearchResults *searchResultsList = NULL;
+ esxVI_HostDatastoreBrowserSearchResults *searchResults = NULL;
+ char *directoryAndFileName = NULL;
+ size_t length;
+ char *datastorePath = NULL;
+ char *volumeName = NULL;
+ esxVI_FileInfo *fileInfo = NULL;
+ char *uuid_string = NULL;
+ char key_candidate[VIR_UUID_STRING_BUFLEN] = "";
+
+ if (STRPREFIX(key, "[")) {
+ /* Key is probably a datastore path */
+ return esxStorageVolumeLookupByPath(conn, key);
+ }
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return NULL;
+ }
+
+ /* Lookup all datastores */
+ if (esxVI_String_AppendValueToList(&propertyNameList, "summary.name") < 0 ||
+ esxVI_LookupDatastoreList(priv->primary, propertyNameList,
+ &datastoreList) < 0) {
+ goto cleanup;
+ }
+
+ for (datastore = datastoreList; datastore != NULL;
+ datastore = datastore->_next) {
+ datastoreName = NULL;
+
+ if (esxVI_GetStringValue(datastore, "summary.name", &datastoreName,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto cleanup;
+ }
+
+ /* Lookup datastore content */
+ esxVI_HostDatastoreBrowserSearchResults_Free(&searchResultsList);
+
+ if (esxVI_LookupDatastoreContentByDatastoreName
+ (priv->primary, datastoreName, &searchResultsList) < 0) {
+ goto cleanup;
+ }
+
+ /* Interpret search result */
+ for (searchResults = searchResultsList; searchResults != NULL;
+ searchResults = searchResults->_next) {
+ VIR_FREE(directoryAndFileName);
+
+ if (esxUtil_ParseDatastorePath(searchResults->folderPath, NULL,
+ NULL, &directoryAndFileName) < 0) {
+ goto cleanup;
+ }
+
+ /* Strip trailing separators */
+ length = strlen(directoryAndFileName);
+
+ while (length > 0 && directoryAndFileName[length - 1] == '/') {
+ directoryAndFileName[length - 1] = '\0';
+ --length;
+ }
+
+ /* Build datastore path and query the UUID */
+ for (fileInfo = searchResults->file; fileInfo != NULL;
+ fileInfo = fileInfo->_next) {
+ VIR_FREE(datastorePath);
+
+ if (length < 1) {
+ if (virAsprintf(&volumeName, "%s",
+ fileInfo->path) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ } else if (virAsprintf(&volumeName, "%s/%s",
+ directoryAndFileName,
+ fileInfo->path) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (virAsprintf(&datastorePath, "[%s] %s", datastoreName,
+ volumeName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (esxVI_VmDiskFileInfo_DynamicCast(fileInfo) == NULL) {
+ /* Only a VirtualDisk has a UUID */
+ continue;
+ }
+
+ VIR_FREE(uuid_string);
+
+ if (esxVI_QueryVirtualDiskUuid
+ (priv->primary, datastorePath,
+ priv->primary->datacenter->_reference,
+ &uuid_string) < 0) {
+ goto cleanup;
+ }
+
+ if (esxUtil_ReformatUuid(uuid_string, key_candidate) < 0) {
+ goto cleanup;
+ }
+
+ if (STREQ(key, key_candidate)) {
+ /* Found matching UUID */
+ volume = virGetStorageVol(conn, datastoreName,
+ volumeName, key);
+ goto cleanup;
+ }
+ }
+ }
+ }
+
+ cleanup:
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&datastoreList);
+ esxVI_HostDatastoreBrowserSearchResults_Free(&searchResultsList);
+ VIR_FREE(directoryAndFileName);
+ VIR_FREE(datastorePath);
+ VIR_FREE(volumeName);
+ VIR_FREE(uuid_string);
return volume;
}
@@ -783,6 +916,8 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
esxVI_FileBackedVirtualDiskSpec *virtualDiskSpec = NULL;
esxVI_ManagedObjectReference *task = NULL;
esxVI_TaskInfoState taskInfoState;
+ char *uuid_string = NULL;
+ char key[VIR_UUID_STRING_BUFLEN] = "";
virCheckFlags(0, NULL);
@@ -935,6 +1070,16 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create volume"));
goto cleanup;
}
+
+ if (esxVI_QueryVirtualDiskUuid(priv->primary, datastorePath,
+ priv->primary->datacenter->_reference,
+ &uuid_string) < 0) {
+ goto cleanup;
+ }
+
+ if (esxUtil_ReformatUuid(uuid_string, key) < 0) {
+ goto cleanup;
+ }
} else {
ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
_("Creation of %s volumes is not supported"),
@@ -942,7 +1087,7 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
goto cleanup;
}
- volume = virGetStorageVol(pool->conn, pool->name, def->name, datastorePath);
+ volume = virGetStorageVol(pool->conn, pool->name, def->name, key);
cleanup:
if (virtualDiskSpec != NULL) {
@@ -960,6 +1105,7 @@ esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
esxVI_FileInfo_Free(&fileInfo);
esxVI_FileBackedVirtualDiskSpec_Free(&virtualDiskSpec);
esxVI_ManagedObjectReference_Free(&task);
+ VIR_FREE(uuid_string);
return volume;
}
@@ -1090,7 +1236,12 @@ esxStorageVolumeDumpXML(virStorageVolPtr volume, unsigned int flags)
floppyImageFileInfo = esxVI_FloppyImageFileInfo_DynamicCast(fileInfo);
def.name = volume->name;
- def.key = datastorePath;
+
+ if (esxVI_LookupStorageVolumeKeyByDatastorePath(priv->primary, datastorePath,
+ &def.key) < 0) {
+ goto cleanup;
+ }
+
def.type = VIR_STORAGE_VOL_FILE;
def.target.path = datastorePath;
@@ -1123,6 +1274,7 @@ esxStorageVolumeDumpXML(virStorageVolPtr volume, unsigned int flags)
esxVI_DatastoreInfo_Free(&datastoreInfo);
VIR_FREE(datastorePath);
esxVI_FileInfo_Free(&fileInfo);
+ VIR_FREE(def.key);
return xml;
}
@@ -1189,8 +1341,8 @@ static virStorageDriver esxStorageDriver = {
esxStoragePoolNumberOfStorageVolumes, /* poolNumOfVolumes */
esxStoragePoolListStorageVolumes, /* poolListVolumes */
esxStorageVolumeLookupByName, /* volLookupByName */
- esxStorageVolumeLookupByKeyOrPath, /* volLookupByKey */
- esxStorageVolumeLookupByKeyOrPath, /* volLookupByPath */
+ esxStorageVolumeLookupByKey, /* volLookupByKey */
+ esxStorageVolumeLookupByPath, /* volLookupByPath */
esxStorageVolumeCreateXML, /* volCreateXML */
NULL, /* volCreateXMLFrom */
NULL, /* volDelete */
diff --git a/src/esx/esx_util.c b/src/esx/esx_util.c
index 08c6c46..99cc4f6 100644
--- a/src/esx/esx_util.c
+++ b/src/esx/esx_util.c
@@ -602,3 +602,22 @@ esxUtil_GetConfigBoolean(virConfPtr conf, const char *name, bool *boolean_,
return 0;
}
+
+
+
+int
+esxUtil_ReformatUuid(const char *input, char *output)
+{
+ unsigned char uuid[VIR_UUID_BUFLEN];
+
+ if (virUUIDParse(input, uuid) < 0) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Could not parse UUID from string '%s'"),
+ input);
+ return -1;
+ }
+
+ virUUIDFormat(uuid, output);
+
+ return 0;
+}
diff --git a/src/esx/esx_util.h b/src/esx/esx_util.h
index 4d92333..650f145 100644
--- a/src/esx/esx_util.h
+++ b/src/esx/esx_util.h
@@ -69,4 +69,6 @@ int esxUtil_GetConfigLong(virConfPtr conf, const char *name, long long *number,
int esxUtil_GetConfigBoolean(virConfPtr conf, const char *name, bool *boolean_,
bool default_, bool optional);
+int esxUtil_ReformatUuid(const char *input, char *output);
+
#endif /* __ESX_UTIL_H__ */
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 8d83eac..fb2a499 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -3254,6 +3254,59 @@ esxVI_LookupDatastoreContentByDatastoreName
int
+esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx,
+ const char *datastorePath,
+ char **key)
+{
+ int result = -1;
+ esxVI_FileInfo *fileInfo = NULL;
+ char *uuid_string = NULL;
+
+ if (key == NULL || *key != NULL) {
+ ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+ return -1;
+ }
+
+ if (esxVI_LookupFileInfoByDatastorePath(ctx, datastorePath, false, &fileInfo,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto cleanup;
+ }
+
+ if (esxVI_VmDiskFileInfo_DynamicCast(fileInfo) != NULL) {
+ /* VirtualDisks have a UUID, use it as key */
+ if (esxVI_QueryVirtualDiskUuid(ctx, datastorePath,
+ ctx->datacenter->_reference,
+ &uuid_string) < 0) {
+ goto cleanup;
+ }
+
+ if (VIR_ALLOC_N(*key, VIR_UUID_STRING_BUFLEN) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (esxUtil_ReformatUuid(uuid_string, *key) < 0) {
+ goto cleanup;
+ }
+ } else {
+ /* Other files don't have a UUID, fall back to the path as key */
+ if (esxVI_String_DeepCopyValue(key, datastorePath) < 0) {
+ goto cleanup;
+ }
+ }
+
+ result = 0;
+
+ cleanup:
+ esxVI_FileInfo_Free(&fileInfo);
+ VIR_FREE(uuid_string);
+
+ return result;
+}
+
+
+
+int
esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx, esxVI_ManagedObjectReference *virtualMachine,
esxVI_VirtualMachineQuestionInfo *questionInfo,
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 773a1c6..bd37b05 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -409,6 +409,10 @@ int esxVI_LookupDatastoreContentByDatastoreName
(esxVI_Context *ctx, const char *datastoreName,
esxVI_HostDatastoreBrowserSearchResults **searchResultsList);
+int esxVI_LookupStorageVolumeKeyByDatastorePath(esxVI_Context *ctx,
+ const char *datastorePath,
+ char **key);
+
int esxVI_HandleVirtualMachineQuestion
(esxVI_Context *ctx,
esxVI_ManagedObjectReference *virtualMachine,
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index b911c22..2ee513a 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -801,6 +801,13 @@ method QueryPerfCounter returns PerfCounterInfo ol
end
+method QueryVirtualDiskUuid returns String r
+ ManagedObjectReference _this:VirtualDiskManager r
+ String name r
+ ManagedObjectReference datacenter o
+end
+
+
method RebootGuest
ManagedObjectReference _this r
end
--
1.7.0.4
14 years, 7 months
[libvirt] [PATCH] esx: Add .vmdk storage volume creation
by Matthias Bolte
---
src/esx/esx_driver.c | 3 +-
src/esx/esx_storage_driver.c | 215 +++++++++++++++++++++++++++++++++++++++-
src/esx/esx_vi.c | 57 +++++++-----
src/esx/esx_vi.h | 1 +
src/esx/esx_vi_generator.input | 32 ++++++
src/esx/esx_vi_generator.py | 7 +-
src/esx/esx_vi_methods.c | 12 +++
7 files changed, 296 insertions(+), 31 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index eda3fc2..f8d4771 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -353,7 +353,8 @@ esxAutodetectSCSIControllerModel(virDomainDiskDefPtr def, int *model,
return 0;
}
- if (esxVI_LookupFileInfoByDatastorePath(data->ctx, def->src, &fileInfo,
+ if (esxVI_LookupFileInfoByDatastorePath(data->ctx, def->src,
+ false, &fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
diff --git a/src/esx/esx_storage_driver.c b/src/esx/esx_storage_driver.c
index d2d8f22..3b959c2 100644
--- a/src/esx/esx_storage_driver.c
+++ b/src/esx/esx_storage_driver.c
@@ -709,7 +709,7 @@ esxStorageVolumeLookupByName(virStoragePoolPtr pool, const char *name)
}
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, datastorePath,
- &fileInfo,
+ false, &fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
@@ -743,7 +743,8 @@ esxStorageVolumeLookupByKeyOrPath(virConnectPtr conn, const char *keyOrPath)
goto cleanup;
}
- if (esxVI_LookupFileInfoByDatastorePath(priv->primary, keyOrPath, &fileInfo,
+ if (esxVI_LookupFileInfoByDatastorePath(priv->primary, keyOrPath,
+ false, &fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
@@ -761,6 +762,210 @@ esxStorageVolumeLookupByKeyOrPath(virConnectPtr conn, const char *keyOrPath)
+static virStorageVolPtr
+esxStorageVolumeCreateXML(virStoragePoolPtr pool, const char *xmldesc,
+ unsigned int flags)
+{
+ virStorageVolPtr volume = NULL;
+ esxPrivate *priv = pool->conn->storagePrivateData;
+ esxVI_String *propertyNameList = NULL;
+ esxVI_ObjectContent *datastore = NULL;
+ esxVI_DynamicProperty *dynamicProperty = NULL;
+ esxVI_DatastoreInfo *datastoreInfo = NULL;
+ virStoragePoolDef poolDef;
+ virStorageVolDefPtr def = NULL;
+ char *tmp1;
+ char *tmp2;
+ char *datastorePath = NULL;
+ char *directoryName = NULL;
+ char *datastorePathWithoutFileName = NULL;
+ esxVI_FileInfo *fileInfo = NULL;
+ esxVI_FileBackedVirtualDiskSpec *virtualDiskSpec = NULL;
+ esxVI_ManagedObjectReference *task = NULL;
+ esxVI_TaskInfoState taskInfoState;
+
+ virCheckFlags(0, NULL);
+
+ memset(&poolDef, 0, sizeof (poolDef));
+
+ if (esxVI_EnsureSession(priv->primary) < 0) {
+ return NULL;
+ }
+
+ /* Lookup storage pool type */
+ if (esxVI_String_AppendValueToList(&propertyNameList, "info") < 0 ||
+ esxVI_LookupDatastoreByName(priv->primary, pool->name,
+ propertyNameList, &datastore,
+ esxVI_Occurrence_RequiredItem) < 0) {
+ goto cleanup;
+ }
+
+ for (dynamicProperty = datastore->propSet; dynamicProperty != NULL;
+ dynamicProperty = dynamicProperty->_next) {
+ if (STREQ(dynamicProperty->name, "info")) {
+ if (esxVI_DatastoreInfo_CastFromAnyType(dynamicProperty->val,
+ &datastoreInfo) < 0) {
+ goto cleanup;
+ }
+
+ break;
+ }
+ }
+
+ if (esxVI_LocalDatastoreInfo_DynamicCast(datastoreInfo) != NULL) {
+ poolDef.type = VIR_STORAGE_POOL_DIR;
+ } else if (esxVI_NasDatastoreInfo_DynamicCast(datastoreInfo) != NULL) {
+ poolDef.type = VIR_STORAGE_POOL_NETFS;
+ } else if (esxVI_VmfsDatastoreInfo_DynamicCast(datastoreInfo) != NULL) {
+ poolDef.type = VIR_STORAGE_POOL_FS;
+ } else {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("DatastoreInfo has unexpected type"));
+ goto cleanup;
+ }
+
+ /* Parse config */
+ def = virStorageVolDefParseString(&poolDef, xmldesc);
+
+ if (def == NULL) {
+ goto cleanup;
+ }
+
+ if (def->type != VIR_STORAGE_VOL_FILE) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Creating non-file volumes is not supported"));
+ goto cleanup;
+ }
+
+ /* Validate config */
+ tmp1 = strchr(def->name, '/');
+ tmp2 = strrchr(def->name, '/');
+
+ if (tmp1 == NULL || tmp1 == def->name ||
+ tmp2 == NULL || tmp2[1] == '\0') {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Volume name '%s' doesn't have expected format "
+ "'<directory>/<file>'"), def->name);
+ goto cleanup;
+ }
+
+ if (! virFileHasSuffix(def->name, ".vmdk")) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Volume name '%s' has unsupported suffix, expecting '.vmdk'"),
+ def->name);
+ goto cleanup;
+ }
+
+ if (virAsprintf(&datastorePath, "[%s] %s", pool->name, def->name) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (def->target.format == VIR_STORAGE_FILE_VMDK) {
+ /* Create directory, if it doesn't exist yet */
+ if (esxUtil_ParseDatastorePath(datastorePath, NULL, &directoryName,
+ NULL) < 0) {
+ goto cleanup;
+ }
+
+ if (virAsprintf(&datastorePathWithoutFileName, "[%s] %s", pool->name,
+ directoryName) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ if (esxVI_LookupFileInfoByDatastorePath
+ (priv->primary, datastorePathWithoutFileName, true, &fileInfo,
+ esxVI_Occurrence_OptionalItem) < 0) {
+ goto cleanup;
+ }
+
+ if (fileInfo == NULL) {
+ if (esxVI_MakeDirectory(priv->primary, datastorePathWithoutFileName,
+ priv->primary->datacenter->_reference,
+ esxVI_Boolean_True) < 0) {
+ goto cleanup;
+ }
+ }
+
+ /* Create VirtualDisk */
+ if (esxVI_FileBackedVirtualDiskSpec_Alloc(&virtualDiskSpec) < 0 ||
+ esxVI_Long_Alloc(&virtualDiskSpec->capacityKb) < 0) {
+ goto cleanup;
+ }
+
+ /* From the vSphere API documentation about VirtualDiskType ... */
+ if (def->allocation == def->capacity) {
+ /*
+ * "A preallocated disk has all space allocated at creation time
+ * and the space is zeroed on demand as the space is used."
+ */
+ virtualDiskSpec->diskType = (char *)"preallocated";
+ } else if (def->allocation == 0) {
+ /*
+ * "Space required for thin-provisioned virtual disk is allocated
+ * and zeroed on demand as the space is used."
+ */
+ virtualDiskSpec->diskType = (char *)"thin";
+ } else {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unsupported capacity-to-allocation relation"));
+ goto cleanup;
+ }
+
+ /*
+ * FIXME: The adapter type is a required parameter, but there is no
+ * way to let the user specifiy it in the volume XML config. Therefore,
+ * default to 'busLogic' here.
+ */
+ virtualDiskSpec->adapterType = (char *)"busLogic";
+
+ virtualDiskSpec->capacityKb->value = def->capacity / 1024; /* Scale from byte to kilobyte */
+
+ if (esxVI_CreateVirtualDisk_Task
+ (priv->primary, datastorePath, priv->primary->datacenter->_reference,
+ esxVI_VirtualDiskSpec_DynamicCast(virtualDiskSpec), &task) < 0 ||
+ esxVI_WaitForTaskCompletion(priv->primary, task, NULL,
+ esxVI_Occurrence_None,
+ priv->autoAnswer, &taskInfoState) < 0) {
+ goto cleanup;
+ }
+
+ if (taskInfoState != esxVI_TaskInfoState_Success) {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not create volume"));
+ goto cleanup;
+ }
+ } else {
+ ESX_ERROR(VIR_ERR_INTERNAL_ERROR,
+ _("Creation of %s volumes is not supported"),
+ virStorageFileFormatTypeToString(def->target.format));
+ goto cleanup;
+ }
+
+ volume = virGetStorageVol(pool->conn, pool->name, def->name, datastorePath);
+
+ cleanup:
+ if (virtualDiskSpec != NULL) {
+ virtualDiskSpec->diskType = NULL;
+ virtualDiskSpec->adapterType = NULL;
+ }
+
+ esxVI_String_Free(&propertyNameList);
+ esxVI_ObjectContent_Free(&datastore);
+ esxVI_DatastoreInfo_Free(&datastoreInfo);
+ virStorageVolDefFree(def);
+ VIR_FREE(datastorePath);
+ VIR_FREE(directoryName);
+ VIR_FREE(datastorePathWithoutFileName);
+ esxVI_FileInfo_Free(&fileInfo);
+ esxVI_FileBackedVirtualDiskSpec_Free(&virtualDiskSpec);
+ esxVI_ManagedObjectReference_Free(&task);
+
+ return volume;
+}
+
+
+
static int
esxStorageVolumeGetInfo(virStorageVolPtr volume, virStorageVolInfoPtr info)
{
@@ -782,7 +987,7 @@ esxStorageVolumeGetInfo(virStorageVolPtr volume, virStorageVolInfoPtr info)
}
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, datastorePath,
- &fileInfo,
+ false, &fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
@@ -875,7 +1080,7 @@ esxStorageVolumeDumpXML(virStorageVolPtr volume, unsigned int flags)
}
if (esxVI_LookupFileInfoByDatastorePath(priv->primary, datastorePath,
- &fileInfo,
+ false, &fileInfo,
esxVI_Occurrence_RequiredItem) < 0) {
goto cleanup;
}
@@ -986,7 +1191,7 @@ static virStorageDriver esxStorageDriver = {
esxStorageVolumeLookupByName, /* volLookupByName */
esxStorageVolumeLookupByKeyOrPath, /* volLookupByKey */
esxStorageVolumeLookupByKeyOrPath, /* volLookupByPath */
- NULL, /* volCreateXML */
+ esxStorageVolumeCreateXML, /* volCreateXML */
NULL, /* volCreateXMLFrom */
NULL, /* volDelete */
NULL, /* volWipe */
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index a6950fd..8d83eac 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -2940,6 +2940,7 @@ esxVI_LookupCurrentSnapshotTree
int
esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
const char *datastorePath,
+ bool lookupFolder,
esxVI_FileInfo **fileInfo,
esxVI_Occurrence occurrence)
{
@@ -2954,6 +2955,7 @@ esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
esxVI_ObjectContent *datastore = NULL;
esxVI_ManagedObjectReference *hostDatastoreBrowser = NULL;
esxVI_HostDatastoreBrowserSearchSpec *searchSpec = NULL;
+ esxVI_FolderFileQuery *folderFileQuery = NULL;
esxVI_VmDiskFileQuery *vmDiskFileQuery = NULL;
esxVI_IsoImageFileQuery *isoImageFileQuery = NULL;
esxVI_FloppyImageFileQuery *floppyImageFileQuery = NULL;
@@ -3030,32 +3032,41 @@ esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
searchSpec->details->fileSize = esxVI_Boolean_True;
searchSpec->details->modification = esxVI_Boolean_False;
- if (esxVI_VmDiskFileQuery_Alloc(&vmDiskFileQuery) < 0 ||
- esxVI_VmDiskFileQueryFlags_Alloc(&vmDiskFileQuery->details) < 0 ||
- esxVI_FileQuery_AppendToList
- (&searchSpec->query,
- esxVI_FileQuery_DynamicCast(vmDiskFileQuery)) < 0) {
- goto cleanup;
- }
+ if (lookupFolder) {
+ if (esxVI_FolderFileQuery_Alloc(&folderFileQuery) < 0 ||
+ esxVI_FileQuery_AppendToList
+ (&searchSpec->query,
+ esxVI_FileQuery_DynamicCast(folderFileQuery)) < 0) {
+ goto cleanup;
+ }
+ } else {
+ if (esxVI_VmDiskFileQuery_Alloc(&vmDiskFileQuery) < 0 ||
+ esxVI_VmDiskFileQueryFlags_Alloc(&vmDiskFileQuery->details) < 0 ||
+ esxVI_FileQuery_AppendToList
+ (&searchSpec->query,
+ esxVI_FileQuery_DynamicCast(vmDiskFileQuery)) < 0) {
+ goto cleanup;
+ }
- vmDiskFileQuery->details->diskType = esxVI_Boolean_False;
- vmDiskFileQuery->details->capacityKb = esxVI_Boolean_True;
- vmDiskFileQuery->details->hardwareVersion = esxVI_Boolean_False;
- vmDiskFileQuery->details->controllerType = esxVI_Boolean_True;
- vmDiskFileQuery->details->diskExtents = esxVI_Boolean_False;
+ vmDiskFileQuery->details->diskType = esxVI_Boolean_False;
+ vmDiskFileQuery->details->capacityKb = esxVI_Boolean_True;
+ vmDiskFileQuery->details->hardwareVersion = esxVI_Boolean_False;
+ vmDiskFileQuery->details->controllerType = esxVI_Boolean_True;
+ vmDiskFileQuery->details->diskExtents = esxVI_Boolean_False;
- if (esxVI_IsoImageFileQuery_Alloc(&isoImageFileQuery) < 0 ||
- esxVI_FileQuery_AppendToList
- (&searchSpec->query,
- esxVI_FileQuery_DynamicCast(isoImageFileQuery)) < 0) {
- goto cleanup;
- }
+ if (esxVI_IsoImageFileQuery_Alloc(&isoImageFileQuery) < 0 ||
+ esxVI_FileQuery_AppendToList
+ (&searchSpec->query,
+ esxVI_FileQuery_DynamicCast(isoImageFileQuery)) < 0) {
+ goto cleanup;
+ }
- if (esxVI_FloppyImageFileQuery_Alloc(&floppyImageFileQuery) < 0 ||
- esxVI_FileQuery_AppendToList
- (&searchSpec->query,
- esxVI_FileQuery_DynamicCast(floppyImageFileQuery)) < 0) {
- goto cleanup;
+ if (esxVI_FloppyImageFileQuery_Alloc(&floppyImageFileQuery) < 0 ||
+ esxVI_FileQuery_AppendToList
+ (&searchSpec->query,
+ esxVI_FileQuery_DynamicCast(floppyImageFileQuery)) < 0) {
+ goto cleanup;
+ }
}
if (esxVI_String_Alloc(&searchSpec->matchPattern) < 0) {
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 3d1aee0..773a1c6 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -401,6 +401,7 @@ int esxVI_LookupCurrentSnapshotTree
int esxVI_LookupFileInfoByDatastorePath(esxVI_Context *ctx,
const char *datastorePath,
+ bool lookupFolder,
esxVI_FileInfo **fileInfo,
esxVI_Occurrence occurrence);
diff --git a/src/esx/esx_vi_generator.input b/src/esx/esx_vi_generator.input
index 0fb9448..b911c22 100644
--- a/src/esx/esx_vi_generator.input
+++ b/src/esx/esx_vi_generator.input
@@ -166,6 +166,11 @@ object Description
end
+object DeviceBackedVirtualDiskSpec extends VirtualDiskSpec
+ String device r
+end
+
+
object DynamicProperty
String name r
AnyType val r
@@ -190,6 +195,11 @@ object Event
end
+object FileBackedVirtualDiskSpec extends VirtualDiskSpec
+ Long capacityKb r
+end
+
+
object FileInfo
String path r
Long fileSize o
@@ -528,6 +538,12 @@ object UserSession
end
+object VirtualDiskSpec
+ String diskType r
+ String adapterType r
+end
+
+
object VirtualMachineConfigSpec
String changeVersion o
String name o
@@ -694,6 +710,14 @@ method CreateSnapshot_Task returns ManagedObjectReference r
end
+method CreateVirtualDisk_Task returns ManagedObjectReference r
+ ManagedObjectReference _this:VirtualDiskManager r
+ String name r
+ ManagedObjectReference datacenter o
+ VirtualDiskSpec spec r
+end
+
+
method DestroyPropertyFilter
ManagedObjectReference _this r
end
@@ -728,6 +752,14 @@ method Logout
end
+method MakeDirectory
+ ManagedObjectReference _this:FileManager r
+ String name r
+ ManagedObjectReference datacenter o
+ Boolean createParentDirectories o
+end
+
+
method MigrateVM_Task returns ManagedObjectReference r
ManagedObjectReference _this r
ManagedObjectReference pool o
diff --git a/src/esx/esx_vi_generator.py b/src/esx/esx_vi_generator.py
index 411fd80..be96a03 100755
--- a/src/esx/esx_vi_generator.py
+++ b/src/esx/esx_vi_generator.py
@@ -45,10 +45,12 @@ valid_occurrences = [OCCURRENCE__REQUIRED_ITEM,
class Parameter:
- autobind_map = { "PerformanceManager" : "perfManager",
+ autobind_map = { "FileManager" : "fileManager",
+ "PerformanceManager" : "perfManager",
"PropertyCollector" : "propertyCollector",
"SearchIndex" : "searchIndex",
- "SessionManager" : "sessionManager" }
+ "SessionManager" : "sessionManager",
+ "VirtualDiskManager" : "virtualDiskManager" }
def __init__(self, type, name, occurrence):
self.type = type
@@ -1146,6 +1148,7 @@ additional_object_features = { "DatastoreHostMount" : Object.FEATURE__DE
"SharesInfo" : Object.FEATURE__ANY_TYPE,
"TaskInfo" : Object.FEATURE__ANY_TYPE | Object.FEATURE__LIST,
"UserSession" : Object.FEATURE__ANY_TYPE,
+ "VirtualDiskSpec" : Object.FEATURE__DYNAMIC_CAST,
"VirtualMachineQuestionInfo" : Object.FEATURE__ANY_TYPE,
"VirtualMachineSnapshotTree" : Object.FEATURE__DEEP_COPY | Object.FEATURE__ANY_TYPE }
diff --git a/src/esx/esx_vi_methods.c b/src/esx/esx_vi_methods.c
index 56d2e58..a00561f 100644
--- a/src/esx/esx_vi_methods.c
+++ b/src/esx/esx_vi_methods.c
@@ -173,6 +173,12 @@
+#define ESX_VI__METHOD__PARAMETER__THIS__fileManager \
+ ESX_VI__METHOD__PARAMETER__THIS_FROM_SERVICE(ManagedObjectReference, \
+ fileManager)
+
+
+
#define ESX_VI__METHOD__PARAMETER__THIS__perfManager \
ESX_VI__METHOD__PARAMETER__THIS_FROM_SERVICE(ManagedObjectReference, \
perfManager)
@@ -197,6 +203,12 @@
+#define ESX_VI__METHOD__PARAMETER__THIS__virtualDiskManager \
+ ESX_VI__METHOD__PARAMETER__THIS_FROM_SERVICE(ManagedObjectReference, \
+ virtualDiskManager)
+
+
+
/*
* A required parameter must be != 0 (NULL for pointers, "undefined" == 0 for
* enumeration values).
--
1.7.0.4
14 years, 7 months