mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-15 09:53:44 -06:00
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:
parent
92427948b3
commit
4882618ed1
@ -1118,6 +1118,7 @@ virCgroupSetMemorySoftLimit;
|
||||
virCgroupSetMemSwapHardLimit;
|
||||
virCgroupSetOwner;
|
||||
virCgroupSupportsCpuBW;
|
||||
virCgroupTerminateMachine;
|
||||
|
||||
|
||||
# util/virclosecallbacks.h
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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__ */
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user