mirror of https://gitee.com/openkylin/libvirt.git
qemu: Add pre-migration hook
This hook is called during the Prepare phase on destination host and may be used for changing domain XML.
This commit is contained in:
parent
8ab785783f
commit
04dec5826d
|
@ -120,6 +120,16 @@
|
|||
called again, <span class="since">since 0.9.0</span>, to allow
|
||||
any additional resource cleanup:<br/>
|
||||
<pre>/etc/libvirt/hooks/qemu guest_name release end -</pre></li>
|
||||
<li><span class="since">Since 0.9.11</span>, the qemu hook script
|
||||
is also called at the beginning of incoming migration. It is called
|
||||
as: <pre>/etc/libvirt/hooks/qemu 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>
|
||||
</ul>
|
||||
|
||||
<h5><a name="lxc">/etc/libvirt/hooks/lxc</a></h5>
|
||||
|
@ -161,19 +171,20 @@
|
|||
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>
|
||||
the <b>destination</b> host is executed with the "migrate"
|
||||
operation.</li>
|
||||
<li>Before QEMU process is spawned, the two operations ("prepare" and
|
||||
"start") called for domain start are executed on
|
||||
<b>destination</b> host.</li>
|
||||
<li>If both of these hook script executions exit successfully (exit
|
||||
status 0), the migration continues. Any other exit code indicates
|
||||
failure, and the migration is aborted.</li>
|
||||
<li>The QEMU guest is then migrated to the destination host.</li>
|
||||
<li>Unless an error occurs during the migration process, the <i>qemu</i>
|
||||
hook script on the <b>source</b> 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>
|
||||
hook script on the <b>source</b> host is then executed with the
|
||||
"stopped" and "release" operations to indicate it is no longer
|
||||
running on this host. Regardless of the return codes, the
|
||||
migration is not aborted as it has already been performed.</li>
|
||||
</ol>
|
||||
<br/>
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "rpc/virnetsocket.h"
|
||||
#include "storage_file.h"
|
||||
#include "viruri.h"
|
||||
#include "hooks.h"
|
||||
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||
|
@ -1130,6 +1131,7 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
|
|||
qemuMigrationCookiePtr mig = NULL;
|
||||
bool tunnel = !!st;
|
||||
char *origname = NULL;
|
||||
char *xmlout = NULL;
|
||||
|
||||
if (virTimeMillisNow(&now) < 0)
|
||||
return -1;
|
||||
|
@ -1150,6 +1152,46 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Let migration hook filter domain XML */
|
||||
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
|
||||
char *xml;
|
||||
int hookret;
|
||||
|
||||
if (!(xml = virDomainDefFormat(def, VIR_DOMAIN_XML_SECURE)))
|
||||
goto cleanup;
|
||||
|
||||
hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
|
||||
VIR_HOOK_QEMU_OP_MIGRATE, VIR_HOOK_SUBOP_BEGIN,
|
||||
NULL, xml, &xmlout);
|
||||
VIR_FREE(xml);
|
||||
|
||||
if (hookret < 0) {
|
||||
goto cleanup;
|
||||
} else if (hookret == 0) {
|
||||
if (!*xmlout) {
|
||||
VIR_DEBUG("Migrate hook filter returned nothing; using the"
|
||||
" original XML");
|
||||
} else {
|
||||
virDomainDefPtr newdef;
|
||||
|
||||
VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
|
||||
newdef = virDomainDefParseString(driver->caps, xmlout,
|
||||
QEMU_EXPECTED_VIRT_TYPES,
|
||||
VIR_DOMAIN_XML_INACTIVE);
|
||||
if (!newdef)
|
||||
goto cleanup;
|
||||
|
||||
if (!virDomainDefCheckABIStability(def, newdef)) {
|
||||
virDomainDefFree(newdef);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
virDomainDefFree(def);
|
||||
def = newdef;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
|
||||
goto cleanup;
|
||||
|
||||
|
@ -1244,6 +1286,7 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
|
|||
|
||||
cleanup:
|
||||
VIR_FREE(origname);
|
||||
VIR_FREE(xmlout);
|
||||
virDomainDefFree(def);
|
||||
VIR_FORCE_CLOSE(dataFD[0]);
|
||||
VIR_FORCE_CLOSE(dataFD[1]);
|
||||
|
|
|
@ -73,7 +73,8 @@ VIR_ENUM_IMPL(virHookQemuOp, VIR_HOOK_QEMU_OP_LAST,
|
|||
"start",
|
||||
"stopped",
|
||||
"prepare",
|
||||
"release")
|
||||
"release",
|
||||
"migrate")
|
||||
|
||||
VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
|
||||
"start",
|
||||
|
|
|
@ -56,6 +56,7 @@ enum virHookQemuOpType {
|
|||
VIR_HOOK_QEMU_OP_STOPPED, /* domain has stopped */
|
||||
VIR_HOOK_QEMU_OP_PREPARE, /* domain startup initiated */
|
||||
VIR_HOOK_QEMU_OP_RELEASE, /* domain destruction is over */
|
||||
VIR_HOOK_QEMU_OP_MIGRATE, /* domain is being migrated */
|
||||
|
||||
VIR_HOOK_QEMU_OP_LAST,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue