[libvirt] [PATCH 3/3] Allow automatic kill of guests when a connection is closed

Daniel P. Berrange berrange at redhat.com
Thu Jun 23 10:58:18 UTC 2011


If an application is using libvirt + KVM as a piece of its
internal infrastructure to perform a specific task, it can
be desirable to guarentee the VM dies when the virConnectPtr
disconnects from libvirtd. This ensures the app can't leak
any VMs it was using. Adding VIR_DOMAIN_START_AUTOKILL as
a flag when starting guests enables this to be done.

* include/libvirt/libvirt.h.in: All VIR_DOMAIN_START_AUTOKILL
* src/qemu/qemu_driver.c: Support automatic killing of guests
  upon connection close
* tools/virsh.c: Add --autokill flag to 'start' and 'create'
  commands
---
 include/libvirt/libvirt.h.in |    1 +
 src/qemu/qemu_driver.c       |   27 ++++++++++++++++++---------
 tools/virsh.c                |    6 ++++++
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 3f634e6..a827697 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -234,6 +234,7 @@ typedef virDomainInfo *virDomainInfoPtr;
 typedef enum {
     VIR_DOMAIN_NONE         = 0,      /* Default behavior */
     VIR_DOMAIN_START_PAUSED = 1 << 0, /* Launch guest in paused state */
+    VIR_DOMAIN_START_AUTOKILL = 1 << 1, /* Automatically kill guest when virConnectPtr is closed */
 } virDomainCreateFlags;
 
 
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 44e1fba..18701a7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -119,7 +119,8 @@ static int qemudShutdown(void);
 static int qemudDomainObjStart(virConnectPtr conn,
                                struct qemud_driver *driver,
                                virDomainObjPtr vm,
-                               bool start_paused);
+                               bool start_paused,
+                               bool autokill);
 
 static int qemudDomainGetMaxVcpus(virDomainPtr dom);
 
@@ -148,7 +149,7 @@ qemuAutostartDomain(void *payload, const void *name ATTRIBUTE_UNUSED, void *opaq
     } else {
         if (vm->autostart &&
             !virDomainObjIsActive(vm) &&
-            qemudDomainObjStart(data->conn, data->driver, vm, false) < 0) {
+            qemudDomainObjStart(data->conn, data->driver, vm, false, false) < 0) {
             err = virGetLastError();
             VIR_ERROR(_("Failed to autostart VM '%s': %s"),
                       vm->def->name,
@@ -1246,7 +1247,8 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
     virDomainPtr dom = NULL;
     virDomainEventPtr event = NULL;
 
-    virCheckFlags(VIR_DOMAIN_START_PAUSED, NULL);
+    virCheckFlags(VIR_DOMAIN_START_PAUSED |
+                  VIR_DOMAIN_START_AUTOKILL, NULL);
 
     qemuDriverLock(driver);
     if (!(def = virDomainDefParseString(driver->caps, xml,
@@ -1277,7 +1279,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
 
     if (qemuProcessStart(conn, driver, vm, NULL,
                          (flags & VIR_DOMAIN_START_PAUSED) != 0,
-                         false,
+                         (flags & VIR_DOMAIN_START_AUTOKILL) != 0,
                          -1, NULL, VIR_VM_OP_CREATE) < 0) {
         qemuAuditDomainStart(vm, "booted", false);
         if (qemuDomainObjEndJob(vm) > 0)
@@ -1295,6 +1297,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char *xml,
     dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
     if (dom) dom->id = vm->def->id;
 
+endjob:
     if (vm &&
         qemuDomainObjEndJob(vm) == 0)
         vm = NULL;
@@ -3819,7 +3822,8 @@ static int qemudNumDefinedDomains(virConnectPtr conn) {
 static int qemudDomainObjStart(virConnectPtr conn,
                                struct qemud_driver *driver,
                                virDomainObjPtr vm,
-                               bool start_paused)
+                               bool start_paused,
+                               bool autokill)
 {
     int ret = -1;
     char *managed_save;
@@ -3843,7 +3847,7 @@ static int qemudDomainObjStart(virConnectPtr conn,
     }
 
     ret = qemuProcessStart(conn, driver, vm, NULL, start_paused,
-                           false, -1, NULL, VIR_VM_OP_CREATE);
+                           autokill, -1, NULL, VIR_VM_OP_CREATE);
     qemuAuditDomainStart(vm, "booted", ret >= 0);
     if (ret >= 0) {
         virDomainEventPtr event =
@@ -3866,7 +3870,8 @@ qemudDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
     virDomainObjPtr vm;
     int ret = -1;
 
-    virCheckFlags(VIR_DOMAIN_START_PAUSED, -1);
+    virCheckFlags(VIR_DOMAIN_START_PAUSED |
+                  VIR_DOMAIN_START_AUTOKILL, -1);
 
     qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -3888,8 +3893,12 @@ qemudDomainStartWithFlags(virDomainPtr dom, unsigned int flags)
         goto endjob;
     }
 
-    ret = qemudDomainObjStart(dom->conn, driver, vm,
-                              (flags & VIR_DOMAIN_START_PAUSED) != 0);
+    if (qemudDomainObjStart(dom->conn, driver, vm,
+                            (flags & VIR_DOMAIN_START_PAUSED) != 0,
+                            (flags & VIR_DOMAIN_START_AUTOKILL) != 0) < 0)
+        goto endjob;
+
+    ret = 0;
 
 endjob:
     if (qemuDomainObjEndJob(vm) == 0)
diff --git a/tools/virsh.c b/tools/virsh.c
index fcd254d..dedf883 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1305,6 +1305,7 @@ static const vshCmdOptDef opts_create[] = {
     {"console", VSH_OT_BOOL, 0, N_("attach to console after creation")},
 #endif
     {"paused", VSH_OT_BOOL, 0, N_("leave the guest paused after creation")},
+    {"autokill", VSH_OT_BOOL, 0, N_("automatically kill the guest when virsh disconnects")},
     {NULL, 0, 0, NULL}
 };
 
@@ -1331,6 +1332,8 @@ cmdCreate(vshControl *ctl, const vshCmd *cmd)
 
     if (vshCommandOptBool(cmd, "paused"))
         flags |= VIR_DOMAIN_START_PAUSED;
+    if (vshCommandOptBool(cmd, "autokill"))
+        flags |= VIR_DOMAIN_START_AUTOKILL;
 
     dom = virDomainCreateXML(ctl->conn, buffer, flags);
     VIR_FREE(buffer);
@@ -1466,6 +1469,7 @@ static const vshCmdOptDef opts_start[] = {
     {"console", VSH_OT_BOOL, 0, N_("attach to console after creation")},
 #endif
     {"paused", VSH_OT_BOOL, 0, N_("leave the guest paused after creation")},
+    {"autokill", VSH_OT_BOOL, 0, N_("automatically kill the guest when virsh disconnects")},
     {NULL, 0, 0, NULL}
 };
 
@@ -1494,6 +1498,8 @@ cmdStart(vshControl *ctl, const vshCmd *cmd)
 
     if (vshCommandOptBool(cmd, "paused"))
         flags |= VIR_DOMAIN_START_PAUSED;
+    if (vshCommandOptBool(cmd, "autokill"))
+        flags |= VIR_DOMAIN_START_AUTOKILL;
 
     /* Prefer older API unless we have to pass a flag.  */
     if ((flags ? virDomainCreateWithFlags(dom, flags)
-- 
1.7.4.4




More information about the libvir-list mailing list