mirror of https://gitee.com/openkylin/libvirt.git
qemu: hook: Provide hook when restoring a domain save image
This commit is contained in:
parent
a552a86e1a
commit
4f3c2e39e5
|
@ -177,6 +177,17 @@
|
|||
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 1.2.9</span>, the qemu hook script is
|
||||
also called when restoring a saved image either via the API or
|
||||
automatically when restoring a managed save machine. It is called
|
||||
as: <pre>/etc/libvirt/hooks/qemu guest_name restore 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, restore of the
|
||||
image will be aborted. This hook may be used, e.g., to change
|
||||
location of disk images for restored domains.</li>
|
||||
<li><span class="since">Since 0.9.13</span>, the qemu hook script
|
||||
is also called when the libvirtd daemon restarts and reconnects
|
||||
to previously running QEMU processes. If the script fails, the
|
||||
|
|
|
@ -5644,20 +5644,24 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
|||
unsigned int flags)
|
||||
{
|
||||
virQEMUDriverPtr driver = conn->privateData;
|
||||
qemuDomainObjPrivatePtr priv = NULL;
|
||||
virDomainDefPtr def = NULL;
|
||||
virDomainDefPtr newdef = NULL;
|
||||
virDomainObjPtr vm = NULL;
|
||||
char *xml = NULL;
|
||||
char *xmlout = NULL;
|
||||
const char *newxml = dxml;
|
||||
int fd = -1;
|
||||
int ret = -1;
|
||||
virQEMUSaveHeader header;
|
||||
virFileWrapperFdPtr wrapperFd = NULL;
|
||||
bool hook_taint = false;
|
||||
|
||||
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
|
||||
VIR_DOMAIN_SAVE_RUNNING |
|
||||
VIR_DOMAIN_SAVE_PAUSED, -1);
|
||||
|
||||
|
||||
fd = qemuDomainSaveImageOpen(driver, path, &def, &header, NULL,
|
||||
fd = qemuDomainSaveImageOpen(driver, path, &def, &header, &xml,
|
||||
(flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
|
||||
&wrapperFd, false, false);
|
||||
if (fd < 0)
|
||||
|
@ -5666,12 +5670,31 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
|||
if (virDomainRestoreFlagsEnsureACL(conn, def) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (dxml) {
|
||||
if (!(newdef = qemuDomainSaveImageUpdateDef(driver, def, dxml)))
|
||||
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
|
||||
int hookret;
|
||||
|
||||
if ((hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
|
||||
VIR_HOOK_QEMU_OP_RESTORE,
|
||||
VIR_HOOK_SUBOP_BEGIN,
|
||||
NULL,
|
||||
dxml ? dxml : xml,
|
||||
&xmlout)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (hookret == 0 && xmlout) {
|
||||
VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
|
||||
hook_taint = true;
|
||||
newxml = xmlout;
|
||||
}
|
||||
}
|
||||
|
||||
if (newxml) {
|
||||
virDomainDefPtr tmp;
|
||||
if (!(tmp = qemuDomainSaveImageUpdateDef(driver, def, newxml)))
|
||||
goto cleanup;
|
||||
|
||||
virDomainDefFree(def);
|
||||
def = newdef;
|
||||
def = tmp;
|
||||
}
|
||||
|
||||
if (!(vm = virDomainObjListAdd(driver->domains, def,
|
||||
|
@ -5687,6 +5710,11 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
|||
else if (flags & VIR_DOMAIN_SAVE_PAUSED)
|
||||
header.was_running = 0;
|
||||
|
||||
if (hook_taint) {
|
||||
priv = vm->privateData;
|
||||
priv->hookRun = true;
|
||||
}
|
||||
|
||||
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
||||
goto cleanup;
|
||||
|
||||
|
@ -5705,6 +5733,8 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
|||
cleanup:
|
||||
virDomainDefFree(def);
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
VIR_FREE(xml);
|
||||
VIR_FREE(xmlout);
|
||||
virFileWrapperFdFree(wrapperFd);
|
||||
if (vm)
|
||||
virObjectUnlock(vm);
|
||||
|
@ -5842,12 +5872,15 @@ qemuDomainObjRestore(virConnectPtr conn,
|
|||
bool bypass_cache)
|
||||
{
|
||||
virDomainDefPtr def = NULL;
|
||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||
int fd = -1;
|
||||
int ret = -1;
|
||||
char *xml = NULL;
|
||||
char *xmlout = NULL;
|
||||
virQEMUSaveHeader header;
|
||||
virFileWrapperFdPtr wrapperFd = NULL;
|
||||
|
||||
fd = qemuDomainSaveImageOpen(driver, path, &def, &header, NULL,
|
||||
fd = qemuDomainSaveImageOpen(driver, path, &def, &header, &xml,
|
||||
bypass_cache, &wrapperFd, false, true);
|
||||
if (fd < 0) {
|
||||
if (fd == -3)
|
||||
|
@ -5855,6 +5888,29 @@ qemuDomainObjRestore(virConnectPtr conn,
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
|
||||
int hookret;
|
||||
|
||||
if ((hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
|
||||
VIR_HOOK_QEMU_OP_RESTORE,
|
||||
VIR_HOOK_SUBOP_BEGIN,
|
||||
NULL, xml, &xmlout)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (hookret == 0 && xmlout) {
|
||||
virDomainDefPtr tmp;
|
||||
|
||||
VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
|
||||
|
||||
if (!(tmp = qemuDomainSaveImageUpdateDef(driver, def, xmlout)))
|
||||
goto cleanup;
|
||||
|
||||
virDomainDefFree(def);
|
||||
def = tmp;
|
||||
priv->hookRun = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (STRNEQ(vm->def->name, def->name) ||
|
||||
memcmp(vm->def->uuid, def->uuid, VIR_UUID_BUFLEN)) {
|
||||
char vm_uuidstr[VIR_UUID_STRING_BUFLEN];
|
||||
|
@ -5878,6 +5934,8 @@ qemuDomainObjRestore(virConnectPtr conn,
|
|||
VIR_WARN("Failed to close %s", path);
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(xml);
|
||||
VIR_FREE(xmlout);
|
||||
virDomainDefFree(def);
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
virFileWrapperFdFree(wrapperFd);
|
||||
|
|
|
@ -77,7 +77,8 @@ VIR_ENUM_IMPL(virHookQemuOp, VIR_HOOK_QEMU_OP_LAST,
|
|||
"migrate",
|
||||
"started",
|
||||
"reconnect",
|
||||
"attach")
|
||||
"attach",
|
||||
"restore")
|
||||
|
||||
VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
|
||||
"start",
|
||||
|
|
|
@ -60,6 +60,7 @@ typedef enum {
|
|||
VIR_HOOK_QEMU_OP_STARTED, /* domain has started */
|
||||
VIR_HOOK_QEMU_OP_RECONNECT, /* domain is being reconnected by libvirt */
|
||||
VIR_HOOK_QEMU_OP_ATTACH, /* domain is being attached to be libvirt */
|
||||
VIR_HOOK_QEMU_OP_RESTORE, /* domain is being restored */
|
||||
|
||||
VIR_HOOK_QEMU_OP_LAST,
|
||||
} virHookQemuOpType;
|
||||
|
|
Loading…
Reference in New Issue