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.
This commit is contained in:
Guido Günther 2014-09-25 13:32:58 +02:00
parent 92427948b3
commit 4882618ed1
6 changed files with 30 additions and 4 deletions

View File

@ -1118,6 +1118,7 @@ virCgroupSetMemorySoftLimit;
virCgroupSetMemSwapHardLimit;
virCgroupSetOwner;
virCgroupSupportsCpuBW;
virCgroupTerminateMachine;
# util/virclosecallbacks.h

View 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);
}

View 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__ */

View 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;

View 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,

View 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);