]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
qemu: use systemd's TerminateMachine to kill all processes
authorGuido Günther <agx@sigxcpu.org>
Thu, 25 Sep 2014 11:32:58 +0000 (13:32 +0200)
committerGuido Günther <agx@sigxcpu.org>
Wed, 1 Oct 2014 18:17:46 +0000 (20:17 +0200)
If we don't properly clean up all processes in the
machine-<vmname>.scope systemd won't remove the cgroup and subsequent vm
starts fail with

  'CreateMachine: File exists'

Additional processes can e.g. be added via

  echo $PID > /sys/fs/cgroup/systemd/machine.slice/machine-${VMNAME}.scope/tasks

but there are other cases like

  http://bugs.debian.org/761521

Invoke TerminateMachine to be on the safe side since systemd tracks the
cgroup anyway. This is a noop if all processes have terminated already.

src/libvirt_private.syms
src/qemu/qemu_cgroup.c
src/qemu/qemu_cgroup.h
src/qemu/qemu_process.c
src/util/vircgroup.c
src/util/vircgroup.h

index 2019ef52d05b9f3877a94355a28d952063e2af65..7cbc35b2c691e0bc703200c2aea7ad4c6f62e22e 100644 (file)
@@ -1118,6 +1118,7 @@ virCgroupSetMemorySoftLimit;
 virCgroupSetMemSwapHardLimit;
 virCgroupSetOwner;
 virCgroupSupportsCpuBW;
+virCgroupTerminateMachine;
 
 
 # util/virclosecallbacks.h
index bd22b7fbd60e9dc00dcd78c699ab257632a332e8..fa894c578bc12546bfb679ddd1ff9ef13c372159 100644 (file)
@@ -1206,13 +1206,22 @@ qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
 }
 
 int
-qemuRemoveCgroup(virDomainObjPtr vm)
+qemuRemoveCgroup(virQEMUDriverPtr driver,
+                 virDomainObjPtr vm)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 
     if (priv->cgroup == NULL)
         return 0; /* Not supported, so claim success */
 
+    if (virCgroupTerminateMachine(vm->def->name,
+                                  "qemu",
+                                  cfg->privileged) < 0) {
+        if (!virCgroupNewIgnoreError())
+            VIR_DEBUG("Failed to terminate cgroup for %s", vm->def->name);
+    }
+
     return virCgroupRemove(priv->cgroup);
 }
 
index 8a2c723bb73a2c046bd11a161a92abf9f22943eb..4a4f22c7789b67df3bdfe95f3360509451274ac7 100644 (file)
@@ -66,7 +66,7 @@ int qemuSetupCgroupForIOThreads(virDomainObjPtr vm);
 int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
                                virDomainObjPtr vm,
                                virBitmapPtr nodemask);
-int qemuRemoveCgroup(virDomainObjPtr vm);
+int qemuRemoveCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm);
 int qemuAddToCgroup(virDomainObjPtr vm);
 
 #endif /* __QEMU_CGROUP_H__ */
index 11eeb3ca380d449470d34d9bac1a9582d6bc8c7d..712a25e0222c7b854a83136b279d4ffab65e2586 100644 (file)
@@ -4143,7 +4143,7 @@ int qemuProcessStart(virConnectPtr conn,
     /* Ensure no historical cgroup for this VM is lying around bogus
      * settings */
     VIR_DEBUG("Ensuring no historical cgroup is lying around");
-    qemuRemoveCgroup(vm);
+    qemuRemoveCgroup(driver, vm);
 
     for (i = 0; i < vm->def->ngraphics; ++i) {
         virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
@@ -4921,7 +4921,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
     }
 
  retry:
-    if ((ret = qemuRemoveCgroup(vm)) < 0) {
+    if ((ret = qemuRemoveCgroup(driver, vm)) < 0) {
         if (ret == -EBUSY && (retries++ < 5)) {
             usleep(200*1000);
             goto retry;
index 1dbe6f99e803fe17a0d9b6ec9fac89aee77404be..d69f71bc22d4d1f230d923c21b4331d9a0ddf9fb 100644 (file)
@@ -1680,6 +1680,17 @@ virCgroupNewMachineSystemd(const char *name,
 }
 
 
+/*
+ * Returns 0 on success, -1 on fatal error
+ */
+int virCgroupTerminateMachine(const char *name,
+                              const char *drivername,
+                              bool privileged)
+{
+    return virSystemdTerminateMachine(name, drivername, privileged);
+}
+
+
 static int
 virCgroupNewMachineManual(const char *name,
                           const char *drivername,
index 19e82d16eb27da9273bca4bf7ce245dd721d98de..7718a07d10fbe5bf031b4f8693fcbf496ab927d8 100644 (file)
@@ -106,6 +106,11 @@ int virCgroupNewMachine(const char *name,
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
     ATTRIBUTE_NONNULL(4);
 
+int virCgroupTerminateMachine(const char *name,
+                              const char *drivername,
+                              bool privileged)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
+
 bool virCgroupNewIgnoreError(void);
 
 void virCgroupFree(virCgroupPtr *group);