mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-27 13:52:20 +00:00
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
|
called again, <span class="since">since 0.9.0</span>, to allow
|
||||||
any additional resource cleanup:<br/>
|
any additional resource cleanup:<br/>
|
||||||
<pre>/etc/libvirt/hooks/qemu guest_name release end -</pre></li>
|
<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>
|
</ul>
|
||||||
|
|
||||||
<h5><a name="lxc">/etc/libvirt/hooks/lxc</a></h5>
|
<h5><a name="lxc">/etc/libvirt/hooks/lxc</a></h5>
|
||||||
@ -161,19 +171,20 @@
|
|||||||
source and destination hosts:</p>
|
source and destination hosts:</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li>At the beginning of the migration, the <i>qemu</i> hook script on
|
<li>At the beginning of the migration, the <i>qemu</i> hook script on
|
||||||
the <b>destination</b> host is executed with the "start"
|
the <b>destination</b> host is executed with the "migrate"
|
||||||
operation.<br/><br/></li>
|
operation.</li>
|
||||||
<li>If this hook script returns indicating success (error code 0), the
|
<li>Before QEMU process is spawned, the two operations ("prepare" and
|
||||||
migration continues. Any other return code indicates failure, and
|
"start") called for domain start are executed on
|
||||||
the migration is aborted.<br/><br/></li>
|
<b>destination</b> host.</li>
|
||||||
<li>The QEMU guest is then migrated to the destination host.<br/>
|
<li>If both of these hook script executions exit successfully (exit
|
||||||
<br/></li>
|
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>
|
<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"
|
hook script on the <b>source</b> host is then executed with the
|
||||||
operation, to indicate it is no longer running on this
|
"stopped" and "release" operations to indicate it is no longer
|
||||||
host.<br/><br/>
|
running on this host. Regardless of the return codes, the
|
||||||
Regardless of the return code from this hook script, the migration
|
migration is not aborted as it has already been performed.</li>
|
||||||
is not aborted as it has already been performed.</li>
|
|
||||||
</ol>
|
</ol>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include "rpc/virnetsocket.h"
|
#include "rpc/virnetsocket.h"
|
||||||
#include "storage_file.h"
|
#include "storage_file.h"
|
||||||
#include "viruri.h"
|
#include "viruri.h"
|
||||||
|
#include "hooks.h"
|
||||||
|
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||||
@ -1130,6 +1131,7 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
|
|||||||
qemuMigrationCookiePtr mig = NULL;
|
qemuMigrationCookiePtr mig = NULL;
|
||||||
bool tunnel = !!st;
|
bool tunnel = !!st;
|
||||||
char *origname = NULL;
|
char *origname = NULL;
|
||||||
|
char *xmlout = NULL;
|
||||||
|
|
||||||
if (virTimeMillisNow(&now) < 0)
|
if (virTimeMillisNow(&now) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
@ -1150,6 +1152,46 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
|
|||||||
goto cleanup;
|
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)
|
if (virDomainObjIsDuplicate(&driver->domains, def, 1) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -1244,6 +1286,7 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(origname);
|
VIR_FREE(origname);
|
||||||
|
VIR_FREE(xmlout);
|
||||||
virDomainDefFree(def);
|
virDomainDefFree(def);
|
||||||
VIR_FORCE_CLOSE(dataFD[0]);
|
VIR_FORCE_CLOSE(dataFD[0]);
|
||||||
VIR_FORCE_CLOSE(dataFD[1]);
|
VIR_FORCE_CLOSE(dataFD[1]);
|
||||||
|
@ -73,7 +73,8 @@ VIR_ENUM_IMPL(virHookQemuOp, VIR_HOOK_QEMU_OP_LAST,
|
|||||||
"start",
|
"start",
|
||||||
"stopped",
|
"stopped",
|
||||||
"prepare",
|
"prepare",
|
||||||
"release")
|
"release",
|
||||||
|
"migrate")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
|
VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
|
||||||
"start",
|
"start",
|
||||||
|
@ -56,6 +56,7 @@ enum virHookQemuOpType {
|
|||||||
VIR_HOOK_QEMU_OP_STOPPED, /* domain has stopped */
|
VIR_HOOK_QEMU_OP_STOPPED, /* domain has stopped */
|
||||||
VIR_HOOK_QEMU_OP_PREPARE, /* domain startup initiated */
|
VIR_HOOK_QEMU_OP_PREPARE, /* domain startup initiated */
|
||||||
VIR_HOOK_QEMU_OP_RELEASE, /* domain destruction is over */
|
VIR_HOOK_QEMU_OP_RELEASE, /* domain destruction is over */
|
||||||
|
VIR_HOOK_QEMU_OP_MIGRATE, /* domain is being migrated */
|
||||||
|
|
||||||
VIR_HOOK_QEMU_OP_LAST,
|
VIR_HOOK_QEMU_OP_LAST,
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user