|
|
9119d9 |
From daa6ee36e4fc3e17119231f110b4de770ffd2b6c Mon Sep 17 00:00:00 2001
|
|
|
9119d9 |
Message-Id: <daa6ee36e4fc3e17119231f110b4de770ffd2b6c@dist-git>
|
|
|
9119d9 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
9119d9 |
Date: Mon, 22 Sep 2014 17:52:40 +0200
|
|
|
9119d9 |
Subject: [PATCH] qemu: hook: Provide hook when restoring a domain save image
|
|
|
9119d9 |
|
|
|
9119d9 |
https://bugzilla.redhat.com/show_bug.cgi?id=1142693
|
|
|
9119d9 |
|
|
|
9119d9 |
(cherry picked from commit 4f3c2e39e5c898c533ddf58b62b452a674df794d)
|
|
|
9119d9 |
|
|
|
9119d9 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
9119d9 |
---
|
|
|
9119d9 |
docs/hooks.html.in | 11 ++++++++
|
|
|
9119d9 |
src/qemu/qemu_driver.c | 70 +++++++++++++++++++++++++++++++++++++++++++++-----
|
|
|
9119d9 |
src/util/virhook.c | 3 ++-
|
|
|
9119d9 |
src/util/virhook.h | 1 +
|
|
|
9119d9 |
4 files changed, 78 insertions(+), 7 deletions(-)
|
|
|
9119d9 |
|
|
|
9119d9 |
diff --git a/docs/hooks.html.in b/docs/hooks.html.in
|
|
|
9119d9 |
index 07b9d49..1aae00c 100644
|
|
|
9119d9 |
--- a/docs/hooks.html.in
|
|
|
9119d9 |
+++ b/docs/hooks.html.in
|
|
|
9119d9 |
@@ -177,6 +177,17 @@
|
|
|
9119d9 |
script returns failure or the output XML is not valid, incoming
|
|
|
9119d9 |
migration will be canceled. This hook may be used, e.g., to change
|
|
|
9119d9 |
location of disk images for incoming domains.
|
|
|
9119d9 |
+ Since 1.2.9, the qemu hook script is
|
|
|
9119d9 |
+ also called when restoring a saved image either via the API or
|
|
|
9119d9 |
+ automatically when restoring a managed save machine. It is called
|
|
|
9119d9 |
+ as: /etc/libvirt/hooks/qemu guest_name restore begin -
|
|
|
9119d9 |
+ with domain XML sent to standard input of the script. In this case,
|
|
|
9119d9 |
+ the script acts as a filter and is supposed to modify the domain
|
|
|
9119d9 |
+ XML and print it out on its standard output. Empty output is
|
|
|
9119d9 |
+ identical to copying the input XML without changing it. In case the
|
|
|
9119d9 |
+ script returns failure or the output XML is not valid, restore of the
|
|
|
9119d9 |
+ image will be aborted. This hook may be used, e.g., to change
|
|
|
9119d9 |
+ location of disk images for restored domains.
|
|
|
9119d9 |
Since 0.9.13, the qemu hook script
|
|
|
9119d9 |
is also called when the libvirtd daemon restarts and reconnects
|
|
|
9119d9 |
to previously running QEMU processes. If the script fails, the
|
|
|
9119d9 |
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
|
9119d9 |
index 580ac17..8f655e5 100644
|
|
|
9119d9 |
--- a/src/qemu/qemu_driver.c
|
|
|
9119d9 |
+++ b/src/qemu/qemu_driver.c
|
|
|
9119d9 |
@@ -5643,20 +5643,24 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
|
|
9119d9 |
unsigned int flags)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
virQEMUDriverPtr driver = conn->privateData;
|
|
|
9119d9 |
+ qemuDomainObjPrivatePtr priv = NULL;
|
|
|
9119d9 |
virDomainDefPtr def = NULL;
|
|
|
9119d9 |
- virDomainDefPtr newdef = NULL;
|
|
|
9119d9 |
virDomainObjPtr vm = NULL;
|
|
|
9119d9 |
+ char *xml = NULL;
|
|
|
9119d9 |
+ char *xmlout = NULL;
|
|
|
9119d9 |
+ const char *newxml = dxml;
|
|
|
9119d9 |
int fd = -1;
|
|
|
9119d9 |
int ret = -1;
|
|
|
9119d9 |
virQEMUSaveHeader header;
|
|
|
9119d9 |
virFileWrapperFdPtr wrapperFd = NULL;
|
|
|
9119d9 |
+ bool hook_taint = false;
|
|
|
9119d9 |
|
|
|
9119d9 |
virCheckFlags(VIR_DOMAIN_SAVE_BYPASS_CACHE |
|
|
|
9119d9 |
VIR_DOMAIN_SAVE_RUNNING |
|
|
|
9119d9 |
VIR_DOMAIN_SAVE_PAUSED, -1);
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
- fd = qemuDomainSaveImageOpen(driver, path, &def, &header, NULL,
|
|
|
9119d9 |
+ fd = qemuDomainSaveImageOpen(driver, path, &def, &header, &xml,
|
|
|
9119d9 |
(flags & VIR_DOMAIN_SAVE_BYPASS_CACHE) != 0,
|
|
|
9119d9 |
&wrapperFd, false, false);
|
|
|
9119d9 |
if (fd < 0)
|
|
|
9119d9 |
@@ -5665,12 +5669,31 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
|
|
9119d9 |
if (virDomainRestoreFlagsEnsureACL(conn, def) < 0)
|
|
|
9119d9 |
goto cleanup;
|
|
|
9119d9 |
|
|
|
9119d9 |
- if (dxml) {
|
|
|
9119d9 |
- if (!(newdef = qemuDomainSaveImageUpdateDef(driver, def, dxml)))
|
|
|
9119d9 |
+ if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
|
|
|
9119d9 |
+ int hookret;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if ((hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
|
|
|
9119d9 |
+ VIR_HOOK_QEMU_OP_RESTORE,
|
|
|
9119d9 |
+ VIR_HOOK_SUBOP_BEGIN,
|
|
|
9119d9 |
+ NULL,
|
|
|
9119d9 |
+ dxml ? dxml : xml,
|
|
|
9119d9 |
+ &xmlout)) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (hookret == 0 && xmlout) {
|
|
|
9119d9 |
+ VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
|
|
|
9119d9 |
+ hook_taint = true;
|
|
|
9119d9 |
+ newxml = xmlout;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (newxml) {
|
|
|
9119d9 |
+ virDomainDefPtr tmp;
|
|
|
9119d9 |
+ if (!(tmp = qemuDomainSaveImageUpdateDef(driver, def, newxml)))
|
|
|
9119d9 |
goto cleanup;
|
|
|
9119d9 |
|
|
|
9119d9 |
virDomainDefFree(def);
|
|
|
9119d9 |
- def = newdef;
|
|
|
9119d9 |
+ def = tmp;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
if (!(vm = virDomainObjListAdd(driver->domains, def,
|
|
|
9119d9 |
@@ -5686,6 +5709,11 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
|
|
9119d9 |
else if (flags & VIR_DOMAIN_SAVE_PAUSED)
|
|
|
9119d9 |
header.was_running = 0;
|
|
|
9119d9 |
|
|
|
9119d9 |
+ if (hook_taint) {
|
|
|
9119d9 |
+ priv = vm->privateData;
|
|
|
9119d9 |
+ priv->hookRun = true;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
|
|
|
9119d9 |
goto cleanup;
|
|
|
9119d9 |
|
|
|
9119d9 |
@@ -5704,6 +5732,8 @@ qemuDomainRestoreFlags(virConnectPtr conn,
|
|
|
9119d9 |
cleanup:
|
|
|
9119d9 |
virDomainDefFree(def);
|
|
|
9119d9 |
VIR_FORCE_CLOSE(fd);
|
|
|
9119d9 |
+ VIR_FREE(xml);
|
|
|
9119d9 |
+ VIR_FREE(xmlout);
|
|
|
9119d9 |
virFileWrapperFdFree(wrapperFd);
|
|
|
9119d9 |
if (vm)
|
|
|
9119d9 |
virObjectUnlock(vm);
|
|
|
9119d9 |
@@ -5841,12 +5871,15 @@ qemuDomainObjRestore(virConnectPtr conn,
|
|
|
9119d9 |
bool bypass_cache)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
virDomainDefPtr def = NULL;
|
|
|
9119d9 |
+ qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
9119d9 |
int fd = -1;
|
|
|
9119d9 |
int ret = -1;
|
|
|
9119d9 |
+ char *xml = NULL;
|
|
|
9119d9 |
+ char *xmlout = NULL;
|
|
|
9119d9 |
virQEMUSaveHeader header;
|
|
|
9119d9 |
virFileWrapperFdPtr wrapperFd = NULL;
|
|
|
9119d9 |
|
|
|
9119d9 |
- fd = qemuDomainSaveImageOpen(driver, path, &def, &header, NULL,
|
|
|
9119d9 |
+ fd = qemuDomainSaveImageOpen(driver, path, &def, &header, &xml,
|
|
|
9119d9 |
bypass_cache, &wrapperFd, false, true);
|
|
|
9119d9 |
if (fd < 0) {
|
|
|
9119d9 |
if (fd == -3)
|
|
|
9119d9 |
@@ -5854,6 +5887,29 @@ qemuDomainObjRestore(virConnectPtr conn,
|
|
|
9119d9 |
goto cleanup;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
+ if (virHookPresent(VIR_HOOK_DRIVER_QEMU)) {
|
|
|
9119d9 |
+ int hookret;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if ((hookret = virHookCall(VIR_HOOK_DRIVER_QEMU, def->name,
|
|
|
9119d9 |
+ VIR_HOOK_QEMU_OP_RESTORE,
|
|
|
9119d9 |
+ VIR_HOOK_SUBOP_BEGIN,
|
|
|
9119d9 |
+ NULL, xml, &xmlout)) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (hookret == 0 && xmlout) {
|
|
|
9119d9 |
+ virDomainDefPtr tmp;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ VIR_DEBUG("Using hook-filtered domain XML: %s", xmlout);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!(tmp = qemuDomainSaveImageUpdateDef(driver, def, xmlout)))
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ virDomainDefFree(def);
|
|
|
9119d9 |
+ def = tmp;
|
|
|
9119d9 |
+ priv->hookRun = true;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
if (STRNEQ(vm->def->name, def->name) ||
|
|
|
9119d9 |
memcmp(vm->def->uuid, def->uuid, VIR_UUID_BUFLEN)) {
|
|
|
9119d9 |
char vm_uuidstr[VIR_UUID_STRING_BUFLEN];
|
|
|
9119d9 |
@@ -5877,6 +5933,8 @@ qemuDomainObjRestore(virConnectPtr conn,
|
|
|
9119d9 |
VIR_WARN("Failed to close %s", path);
|
|
|
9119d9 |
|
|
|
9119d9 |
cleanup:
|
|
|
9119d9 |
+ VIR_FREE(xml);
|
|
|
9119d9 |
+ VIR_FREE(xmlout);
|
|
|
9119d9 |
virDomainDefFree(def);
|
|
|
9119d9 |
VIR_FORCE_CLOSE(fd);
|
|
|
9119d9 |
virFileWrapperFdFree(wrapperFd);
|
|
|
9119d9 |
diff --git a/src/util/virhook.c b/src/util/virhook.c
|
|
|
9119d9 |
index ac7b40f..25d0783 100644
|
|
|
9119d9 |
--- a/src/util/virhook.c
|
|
|
9119d9 |
+++ b/src/util/virhook.c
|
|
|
9119d9 |
@@ -77,7 +77,8 @@ VIR_ENUM_IMPL(virHookQemuOp, VIR_HOOK_QEMU_OP_LAST,
|
|
|
9119d9 |
"migrate",
|
|
|
9119d9 |
"started",
|
|
|
9119d9 |
"reconnect",
|
|
|
9119d9 |
- "attach")
|
|
|
9119d9 |
+ "attach",
|
|
|
9119d9 |
+ "restore")
|
|
|
9119d9 |
|
|
|
9119d9 |
VIR_ENUM_IMPL(virHookLxcOp, VIR_HOOK_LXC_OP_LAST,
|
|
|
9119d9 |
"start",
|
|
|
9119d9 |
diff --git a/src/util/virhook.h b/src/util/virhook.h
|
|
|
9119d9 |
index 5bc0a5f..550ef84 100644
|
|
|
9119d9 |
--- a/src/util/virhook.h
|
|
|
9119d9 |
+++ b/src/util/virhook.h
|
|
|
9119d9 |
@@ -60,6 +60,7 @@ typedef enum {
|
|
|
9119d9 |
VIR_HOOK_QEMU_OP_STARTED, /* domain has started */
|
|
|
9119d9 |
VIR_HOOK_QEMU_OP_RECONNECT, /* domain is being reconnected by libvirt */
|
|
|
9119d9 |
VIR_HOOK_QEMU_OP_ATTACH, /* domain is being attached to be libvirt */
|
|
|
9119d9 |
+ VIR_HOOK_QEMU_OP_RESTORE, /* domain is being restored */
|
|
|
9119d9 |
|
|
|
9119d9 |
VIR_HOOK_QEMU_OP_LAST,
|
|
|
9119d9 |
} virHookQemuOpType;
|
|
|
9119d9 |
--
|
|
|
9119d9 |
2.1.1
|
|
|
9119d9 |
|