mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-08 14:29:56 +00: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;
|
virCgroupSetMemSwapHardLimit;
|
||||||
virCgroupSetOwner;
|
virCgroupSetOwner;
|
||||||
virCgroupSupportsCpuBW;
|
virCgroupSupportsCpuBW;
|
||||||
|
virCgroupTerminateMachine;
|
||||||
|
|
||||||
|
|
||||||
# util/virclosecallbacks.h
|
# util/virclosecallbacks.h
|
||||||
|
@ -1206,13 +1206,22 @@ qemuSetupCgroupForIOThreads(virDomainObjPtr vm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuRemoveCgroup(virDomainObjPtr vm)
|
qemuRemoveCgroup(virQEMUDriverPtr driver,
|
||||||
|
virDomainObjPtr vm)
|
||||||
{
|
{
|
||||||
qemuDomainObjPrivatePtr priv = vm->privateData;
|
qemuDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
|
||||||
|
|
||||||
if (priv->cgroup == NULL)
|
if (priv->cgroup == NULL)
|
||||||
return 0; /* Not supported, so claim success */
|
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);
|
return virCgroupRemove(priv->cgroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ int qemuSetupCgroupForIOThreads(virDomainObjPtr vm);
|
|||||||
int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
|
int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virBitmapPtr nodemask);
|
virBitmapPtr nodemask);
|
||||||
int qemuRemoveCgroup(virDomainObjPtr vm);
|
int qemuRemoveCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm);
|
||||||
int qemuAddToCgroup(virDomainObjPtr vm);
|
int qemuAddToCgroup(virDomainObjPtr vm);
|
||||||
|
|
||||||
#endif /* __QEMU_CGROUP_H__ */
|
#endif /* __QEMU_CGROUP_H__ */
|
||||||
|
@ -4143,7 +4143,7 @@ int qemuProcessStart(virConnectPtr conn,
|
|||||||
/* Ensure no historical cgroup for this VM is lying around bogus
|
/* Ensure no historical cgroup for this VM is lying around bogus
|
||||||
* settings */
|
* settings */
|
||||||
VIR_DEBUG("Ensuring no historical cgroup is lying around");
|
VIR_DEBUG("Ensuring no historical cgroup is lying around");
|
||||||
qemuRemoveCgroup(vm);
|
qemuRemoveCgroup(driver, vm);
|
||||||
|
|
||||||
for (i = 0; i < vm->def->ngraphics; ++i) {
|
for (i = 0; i < vm->def->ngraphics; ++i) {
|
||||||
virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
|
virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
|
||||||
@ -4921,7 +4921,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
if ((ret = qemuRemoveCgroup(vm)) < 0) {
|
if ((ret = qemuRemoveCgroup(driver, vm)) < 0) {
|
||||||
if (ret == -EBUSY && (retries++ < 5)) {
|
if (ret == -EBUSY && (retries++ < 5)) {
|
||||||
usleep(200*1000);
|
usleep(200*1000);
|
||||||
goto retry;
|
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
|
static int
|
||||||
virCgroupNewMachineManual(const char *name,
|
virCgroupNewMachineManual(const char *name,
|
||||||
const char *drivername,
|
const char *drivername,
|
||||||
|
@ -106,6 +106,11 @@ int virCgroupNewMachine(const char *name,
|
|||||||
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
|
||||||
ATTRIBUTE_NONNULL(4);
|
ATTRIBUTE_NONNULL(4);
|
||||||
|
|
||||||
|
int virCgroupTerminateMachine(const char *name,
|
||||||
|
const char *drivername,
|
||||||
|
bool privileged)
|
||||||
|
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
|
||||||
|
|
||||||
bool virCgroupNewIgnoreError(void);
|
bool virCgroupNewIgnoreError(void);
|
||||||
|
|
||||||
void virCgroupFree(virCgroupPtr *group);
|
void virCgroupFree(virCgroupPtr *group);
|
||||||
|
Loading…
Reference in New Issue
Block a user