We need to send allowReboot in the migration cookie to ensure the same
behavior of the virDomainSetLifecycleAction() API on the destination.
Consider this scenario:
1. On the source the domain is started with:
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
2. User calls an API to set "destroy" for <on_reboot>:
<on_poweroff>destroy</on_poweroff>
<on_reboot>destroy</on_reboot>
<on_crash>destroy</on_crash>
3. The guest is migrated to a different host
4a. Without the allowReboot in the migration cookie the QEMU
process on destination would be started with -no-reboot
which would prevent using the virDomainSetLifecycleAction() API
for the rest of the guest lifetime.
4b. With the allowReboot in the migration cookie the QEMU process
on destination is started without -no-reboot like it was started
on the source host and the virDomainSetLifecycleAction() API
continues to work.
The following patch adds a QEMU implementation of the
virDomainSetLifecycleAction() API and that implementation disallows
using the API if all actions are set to "destroy" because we add
"-no-reboot" on the QEMU command line. Changing the lifecycle action
is in this case pointless because the QEMU process is always terminated.
Signed-off-by: Pavel Hrdina <phrdina(a)redhat.com>
---
src/qemu/qemu_domain.c | 4 ++--
src/qemu/qemu_domain.h | 8 ++++++++
src/qemu/qemu_migration.c | 7 ++++++-
src/qemu/qemu_migration_cookie.c | 25 ++++++++++++++++++++++++-
src/qemu/qemu_migration_cookie.h | 5 +++++
5 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2630b73221..d74703fd3e 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1877,7 +1877,7 @@ qemuDomainObjPrivateXMLFormatBlockjobs(virBufferPtr buf,
}
-static void
+void
qemuDomainObjPrivateXMLFormatAllowReboot(virBufferPtr buf,
virTristateBool allowReboot)
{
@@ -2121,7 +2121,7 @@ qemuDomainObjPrivateXMLParseBlockjobs(qemuDomainObjPrivatePtr priv,
}
-static int
+int
qemuDomainObjPrivateXMLParseAllowReboot(xmlXPathContextPtr ctxt,
virTristateBool *allowReboot)
{
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index be4aaa5613..563438f0cc 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -975,4 +975,12 @@ qemuDomainUpdateCPU(virDomainObjPtr vm,
char *
qemuDomainGetMachineName(virDomainObjPtr vm);
+void
+qemuDomainObjPrivateXMLFormatAllowReboot(virBufferPtr buf,
+ virTristateBool allowReboot);
+
+int
+qemuDomainObjPrivateXMLParseAllowReboot(xmlXPathContextPtr ctxt,
+ virTristateBool *allowReboot);
+
#endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index dd60071bfd..5b394d3bbc 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2013,6 +2013,8 @@ qemuMigrationBeginPhase(virQEMUDriverPtr driver,
if (priv->origCPU)
cookieFlags |= QEMU_MIGRATION_COOKIE_CPU;
+ cookieFlags |= QEMU_MIGRATION_COOKIE_ALLOW_REBOOT;
+
if (!(mig = qemuMigrationEatCookie(driver, vm, NULL, 0, 0)))
goto cleanup;
@@ -2639,7 +2641,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
QEMU_MIGRATION_COOKIE_NBD |
QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG |
QEMU_MIGRATION_COOKIE_CPU_HOTPLUG |
- QEMU_MIGRATION_COOKIE_CPU)))
+ QEMU_MIGRATION_COOKIE_CPU |
+ QEMU_MIGRATION_COOKIE_ALLOW_REBOOT)))
goto cleanup;
if (STREQ_NULLABLE(protocol, "rdma") &&
@@ -2679,6 +2682,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
goto stopjob;
stopProcess = true;
+ priv->allowReboot = mig->allowReboot;
+
if (!(incoming = qemuMigrationPrepareIncoming(vm, tunnel, protocol,
listenAddress, port,
dataFD[0])))
diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
index bc6a8dc552..2877913793 100644
--- a/src/qemu/qemu_migration_cookie.c
+++ b/src/qemu/qemu_migration_cookie.c
@@ -49,7 +49,8 @@ VIR_ENUM_IMPL(qemuMigrationCookieFlag,
"statistics",
"memory-hotplug",
"cpu-hotplug",
- "cpu");
+ "cpu",
+ "allowReboot");
static void
@@ -538,6 +539,18 @@ qemuMigrationCookieAddCPU(qemuMigrationCookiePtr mig,
static void
+qemuMigrationCookieAddAllowReboot(qemuMigrationCookiePtr mig,
+ virDomainObjPtr vm)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+
+ mig->allowReboot = priv->allowReboot;
+
+ mig->flags |= QEMU_MIGRATION_COOKIE_ALLOW_REBOOT;
+}
+
+
+static void
qemuMigrationCookieGraphicsXMLFormat(virBufferPtr buf,
qemuMigrationCookieGraphicsPtr grap)
{
@@ -777,6 +790,9 @@ qemuMigrationCookieXMLFormat(virQEMUDriverPtr driver,
if (mig->flags & QEMU_MIGRATION_COOKIE_CPU && mig->cpu)
virCPUDefFormatBufFull(buf, mig->cpu, NULL);
+ if (mig->flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT)
+ qemuDomainObjPrivateXMLFormatAllowReboot(buf, mig->allowReboot);
+
virBufferAdjustIndent(buf, -2);
virBufferAddLit(buf, "</qemu-migration>\n");
return 0;
@@ -1225,6 +1241,10 @@ qemuMigrationCookieXMLParse(qemuMigrationCookiePtr mig,
virCPUDefParseXML(ctxt, "./cpu[1]", VIR_CPU_TYPE_GUEST,
&mig->cpu) < 0)
goto error;
+ if (flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT &&
+ qemuDomainObjPrivateXMLParseAllowReboot(ctxt, &mig->allowReboot) < 0)
+ goto error;
+
virObjectUnref(caps);
return 0;
@@ -1305,6 +1325,9 @@ qemuMigrationBakeCookie(qemuMigrationCookiePtr mig,
qemuMigrationCookieAddCPU(mig, dom) < 0)
return -1;
+ if (flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT)
+ qemuMigrationCookieAddAllowReboot(mig, dom);
+
if (!(*cookieout = qemuMigrationCookieXMLFormatStr(driver, mig)))
return -1;
diff --git a/src/qemu/qemu_migration_cookie.h b/src/qemu/qemu_migration_cookie.h
index e5f3d75a95..4a25511a9a 100644
--- a/src/qemu/qemu_migration_cookie.h
+++ b/src/qemu/qemu_migration_cookie.h
@@ -29,6 +29,7 @@ typedef enum {
QEMU_MIGRATION_COOKIE_FLAG_MEMORY_HOTPLUG,
QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG,
QEMU_MIGRATION_COOKIE_FLAG_CPU,
+ QEMU_MIGRATION_COOKIE_FLAG_ALLOW_REBOOT,
QEMU_MIGRATION_COOKIE_FLAG_LAST
} qemuMigrationCookieFlags;
@@ -45,6 +46,7 @@ typedef enum {
QEMU_MIGRATION_COOKIE_MEMORY_HOTPLUG = (1 <<
QEMU_MIGRATION_COOKIE_FLAG_MEMORY_HOTPLUG),
QEMU_MIGRATION_COOKIE_CPU_HOTPLUG = (1 <<
QEMU_MIGRATION_COOKIE_FLAG_CPU_HOTPLUG),
QEMU_MIGRATION_COOKIE_CPU = (1 << QEMU_MIGRATION_COOKIE_FLAG_CPU),
+ QEMU_MIGRATION_COOKIE_ALLOW_REBOOT = (1 <<
QEMU_MIGRATION_COOKIE_FLAG_ALLOW_REBOOT),
} qemuMigrationCookieFeatures;
typedef struct _qemuMigrationCookieGraphics qemuMigrationCookieGraphics;
@@ -127,6 +129,9 @@ struct _qemuMigrationCookie {
/* If flags & QEMU_MIGRATION_COOKIE_CPU */
virCPUDefPtr cpu;
+
+ /* If flags & QEMU_MIGRATION_COOKIE_ALLOW_REBOOT */
+ virTristateBool allowReboot;
};
--
2.13.6