[libvirt] [PATCH 14/14] qemu: implement virDomainSetLifecycleAction() API

Pavel Hrdina phrdina at redhat.com
Mon Oct 16 11:06:27 UTC 2017


There is one limitation for using this API, when the guest is started
with all actions set to "destroy" we put "-no-reboot" on the QEMU
command line.  That cannot be changed while QEMU is running and
the QEMU process is always terminated no matter what is configured
for any action.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1460677

Signed-off-by: Pavel Hrdina <phrdina at redhat.com>
---
 src/conf/domain_conf.c   |  2 +-
 src/conf/domain_conf.h   |  4 +++
 src/libvirt-domain.c     |  4 +++
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_driver.c   | 94 +++++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 103 insertions(+), 2 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f69bcc2530..feea8523a7 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5612,7 +5612,7 @@ virDomainDefCheckDuplicateDriveAddresses(const virDomainDef *def)
 }
 
 
-static bool
+bool
 virDomainDefLifecycleActionAllowed(virDomainLifecycle type,
                                    virDomainLifecycleAction action)
 {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 8240433611..354b7adfa5 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3409,4 +3409,8 @@ virDomainNetTypeSharesHostView(const virDomainNetDef *net)
     return false;
 }
 
+bool
+virDomainDefLifecycleActionAllowed(virDomainLifecycle type,
+                                   virDomainLifecycleAction action);
+
 #endif /* __DOMAIN_CONF_H */
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index a51d8e3820..eaec0979ad 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -12047,6 +12047,10 @@ virDomainSetBlockThreshold(virDomainPtr domain,
  * Changes the actions of lifecycle events for domain represented as
  * <on_$type>$action</on_$type> in the domain XML.
  *
+ * QEMU driver has a limitation that if all lifecycle events are set
+ * to destroy when the domain is started, it's not possible to change
+ * any action for running domain.
+ *
  * Returns 0 on success, -1 on failure.
  */
 int virDomainSetLifecycleAction(virDomainPtr domain,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4cd328eded..a8983f2246 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -269,6 +269,7 @@ virDomainDefHasDeviceAddress;
 virDomainDefHasMemballoon;
 virDomainDefHasMemoryHotplug;
 virDomainDefHasVcpusOffline;
+virDomainDefLifecycleActionAllowed;
 virDomainDefMaybeAddController;
 virDomainDefMaybeAddInput;
 virDomainDefNeedsPlacementAdvice;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index f7d713ab59..58a1c7d94e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -20914,6 +20914,97 @@ qemuDomainSetBlockThreshold(virDomainPtr dom,
 }
 
 
+static void
+qemuDomainModifyLifecycleAction(virDomainDefPtr def,
+                                virDomainLifecycle type,
+                                virDomainLifecycleAction action)
+{
+    switch (type) {
+    case VIR_DOMAIN_LIFECYCLE_POWEROFF:
+        def->onPoweroff = action;
+        break;
+    case VIR_DOMAIN_LIFECYCLE_REBOOT:
+        def->onReboot = action;
+        break;
+    case VIR_DOMAIN_LIFECYCLE_CRASH:
+        def->onCrash = action;
+        break;
+    case VIR_DOMAIN_LIFECYCLE_LAST:
+        break;
+    }
+}
+
+
+
+static int
+qemuDomainSetLifecycleAction(virDomainPtr dom,
+                             unsigned int type,
+                             unsigned int action,
+                             unsigned int flags)
+{
+    virQEMUDriverPtr driver = dom->conn->privateData;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    qemuDomainObjPrivatePtr priv;
+    virDomainObjPtr vm = NULL;
+    virDomainDefPtr def = NULL;
+    virDomainDefPtr persistentDef = NULL;
+    int ret = -1;
+
+    virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
+                  VIR_DOMAIN_AFFECT_CONFIG, -1);
+
+    if (!virDomainDefLifecycleActionAllowed(type, action))
+        goto cleanup;
+
+    if (!(vm = qemuDomObjFromDomain(dom)))
+        goto cleanup;
+
+    priv = vm->privateData;
+
+    if (virDomainSetLifecycleActionEnsureACL(dom->conn, vm->def) < 0)
+        goto cleanup;
+
+    if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+        goto cleanup;
+
+    if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0)
+        goto endjob;
+
+    if (def) {
+        if (priv->allowReboot == VIR_TRISTATE_BOOL_NO) {
+            virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+                           _("cannot update lifecycle action because QEMU "
+                             "was started with -no-reboot option"));
+            goto endjob;
+        }
+
+        qemuDomainModifyLifecycleAction(def, type, action);
+
+        if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir,
+                                vm, driver->caps) < 0)
+            goto endjob;
+    }
+
+    if (persistentDef) {
+        qemuDomainModifyLifecycleAction(persistentDef, type, action);
+
+        if (virDomainSaveConfig(cfg->configDir, driver->caps,
+                                persistentDef) < 0)
+            goto endjob;
+    }
+
+    ret = 0;
+
+ endjob:
+    qemuDomainObjEndJob(driver, vm);
+
+ cleanup:
+    virDomainObjEndAPI(&vm);
+    virObjectUnref(cfg);
+    return ret;
+}
+
+
 static virHypervisorDriver qemuHypervisorDriver = {
     .name = QEMU_DRIVER_NAME,
     .connectOpen = qemuConnectOpen, /* 0.2.0 */
@@ -21131,7 +21222,8 @@ static virHypervisorDriver qemuHypervisorDriver = {
     .domainGetGuestVcpus = qemuDomainGetGuestVcpus, /* 2.0.0 */
     .domainSetGuestVcpus = qemuDomainSetGuestVcpus, /* 2.0.0 */
     .domainSetVcpu = qemuDomainSetVcpu, /* 3.1.0 */
-    .domainSetBlockThreshold = qemuDomainSetBlockThreshold /* 3.2.0 */
+    .domainSetBlockThreshold = qemuDomainSetBlockThreshold, /* 3.2.0 */
+    .domainSetLifecycleAction = qemuDomainSetLifecycleAction, /* 3.9.0 */
 };
 
 
-- 
2.13.6




More information about the libvir-list mailing list