[libvirt] [PATCH] docs: Remove <code> from <summary> entries due to RNG error
by John Ferlan
commit '96e55048' caused make check failure for virschematest:
1929) Checking ../docs/news.xml against ../news.rng ... libvirt: XML Util error : XML document failed to validate against schema: Unable to validate doc against /home/jferlan/git/libvirt.work/docs/schemas/../news.rng
Datatype element summary has child elements
Element summary failed to validate content
Datatype element summary has child elements
Element summary failed to validate content
^[[31m^[[1mFAILED^[[0m
That's because <code> elements don't appear to be allowed in the schema.
Rather than attempt to fix the schema, figured it was simpler to just
remove them and let the schema fix happen later.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
Pushed as build breaker.
docs/news.xml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/news.xml b/docs/news.xml
index 7e9395b..dd2e653 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -176,7 +176,7 @@
</change>
<change>
<summary>
- qemu: Honor <code><on_reboot/></code> setting
+ qemu: Honor <on_reboot/> setting
</summary>
<description>
The setting was accepted by the parser, but not actually implemented.
@@ -184,7 +184,7 @@
</change>
<change>
<summary>
- Fix <code>--verbose</code> option for all daemons
+ Fix --verbose option for all daemons
</summary>
<description>
Since v3.0.0, the option had been ignored by all libvirt deamons
--
2.9.5
7 years, 1 month
[libvirt] [PATCH] qemu: Remove unused params from qemuDomainDeviceDefValidate
by John Ferlan
Neither @cfg nor (now) @driver is used in the API, so remove them
and mark @opaque as UNUSED.
NB: Commit id 'fa3c558596' dropped the unused @qemuCaps which was the
last consumer of @driver other than @cfg, but even @cfg was never used
even in the original implementation from commit id 'd987f63a'.
Signed-off-by: John Ferlan <jferlan(a)redhat.com>
---
Another rogue piece of unused data seen whilst working through the
VxHS patches.
src/qemu/qemu_domain.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index b98ffff..cd53c6f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3302,10 +3302,8 @@ qemuDomainRedirdevDefValidate(const virDomainRedirdevDef *def)
static int
qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
const virDomainDef *def ATTRIBUTE_UNUSED,
- void *opaque)
+ void *opaque ATTRIBUTE_UNUSED)
{
- virQEMUDriverPtr driver = opaque;
- virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
int ret = -1;
if (dev->type == VIR_DOMAIN_DEVICE_NET) {
@@ -3389,7 +3387,6 @@ qemuDomainDeviceDefValidate(const virDomainDeviceDef *dev,
ret = 0;
cleanup:
- virObjectUnref(cfg);
return ret;
}
--
2.9.5
7 years, 1 month
[libvirt] [PATCH v2 0/2] Add support for qcow2 cache
by Liu Qing
Qcow2 small IO random write performance will drop dramatically if the l2
cache table could not cover the whole disk. This will be a lot of l2
cache table RW operations if cache miss happens frequently.
This patch exports the qcow2 driver parameter
l2-cache-size/refcount-cache-size, first added in Qemu 2.2, and
cache-clean-interval, first added in Qemu 2.5, in libvirt.
*** BLURB HERE ***
Liu Qing (2):
conf, docs: Add qcow2 cache configuration support
qemu: add capability checking for qcow2 cache configuration
docs/formatdomain.html.in | 21 ++++++++++
docs/schemas/domaincommon.rng | 24 +++++++++++
src/conf/domain_conf.c | 30 ++++++++++++++
src/qemu/qemu_capabilities.c | 15 +++++++
src/qemu/qemu_capabilities.h | 3 ++
src/qemu/qemu_command.c | 47 ++++++++++++++++++++++
src/util/virstoragefile.c | 3 ++
src/util/virstoragefile.h | 4 ++
tests/qemucapabilitiesdata/caps_2.4.0.x86_64.xml | 2 +
tests/qemucapabilitiesdata/caps_2.5.0.x86_64.xml | 3 ++
.../caps_2.6.0-gicv2.aarch64.xml | 3 ++
.../caps_2.6.0-gicv3.aarch64.xml | 3 ++
tests/qemucapabilitiesdata/caps_2.6.0.ppc64le.xml | 3 ++
tests/qemucapabilitiesdata/caps_2.6.0.x86_64.xml | 3 ++
tests/qemucapabilitiesdata/caps_2.7.0.s390x.xml | 3 ++
tests/qemucapabilitiesdata/caps_2.7.0.x86_64.xml | 3 ++
tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml | 3 ++
tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml | 3 ++
tests/qemucapabilitiesdata/caps_2.9.0.ppc64le.xml | 3 ++
tests/qemucapabilitiesdata/caps_2.9.0.s390x.xml | 3 ++
tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml | 3 ++
...argv-disk-drive-qcow2-cache-clean-interval.args | 27 +++++++++++++
...2argv-disk-drive-qcow2-cache-clean-interval.xml | 37 +++++++++++++++++
...emuxml2argv-disk-drive-qcow2-l2-cache-size.args | 27 +++++++++++++
...qemuxml2argv-disk-drive-qcow2-l2-cache-size.xml | 37 +++++++++++++++++
...2argv-disk-drive-qcow2-refcount-cache-size.args | 27 +++++++++++++
...l2argv-disk-drive-qcow2-refcount-cache-size.xml | 37 +++++++++++++++++
tests/qemuxml2argvtest.c | 6 +++
...mlout-disk-drive-qcow2-cache-clean-interval.xml | 41 +++++++++++++++++++
...muxml2xmlout-disk-drive-qcow2-l2-cache-size.xml | 41 +++++++++++++++++++
...xmlout-disk-drive-qcow2-refcount-cache-size.xml | 41 +++++++++++++++++++
tests/qemuxml2xmltest.c | 3 ++
32 files changed, 509 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache-clean-interval.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-cache-clean-interval.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-l2-cache-size.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-l2-cache-size.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-refcount-cache-size.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-drive-qcow2-refcount-cache-size.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-cache-clean-interval.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-l2-cache-size.xml
create mode 100644 tests/qemuxml2xmloutdata/qemuxml2xmlout-disk-drive-qcow2-refcount-cache-size.xml
--
1.8.3.1
7 years, 1 month
[libvirt] [PATCH v2] news: Prepare for 3.7.0 release
by Andrea Bolognani
Documents some changes that have slipped through the cracks
during the development cycle.
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
Changes from [v1]:
* rebase on top of master
* remove the part about guests no longer disappearing if the
QEMU binary is missing, since Peter already documented that
[v1] https://www.redhat.com/archives/libvir-list/2017-September/msg00030.html
docs/news.xml | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/docs/news.xml b/docs/news.xml
index dd8967e25..141b1a42a 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -69,6 +69,18 @@
you can configure reconnect timeout if the connection is closed.
</description>
</change>
+ <change>
+ <summary>
+ qemu: Implement editing guest configuration for managed save files
+ </summary>
+ <description>
+ New <code>managedsave-define</code>, <code>managedsave-edit</code>
+ and <code>managedsave-dumpxml</code> commands have been added to
+ <code>virsh</code> to allow editing the guest configuration for
+ managed save files just like it was already possible for unmanaged
+ save files.
+ </description>
+ </change>
</section>
<section title="Improvements">
<change>
@@ -81,6 +93,43 @@
indication for users (and devs).
</description>
</change>
+ <change>
+ <summary>
+ apparmor: Update for QEMU 2.10 compatibility
+ </summary>
+ <description>
+ Starting with version 2.10, QEMU locks disk images and NVRAM files
+ to prevent them from being corrupted; however, file locking needs to
+ be explicitly allowed through <code>virt-aa-helper</code> or AppArmor
+ will reject the requests and the guest will not be able to run.
+ </description>
+ </change>
+ <change>
+ <summary>
+ virsh: List Unix sockets in 'domdisplay' output
+ </summary>
+ <description>
+ VNC and SPICE graphics can use Unix sockets instead of TCP/IP sockets
+ as connection endpoints, but such a configuration was not handled
+ correctly by <code>virsh domdisplay</code>, causing the respective
+ endpoints to be missing from the output.
+ </description>
+ </change>
+ <change>
+ <summary>
+ qemu: Don't check whether offline migration is safe
+ </summary>
+ <description>
+ Since offline migration only copies the guest definition to the
+ destination host, data corruption is not a concern and the operation
+ can always be performed safely.
+ </description>
+ </change>
+ <change>
+ <summary>
+ virt-host-validate: Fix IOMMU detection on ppc64
+ </summary>
+ </change>
</section>
<section title="Bug fixes">
<change>
@@ -115,6 +164,33 @@
are missing during startup.
</description>
</change>
+ <change>
+ <summary>
+ qemu: Prevent pSeries guests from disappearing in some situations
+ </summary>
+ <description>
+ pSeries guest would disappear if any of the host devices they were
+ configured to use was not available during libvirtd startup, which
+ could easily happen for SR-IOV Virtual Functions. This scenario is
+ now handled correctly.
+ </description>
+ </change>
+ <change>
+ <summary>
+ qemu: Honor <code><on_reboot/></code> setting
+ </summary>
+ <description>
+ The setting was accepted by the parser, but not actually implemented.
+ </description>
+ </change>
+ <change>
+ <summary>
+ daemon: Fix <code>--verbose</code> option
+ </summary>
+ <description>
+ The option had not been working as intended from v3.0.0 onwards.
+ </description>
+ </change>
</section>
</release>
<release version="v3.6.0" date="2017-08-02">
--
2.13.5
7 years, 2 months
[libvirt] [PATCH v2 0/2] Fix docs/news.xml template structure and add new features
by Kothapally Madhu Pavan
This patchset will fix docs/news.xml template structure which is broken by
commit b7e779c1a51793 and add support for managedsave-define, managedsave-edit
and managedsave-dumpxml commands.
Kothapally Madhu Pavan (2):
docs: Fix docs/news.xml template structure
docs: Document managedsave-edit commands support
docs/news.xml | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
--
1.8.3.1
7 years, 2 months
[libvirt] [PATCH] news: Prepare for 3.7.0 release
by Andrea Bolognani
Documents some changes that have slipped through the cracks
during the development cycle.
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
I'll push this by the end of tomorrow under the "nobody
reads the release notes" rule, unless I get either an ACK
or a NACK earlier.
docs/news.xml | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/docs/news.xml b/docs/news.xml
index 4b48f0fb3..40dec513f 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -69,8 +69,57 @@
you can configure reconnect timeout if the connection is closed.
</description>
</change>
+ <change>
+ <summary>
+ qemu: Implement editing guest configuration for managed save files
+ </summary>
+ <description>
+ New <code>managedsave-define</code>, <code>managedsave-edit</code>
+ and <code>managedsave-dumpxml</code> commands have been added to
+ <code>virsh</code> to allow editing the guest configuration for
+ managed save files just like it was already possible for unmanaged
+ save files.
+ </description>
+ </change>
</section>
<section title="Improvements">
+ <change>
+ <summary>
+ apparmor: Update for QEMU 2.10 compatibility
+ </summary>
+ <description>
+ Starting with version 2.10, QEMU locks disk images and NVRAM files
+ to prevent them from being corrupted; however, file locking needs to
+ be explicitly allowed through <code>virt-aa-helper</code> or AppArmor
+ will reject the requests and the guest will not be able to run.
+ </description>
+ </change>
+ <change>
+ <summary>
+ virsh: List Unix sockets in 'domdisplay' output
+ </summary>
+ <description>
+ VNC and SPICE graphics can use Unix sockets instead of TCP/IP sockets
+ as connection endpoints, but such a configuration was not handled
+ correctly by <code>virsh domdisplay</code>, causing the respective
+ endpoints to be missing from the output.
+ </description>
+ </change>
+ <change>
+ <summary>
+ qemu: Don't check whether offline migration is safe
+ </summary>
+ <description>
+ Since offline migration only copies the guest definition to the
+ destination host, data corruption is not a concern and the operation
+ can always be performed safely.
+ </description>
+ </change>
+ <change>
+ <summary>
+ virt-host-validate: Fix IOMMU detection on ppc64
+ </summary>
+ </change>
</section>
<section title="Bug fixes">
<change>
@@ -93,6 +142,34 @@
The path is now generated with shortened name instead.
</description>
</change>
+ <change>
+ <summary>
+ qemu: Prevent guests from disappearing in some situations
+ </summary>
+ <description>
+ pSeries guest would disappear if any of the host devices they were
+ configured to use was not available during libvirtd startup, which
+ could easily happen for SR-IOV Virtual Functions; additionally,
+ guests would disappear if the QEMU binary was removed or renamed.
+ Both scenarios are now handled correctly.
+ </description>
+ </change>
+ <change>
+ <summary>
+ qemu: Honor <code><on_reboot/></code> setting
+ </summary>
+ <description>
+ The setting was accepted by the parser, but not actually implemented.
+ </description>
+ </change>
+ <change>
+ <summary>
+ daemon: Fix <code>--verbose</code> option
+ </summary>
+ <description>
+ The option had not been working as intended from v3.0.0 onwards.
+ </description>
+ </change>
</section>
</release>
<release version="v3.6.0" date="2017-08-02">
--
2.13.5
7 years, 2 months
[libvirt] [PATCH 2/3] libvirtaio: add allow for moving callbacks to other event loop
by Wojtek Porczyk
The virEvent implementation is tied to a particular loop. When spinning
another loop, the callbacks have to be moved to another implementation,
so they will have a chance to be invoked, should they be scheduled. If
not, file descriptors will be leaking.
Signed-off-by: Wojtek Porczyk <woju(a)invisiblethingslab.com>
---
libvirtaio.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 51 insertions(+), 13 deletions(-)
diff --git a/libvirtaio.py b/libvirtaio.py
index fc868bd..d161cd1 100644
--- a/libvirtaio.py
+++ b/libvirtaio.py
@@ -195,9 +195,10 @@ class FDCallback(Callback):
return '<{} iden={} fd={} event={}>'.format(
self.__class__.__name__, self.iden, self.descriptor.fd, self.event)
- def update(self, event):
+ def update(self, event=None):
'''Update the callback and fix descriptor's watchers'''
- self.event = event
+ if event is not None:
+ self.event = event
self.descriptor.update()
#
@@ -238,20 +239,21 @@ class TimeoutCallback(Callback):
self.cb(self.iden, self.opaque)
self.impl.log.debug('timer %r callback ended', self.iden)
- def update(self, timeout):
+ def update(self, timeout=None):
'''Start or the timer, possibly updating timeout'''
- self.timeout = timeout
-
- if self.timeout >= 0 and self._task is None:
- self.impl.log.debug('timer %r start', self.iden)
- self._task = ensure_future(self._timer(),
- loop=self.impl.loop)
+ if timeout is not None:
+ self.timeout = timeout
- elif self.timeout < 0 and self._task is not None:
+ if self._task is not None:
self.impl.log.debug('timer %r stop', self.iden)
self._task.cancel() # pylint: disable=no-member
self._task = None
+ if self.timeout >= 0:
+ self.impl.log.debug('timer %r start', self.iden)
+ self._task = ensure_future(self._timer(),
+ loop=self.impl.loop)
+
def close(self):
'''Stop the timer and call ff callback'''
super(TimeoutCallback, self).close()
@@ -274,6 +276,7 @@ class virEventAsyncIOImpl(object):
self.callbacks = {}
self.descriptors = DescriptorDict(self)
self.log = logging.getLogger(self.__class__.__name__)
+ self.pending_tasks = set()
def register(self):
'''Register this instance as event loop implementation'''
@@ -284,9 +287,30 @@ class virEventAsyncIOImpl(object):
self._add_timeout, self._update_timeout, self._remove_timeout)
return self
+ def takeover(self, other):
+ '''Take over other implementation, probably registered on another loop
+
+ :param virEventAsyncIOImpl other: other implementation to be taken over
+ '''
+ self.log.warning('%r taking over %r', self, other)
+
+ while other.callbacks:
+ iden, callback = other.callbacks.popitem()
+ self.log.debug(' takeover %d %r', iden, callback)
+ assert callback.iden == iden
+ callback.impl = self
+ self.callbacks[iden] = callback
+
+ if isinstance(callback, FDCallback):
+ fd = callback.descriptor.fd
+ assert callback is other.descriptors[fd].remove_handle(iden)
+ self.descriptors[fd].add_handle(callback)
+
def schedule_ff_callback(self, iden, opaque):
'''Schedule a ff callback from one of the handles or timers'''
- ensure_future(self._ff_callback(iden, opaque), loop=self.loop)
+ fut = ensure_future(self._ff_callback(iden, opaque), loop=self.loop)
+ self.pending_tasks.add(fut)
+ fut.add_done_callback(self.pending_tasks.remove)
@asyncio.coroutine
def _ff_callback(self, iden, opaque):
@@ -297,13 +321,19 @@ class virEventAsyncIOImpl(object):
self.log.debug('ff_callback(iden=%d, opaque=...)', iden)
return libvirt.virEventInvokeFreeCallback(opaque)
+ @asyncio.coroutine
+ def drain(self):
+ self.log.debug('drain()')
+ if self.pending_tasks:
+ yield from asyncio.wait(self.pending_tasks, loop=self.loop)
+
def is_idle(self):
'''Returns False if there are leftovers from a connection
Those may happen if there are sematical problems while closing
a connection. For example, not deregistered events before .close().
'''
- return not self.callbacks
+ return not self.callbacks and not self.pending_tasks
def _add_handle(self, fd, event, cb, opaque):
'''Register a callback for monitoring file handle events
@@ -403,10 +433,18 @@ class virEventAsyncIOImpl(object):
callback = self.callbacks.pop(timer)
callback.close()
+
+_current_impl = None
def virEventRegisterAsyncIOImpl(loop=None):
'''Arrange for libvirt's callbacks to be dispatched via asyncio event loop
The implementation object is returned, but in normal usage it can safely be
discarded.
'''
- return virEventAsyncIOImpl(loop=loop).register()
+ global _current_impl
+ impl = virEventAsyncIOImpl(loop=loop)
+ impl.register()
+ if _current_impl is not None:
+ impl.takeover(_current_impl)
+ _current_impl = impl
+ return impl
--
2.9.4
7 years, 2 months
[libvirt] [PATCH] news: Add stuff for 3.7.0
by Peter Krempa
---
docs/news.xml | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/docs/news.xml b/docs/news.xml
index 4b48f0fb3..dd8967e25 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -71,6 +71,16 @@
</change>
</section>
<section title="Improvements">
+ <change>
+ <summary>
+ qemu: Report a clear error when dropping a VM during startup
+ </summary>
+ <description>
+ "Failed to load config for domain 'DOMNAME'" is now reported if a VM
+ config can't be parsed for some reason, and thus provides a clear
+ indication for users (and devs).
+ </description>
+ </change>
</section>
<section title="Bug fixes">
<change>
@@ -93,6 +103,18 @@
The path is now generated with shortened name instead.
</description>
</change>
+ <change>
+ <summary>
+ qemu: Tolerate missing emulator binary during libvirtd restart
+ </summary>
+ <description>
+ For some time libvirt required qemu capabilities being present when
+ parsing VM configs during startup. As a side effect VM configs would
+ fail to parse and thus vanish, if the emulator binary would be
+ uninstalled or broken. Libvirt now tolerates when capabilities
+ are missing during startup.
+ </description>
+ </change>
</section>
</release>
<release version="v3.6.0" date="2017-08-02">
--
2.14.1
7 years, 2 months
[libvirt] [PATCH] virnetdaemon: Don't deadlock when talking to D-Bus
by Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1487322
In ace45e67abbd I've tried to fix a problem that we get the reply
to a D-Bus call while we were sleeping. In that case the callback
was never set. So I've changed the code that the callback is
called directly in this case. However, I hadn't realized that
since callback is called out of order it lock the virNetDaemon.
Exactly the very same virNetDaemon that we are dealing with right
now and have it locked already (in
virNetDaemonAddShutdownInhibition())
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/rpc/virnetdaemon.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c
index 00247cfc3..e3b9390af 100644
--- a/src/rpc/virnetdaemon.c
+++ b/src/rpc/virnetdaemon.c
@@ -439,14 +439,12 @@ virNetDaemonAutoShutdown(virNetDaemonPtr dmn,
#if defined(WITH_DBUS) && defined(DBUS_TYPE_UNIX_FD)
static void
-virNetDaemonGotInhibitReply(DBusPendingCall *pending,
- void *opaque)
+virNetDaemonGotInhibitReplyLocked(DBusPendingCall *pending,
+ virNetDaemonPtr dmn)
{
- virNetDaemonPtr dmn = opaque;
DBusMessage *reply;
int fd;
- virObjectLock(dmn);
dmn->autoShutdownCallingInhibit = false;
VIR_DEBUG("dmn=%p", dmn);
@@ -470,11 +468,22 @@ virNetDaemonGotInhibitReply(DBusPendingCall *pending,
virDBusMessageUnref(reply);
cleanup:
- virObjectUnlock(dmn);
dbus_pending_call_unref(pending);
}
+static void
+virNetDaemonGotInhibitReply(DBusPendingCall *pending,
+ void *opaque)
+{
+ virNetDaemonPtr dmn = opaque;
+
+ virObjectLock(dmn);
+ virNetDaemonGotInhibitReplyLocked(pending, dmn);
+ virObjectUnlock(dmn);
+}
+
+
/* As per: http://www.freedesktop.org/wiki/Software/systemd/inhibit */
static void
virNetDaemonCallInhibit(virNetDaemonPtr dmn,
@@ -516,7 +525,7 @@ virNetDaemonCallInhibit(virNetDaemonPtr dmn,
25 * 1000) &&
pendingReply) {
if (dbus_pending_call_get_completed(pendingReply)) {
- virNetDaemonGotInhibitReply(pendingReply, dmn);
+ virNetDaemonGotInhibitReplyLocked(pendingReply, dmn);
} else {
dbus_pending_call_set_notify(pendingReply,
virNetDaemonGotInhibitReply,
--
2.13.5
7 years, 2 months
[libvirt] [PATCH] vmx: Expose VMware Managed Object Reference (moref) in XML.
by Richard W.M. Jones
If you use the VDDK library to access virtual machines remotely, you
really need to know the Managed Object Reference ("moref") of the VM.
This must be passed each time you connect to the API.
For example nbdkit's VDDK plugin requires a moref to be passed to
mount up a VM's disk remotely:
nbdkit vddk user=root password=+/tmp/rootpw \
server=esxi.example.com thumbprint=xx:xx:xx:... \
vm=moref=2 \
file="[datastore1] Fedora/Fedora.vmdk"
Getting the moref is a huge pain. To get some idea of what it is, why
it is needed, and how much trouble it is to get it, see:
https://blogs.vmware.com/vsphere/2012/02/uniquely-identifying-virtual-mac...
https://blogs.vmware.com/vsphere/2012/02/uniquely-identifying-virtual-mac...
However the moref is available conveniently in the internals of the
libvirt VMX driver. This patch exposes it as a custom XML element
using the same "vmware:" namespace which was previously used for the
datacenterpath (see libvirt commit 636a99058758a044).
It appears in the XML like this:
<domain type='vmware' xmlns:vmware='http://libvirt.org/schemas/domain/vmware/1.0'>
<name>Fedora</name>
...
<vmware:datacenterpath>ha-datacenter</vmware:datacenterpath>
<vmware:moref>2</vmware:moref>
</domain>
Note that the moref can appear as either a simple ID (for esx://
connections) or as a "vm-<ID>" (for vpx:// connections). It should be
treated by users as an opaque string.
---
src/esx/esx_driver.c | 7 +++++++
src/esx/esx_vi.c | 15 +++++++++++++++
src/esx/esx_vi.h | 4 ++++
src/vmx/vmx.c | 51 +++++++++++++++++++++++++++++++++++++++++----------
src/vmx/vmx.h | 2 ++
5 files changed, 69 insertions(+), 10 deletions(-)
diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c
index 1f4f2c7a7..0cce0a41a 100644
--- a/src/esx/esx_driver.c
+++ b/src/esx/esx_driver.c
@@ -2645,6 +2645,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
esxVI_ObjectContent *virtualMachine = NULL;
esxVI_VirtualMachinePowerState powerState;
int id;
+ char *moref = NULL;
char *vmPathName = NULL;
char *datastoreName = NULL;
char *directoryName = NULL;
@@ -2670,6 +2671,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
esxVI_LookupVirtualMachineByUuid(priv->primary, domain->uuid,
propertyNameList, &virtualMachine,
esxVI_Occurrence_RequiredItem) < 0 ||
+ esxVI_GetVirtualMachineMORef(virtualMachine, &moref) < 0 ||
esxVI_GetVirtualMachinePowerState(virtualMachine, &powerState) < 0 ||
esxVI_GetVirtualMachineIdentity(virtualMachine, &id, NULL, NULL) < 0 ||
esxVI_GetStringValue(virtualMachine, "config.files.vmPathName",
@@ -2715,6 +2717,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
ctx.formatFileName = NULL;
ctx.autodetectSCSIControllerModel = NULL;
ctx.datacenterPath = priv->primary->datacenterPath;
+ ctx.moref = moref;
def = virVMXParseConfig(&ctx, priv->xmlopt, priv->caps, vmx);
@@ -2732,6 +2735,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
esxVI_String_Free(&propertyNameList);
esxVI_ObjectContent_Free(&virtualMachine);
+ VIR_FREE(moref);
VIR_FREE(datastoreName);
VIR_FREE(directoryName);
VIR_FREE(directoryAndFileName);
@@ -2774,6 +2778,7 @@ esxConnectDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat,
ctx.formatFileName = NULL;
ctx.autodetectSCSIControllerModel = NULL;
ctx.datacenterPath = NULL;
+ ctx.moref = NULL;
def = virVMXParseConfig(&ctx, priv->xmlopt, priv->caps, nativeConfig);
@@ -2830,6 +2835,7 @@ esxConnectDomainXMLToNative(virConnectPtr conn, const char *nativeFormat,
ctx.formatFileName = esxFormatVMXFileName;
ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel;
ctx.datacenterPath = NULL;
+ ctx.moref = NULL;
vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version);
@@ -3077,6 +3083,7 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags)
ctx.formatFileName = esxFormatVMXFileName;
ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel;
ctx.datacenterPath = NULL;
+ ctx.moref = NULL;
vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version);
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 8586e3ff0..77bcfd9b6 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -2390,6 +2390,21 @@ esxVI_GetVirtualMachineQuestionInfo
}
+int
+esxVI_GetVirtualMachineMORef(esxVI_ObjectContent *virtualMachine,
+ char **moref)
+{
+ for (; virtualMachine != NULL; virtualMachine = virtualMachine->_next) {
+ if (virtualMachine->obj &&
+ STREQ(virtualMachine->obj->type, "VirtualMachine") &&
+ virtualMachine->obj->value) {
+ if (VIR_STRDUP(*moref, virtualMachine->obj->value) < 0)
+ return -1;
+ return 0;
+ }
+ }
+ return -1;
+}
int
esxVI_GetBoolean(esxVI_ObjectContent *objectContent, const char *propertyName,
diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
index 7c53f3781..47d518dd1 100644
--- a/src/esx/esx_vi.h
+++ b/src/esx/esx_vi.h
@@ -334,6 +334,10 @@ int esxVI_GetVirtualMachineQuestionInfo
(esxVI_ObjectContent *virtualMachine,
esxVI_VirtualMachineQuestionInfo **questionInfo);
+int esxVI_GetVirtualMachineMORef
+ (esxVI_ObjectContent *virtualMachine,
+ char **moref);
+
int esxVI_GetBoolean(esxVI_ObjectContent *objectContent,
const char *propertyName,
esxVI_Boolean *value, esxVI_Occurrence occurrence);
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index d1d8184c5..6f96f4cbf 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -553,23 +553,41 @@ static virDomainDefParserConfig virVMXDomainDefParserConfig = {
VIR_DOMAIN_DEF_FEATURE_NAME_SLASH),
};
+struct virVMXDomainDefNamespaceData {
+ char *datacenterPath;
+ char *moref;
+};
+
static void
virVMXDomainDefNamespaceFree(void *nsdata)
{
- VIR_FREE(nsdata);
+ struct virVMXDomainDefNamespaceData *data = nsdata;
+
+ if (data) {
+ VIR_FREE(data->datacenterPath);
+ VIR_FREE(data->moref);
+ }
+ VIR_FREE(data);
}
static int
virVMXDomainDefNamespaceFormatXML(virBufferPtr buf, void *nsdata)
{
- const char *datacenterPath = nsdata;
+ struct virVMXDomainDefNamespaceData *data = nsdata;
- if (!datacenterPath)
+ if (!data)
return 0;
- virBufferAddLit(buf, "<vmware:datacenterpath>");
- virBufferEscapeString(buf, "%s", datacenterPath);
- virBufferAddLit(buf, "</vmware:datacenterpath>\n");
+ if (data->datacenterPath) {
+ virBufferAddLit(buf, "<vmware:datacenterpath>");
+ virBufferEscapeString(buf, "%s", data->datacenterPath);
+ virBufferAddLit(buf, "</vmware:datacenterpath>\n");
+ }
+ if (data->moref) {
+ virBufferAddLit(buf, "<vmware:moref>");
+ virBufferEscapeString(buf, "%s", data->moref);
+ virBufferAddLit(buf, "</vmware:moref>\n");
+ }
return 0;
}
@@ -1304,7 +1322,6 @@ virVMXParseConfig(virVMXContext *ctx,
bool hgfs_disabled = true;
long long sharedFolder_maxNum = 0;
int cpumasklen;
- char *namespaceData;
if (ctx->parseFileName == NULL) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1802,12 +1819,26 @@ virVMXParseConfig(virVMXContext *ctx,
}
/* ctx:datacenterPath -> def:namespaceData */
- if (ctx->datacenterPath) {
- if (VIR_STRDUP(namespaceData, ctx->datacenterPath) < 0)
+ if (ctx->datacenterPath || ctx->moref) {
+ struct virVMXDomainDefNamespaceData *nsdata;
+
+ if (VIR_ALLOC(nsdata) < 0)
goto cleanup;
+ nsdata->datacenterPath = NULL;
+ nsdata->moref = NULL;
+
+ if (ctx->datacenterPath) {
+ if (VIR_STRDUP(nsdata->datacenterPath, ctx->datacenterPath) < 0)
+ goto cleanup;
+ }
+
+ if (ctx->moref) {
+ if (VIR_STRDUP(nsdata->moref, ctx->moref) < 0)
+ goto cleanup;
+ }
def->ns = *virDomainXMLOptionGetNamespace(xmlopt);
- def->namespaceData = namespaceData;
+ def->namespaceData = nsdata;
}
if (virDomainDefPostParse(def, caps, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE,
diff --git a/src/vmx/vmx.h b/src/vmx/vmx.h
index 08b627765..6b3d880d6 100644
--- a/src/vmx/vmx.h
+++ b/src/vmx/vmx.h
@@ -45,6 +45,7 @@ typedef int (*virVMXAutodetectSCSIControllerModel)(virDomainDiskDefPtr def,
* formatFileName is only used by virVMXFormatConfig.
* autodetectSCSIControllerModel is optionally used by virVMXFormatConfig.
* datacenterPath is only used by virVMXFormatConfig.
+ * moref is only used by virVMXFormatConfig.
*/
struct _virVMXContext {
void *opaque;
@@ -52,6 +53,7 @@ struct _virVMXContext {
virVMXFormatFileName formatFileName;
virVMXAutodetectSCSIControllerModel autodetectSCSIControllerModel;
const char *datacenterPath; /* including folders */
+ const char *moref;
};
--
2.13.2
7 years, 2 months