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