File 4882618-qemu-terminatemachine.patch of Package libvirt.239
commit 4882618ed13b469d92fa8b2b4a158fdb17dbe9f1
Author: Guido Günther <agx@sigxcpu.org>
Date: Thu Sep 25 13:32:58 2014 +0200
qemu: use systemd's TerminateMachine to kill all processes
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.
Index: libvirt-1.2.5/src/libvirt_private.syms
===================================================================
--- libvirt-1.2.5.orig/src/libvirt_private.syms
+++ libvirt-1.2.5/src/libvirt_private.syms
@@ -1079,6 +1079,7 @@ virCgroupSetMemorySoftLimit;
virCgroupSetMemSwapHardLimit;
virCgroupSetOwner;
virCgroupSupportsCpuBW;
+virCgroupTerminateMachine;
# util/virclosecallbacks.h
Index: libvirt-1.2.5/src/qemu/qemu_cgroup.c
===================================================================
--- libvirt-1.2.5.orig/src/qemu/qemu_cgroup.c
+++ libvirt-1.2.5/src/qemu/qemu_cgroup.c
@@ -1030,13 +1030,22 @@ qemuSetupCgroupForEmulator(virQEMUDriver
}
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: libvirt-1.2.5/src/qemu/qemu_cgroup.h
===================================================================
--- libvirt-1.2.5.orig/src/qemu/qemu_cgroup.h
+++ libvirt-1.2.5/src/qemu/qemu_cgroup.h
@@ -56,7 +56,7 @@ int qemuSetupCgroupForVcpu(virDomainObjP
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: libvirt-1.2.5/src/qemu/qemu_process.c
===================================================================
--- libvirt-1.2.5.orig/src/qemu/qemu_process.c
+++ libvirt-1.2.5/src/qemu/qemu_process.c
@@ -3777,7 +3777,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];
@@ -4470,7 +4470,7 @@ void qemuProcessStop(virQEMUDriverPtr dr
}
retry:
- if ((ret = qemuRemoveCgroup(vm)) < 0) {
+ if ((ret = qemuRemoveCgroup(driver, vm)) < 0) {
if (ret == -EBUSY && (retries++ < 5)) {
usleep(200*1000);
goto retry;
Index: libvirt-1.2.5/src/util/vircgroup.c
===================================================================
--- libvirt-1.2.5.orig/src/util/vircgroup.c
+++ libvirt-1.2.5/src/util/vircgroup.c
@@ -1599,6 +1599,17 @@ virCgroupNewMachineSystemd(const char *n
}
+/*
+ * 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: libvirt-1.2.5/src/util/vircgroup.h
===================================================================
--- libvirt-1.2.5.orig/src/util/vircgroup.h
+++ libvirt-1.2.5/src/util/vircgroup.h
@@ -100,6 +100,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);