diff mbox

[RFC,4/7] qemu-agent: add qemuAgentCreateBond interface

Message ID 8c75b9fdf0d95c02292507e50abe3176f414bf3a.1429256889.git.chen.fan.fnst@cn.fujitsu.com
State New
Headers show

Commit Message

chenfan April 17, 2015, 8:53 a.m. UTC
via initialize callback to create bond device.

Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com>
---
 src/qemu/qemu_agent.c   | 118 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_agent.h   |  10 ++++
 src/qemu/qemu_domain.c  |  70 ++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h  |   7 +++
 src/qemu/qemu_process.c |   4 ++
 5 files changed, 209 insertions(+)

Comments

Michael S. Tsirkin May 19, 2015, 9:13 a.m. UTC | #1
On Fri, Apr 17, 2015 at 04:53:06PM +0800, Chen Fan wrote:
> via initialize callback to create bond device.
> 
> Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com>
> ---
>  src/qemu/qemu_agent.c   | 118 ++++++++++++++++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_agent.h   |  10 ++++
>  src/qemu/qemu_domain.c  |  70 ++++++++++++++++++++++++++++
>  src/qemu/qemu_domain.h  |   7 +++
>  src/qemu/qemu_process.c |   4 ++
>  5 files changed, 209 insertions(+)
> 
> diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
> index cee0f8b..b8eba01 100644
> --- a/src/qemu/qemu_agent.c
> +++ b/src/qemu/qemu_agent.c
> @@ -2169,3 +2169,121 @@ qemuAgentGetInterfaces(qemuAgentPtr mon,
>  
>      goto cleanup;
>  }
> +
> +static virDomainInterfacePtr
> +findInterfaceByMac(virDomainInterfacePtr *info,
> +                   size_t len,
> +                   const char *macstr)
> +{
> +    size_t i;
> +    bool found = false;
> +
> +    for (i = 0; i < len; i++) {
> +        if (info[i]->hwaddr &&
> +            STREQ(info[i]->hwaddr, macstr)) {
> +            found = true;
> +            break;
> +        }
> +    }
> +
> +    if (found) {
> +        return info[i];
> +    }
> +
> +    return NULL;
> +}
> +

I think PCI addresses are a better way to identify the devices
for this purpose. This will mean softmac doesn't break this
functionality.
See anything wrong with it?


> +/*
> + * qemuAgentSetInterface:
> + */
> +int
> +qemuAgentCreateBond(qemuAgentPtr mon,
> +                    virDomainHostdevSubsysPCIPtr pcisrc)
> +{
> +    int ret = -1;
> +    virJSONValuePtr cmd = NULL;
> +    virJSONValuePtr reply = NULL;
> +    size_t i;
> +    char macstr[VIR_MAC_STRING_BUFLEN];
> +    virDomainInterfacePtr *interfaceInfo = NULL;
> +    virDomainInterfacePtr interface;
> +    virJSONValuePtr new_interface = NULL;
> +    virJSONValuePtr subInterfaces = NULL;
> +    virJSONValuePtr subInterface = NULL;
> +    int len;
> +
> +    if (!(pcisrc->nmac || pcisrc->macs))
> +        return ret;
> +
> +    len = qemuAgentGetInterfaces(mon, &interfaceInfo);
> +    if (len < 0)
> +        return ret;
> +
> +    if (!(new_interface = virJSONValueNewObject()))
> +        goto cleanup;
> +
> +    if (virJSONValueObjectAppendString(new_interface, "type", "bond") < 0)
> +        goto cleanup;
> +
> +    if (virJSONValueObjectAppendString(new_interface, "name", "bond0") < 0)
> +        goto cleanup;
> +
> +    if (virJSONValueObjectAppendString(new_interface, "onboot", "onboot") < 0)
> +        goto cleanup;
> +
> +    if (!(subInterfaces = virJSONValueNewArray()))
> +        goto cleanup;
> +
> +    for (i = 0; i < pcisrc->nmac; i++) {
> +        virMacAddrFormat(&pcisrc->macs[i], macstr);
> +        interface = findInterfaceByMac(interfaceInfo, len, macstr);
> +        if (!interface) {
> +            goto cleanup;
> +        }
> +
> +        if (!(subInterface = virJSONValueNewObject()))
> +            goto cleanup;
> +
> +        if (virJSONValueObjectAppendString(subInterface, "name", interface->name) < 0)
> +            goto cleanup;
> +
> +        if (virJSONValueArrayAppend(subInterfaces, subInterface) < 0)
> +            goto cleanup;
> +
> +        subInterface = NULL;
> +    }
> +
> +    if (i && virJSONValueObjectAppend(new_interface, "subInterfaces", subInterfaces) < 0)
> +        goto cleanup;
> +
> +    cmd = qemuAgentMakeCommand("guest-network-set-interface",
> +                               "a:interface", new_interface,
> +                               NULL);
> +
> +    if (!cmd)
> +        goto cleanup;
> +
> +    subInterfaces = NULL;
> +    new_interface = NULL;
> +
> +    if (qemuAgentCommand(mon, cmd, &reply, true,
> +                         VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
> +        goto cleanup;
> +
> +    if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) {
> +        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +                       _("malformed return value"));
> +    }
> +
> + cleanup:
> +    virJSONValueFree(subInterfaces);
> +    virJSONValueFree(subInterface);
> +    virJSONValueFree(new_interface);
> +    virJSONValueFree(cmd);
> +    virJSONValueFree(reply);
> +    if (interfaceInfo)
> +        for (i = 0; i < len; i++)
> +            virDomainInterfaceFree(interfaceInfo[i]);
> +    VIR_FREE(interfaceInfo);
> +    return ret;
> +}
> diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
> index 42414a7..744cb0a 100644
> --- a/src/qemu/qemu_agent.h
> +++ b/src/qemu/qemu_agent.h
> @@ -97,6 +97,13 @@ struct _qemuAgentCPUInfo {
>      bool offlinable;    /* true if the CPU can be offlined */
>  };
>  
> +typedef struct _qemuAgentInterfaceInfo qemuAgentInterfaceInfo;
> +typedef qemuAgentInterfaceInfo *qemuAgentInterfaceInfoPtr;
> +struct _qemuAgentInterfaceInfo {
> +    char *name;
> +    char *hardware_address;
> +};
> +
>  int qemuAgentGetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr *info);
>  int qemuAgentSetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr cpus, size_t ncpus);
>  int qemuAgentUpdateCPUInfo(unsigned int nvcpus,
> @@ -114,4 +121,7 @@ int qemuAgentSetTime(qemuAgentPtr mon,
>  int qemuAgentGetInterfaces(qemuAgentPtr mon,
>                             virDomainInterfacePtr **ifaces);
>  
> +int qemuAgentCreateBond(qemuAgentPtr mon,
> +                        virDomainHostdevSubsysPCIPtr pcisrc);
> +
>  #endif /* __QEMU_AGENT_H__ */
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 603360f..584fefb 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -2722,6 +2722,46 @@ qemuDomainCleanupRun(virQEMUDriverPtr driver,
>      priv->ncleanupCallbacks_max = 0;
>  }
>  
> +/*
> + * The vm must be locked when any of the following init functions is
> + * called.
> + */
> +int
> +qemuDomainInitAdd(virDomainObjPtr vm,
> +                  qemuDomainInitCallback cb)
> +{
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    size_t i;
> +
> +    VIR_DEBUG("vm=%s, cb=%p", vm->def->name, cb);
> +
> +    for (i = 0; i < priv->nInitCallbacks; i++) {
> +        if (priv->initCallbacks[i] == cb)
> +            return 0;
> +    }
> +
> +    if (VIR_RESIZE_N(priv->initCallbacks,
> +                     priv->nInitCallbacks_max,
> +                     priv->nInitCallbacks, 1) < 0)
> +        return -1;
> +
> +    priv->initCallbacks[priv->nInitCallbacks++] = cb;
> +    return 0;
> +}
> +
> +void
> +qemuDomainInitCleanup(virDomainObjPtr vm)
> +{
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +
> +    VIR_DEBUG("vm=%s", vm->def->name);
> +
> +    VIR_FREE(priv->cleanupCallbacks);
> +    priv->ncleanupCallbacks = 0;
> +    priv->ncleanupCallbacks_max = 0;
> +}
> +
> +
>  static void
>  qemuDomainGetImageIds(virQEMUDriverConfigPtr cfg,
>                        virDomainObjPtr vm,
> @@ -3083,3 +3123,33 @@ qemuDomainSupportsBlockJobs(virDomainObjPtr vm,
>  
>      return 0;
>  }
> +
> +void
> +qemuDomainPrepareHostdevInit(virDomainObjPtr vm)
> +{
> +    qemuDomainObjPrivatePtr priv = vm->privateData;
> +    virDomainDefPtr def = vm->def;
> +    int i;
> +
> +    if (!def->nhostdevs)
> +        return;
> +
> +    if (!qemuDomainAgentAvailable(vm, false))
> +        return;
> +
> +    if (!virDomainObjIsActive(vm))
> +        return;
> +
> +    for (i = 0; i < def->nhostdevs; i++) {
> +        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
> +        virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;
> +
> +        if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
> +            hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
> +            hostdev->source.subsys.u.pci.device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND) {
> +            qemuDomainObjEnterAgent(vm);
> +            qemuAgentCreateBond(priv->agent, pcisrc);
> +            qemuDomainObjExitAgent(vm);
> +        }
> +    }
> +}
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 19f4b27..3244ca0 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -403,6 +403,10 @@ void qemuDomainCleanupRemove(virDomainObjPtr vm,
>  void qemuDomainCleanupRun(virQEMUDriverPtr driver,
>                            virDomainObjPtr vm);
>  
> +int qemuDomainInitAdd(virDomainObjPtr vm,
> +                      qemuDomainInitCallback cb);
> +void qemuDomainInitCleanup(virDomainObjPtr vm);
> +
>  extern virDomainXMLPrivateDataCallbacks virQEMUDriverPrivateDataCallbacks;
>  extern virDomainXMLNamespace virQEMUDriverDomainXMLNamespace;
>  extern virDomainDefParserConfig virQEMUDriverDomainDefParserConfig;
> @@ -444,4 +448,7 @@ void qemuDomObjEndAPI(virDomainObjPtr *vm);
>  int qemuDomainAlignMemorySizes(virDomainDefPtr def);
>  void qemuDomainMemoryDeviceAlignSize(virDomainMemoryDefPtr mem);
>  
> +void
> +qemuDomainPrepareHostdevInit(virDomainObjPtr vm);
> +
>  #endif /* __QEMU_DOMAIN_H__ */
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index fcc0566..0a72aca 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -4444,6 +4444,9 @@ int qemuProcessStart(virConnectPtr conn,
>                                 hostdev_flags) < 0)
>          goto cleanup;
>  
> +    if (qemuDomainInitAdd(vm, qemuDomainPrepareHostdevInit))
> +        goto cleanup;
> +
>      VIR_DEBUG("Preparing chr devices");
>      if (virDomainChrDefForeach(vm->def,
>                                 true,
> @@ -5186,6 +5189,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
>                                   VIR_QEMU_PROCESS_KILL_NOCHECK));
>  
>      qemuDomainCleanupRun(driver, vm);
> +    qemuDomainInitCleanup(vm);
>  
>      /* Stop autodestroy in case guest is restarted */
>      qemuProcessAutoDestroyRemove(driver, vm);
> -- 
> 1.9.3
>
Michal Prívozník May 29, 2015, 7:37 a.m. UTC | #2
On 17.04.2015 10:53, Chen Fan wrote:
> via initialize callback to create bond device.
> 
> Signed-off-by: Chen Fan <chen.fan.fnst@cn.fujitsu.com>
> ---
>  src/qemu/qemu_agent.c   | 118 ++++++++++++++++++++++++++++++++++++++++++++++++
>  src/qemu/qemu_agent.h   |  10 ++++
>  src/qemu/qemu_domain.c  |  70 ++++++++++++++++++++++++++++
>  src/qemu/qemu_domain.h  |   7 +++
>  src/qemu/qemu_process.c |   4 ++
>  5 files changed, 209 insertions(+)
> 

If we go this way, we should introduce much broader set of interface
types to create. In fact, I don't like idea of qemu-ga mangling guest
network, esp. when there are so many tools for that.

Michal
diff mbox

Patch

diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index cee0f8b..b8eba01 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -2169,3 +2169,121 @@  qemuAgentGetInterfaces(qemuAgentPtr mon,
 
     goto cleanup;
 }
+
+static virDomainInterfacePtr
+findInterfaceByMac(virDomainInterfacePtr *info,
+                   size_t len,
+                   const char *macstr)
+{
+    size_t i;
+    bool found = false;
+
+    for (i = 0; i < len; i++) {
+        if (info[i]->hwaddr &&
+            STREQ(info[i]->hwaddr, macstr)) {
+            found = true;
+            break;
+        }
+    }
+
+    if (found) {
+        return info[i];
+    }
+
+    return NULL;
+}
+
+/*
+ * qemuAgentSetInterface:
+ */
+int
+qemuAgentCreateBond(qemuAgentPtr mon,
+                    virDomainHostdevSubsysPCIPtr pcisrc)
+{
+    int ret = -1;
+    virJSONValuePtr cmd = NULL;
+    virJSONValuePtr reply = NULL;
+    size_t i;
+    char macstr[VIR_MAC_STRING_BUFLEN];
+    virDomainInterfacePtr *interfaceInfo = NULL;
+    virDomainInterfacePtr interface;
+    virJSONValuePtr new_interface = NULL;
+    virJSONValuePtr subInterfaces = NULL;
+    virJSONValuePtr subInterface = NULL;
+    int len;
+
+    if (!(pcisrc->nmac || pcisrc->macs))
+        return ret;
+
+    len = qemuAgentGetInterfaces(mon, &interfaceInfo);
+    if (len < 0)
+        return ret;
+
+    if (!(new_interface = virJSONValueNewObject()))
+        goto cleanup;
+
+    if (virJSONValueObjectAppendString(new_interface, "type", "bond") < 0)
+        goto cleanup;
+
+    if (virJSONValueObjectAppendString(new_interface, "name", "bond0") < 0)
+        goto cleanup;
+
+    if (virJSONValueObjectAppendString(new_interface, "onboot", "onboot") < 0)
+        goto cleanup;
+
+    if (!(subInterfaces = virJSONValueNewArray()))
+        goto cleanup;
+
+    for (i = 0; i < pcisrc->nmac; i++) {
+        virMacAddrFormat(&pcisrc->macs[i], macstr);
+        interface = findInterfaceByMac(interfaceInfo, len, macstr);
+        if (!interface) {
+            goto cleanup;
+        }
+
+        if (!(subInterface = virJSONValueNewObject()))
+            goto cleanup;
+
+        if (virJSONValueObjectAppendString(subInterface, "name", interface->name) < 0)
+            goto cleanup;
+
+        if (virJSONValueArrayAppend(subInterfaces, subInterface) < 0)
+            goto cleanup;
+
+        subInterface = NULL;
+    }
+
+    if (i && virJSONValueObjectAppend(new_interface, "subInterfaces", subInterfaces) < 0)
+        goto cleanup;
+
+    cmd = qemuAgentMakeCommand("guest-network-set-interface",
+                               "a:interface", new_interface,
+                               NULL);
+
+    if (!cmd)
+        goto cleanup;
+
+    subInterfaces = NULL;
+    new_interface = NULL;
+
+    if (qemuAgentCommand(mon, cmd, &reply, true,
+                         VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+        goto cleanup;
+
+    if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("malformed return value"));
+    }
+
+ cleanup:
+    virJSONValueFree(subInterfaces);
+    virJSONValueFree(subInterface);
+    virJSONValueFree(new_interface);
+    virJSONValueFree(cmd);
+    virJSONValueFree(reply);
+    if (interfaceInfo)
+        for (i = 0; i < len; i++)
+            virDomainInterfaceFree(interfaceInfo[i]);
+    VIR_FREE(interfaceInfo);
+    return ret;
+}
diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h
index 42414a7..744cb0a 100644
--- a/src/qemu/qemu_agent.h
+++ b/src/qemu/qemu_agent.h
@@ -97,6 +97,13 @@  struct _qemuAgentCPUInfo {
     bool offlinable;    /* true if the CPU can be offlined */
 };
 
+typedef struct _qemuAgentInterfaceInfo qemuAgentInterfaceInfo;
+typedef qemuAgentInterfaceInfo *qemuAgentInterfaceInfoPtr;
+struct _qemuAgentInterfaceInfo {
+    char *name;
+    char *hardware_address;
+};
+
 int qemuAgentGetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr *info);
 int qemuAgentSetVCPUs(qemuAgentPtr mon, qemuAgentCPUInfoPtr cpus, size_t ncpus);
 int qemuAgentUpdateCPUInfo(unsigned int nvcpus,
@@ -114,4 +121,7 @@  int qemuAgentSetTime(qemuAgentPtr mon,
 int qemuAgentGetInterfaces(qemuAgentPtr mon,
                            virDomainInterfacePtr **ifaces);
 
+int qemuAgentCreateBond(qemuAgentPtr mon,
+                        virDomainHostdevSubsysPCIPtr pcisrc);
+
 #endif /* __QEMU_AGENT_H__ */
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 603360f..584fefb 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2722,6 +2722,46 @@  qemuDomainCleanupRun(virQEMUDriverPtr driver,
     priv->ncleanupCallbacks_max = 0;
 }
 
+/*
+ * The vm must be locked when any of the following init functions is
+ * called.
+ */
+int
+qemuDomainInitAdd(virDomainObjPtr vm,
+                  qemuDomainInitCallback cb)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    size_t i;
+
+    VIR_DEBUG("vm=%s, cb=%p", vm->def->name, cb);
+
+    for (i = 0; i < priv->nInitCallbacks; i++) {
+        if (priv->initCallbacks[i] == cb)
+            return 0;
+    }
+
+    if (VIR_RESIZE_N(priv->initCallbacks,
+                     priv->nInitCallbacks_max,
+                     priv->nInitCallbacks, 1) < 0)
+        return -1;
+
+    priv->initCallbacks[priv->nInitCallbacks++] = cb;
+    return 0;
+}
+
+void
+qemuDomainInitCleanup(virDomainObjPtr vm)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+
+    VIR_DEBUG("vm=%s", vm->def->name);
+
+    VIR_FREE(priv->cleanupCallbacks);
+    priv->ncleanupCallbacks = 0;
+    priv->ncleanupCallbacks_max = 0;
+}
+
+
 static void
 qemuDomainGetImageIds(virQEMUDriverConfigPtr cfg,
                       virDomainObjPtr vm,
@@ -3083,3 +3123,33 @@  qemuDomainSupportsBlockJobs(virDomainObjPtr vm,
 
     return 0;
 }
+
+void
+qemuDomainPrepareHostdevInit(virDomainObjPtr vm)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    virDomainDefPtr def = vm->def;
+    int i;
+
+    if (!def->nhostdevs)
+        return;
+
+    if (!qemuDomainAgentAvailable(vm, false))
+        return;
+
+    if (!virDomainObjIsActive(vm))
+        return;
+
+    for (i = 0; i < def->nhostdevs; i++) {
+        virDomainHostdevDefPtr hostdev = def->hostdevs[i];
+        virDomainHostdevSubsysPCIPtr pcisrc = &hostdev->source.subsys.u.pci;
+
+        if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+            hostdev->source.subsys.u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
+            hostdev->source.subsys.u.pci.device == VIR_DOMAIN_HOSTDEV_PCI_DEVICE_BOND) {
+            qemuDomainObjEnterAgent(vm);
+            qemuAgentCreateBond(priv->agent, pcisrc);
+            qemuDomainObjExitAgent(vm);
+        }
+    }
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 19f4b27..3244ca0 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -403,6 +403,10 @@  void qemuDomainCleanupRemove(virDomainObjPtr vm,
 void qemuDomainCleanupRun(virQEMUDriverPtr driver,
                           virDomainObjPtr vm);
 
+int qemuDomainInitAdd(virDomainObjPtr vm,
+                      qemuDomainInitCallback cb);
+void qemuDomainInitCleanup(virDomainObjPtr vm);
+
 extern virDomainXMLPrivateDataCallbacks virQEMUDriverPrivateDataCallbacks;
 extern virDomainXMLNamespace virQEMUDriverDomainXMLNamespace;
 extern virDomainDefParserConfig virQEMUDriverDomainDefParserConfig;
@@ -444,4 +448,7 @@  void qemuDomObjEndAPI(virDomainObjPtr *vm);
 int qemuDomainAlignMemorySizes(virDomainDefPtr def);
 void qemuDomainMemoryDeviceAlignSize(virDomainMemoryDefPtr mem);
 
+void
+qemuDomainPrepareHostdevInit(virDomainObjPtr vm);
+
 #endif /* __QEMU_DOMAIN_H__ */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index fcc0566..0a72aca 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4444,6 +4444,9 @@  int qemuProcessStart(virConnectPtr conn,
                                hostdev_flags) < 0)
         goto cleanup;
 
+    if (qemuDomainInitAdd(vm, qemuDomainPrepareHostdevInit))
+        goto cleanup;
+
     VIR_DEBUG("Preparing chr devices");
     if (virDomainChrDefForeach(vm->def,
                                true,
@@ -5186,6 +5189,7 @@  void qemuProcessStop(virQEMUDriverPtr driver,
                                  VIR_QEMU_PROCESS_KILL_NOCHECK));
 
     qemuDomainCleanupRun(driver, vm);
+    qemuDomainInitCleanup(vm);
 
     /* Stop autodestroy in case guest is restarted */
     qemuProcessAutoDestroyRemove(driver, vm);