[libvirt] [PATCH] Add support for autodestroy of guests to the LXC and UML drivers

Daniel P. Berrange berrange at redhat.com
Mon Oct 17 10:32:45 UTC 2011


From: "Daniel P. Berrange" <berrange at redhat.com>

I wrote this months ago and thought I had already submitted/merged
it. Obviously not. I need this for the virt sandbox tools asap.

We recently added support for VIR_DOMAIN_START_AUTODESTROY and
an impl to the QEMU driver. It is very desirable to support in
other drivers, so this adds it to LXC and UML

* src/lxc/lxc_conf.h, src/lxc/lxc_driver.c,
  src/uml/uml_conf.h, src/uml/uml_driver.c: Wire up autodestroy
  functions
---
 src/lxc/lxc_conf.h   |    5 ++
 src/lxc/lxc_driver.c |  140 +++++++++++++++++++++++++++++++++++++++++--
 src/uml/uml_conf.h   |    6 ++
 src/uml/uml_driver.c |  164 +++++++++++++++++++++++++++++++++++++++++++-------
 4 files changed, 289 insertions(+), 26 deletions(-)

diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h
index 66aa469..b124330 100644
--- a/src/lxc/lxc_conf.h
+++ b/src/lxc/lxc_conf.h
@@ -56,6 +56,11 @@ struct __lxc_driver {
     int have_netns;
 
     virDomainEventStatePtr domainEventState;
+
+    /* Mapping of 'char *uuidstr' -> virConnectPtr
+     * of guests which will be automatically killed
+     * when the virConnectPtr is closed*/
+    virHashTablePtr autodestroy;
 };
 
 int lxcLoadDriverConfig(lxc_driver_t *driver);
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index c475887..f08e8d1 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -110,6 +110,19 @@ static void lxcDomainEventFlush(int timer, void *opaque);
 static void lxcDomainEventQueue(lxc_driver_t *driver,
                                 virDomainEventPtr event);
 
+static int lxcVmTerminate(lxc_driver_t *driver,
+                          virDomainObjPtr vm,
+                          virDomainShutoffReason reason);
+static int lxcProcessAutoDestroyInit(lxc_driver_t *driver);
+static void lxcProcessAutoDestroyRun(lxc_driver_t *driver,
+                                     virConnectPtr conn);
+static void lxcProcessAutoDestroyShutdown(lxc_driver_t *driver);
+static int lxcProcessAutoDestroyAdd(lxc_driver_t *driver,
+                                    virDomainObjPtr vm,
+                                    virConnectPtr conn);
+static int lxcProcessAutoDestroyRemove(lxc_driver_t *driver,
+                                       virDomainObjPtr vm);
+
 
 static virDrvOpenStatus lxcOpen(virConnectPtr conn,
                                 virConnectAuthPtr auth ATTRIBUTE_UNUSED,
@@ -165,6 +178,7 @@ static int lxcClose(virConnectPtr conn)
     lxcDriverLock(driver);
     virDomainEventCallbackListRemoveConn(conn,
                                          driver->domainEventState->callbacks);
+    lxcProcessAutoDestroyRun(driver, conn);
     lxcDriverUnlock(driver);
 
     conn->privateData = NULL;
@@ -1001,6 +1015,104 @@ cleanup:
 }
 
 
+static int lxcProcessAutoDestroyInit(lxc_driver_t *driver)
+{
+    if (!(driver->autodestroy = virHashCreate(5, NULL)))
+        return -1;
+
+    return 0;
+}
+
+struct lxcProcessAutoDestroyData {
+    lxc_driver_t *driver;
+    virConnectPtr conn;
+};
+
+static void lxcProcessAutoDestroyDom(void *payload,
+                                     const void *name,
+                                     void *opaque)
+{
+    struct lxcProcessAutoDestroyData *data = opaque;
+    virConnectPtr conn = payload;
+    const char *uuidstr = name;
+    unsigned char uuid[VIR_UUID_BUFLEN];
+    virDomainObjPtr dom;
+    virDomainEventPtr event = NULL;
+
+    VIR_DEBUG("conn=%p uuidstr=%s thisconn=%p", conn, uuidstr, data->conn);
+
+    if (data->conn != conn)
+        return;
+
+    if (virUUIDParse(uuidstr, uuid) < 0) {
+        VIR_WARN("Failed to parse %s", uuidstr);
+        return;
+    }
+
+    if (!(dom = virDomainFindByUUID(&data->driver->domains,
+                                    uuid))) {
+        VIR_DEBUG("No domain object to kill");
+        return;
+    }
+
+    VIR_DEBUG("Killing domain");
+    lxcVmTerminate(data->driver, dom, VIR_DOMAIN_SHUTOFF_DESTROYED);
+    virDomainAuditStop(dom, "destroyed");
+    event = virDomainEventNewFromObj(dom,
+                                     VIR_DOMAIN_EVENT_STOPPED,
+                                     VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
+
+    if (dom && !dom->persistent)
+        virDomainRemoveInactive(&data->driver->domains, dom);
+
+    if (dom)
+        virDomainObjUnlock(dom);
+    if (event)
+        lxcDomainEventQueue(data->driver, event);
+    virHashRemoveEntry(data->driver->autodestroy, uuidstr);
+}
+
+/*
+ * Precondition: driver is locked
+ */
+static void lxcProcessAutoDestroyRun(lxc_driver_t *driver, virConnectPtr conn)
+{
+    struct lxcProcessAutoDestroyData data = {
+        driver, conn
+    };
+    VIR_DEBUG("conn=%p", conn);
+    virHashForEach(driver->autodestroy, lxcProcessAutoDestroyDom, &data);
+}
+
+static void lxcProcessAutoDestroyShutdown(lxc_driver_t *driver)
+{
+    virHashFree(driver->autodestroy);
+}
+
+static int lxcProcessAutoDestroyAdd(lxc_driver_t *driver,
+                                    virDomainObjPtr vm,
+                                    virConnectPtr conn)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    virUUIDFormat(vm->def->uuid, uuidstr);
+    VIR_DEBUG("vm=%s uuid=%s conn=%p", vm->def->name, uuidstr, conn);
+    if (virHashAddEntry(driver->autodestroy, uuidstr, conn) < 0)
+        return -1;
+    return 0;
+}
+
+static int lxcProcessAutoDestroyRemove(lxc_driver_t *driver,
+                                       virDomainObjPtr vm)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    virUUIDFormat(vm->def->uuid, uuidstr);
+    VIR_DEBUG("vm=%s uuid=%s", vm->def->name, uuidstr);
+    if (virHashRemoveEntry(driver->autodestroy, uuidstr) < 0)
+        return -1;
+    return 0;
+}
+
+
 /**
  * lxcVmCleanup:
  * @driver: pointer to driver structure
@@ -1028,6 +1140,9 @@ static void lxcVmCleanup(lxc_driver_t *driver,
         VIR_FREE(xml);
     }
 
+    /* Stop autodestroy in case guest is restarted */
+    lxcProcessAutoDestroyRemove(driver, vm);
+
     virEventRemoveHandle(priv->monitorWatch);
     VIR_FORCE_CLOSE(priv->monitor);
 
@@ -1496,6 +1611,7 @@ cleanup:
  * @conn: pointer to connection
  * @driver: pointer to driver structure
  * @vm: pointer to virtual machine structure
+ * @autoDestroy: mark the domain for auto destruction
  * @reason: reason for switching vm to running state
  *
  * Starts a vm
@@ -1505,6 +1621,7 @@ cleanup:
 static int lxcVmStart(virConnectPtr conn,
                       lxc_driver_t * driver,
                       virDomainObjPtr vm,
+                      bool autoDestroy,
                       virDomainRunningReason reason)
 {
     int rc = -1, r;
@@ -1665,6 +1782,10 @@ static int lxcVmStart(virConnectPtr conn,
         goto cleanup;
     }
 
+    if (autoDestroy &&
+        lxcProcessAutoDestroyAdd(driver, vm, conn) < 0)
+        goto cleanup;
+
     /*
      * Again, need to save the live configuration, because the function
      * requires vm->def->id != -1 to save tty info surely.
@@ -1719,7 +1840,7 @@ static int lxcDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
     virDomainEventPtr event = NULL;
     int ret = -1;
 
-    virCheckFlags(0, -1);
+    virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, -1);
 
     lxcDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -1743,7 +1864,9 @@ static int lxcDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
         goto cleanup;
     }
 
-    ret = lxcVmStart(dom->conn, driver, vm, VIR_DOMAIN_RUNNING_BOOTED);
+    ret = lxcVmStart(dom->conn, driver, vm,
+                     (flags & VIR_DOMAIN_START_AUTODESTROY),
+                     VIR_DOMAIN_RUNNING_BOOTED);
 
     if (ret == 0) {
         event = virDomainEventNewFromObj(vm,
@@ -1796,7 +1919,7 @@ lxcDomainCreateAndStart(virConnectPtr conn,
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
 
-    virCheckFlags(0, NULL);
+    virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, NULL);
 
     lxcDriverLock(driver);
     if (!(def = virDomainDefParseString(driver->caps, xml,
@@ -1819,7 +1942,9 @@ lxcDomainCreateAndStart(virConnectPtr conn,
         goto cleanup;
     def = NULL;
 
-    if (lxcVmStart(conn, driver, vm, VIR_DOMAIN_RUNNING_BOOTED) < 0) {
+    if (lxcVmStart(conn, driver, vm,
+                   (flags & VIR_DOMAIN_START_AUTODESTROY),
+                   VIR_DOMAIN_RUNNING_BOOTED) < 0) {
         virDomainAuditStart(vm, "booted", false);
         virDomainRemoveInactive(&driver->domains, vm);
         vm = NULL;
@@ -2054,7 +2179,7 @@ lxcAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaqu
     virDomainObjLock(vm);
     if (vm->autostart &&
         !virDomainObjIsActive(vm)) {
-        int ret = lxcVmStart(data->conn, data->driver, vm,
+        int ret = lxcVmStart(data->conn, data->driver, vm, false,
                              VIR_DOMAIN_RUNNING_BOOTED);
         virDomainAuditStart(vm, "booted", ret >= 0);
         if (ret < 0) {
@@ -2205,6 +2330,9 @@ static int lxcStartup(int privileged)
     lxc_driver->caps->privateDataAllocFunc = lxcDomainObjPrivateAlloc;
     lxc_driver->caps->privateDataFreeFunc = lxcDomainObjPrivateFree;
 
+    if (lxcProcessAutoDestroyInit(lxc_driver) < 0)
+        goto cleanup;
+
     /* Get all the running persistent or transient configs first */
     if (virDomainLoadAllConfigs(lxc_driver->caps,
                                 &lxc_driver->domains,
@@ -2285,6 +2413,8 @@ static int lxcShutdown(void)
     virDomainObjListDeinit(&lxc_driver->domains);
     virDomainEventStateFree(lxc_driver->domainEventState);
 
+    lxcProcessAutoDestroyShutdown(lxc_driver);
+
     virCapabilitiesFree(lxc_driver->caps);
     VIR_FREE(lxc_driver->configDir);
     VIR_FREE(lxc_driver->autostartDir);
diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h
index 5401a7e..657f877 100644
--- a/src/uml/uml_conf.h
+++ b/src/uml/uml_conf.h
@@ -33,6 +33,7 @@
 # include "virterror_internal.h"
 # include "threads.h"
 # include "command.h"
+# include "hash.h"
 
 # define umlDebug(fmt, ...) do {} while(0)
 
@@ -64,6 +65,11 @@ struct uml_driver {
 
     /* Event handling */
     virDomainEventStatePtr domainEventState;
+
+    /* Mapping of 'char *uuidstr' -> virConnectPtr
+     * of guests which will be automatically killed
+     * when the virConnectPtr is closed*/
+    virHashTablePtr autodestroy;
 };
 
 
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index 2b7219a..16ab73a 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -75,6 +75,16 @@ struct _umlDomainObjPrivate {
     int monitorWatch;
 };
 
+static int umlProcessAutoDestroyInit(struct uml_driver *driver);
+static void umlProcessAutoDestroyRun(struct uml_driver *driver,
+                                     virConnectPtr conn);
+static void umlProcessAutoDestroyShutdown(struct uml_driver *driver);
+static int umlProcessAutoDestroyAdd(struct uml_driver *driver,
+                                    virDomainObjPtr vm,
+                                    virConnectPtr conn);
+static int umlProcessAutoDestroyRemove(struct uml_driver *driver,
+                                       virDomainObjPtr vm);
+
 
 static int umlShutdown(void);
 
@@ -119,10 +129,10 @@ static void umlDomainEventQueue(struct uml_driver *driver,
 
 static int umlStartVMDaemon(virConnectPtr conn,
                             struct uml_driver *driver,
-                            virDomainObjPtr vm);
+                            virDomainObjPtr vm,
+                            bool autoDestroy);
 
-static void umlShutdownVMDaemon(virConnectPtr conn,
-                                struct uml_driver *driver,
+static void umlShutdownVMDaemon(struct uml_driver *driver,
                                 virDomainObjPtr vm,
                                 virDomainShutoffReason reason);
 
@@ -150,7 +160,7 @@ umlAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaqu
         !virDomainObjIsActive(vm)) {
         int ret;
         virResetLastError();
-        ret = umlStartVMDaemon(data->conn, data->driver, vm);
+        ret = umlStartVMDaemon(data->conn, data->driver, vm, false);
         virDomainAuditStart(vm, "booted", ret >= 0);
         if (ret < 0) {
             virErrorPtr err = virGetLastError();
@@ -309,7 +319,7 @@ reread:
                 continue;
             }
 
-            umlShutdownVMDaemon(NULL, driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
+            umlShutdownVMDaemon(driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
             virDomainAuditStop(dom, "shutdown");
             event = virDomainEventNewFromObj(dom,
                                              VIR_DOMAIN_EVENT_STOPPED,
@@ -337,7 +347,7 @@ reread:
 
             if (umlOpenMonitor(driver, dom) < 0) {
                 VIR_WARN("Could not open monitor for new domain");
-                umlShutdownVMDaemon(NULL, driver, dom,
+                umlShutdownVMDaemon(driver, dom,
                                     VIR_DOMAIN_SHUTOFF_FAILED);
                 virDomainAuditStop(dom, "failed");
                 event = virDomainEventNewFromObj(dom,
@@ -350,7 +360,7 @@ reread:
                 }
             } else if (umlIdentifyChrPTY(driver, dom) < 0) {
                 VIR_WARN("Could not identify character devices for new domain");
-                umlShutdownVMDaemon(NULL, driver, dom,
+                umlShutdownVMDaemon(driver, dom,
                                     VIR_DOMAIN_SHUTOFF_FAILED);
                 virDomainAuditStop(dom, "failed");
                 event = virDomainEventNewFromObj(dom,
@@ -480,6 +490,9 @@ umlStartup(int privileged)
                            umlInotifyEvent, uml_driver, NULL)) < 0)
         goto error;
 
+    if (umlProcessAutoDestroyInit(uml_driver) < 0)
+        goto error;
+
     if (virDomainLoadAllConfigs(uml_driver->caps,
                                 &uml_driver->domains,
                                 uml_driver->configDir,
@@ -577,7 +590,7 @@ umlShutdownOneVM(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaque)
 
     virDomainObjLock(dom);
     if (virDomainObjIsActive(dom)) {
-        umlShutdownVMDaemon(NULL, driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
+        umlShutdownVMDaemon(driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
         virDomainAuditStop(dom, "shutdown");
     }
     virDomainObjUnlock(dom);
@@ -612,6 +625,8 @@ umlShutdown(void) {
     VIR_FREE(uml_driver->autostartDir);
     VIR_FREE(uml_driver->monitorDir);
 
+    umlProcessAutoDestroyShutdown(uml_driver);
+
     if (uml_driver->brctl)
         brShutdown(uml_driver->brctl);
 
@@ -623,6 +638,104 @@ umlShutdown(void) {
 }
 
 
+static int umlProcessAutoDestroyInit(struct uml_driver *driver)
+{
+    if (!(driver->autodestroy = virHashCreate(5, NULL)))
+        return -1;
+
+    return 0;
+}
+
+struct umlProcessAutoDestroyData {
+    struct uml_driver *driver;
+    virConnectPtr conn;
+};
+
+static void umlProcessAutoDestroyDom(void *payload,
+                                     const void *name,
+                                     void *opaque)
+{
+    struct umlProcessAutoDestroyData *data = opaque;
+    virConnectPtr conn = payload;
+    const char *uuidstr = name;
+    unsigned char uuid[VIR_UUID_BUFLEN];
+    virDomainObjPtr dom;
+    virDomainEventPtr event = NULL;
+
+    VIR_DEBUG("conn=%p uuidstr=%s thisconn=%p", conn, uuidstr, data->conn);
+
+    if (data->conn != conn)
+        return;
+
+    if (virUUIDParse(uuidstr, uuid) < 0) {
+        VIR_WARN("Failed to parse %s", uuidstr);
+        return;
+    }
+
+    if (!(dom = virDomainFindByUUID(&data->driver->domains,
+                                    uuid))) {
+        VIR_DEBUG("No domain object to kill");
+        return;
+    }
+
+    VIR_DEBUG("Killing domain");
+    umlShutdownVMDaemon(data->driver, dom, VIR_DOMAIN_SHUTOFF_DESTROYED);
+    virDomainAuditStop(dom, "destroyed");
+    event = virDomainEventNewFromObj(dom,
+                                     VIR_DOMAIN_EVENT_STOPPED,
+                                     VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
+
+    if (dom && !dom->persistent)
+        virDomainRemoveInactive(&data->driver->domains, dom);
+
+    if (dom)
+        virDomainObjUnlock(dom);
+    if (event)
+        umlDomainEventQueue(data->driver, event);
+    virHashRemoveEntry(data->driver->autodestroy, uuidstr);
+}
+
+/*
+ * Precondition: driver is locked
+ */
+static void umlProcessAutoDestroyRun(struct uml_driver *driver, virConnectPtr conn)
+{
+    struct umlProcessAutoDestroyData data = {
+        driver, conn
+    };
+    VIR_DEBUG("conn=%p", conn);
+    virHashForEach(driver->autodestroy, umlProcessAutoDestroyDom, &data);
+}
+
+static void umlProcessAutoDestroyShutdown(struct uml_driver *driver)
+{
+    virHashFree(driver->autodestroy);
+}
+
+static int umlProcessAutoDestroyAdd(struct uml_driver *driver,
+                                    virDomainObjPtr vm,
+                                    virConnectPtr conn)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    virUUIDFormat(vm->def->uuid, uuidstr);
+    VIR_DEBUG("vm=%s uuid=%s conn=%p", vm->def->name, uuidstr, conn);
+    if (virHashAddEntry(driver->autodestroy, uuidstr, conn) < 0)
+        return -1;
+    return 0;
+}
+
+static int umlProcessAutoDestroyRemove(struct uml_driver *driver,
+                                       virDomainObjPtr vm)
+{
+    char uuidstr[VIR_UUID_STRING_BUFLEN];
+    virUUIDFormat(vm->def->uuid, uuidstr);
+    VIR_DEBUG("vm=%s uuid=%s", vm->def->name, uuidstr);
+    if (virHashRemoveEntry(driver->autodestroy, uuidstr) < 0)
+        return -1;
+    return 0;
+}
+
+
 static int umlReadPidFile(struct uml_driver *driver,
                           virDomainObjPtr vm)
 {
@@ -842,8 +955,7 @@ error:
 }
 
 
-static int umlCleanupTapDevices(virConnectPtr conn ATTRIBUTE_UNUSED,
-                                virDomainObjPtr vm) {
+static int umlCleanupTapDevices(virDomainObjPtr vm) {
     int i;
     int err;
     int ret = 0;
@@ -873,7 +985,8 @@ static int umlCleanupTapDevices(virConnectPtr conn ATTRIBUTE_UNUSED,
 
 static int umlStartVMDaemon(virConnectPtr conn,
                             struct uml_driver *driver,
-                            virDomainObjPtr vm) {
+                            virDomainObjPtr vm,
+                            bool autoDestroy) {
     int ret;
     char *logfile;
     int logfd = -1;
@@ -935,7 +1048,7 @@ static int umlStartVMDaemon(virConnectPtr conn,
     if (!(cmd = umlBuildCommandLine(conn, driver, vm))) {
         VIR_FORCE_CLOSE(logfd);
         virDomainConfVMNWFilterTeardown(vm);
-        umlCleanupTapDevices(conn, vm);
+        umlCleanupTapDevices(vm);
         return -1;
     }
 
@@ -953,13 +1066,17 @@ static int umlStartVMDaemon(virConnectPtr conn,
     if (ret < 0)
         goto cleanup;
 
+    if (autoDestroy &&
+        umlProcessAutoDestroyAdd(driver, vm, conn) < 0)
+        goto cleanup;
+
     ret = virDomainObjSetDefTransient(driver->caps, vm, false);
 cleanup:
     virCommandFree(cmd);
 
     if (ret < 0) {
         virDomainConfVMNWFilterTeardown(vm);
-        umlCleanupTapDevices(conn, vm);
+        umlCleanupTapDevices(vm);
     }
 
     /* NB we don't mark it running here - we do that async
@@ -972,8 +1089,7 @@ cleanup:
     return ret;
 }
 
-static void umlShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
-                                struct uml_driver *driver ATTRIBUTE_UNUSED,
+static void umlShutdownVMDaemon(struct uml_driver *driver,
                                 virDomainObjPtr vm,
                                 virDomainShutoffReason reason)
 {
@@ -997,7 +1113,10 @@ static void umlShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
     virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason);
 
     virDomainConfVMNWFilterTeardown(vm);
-    umlCleanupTapDevices(conn, vm);
+    umlCleanupTapDevices(vm);
+
+    /* Stop autodestroy in case guest is restarted */
+    umlProcessAutoDestroyRemove(driver, vm);
 
     if (vm->newDef) {
         virDomainDefFree(vm->def);
@@ -1072,6 +1191,7 @@ static int umlClose(virConnectPtr conn) {
     umlDriverLock(driver);
     virDomainEventCallbackListRemoveConn(conn,
                                          driver->domainEventState->callbacks);
+    umlProcessAutoDestroyRun(driver, conn);
     umlDriverUnlock(driver);
 
     conn->privateData = NULL;
@@ -1342,7 +1462,7 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
 
-    virCheckFlags(0, NULL);
+    virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, NULL);
 
     umlDriverLock(driver);
     if (!(def = virDomainDefParseString(driver->caps, xml,
@@ -1359,7 +1479,8 @@ static virDomainPtr umlDomainCreate(virConnectPtr conn, const char *xml,
         goto cleanup;
     def = NULL;
 
-    if (umlStartVMDaemon(conn, driver, vm) < 0) {
+    if (umlStartVMDaemon(conn, driver, vm,
+                         (flags & VIR_DOMAIN_START_AUTODESTROY)) < 0) {
         virDomainAuditStart(vm, "booted", false);
         virDomainRemoveInactive(&driver->domains,
                                 vm);
@@ -1436,7 +1557,7 @@ umlDomainDestroyFlags(virDomainPtr dom,
         goto cleanup;
     }
 
-    umlShutdownVMDaemon(dom->conn, driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
+    umlShutdownVMDaemon(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED);
     virDomainAuditStop(vm, "destroyed");
     event = virDomainEventNewFromObj(vm,
                                      VIR_DOMAIN_EVENT_STOPPED,
@@ -1717,7 +1838,7 @@ static int umlDomainStartWithFlags(virDomainPtr dom, unsigned int flags) {
     virDomainEventPtr event = NULL;
     int ret = -1;
 
-    virCheckFlags(0, -1);
+    virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, -1);
 
     umlDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -1728,7 +1849,8 @@ static int umlDomainStartWithFlags(virDomainPtr dom, unsigned int flags) {
         goto cleanup;
     }
 
-    ret = umlStartVMDaemon(dom->conn, driver, vm);
+    ret = umlStartVMDaemon(dom->conn, driver, vm,
+                           (flags & VIR_DOMAIN_START_AUTODESTROY));
     virDomainAuditStart(vm, "booted", ret >= 0);
     if (ret == 0)
         event = virDomainEventNewFromObj(vm,
-- 
1.7.6.4




More information about the libvir-list mailing list