--- Also available for easy review online here for a while: http://justinclift.fedorapeople.org/libvirt_docs/hooks.html docs/hooks.html.in | 226 +++++++++++++++++++++++++++++++++++++-------------- 1 files changed, 164 insertions(+), 62 deletions(-) diff --git a/docs/hooks.html.in b/docs/hooks.html.in index 2afdecf..5eeec27 100644 --- a/docs/hooks.html.in +++ b/docs/hooks.html.in @@ -2,69 +2,171 @@ <html> <body> <h1>Hooks for specific system management</h1> - <p>Libvirt includes synchronous hooks, starting from version 0.8.0, as a - way to tie in specific tailored system actions at a specific time. - If these scripts are present on the host where the hypervisor - is running, then they are called when the libvirt daemon is doingi - some significant action.</p> - <p>The scripts are expected to execute quickly, return a zero exit - status if all conditions are set for the daemon to continue the - action (non zero will be considered a failure which may - be ignored but in general will stop the ongoing operation). - The script also should not call back into libvirt as the daemon - is waiting for the script exit and deadlock is likely to occur.</p> - <p>The scripts are stored in the directory <code>/etc/libvirt/hooks/</code> - when using a standard installation path - (<code>$SYSCONF_DIR/libvirt/hooks/</code> in general).</p> - <p>Each script is given the following command line arguments:</p> - <ul> - <li> the first argument is the name of the object involved in the - operation, or '-' if there is none. - <li> the second argument is the name of the operation. - <li> the third argument is a suboperation indication like 'start' or - 'end', or '-' if there is none. - <li> the last argument is an extra argument string or '-' if there - is none. - </ul> - <p>There are currently scripts for 3 domains of operation: + + <ul id="toc"></ul> + + <h2><a name="intro">Custom event scripts</a></h2> + <p>Beginning with libvirt 0.8.0, specific events on a host system will + trigger custom scripts.</p> + <p>These custom <b>hook</b> scripts are executed when any of the following + actions occur:</p> <ul> - <li><p><code>/etc/libvirt/hooks/daemon</code> script if - present is called at 3 points in time:</p> - <p>at daemon startup, typically started with the following - arguments:</p> - <pre>/etc/libvirt/hooks/daemon - start - start</pre> - <p>at daemon shutdown when it is about to exit, with the following - arguments:</p> - <pre>/etc/libvirt/hooks/daemon - shutdown - shutdown</pre> - <p>When the daemon is asked to reload its driver state when - receiving the SIGHUP signal, arguments are:</p> - <pre>/etc/libvirt/hooks/daemon - reload begin SIGHUP</pre> - </li> - <li><p><code>/etc/libvirt/hooks/qemu</code> script and <br/> - <code>/etc/libvirt/hooks/lxc</code> associate hooks for domain - operation on the respective QEmu/KVM and LXC drivers.</p> - <p> The domain related hooks also receive the full XML description - for the concerned domain on their stdin, which allows them to get - all the information from the domain, including UUID or storage - if that is needed for the script operation.</p> - <p> Currently only domain startup and domain end operations - involve the hook, the first one just before the domain gets - created. - For example if starting a QEmu domain named <code>test</code> - the following script will get called:</p> - <pre>/etc/libvirt/hooks/qemu test start begin -</pre> - <p> note that a non-zero return value from the script will abort the - domain startup operation, and if an error string is passed on - stderr by the hook script, it will be provided back to the user - at the libvirt API level.</p> - <p> For domain shutdown, the script will be called just after the - domain has finished execution, and the script will get:</p> - <pre>/etc/libvirt/hooks/qemu test stopped end -</pre> - <p> It is expected that other operations will be associated to hooks - but at the time of 0.8.0 only those 2 are associated to the - domains life cycle</p> - </li> + <li>The libvirt daemon starts, stops, or reloads its + configuration<br/><br/></li> + <li>A QEMU guest is started or stopped<br/><br/></li> + <li>An LXC guest is started or stopped<br/><br/></li> </ul> - <p></p> + + <h2><a name="location">Script Location</a></h2> + <p>The libvirt hook scripts are located in the directory + <code>$SYSCONF_DIR/etc/libvirt/hooks/</code>. + <p>With Fedora and RHEL, this is <code>/etc/libvirt/hooks/</code>. + On other Linux distributions this may be different.</p> + <br/> + + <h2><a name="names">Script names</a></h2> + <p>At present, there are three hook scripts:</p> + <ul> + <li><code>/etc/libvirt/hooks/daemon</code><br/><br/> + Executed when the libvirt daemon is started, stopped, or reloads + its configuration<br/><br/></li> + <li><code>/etc/libvirt/hooks/qemu</code><br/><br/> + 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> + </ul> + <br/> + + <h2><a name="structure">Script structure</a></h2> + <p>The hook scripts are executed using standard Linux process creation + functions. Therefore, they must begin with the declaration of the + command interpreter to use.</p> + <p>For example:</p> + <pre>#!/bin/bash</pre> + <p>or:</p> + <pre>#!/usr/bin/python</pre> + <p>Other command interpreters are equally valid, as is any executable + binary, so you are welcome to use your favourite languages.</p> + <br/> + + <h2><a name="arguments">Script arguments</a></h2> + <p>The hook scripts are called with specific command line arguments, + depending upon the script, and the operation being performed.</p> + <p>The guest hook scripts, qemu and lxc, are also given the <b>full</b> + XML description for the domain on their stdin. This includes items + such the UUID of the domain and its storage information, and is + intended to provide all the libvirt information the script needs.</p> + + <p>The command line arguments take this approach:</p> + <ol> + <li>The first argument is the name of the <b>object</b> involved in the + operation, or '-' if there is none.<br/><br/> + For example, the name of a guest being started.<br/><br/></li> + <li>The second argument is the name of the <b>operation</b> being + performed.<br/><br/> + For example, "start" if a guest is being started.<br/><br/></li> + <li>The third argument is a <b>sub-operation</b> indication, or '-' if there + is none.<br/><br/></li> + <li>The last argument is an <b>extra argument</b> string, or '-' if there is + none.</li> + </ol> + + <h4><a name="arguments_specifics">Specifics</a></h4> + <p>This translates to the following specifics for each hook script:</p> + + <h5><a name="daemon">/etc/libvirt/hooks/daemon</a></h5> + <ul> + <li>When the libvirt daemon is started, this script is called as:<br/> + <pre>/etc/libvirt/hooks/daemon - start - start</pre></li> + <li>When the libvirt daemon is shut down, this script is called as:<br/> + <pre>/etc/libvirt/hooks/daemon - shutdown - shutdown</pre></li> + <li>When the libvirt daemon receives the SIGHUP signal, it reloads its + configuration and triggers the hook script as:<br/> + <pre>/etc/libvirt/hooks/daemon - reload begin SIGHUP</pre></li> + </ul> + + <h5><a name="qemu">/etc/libvirt/hooks/qemu</a></h5> + <ul> + <li>When a QEMU guest is started, the qemu hook script is called as:<br/> + <pre>/etc/libvirt/hooks/qemu guest_name start begin -</pre></li> + <li>When a QEMU guest is stopped, the qemu hook script is called + as:<br/> + <pre>/etc/libvirt/hooks/qemu guest_name stopped end -</pre></li> + </ul> + + <h5><a name="lxc">/etc/libvirt/hooks/lxc</a></h5> + <ul> + <li>When an LXC guest is started, the lxc hook script is called as:<br/> + <pre>/etc/libvirt/hooks/lxc guest_name start begin -</pre></li> + <li>When a LXC guest is stopped, the lxc hook script is called + as:<br/> + <pre>/etc/libvirt/hooks/lxc guest_name stopped end -</pre></li> + </ul> + <br/> + + <h2><a name="execution">Script execution</a></h2> + <ul> + <li>The "start" operation for the guest hook scripts, qemu and lxc, + executes <b>prior</b> to the guest being created. This allows the + guest start operation to be aborted if the script returns indicating + failure.<br/><br/></li> + <li>The "shutdown" operation for the guest hook scripts, qemu and lxc, + executes <b>after</b> the guest has stopped. If the hook script + indicates failure in its return, the shut down of the guest cannot + be aborted because it has already been performed.<br/><br/></li> + <li>Hook scripts execute in a synchronous fashion. Libvirt waits + for them to return before continuing the given operation.<br/><br/> + This is most noticeable with the guest start operation, as a lengthy + operation in the hook script can mean an extended wait for the guest + to be available to end users.<br/><br/></li> + <li>For a hook script to be utilised, it have it's execute bit set + (ie. chmod +x <i>qemu</i>), and must be present when the libvirt + daemon is started.<br/><br/></li> + <li>If a hook script is added to a host after the libvirt daemon is + already running, it won't be used until the libvirt daemon + next starts.</li> + </ul> + <br/> + + <h2><a name="qemu_migration">QEMU guest migration</a></h2> + <p>Migration of a QEMU guest involves running the hook scripts on both the + source and destination hosts:</p> + <ol> + <li>At the beginning of the migration, the <i>qemu</i> hook script on + the <b>destination</b> host is executed with the "start" + operation.<br/><br/></li> + <li>If this hook script returns indicating success (error code 0), the + migration continues. Any other return code indicates failure, and + the migration is aborted.<br/><br/></li> + <li>The QEMU guest is then migrated to the destination host.<br/> + <br/></li> + <li>Unless an error occurs during the migration process, the <i>qemu</i> + hook script on the source host is then executed with the "stopped" + operation, to indicate it is no longer running on this + host.<br/><br/> + Regardless of the return code from this hook script, the migration + is not aborted as it has already been performed.</li> + </ol> + <br/> + + <h2><a name="recursive">Calling libvirt functions from within a hook script</a></h2> + <p><b>DO NOT DO THIS!</b></p> + <p>A hook script must not call back into libvirt, as the libvirt daemon + is already waiting for the script to exit.</p> + <p>A deadlock is likely to occur.</p> + <br/> + + <h2><a name="return_codes">Return codes and logging</a></h2> + <p>If a hook script returns with an exit code of 0, the libvirt daemon + regards this as successful and performs no logging of it.</p> + <p>However, if a hook script returns with a non zero exit code, the libvirt + daemon regards this as a failure, logs it with return code 256, and + additionally logs anything on stderr the hook script returns.</p> + <p>For example, a hook script might use this code to indicate failure, + and send a text string to stderr:</p> + <pre>echo "Could not find required XYZZY" >&2 +exit 1</pre> + <p>The resulting entry in the libvirt log will appear as:</p> + <pre>20:02:40.297: error : virHookCall:416 : Hook script execution failed: Hook script /etc/libvirt/hooks/qemu qemu failed with error code 256:Could not find required XYZZY</pre> </body> </html> -- 1.7.2 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list