On 28.07.2016 11:57, Cédric Bosdonnat wrote:
Introduce libxl hook and use it for start, prepare, started,
stop, stopped, migrate events.
---
docs/hooks.html.in | 53 ++++++++++++++++++++++++++++++--
src/libxl/libxl_domain.c | 74 +++++++++++++++++++++++++++++++++++++++++++++
src/libxl/libxl_driver.c | 22 ++++++++++++++
src/libxl/libxl_migration.c | 57 ++++++++++++++++++++++++++++++++++
src/util/virhook.c | 16 +++++++++-
src/util/virhook.h | 13 ++++++++
6 files changed, 232 insertions(+), 3 deletions(-)
diff --git a/docs/hooks.html.in b/docs/hooks.html.in
index d4f4ac3..11073cb 100644
--- a/docs/hooks.html.in
+++ b/docs/hooks.html.in
@@ -17,8 +17,10 @@
(<span class="since">since
0.8.0</span>)<br/><br/></li>
<li>A QEMU guest is started or stopped
(<span class="since">since
0.8.0</span>)<br/><br/></li>
- <li>An LXC guest is started or stopped
+ <li>An LXC guest is started or stopped
(<span class="since">since
0.8.0</span>)<br/><br/></li>
+ <li>A libxl-handled Xen guest is started or stopped
+ (<span class="since">since
2.1.0</span>)<br/><br/></li>
<li>A network is started or stopped or an interface is
plugged/unplugged to/from the network
(<span class="since">since
1.2.2</span>)<br/><br/></li>
@@ -41,7 +43,7 @@
<br/>
<h2><a name="names">Script names</a></h2>
- <p>At present, there are three hook scripts that can be called:</p>
+ <p>At present, there are five hook scripts that can be called:</p>
<ul>
<li><code>/etc/libvirt/hooks/daemon</code><br/><br/>
Executed when the libvirt daemon is started, stopped, or reloads
@@ -50,6 +52,9 @@
Executed when a QEMU guest is started, stopped, or
migrated<br/><br/></li>
<li><code>/etc/libvirt/hooks/lxc</code><br /><br/>
Executed when an LXC guest is started or stopped</li>
+ <li><code>/etc/libvirt/hooks/libxl</code><br/><br/>
+ Executed when a libxl-handled Xen guest is started, stopped, or
+ migrated<br/><br/></li>
<li><code>/etc/libvirt/hooks/network</code><br/><br/>
Executed when a network is started or stopped or an
interface is plugged/unplugged to/from the network</li>
@@ -235,6 +240,50 @@
</li>
</ul>
+ <h5><a
name="libxl">/etc/libvirt/hooks/libxl</a></h5>
+ <ul>
+ <li>Before a Xen guest is started using libxl driver, the libxl hook
+ script is called in three locations; if any location fails, the guest
+ is not started. The first location, <span class="since">since
+ 2.1.0</span>, is before libvirt performs any resource
+ labeling, and the hook can allocate resources not managed by
+ libvirt. This is called as:<br/>
+ <pre>/etc/libvirt/hooks/libxl guest_name prepare begin -</pre>
+ The second location, available <span class="since">Since
+ 2.1.0</span>, occurs after libvirt has finished labeling
+ all resources, but has not yet started the guest, called as:<br/>
+ <pre>/etc/libvirt/hooks/libxl guest_name start begin -</pre>
+ The third location, <span class="since">2.1.0</span>,
+ occurs after the domain has successfully started up:<br/>
+ <pre>/etc/libvirt/hooks/libxl guest_name started begin -</pre>
+ </li>
+ <li>When a libxl-handled Xen guest is stopped, the libxl hook script
+ is called in two locations, to match the startup.
+ First, <span class="since">since 2.1.0</span>, the hook
is
+ called before libvirt restores any labels:<br/>
+ <pre>/etc/libvirt/hooks/libxl guest_name stopped end -</pre>
+ Then, after libvirt has released all resources, the hook is
+ called again, <span class="since">since 2.1.0</span>, to
allow
+ any additional resource cleanup:<br/>
+ <pre>/etc/libvirt/hooks/libxl guest_name release end
-</pre></li>
+ <li><span class="since">Since 2.1.0</span>, the libxl
hook script
+ is also called at the beginning of incoming migration. It is called
+ as: <pre>/etc/libvirt/hooks/libxl guest_name migrate begin -</pre>
+ with domain XML sent to standard input of the script. In this case,
+ the script acts as a filter and is supposed to modify the domain
+ XML and print it out on its standard output. Empty output is
+ identical to copying the input XML without changing it. In case the
+ script returns failure or the output XML is not valid, incoming
+ migration will be canceled. This hook may be used, e.g., to change
+ location of disk images for incoming domains.</li>
+ <li><span class="since">Since 2.1.0</span>, the libxl
hook script
+ is also called when the libvirtd daemon restarts and reconnects
+ to previously running Xen domains. If the script fails, the
+ existing Xen domains will be killed off. It is called as:
+ <pre>/etc/libvirt/hooks/libxl guest_name reconnect begin -</pre>
+ </li>
+ </ul>
+
<h5><a
name="network">/etc/libvirt/hooks/network</a></h5>
<ul>
<li><span class="since">Since 1.2.2</span>, before a
network is started,
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 886b40f..d99f903 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -32,6 +32,7 @@
#include "viratomic.h"
#include "virfile.h"
#include "virerror.h"
+#include "virhook.h"
#include "virlog.h"
#include "virstring.h"
#include "virtime.h"
@@ -737,6 +738,17 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver,
hostdev_flags |= VIR_HOSTDEV_SP_USB;
#endif
+ /* now that we know it's stopped call the hook if present */
+ if (virHookPresent(VIR_HOOK_DRIVER_LIBXL)) {
+ char *xml = virDomainDefFormat(vm->def, cfg->caps, 0);
+
+ /* we can't stop the operation even if the script raised an error */
+ ignore_value(virHookCall(VIR_HOOK_DRIVER_LIBXL, vm->def->name,
+ VIR_HOOK_LIBXL_OP_STOPPED, VIR_HOOK_SUBOP_END,
+ NULL, xml, NULL));
Here ^^
+ VIR_FREE(xml);
+ }
+
virHostdevReAttachDomainDevices(hostdev_mgr, LIBXL_DRIVER_NAME,
vm->def, hostdev_flags, NULL);
@@ -788,6 +800,17 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver,
VIR_FREE(file);
}
+ /* The "release" hook cleans up additional resources */
+ if (virHookPresent(VIR_HOOK_DRIVER_LIBXL)) {
+ char *xml = virDomainDefFormat(vm->def, cfg->caps, 0);
+
+ /* we can't stop the operation even if the script raised an error */
+ ignore_value(virHookCall(VIR_HOOK_DRIVER_LIBXL, vm->def->name,
+ VIR_HOOK_LIBXL_OP_RELEASE, VIR_HOOK_SUBOP_END,
+ NULL, xml, NULL);
And here ^^^ I'd drop the ignore_value(). The virHookCall() is not
declared with CHECK_RETURN, so there's no need for ignore_value() macro.
+ VIR_FREE(xml);
+ }
+
Michal