[libvirt] [RFC PATCH 4/4] Implement signal propagation to dependancy domains

Valentin BOUSSON v.bousson at virtualopensystems.com
Wed Mar 23 08:55:22 UTC 2016


This patch implements the propagation of different signals across the 
dependency relation between domains:
 - CreateXML: 
        When a domain with dependency is instanciated via this function, 
        all the depencies it depends on are instanciated in the same time

 - Destroy: 
        (When a domain with dependencies is destroyed, its dependencies are
        destroyed in the meantime)

 - Suspend 
        (When a domain with dependencies is suspended, its dependencies are 
        suspended in the meantime)

 - Resume 
        (When a domain with dependencies is resumed, its dependencies are 
        resumed in the meantime)

---
 src/qemu/qemu_driver.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 124 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 37eef7e..094b536 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1783,6 +1783,10 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
     virCapsPtr caps = NULL;
     unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE |
                                VIR_DOMAIN_DEF_PARSE_ABI_UPDATE;
+    int i = 0;
+    char *buffer = NULL;
+    virDomainDefPtr def_slave = NULL;
+    virDomainObjPtr vm_slave = NULL;
 
     virCheckFlags(VIR_DOMAIN_START_PAUSED |
                   VIR_DOMAIN_START_AUTODESTROY |
@@ -1820,7 +1824,6 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
                                    NULL)))
         goto cleanup;
     virObjectRef(vm);
-    def = NULL;
 
     if (qemuProcessBeginJob(driver, vm) < 0) {
         qemuDomainRemoveInactive(driver, vm);
@@ -1852,6 +1855,83 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
     }
     virDomainAuditStart(vm, "booted", true);
 
+    for (i=0; i < def->ndomaindependencies; ++i) {
+        /* Constant for creation of new domains from an XML descriptions is specified in
+         * ../tools/vsh.h:43 : # define VSH_MAX_XML_FILE (10*1024*1024)
+         */
+        if (virFileReadAll(def->domaindependencies[i]->filePath,
+                           10*1024*1024,
+                           &buffer) < 0)
+            goto cleanup;
+
+        if (!(def_slave = virDomainDefParseString(buffer, caps, driver->xmlopt,
+                                                  parse_flags)))
+            goto cleanup;
+
+        if (virDomainCreateXMLEnsureACL(conn, def_slave) < 0)
+            goto cleanup;
+
+        if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache, def_slave->emulator)))
+            goto cleanup;
+
+        if (qemuDomainAssignAddresses(def_slave, qemuCaps, NULL) < 0)
+            goto cleanup;
+
+        if (!(vm_slave = virDomainObjListAdd(driver->domains,
+                                             def_slave,
+                                             driver->xmlopt,
+                                             VIR_DOMAIN_OBJ_LIST_ADD_LIVE | VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE,
+                                             NULL)))
+            goto cleanup;
+        virObjectRef(vm_slave);
+        def_slave = NULL;
+
+        if (qemuProcessBeginJob(driver, vm_slave) < 0) {
+            qemuDomainRemoveInactive(driver, vm_slave);
+            goto cleanup;
+        }
+
+        if (qemuProcessStart(conn, driver, vm_slave, QEMU_ASYNC_JOB_START,
+                             NULL, -1, NULL, NULL,
+                             VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
+                             start_flags) < 0) {
+            virDomainAuditStart(vm_slave, "booted", false);
+            qemuProcessEndJob(driver, vm_slave);
+            qemuDomainRemoveInactive(driver, vm_slave);
+            goto cleanup;
+        }
+
+        event = virDomainEventLifecycleNewFromObj(vm_slave,
+                                                  VIR_DOMAIN_EVENT_STARTED,
+                                                  VIR_DOMAIN_EVENT_STARTED_BOOTED);
+
+        if (event && (flags & VIR_DOMAIN_START_PAUSED)) {
+            event2 = virDomainEventLifecycleNewFromObj(vm_slave,
+                                                       VIR_DOMAIN_EVENT_SUSPENDED,
+                                                       VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
+        }
+        virDomainAuditStart(vm_slave, "booted", true);
+
+        /* Registering domain name for live dependency */
+        if (VIR_ALLOC_N(def->domaindependencies[i]->domainName, strlen(vm_slave->def->name)+1) < 0) {
+            goto cleanup;
+        }
+        else {
+            if (virStrcpy(def->domaindependencies[i]->domainName,
+                          vm_slave->def->name,
+                          strlen(vm_slave->def->name)+1) == NULL) {
+
+            }
+            else {
+                for (int j = 0; j < VIR_UUID_BUFLEN; ++j) {
+                    def->domaindependencies[i]->domainUuid[j] = vm_slave->def->uuid[j];
+                }
+            }
+        }
+        qemuProcessEndJob(driver,vm_slave);
+    }
+    def = NULL;
+
     dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
     if (dom)
         dom->id = vm->def->id;
@@ -1861,6 +1941,8 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
  cleanup:
     virDomainDefFree(def);
     virDomainObjEndAPI(&vm);
+    virDomainDefFree(def_slave);
+    virDomainObjEndAPI(&vm_slave);
     if (event) {
         qemuDomainEventQueue(driver, event);
         qemuDomainEventQueue(driver, event2);
@@ -1884,9 +1966,22 @@ static int qemuDomainSuspend(virDomainPtr dom)
     int state;
     virQEMUDriverConfigPtr cfg = NULL;
 
+    int i = 0;
+
     if (!(vm = qemuDomObjFromDomain(dom)))
         return -1;
 
+    for (i = 0; i < vm->def->ndomaindependencies; ++i) {
+        if (qemuDomainSuspend(virGetDomain(dom->conn,
+                        vm->def->domaindependencies[i]->domainName,
+                        vm->def->domaindependencies[i]->domainUuid)) < 0) {
+            VIR_WARN("Problem to suspend domain %s.", vm->def->domaindependencies[i]->domainName);
+        }
+        else {
+            VIR_INFO("Domain %s successfully suspended.", vm->def->domaindependencies[i]->domainName);
+        }
+    }
+
     if (virDomainSuspendEnsureACL(dom->conn, vm->def) < 0)
         goto cleanup;
 
@@ -1960,9 +2055,23 @@ static int qemuDomainResume(virDomainPtr dom)
     int reason;
     virQEMUDriverConfigPtr cfg = NULL;
 
+    int i = 0;
+
     if (!(vm = qemuDomObjFromDomain(dom)))
         return -1;
 
+    for (i = 0; i < vm->def->ndomaindependencies; ++i) {
+        if (qemuDomainResume(virGetDomain(dom->conn,
+                        vm->def->domaindependencies[i]->domainName,
+                        vm->def->domaindependencies[i]->domainUuid)) < 0) {
+            VIR_WARN("Problem to resume domain %s.", vm->def->domaindependencies[i]->domainName);
+        }
+        else {
+            VIR_INFO("Domain %s successfully resumed.", vm->def->domaindependencies[i]->domainName);
+        }
+    }
+
+
     cfg = virQEMUDriverGetConfig(driver);
 
     if (virDomainResumeEnsureACL(dom->conn, vm->def) < 0)
@@ -2265,11 +2374,25 @@ qemuDomainDestroyFlags(virDomainPtr dom,
     qemuDomainObjPrivatePtr priv;
     unsigned int stopFlags = 0;
 
+    int i = 0;
+
     virCheckFlags(VIR_DOMAIN_DESTROY_GRACEFUL, -1);
 
     if (!(vm = qemuDomObjFromDomain(dom)))
         return -1;
 
+    for (i = 0; i < vm->def->ndomaindependencies; ++i) {
+        /* The dependency domain is destroyed with the same flag as the parent */
+        if (qemuDomainDestroyFlags(virGetDomain(dom->conn,
+                                                vm->def->domaindependencies[i]->domainName,
+                                                vm->def->domaindependencies[i]->domainUuid), flags) < 0) {
+            VIR_WARN("Problem occurs : impossible to destroy domain %s.", vm->def->domaindependencies[i]->domainName);
+        }
+        else {
+            VIR_INFO("Domain %s successfully destroyed.", vm->def->domaindependencies[i]->domainName);
+        }
+    }
+
     priv = vm->privateData;
 
     if (virDomainDestroyFlagsEnsureACL(dom->conn, vm->def) < 0)
-- 
1.9.1




More information about the libvir-list mailing list