1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2025-08-27 21:50:11 +03:00

Store a virCgroupPtr instance in qemuDomainObjPrivatePtr

Instead of calling virCgroupForDomain every time we need
the virCgrouPtr instance, just do it once at Vm startup
and cache a reference to the object in qemuDomainObjPrivatePtr
until shutdown of the VM. Removing the virCgroupPtr from
the QEMU driver state also means we don't have stale mount
info, if someone mounts the cgroups filesystem after libvirtd
has been started

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange
2013-03-21 14:40:29 +00:00
parent c9b8cdfec1
commit 632f78caaf
9 changed files with 300 additions and 517 deletions

View File

@ -45,26 +45,21 @@ static const char *const defaultDeviceACL[] = {
#define DEVICE_PTY_MAJOR 136 #define DEVICE_PTY_MAJOR 136
#define DEVICE_SND_MAJOR 116 #define DEVICE_SND_MAJOR 116
bool qemuCgroupControllerActive(virQEMUDriverPtr driver,
int controller)
{
return virCgroupHasController(driver->cgroup, controller);
}
static int static int
qemuSetupDiskPathAllow(virDomainDiskDefPtr disk, qemuSetupDiskPathAllow(virDomainDiskDefPtr disk,
const char *path, const char *path,
size_t depth ATTRIBUTE_UNUSED, size_t depth ATTRIBUTE_UNUSED,
void *opaque) void *opaque)
{ {
qemuCgroupData *data = opaque; virDomainObjPtr vm = opaque;
qemuDomainObjPrivatePtr priv = vm->privateData;
int rc; int rc;
VIR_DEBUG("Process path %s for disk", path); VIR_DEBUG("Process path %s for disk", path);
rc = virCgroupAllowDevicePath(data->cgroup, path, rc = virCgroupAllowDevicePath(priv->cgroup, path,
(disk->readonly ? VIR_CGROUP_DEVICE_READ (disk->readonly ? VIR_CGROUP_DEVICE_READ
: VIR_CGROUP_DEVICE_RW)); : VIR_CGROUP_DEVICE_RW));
virDomainAuditCgroupPath(data->vm, data->cgroup, "allow", path, virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path,
disk->readonly ? "r" : "rw", rc); disk->readonly ? "r" : "rw", rc);
if (rc < 0) { if (rc < 0) {
if (rc == -EACCES) { /* Get this for root squash NFS */ if (rc == -EACCES) { /* Get this for root squash NFS */
@ -81,14 +76,18 @@ qemuSetupDiskPathAllow(virDomainDiskDefPtr disk,
int qemuSetupDiskCgroup(virDomainObjPtr vm, int qemuSetupDiskCgroup(virDomainObjPtr vm,
virCgroupPtr cgroup,
virDomainDiskDefPtr disk) virDomainDiskDefPtr disk)
{ {
qemuCgroupData data = { vm, cgroup }; qemuDomainObjPrivatePtr priv = vm->privateData;
if (!virCgroupHasController(priv->cgroup,
VIR_CGROUP_CONTROLLER_DEVICES))
return 0;
return virDomainDiskDefForeachPath(disk, return virDomainDiskDefForeachPath(disk,
true, true,
qemuSetupDiskPathAllow, qemuSetupDiskPathAllow,
&data); vm);
} }
@ -98,13 +97,14 @@ qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
size_t depth ATTRIBUTE_UNUSED, size_t depth ATTRIBUTE_UNUSED,
void *opaque) void *opaque)
{ {
qemuCgroupData *data = opaque; virDomainObjPtr vm = opaque;
qemuDomainObjPrivatePtr priv = vm->privateData;
int rc; int rc;
VIR_DEBUG("Process path %s for disk", path); VIR_DEBUG("Process path %s for disk", path);
rc = virCgroupDenyDevicePath(data->cgroup, path, rc = virCgroupDenyDevicePath(priv->cgroup, path,
VIR_CGROUP_DEVICE_RWM); VIR_CGROUP_DEVICE_RWM);
virDomainAuditCgroupPath(data->vm, data->cgroup, "deny", path, "rwm", rc); virDomainAuditCgroupPath(vm, priv->cgroup, "deny", path, "rwm", rc);
if (rc < 0) { if (rc < 0) {
if (rc == -EACCES) { /* Get this for root squash NFS */ if (rc == -EACCES) { /* Get this for root squash NFS */
VIR_DEBUG("Ignoring EACCES for %s", path); VIR_DEBUG("Ignoring EACCES for %s", path);
@ -120,21 +120,27 @@ qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED,
int qemuTeardownDiskCgroup(virDomainObjPtr vm, int qemuTeardownDiskCgroup(virDomainObjPtr vm,
virCgroupPtr cgroup,
virDomainDiskDefPtr disk) virDomainDiskDefPtr disk)
{ {
qemuCgroupData data = { vm, cgroup }; qemuDomainObjPrivatePtr priv = vm->privateData;
if (!virCgroupHasController(priv->cgroup,
VIR_CGROUP_CONTROLLER_DEVICES))
return 0;
return virDomainDiskDefForeachPath(disk, return virDomainDiskDefForeachPath(disk,
true, true,
qemuTeardownDiskPathDeny, qemuTeardownDiskPathDeny,
&data); vm);
} }
static int static int
qemuSetupChrSourceCgroup(virDomainDefPtr def, qemuSetupChrSourceCgroup(virDomainDefPtr def,
virDomainChrSourceDefPtr dev, virDomainChrSourceDefPtr dev,
qemuCgroupData *data) void *opaque)
{ {
virDomainObjPtr vm = opaque;
qemuDomainObjPrivatePtr priv = vm->privateData;
int rc; int rc;
if (dev->type != VIR_DOMAIN_CHR_TYPE_DEV) if (dev->type != VIR_DOMAIN_CHR_TYPE_DEV)
@ -142,9 +148,9 @@ qemuSetupChrSourceCgroup(virDomainDefPtr def,
VIR_DEBUG("Process path '%s' for device", dev->data.file.path); VIR_DEBUG("Process path '%s' for device", dev->data.file.path);
rc = virCgroupAllowDevicePath(data->cgroup, dev->data.file.path, rc = virCgroupAllowDevicePath(priv->cgroup, dev->data.file.path,
VIR_CGROUP_DEVICE_RW); VIR_CGROUP_DEVICE_RW);
virDomainAuditCgroupPath(data->vm, data->cgroup, "allow", virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
dev->data.file.path, "rw", rc); dev->data.file.path, "rw", rc);
if (rc < 0) { if (rc < 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
@ -161,23 +167,21 @@ qemuSetupChardevCgroup(virDomainDefPtr def,
virDomainChrDefPtr dev, virDomainChrDefPtr dev,
void *opaque) void *opaque)
{ {
qemuCgroupData *data = opaque; return qemuSetupChrSourceCgroup(def, &dev->source, opaque);
return qemuSetupChrSourceCgroup(def, &dev->source, data);
} }
static int static int
qemuSetupTPMCgroup(virDomainDefPtr def, qemuSetupTPMCgroup(virDomainDefPtr def,
virDomainTPMDefPtr dev, virDomainTPMDefPtr dev,
qemuCgroupData *data) void *opaque)
{ {
int rc = 0; int rc = 0;
switch (dev->type) { switch (dev->type) {
case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH: case VIR_DOMAIN_TPM_TYPE_PASSTHROUGH:
rc = qemuSetupChrSourceCgroup(def, &dev->data.passthrough.source, rc = qemuSetupChrSourceCgroup(def, &dev->data.passthrough.source,
data); opaque);
break; break;
case VIR_DOMAIN_TPM_TYPE_LAST: case VIR_DOMAIN_TPM_TYPE_LAST:
break; break;
@ -191,13 +195,14 @@ int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
const char *path, const char *path,
void *opaque) void *opaque)
{ {
qemuCgroupData *data = opaque; virDomainObjPtr vm = opaque;
qemuDomainObjPrivatePtr priv = vm->privateData;
int rc; int rc;
VIR_DEBUG("Process path '%s' for USB device", path); VIR_DEBUG("Process path '%s' for USB device", path);
rc = virCgroupAllowDevicePath(data->cgroup, path, rc = virCgroupAllowDevicePath(priv->cgroup, path,
VIR_CGROUP_DEVICE_RW); VIR_CGROUP_DEVICE_RW);
virDomainAuditCgroupPath(data->vm, data->cgroup, "allow", path, "rw", rc); virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path, "rw", rc);
if (rc < 0) { if (rc < 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to allow device %s"), _("Unable to allow device %s"),
@ -208,23 +213,35 @@ int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev ATTRIBUTE_UNUSED,
return 0; return 0;
} }
int qemuSetupCgroup(virQEMUDriverPtr driver,
virDomainObjPtr vm, int qemuInitCgroup(virQEMUDriverPtr driver,
virBitmapPtr nodemask) virDomainObjPtr vm)
{ {
virCgroupPtr cgroup = NULL;
int rc; int rc;
unsigned int i; qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr driverGroup = NULL;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
const char *const *deviceACL =
cfg->cgroupDeviceACL ?
(const char *const *)cfg->cgroupDeviceACL :
defaultDeviceACL;
if (driver->cgroup == NULL) virCgroupFree(&priv->cgroup);
goto done; /* Not supported, so claim success */
rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 1); rc = virCgroupForDriver("qemu", &driverGroup,
cfg->privileged, true,
cfg->cgroupControllers);
if (rc != 0) {
if (rc == -ENXIO ||
rc == -EPERM ||
rc == -EACCES) { /* No cgroups mounts == success */
VIR_DEBUG("No cgroups present/configured/accessible, ignoring error");
goto done;
}
virReportSystemError(-rc,
_("Unable to create cgroup for %s"),
vm->def->name);
goto cleanup;
}
rc = virCgroupForDomain(driverGroup, vm->def->name, &priv->cgroup, 1);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to create cgroup for %s"), _("Unable to create cgroup for %s"),
@ -232,10 +249,37 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { done:
qemuCgroupData data = { vm, cgroup }; rc = 0;
rc = virCgroupDenyAllDevices(cgroup); cleanup:
virDomainAuditCgroup(vm, cgroup, "deny", "all", rc == 0); virCgroupFree(&driverGroup);
virObjectUnref(cfg);
return rc;
}
int qemuSetupCgroup(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virBitmapPtr nodemask)
{
int rc = -1;
unsigned int i;
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
qemuDomainObjPrivatePtr priv = vm->privateData;
const char *const *deviceACL =
cfg->cgroupDeviceACL ?
(const char *const *)cfg->cgroupDeviceACL :
defaultDeviceACL;
if (qemuInitCgroup(driver, vm) < 0)
return -1;
if (!priv->cgroup)
goto done;
if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) {
rc = virCgroupDenyAllDevices(priv->cgroup);
virDomainAuditCgroup(vm, priv->cgroup, "deny", "all", rc == 0);
if (rc != 0) { if (rc != 0) {
if (rc == -EPERM) { if (rc == -EPERM) {
VIR_WARN("Group devices ACL is not accessible, disabling whitelisting"); VIR_WARN("Group devices ACL is not accessible, disabling whitelisting");
@ -248,13 +292,13 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
} }
for (i = 0; i < vm->def->ndisks ; i++) { for (i = 0; i < vm->def->ndisks ; i++) {
if (qemuSetupDiskCgroup(vm, cgroup, vm->def->disks[i]) < 0) if (qemuSetupDiskCgroup(vm, vm->def->disks[i]) < 0)
goto cleanup; goto cleanup;
} }
rc = virCgroupAllowDeviceMajor(cgroup, 'c', DEVICE_PTY_MAJOR, rc = virCgroupAllowDeviceMajor(priv->cgroup, 'c', DEVICE_PTY_MAJOR,
VIR_CGROUP_DEVICE_RW); VIR_CGROUP_DEVICE_RW);
virDomainAuditCgroupMajor(vm, cgroup, "allow", DEVICE_PTY_MAJOR, virDomainAuditCgroupMajor(vm, priv->cgroup, "allow", DEVICE_PTY_MAJOR,
"pty", "rw", rc == 0); "pty", "rw", rc == 0);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, "%s", virReportSystemError(-rc, "%s",
@ -267,9 +311,9 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
((vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && ((vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC &&
cfg->vncAllowHostAudio) || cfg->vncAllowHostAudio) ||
(vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL)))) { (vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL)))) {
rc = virCgroupAllowDeviceMajor(cgroup, 'c', DEVICE_SND_MAJOR, rc = virCgroupAllowDeviceMajor(priv->cgroup, 'c', DEVICE_SND_MAJOR,
VIR_CGROUP_DEVICE_RW); VIR_CGROUP_DEVICE_RW);
virDomainAuditCgroupMajor(vm, cgroup, "allow", DEVICE_SND_MAJOR, virDomainAuditCgroupMajor(vm, priv->cgroup, "allow", DEVICE_SND_MAJOR,
"sound", "rw", rc == 0); "sound", "rw", rc == 0);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, "%s", virReportSystemError(-rc, "%s",
@ -285,9 +329,9 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
continue; continue;
} }
rc = virCgroupAllowDevicePath(cgroup, deviceACL[i], rc = virCgroupAllowDevicePath(priv->cgroup, deviceACL[i],
VIR_CGROUP_DEVICE_RW); VIR_CGROUP_DEVICE_RW);
virDomainAuditCgroupPath(vm, cgroup, "allow", deviceACL[i], "rw", rc); virDomainAuditCgroupPath(vm, priv->cgroup, "allow", deviceACL[i], "rw", rc);
if (rc < 0 && if (rc < 0 &&
rc != -ENOENT) { rc != -ENOENT) {
virReportSystemError(-rc, virReportSystemError(-rc,
@ -300,13 +344,14 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
if (virDomainChrDefForeach(vm->def, if (virDomainChrDefForeach(vm->def,
true, true,
qemuSetupChardevCgroup, qemuSetupChardevCgroup,
&data) < 0) vm) < 0)
goto cleanup; goto cleanup;
if (vm->def->tpm) if (vm->def->tpm &&
qemuSetupTPMCgroup(vm->def, (qemuSetupTPMCgroup(vm->def,
vm->def->tpm, vm->def->tpm,
&data); vm) < 0))
goto cleanup;
for (i = 0; i < vm->def->nhostdevs; i++) { for (i = 0; i < vm->def->nhostdevs; i++) {
virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i]; virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
@ -325,7 +370,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup,
&data) < 0) { vm) < 0) {
virUSBDeviceFree(usb); virUSBDeviceFree(usb);
goto cleanup; goto cleanup;
} }
@ -334,8 +379,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
} }
if (vm->def->blkio.weight != 0) { if (vm->def->blkio.weight != 0) {
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_BLKIO)) {
rc = virCgroupSetBlkioWeight(cgroup, vm->def->blkio.weight); rc = virCgroupSetBlkioWeight(priv->cgroup, vm->def->blkio.weight);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to set io weight for domain %s"), _("Unable to set io weight for domain %s"),
@ -350,12 +395,12 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
} }
if (vm->def->blkio.ndevices) { if (vm->def->blkio.ndevices) {
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_BLKIO)) {
for (i = 0; i < vm->def->blkio.ndevices; i++) { for (i = 0; i < vm->def->blkio.ndevices; i++) {
virBlkioDeviceWeightPtr dw = &vm->def->blkio.devices[i]; virBlkioDeviceWeightPtr dw = &vm->def->blkio.devices[i];
if (!dw->weight) if (!dw->weight)
continue; continue;
rc = virCgroupSetBlkioDeviceWeight(cgroup, dw->path, rc = virCgroupSetBlkioDeviceWeight(priv->cgroup, dw->path,
dw->weight); dw->weight);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
@ -372,7 +417,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
} }
} }
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) { if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_MEMORY)) {
unsigned long long hard_limit = vm->def->mem.hard_limit; unsigned long long hard_limit = vm->def->mem.hard_limit;
if (!hard_limit) { if (!hard_limit) {
@ -390,7 +435,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
hard_limit += vm->def->ndisks * 32768; hard_limit += vm->def->ndisks * 32768;
} }
rc = virCgroupSetMemoryHardLimit(cgroup, hard_limit); rc = virCgroupSetMemoryHardLimit(priv->cgroup, hard_limit);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to set memory hard limit for domain %s"), _("Unable to set memory hard limit for domain %s"),
@ -398,7 +443,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
if (vm->def->mem.soft_limit != 0) { if (vm->def->mem.soft_limit != 0) {
rc = virCgroupSetMemorySoftLimit(cgroup, vm->def->mem.soft_limit); rc = virCgroupSetMemorySoftLimit(priv->cgroup, vm->def->mem.soft_limit);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to set memory soft limit for domain %s"), _("Unable to set memory soft limit for domain %s"),
@ -408,7 +453,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
} }
if (vm->def->mem.swap_hard_limit != 0) { if (vm->def->mem.swap_hard_limit != 0) {
rc = virCgroupSetMemSwapHardLimit(cgroup, vm->def->mem.swap_hard_limit); rc = virCgroupSetMemSwapHardLimit(priv->cgroup, vm->def->mem.swap_hard_limit);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to set swap hard limit for domain %s"), _("Unable to set swap hard limit for domain %s"),
@ -426,8 +471,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
} }
if (vm->def->cputune.shares != 0) { if (vm->def->cputune.shares != 0) {
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
rc = virCgroupSetCpuShares(cgroup, vm->def->cputune.shares); rc = virCgroupSetCpuShares(priv->cgroup, vm->def->cputune.shares);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to set io cpu shares for domain %s"), _("Unable to set io cpu shares for domain %s"),
@ -444,7 +489,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
(vm->def->numatune.memory.placement_mode == (vm->def->numatune.memory.placement_mode ==
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) && VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)) &&
vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT && vm->def->numatune.memory.mode == VIR_DOMAIN_NUMATUNE_MEM_STRICT &&
qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
char *mask = NULL; char *mask = NULL;
if (vm->def->numatune.memory.placement_mode == if (vm->def->numatune.memory.placement_mode ==
VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO) VIR_NUMA_TUNE_MEM_PLACEMENT_MODE_AUTO)
@ -457,7 +502,7 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
rc = virCgroupSetCpusetMems(cgroup, mask); rc = virCgroupSetCpusetMems(priv->cgroup, mask);
VIR_FREE(mask); VIR_FREE(mask);
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
@ -466,18 +511,12 @@ int qemuSetupCgroup(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
} }
done:
virObjectUnref(cfg);
virCgroupFree(&cgroup);
return 0;
done:
rc = 0;
cleanup: cleanup:
virObjectUnref(cfg); virObjectUnref(cfg);
if (cgroup) { return rc == 0 ? 0 : -1;
virCgroupRemove(cgroup);
virCgroupFree(&cgroup);
}
return -1;
} }
int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup, unsigned long long period, int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup, unsigned long long period,
@ -571,9 +610,8 @@ cleanup:
return rc; return rc;
} }
int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm) int qemuSetupCgroupForVcpu(virDomainObjPtr vm)
{ {
virCgroupPtr cgroup = NULL;
virCgroupPtr cgroup_vcpu = NULL; virCgroupPtr cgroup_vcpu = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virDomainDefPtr def = vm->def; virDomainDefPtr def = vm->def;
@ -583,8 +621,7 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
long long quota = vm->def->cputune.quota; long long quota = vm->def->cputune.quota;
if ((period || quota) && if ((period || quota) &&
(!driver->cgroup || !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU))) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("cgroup cpu is required for scheduler tuning")); _("cgroup cpu is required for scheduler tuning"));
return -1; return -1;
@ -594,28 +631,19 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
* with virProcessInfoSetAffinity, thus the lack of cgroups is not fatal * with virProcessInfoSetAffinity, thus the lack of cgroups is not fatal
* here. * here.
*/ */
if (driver->cgroup == NULL) if (priv->cgroup == NULL)
return 0; return 0;
rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0);
if (rc != 0) {
virReportSystemError(-rc,
_("Unable to find cgroup for %s"),
vm->def->name);
goto cleanup;
}
if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) { if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) {
/* If we don't know VCPU<->PID mapping or all vcpu runs in the same /* If we don't know VCPU<->PID mapping or all vcpu runs in the same
* thread, we cannot control each vcpu. * thread, we cannot control each vcpu.
*/ */
VIR_WARN("Unable to get vcpus' pids."); VIR_WARN("Unable to get vcpus' pids.");
virCgroupFree(&cgroup);
return 0; return 0;
} }
for (i = 0; i < priv->nvcpupids; i++) { for (i = 0; i < priv->nvcpupids; i++) {
rc = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 1); rc = virCgroupForVcpu(priv->cgroup, i, &cgroup_vcpu, 1);
if (rc < 0) { if (rc < 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to create vcpu cgroup for %s(vcpu:" _("Unable to create vcpu cgroup for %s(vcpu:"
@ -639,7 +667,7 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
} }
/* Set vcpupin in cgroup if vcpupin xml is provided */ /* Set vcpupin in cgroup if vcpupin xml is provided */
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
/* find the right CPU to pin, otherwise /* find the right CPU to pin, otherwise
* qemuSetupCgroupVcpuPin will fail. */ * qemuSetupCgroupVcpuPin will fail. */
for (j = 0; j < def->cputune.nvcpupin; j++) { for (j = 0; j < def->cputune.nvcpupin; j++) {
@ -659,7 +687,6 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm)
virCgroupFree(&cgroup_vcpu); virCgroupFree(&cgroup_vcpu);
} }
virCgroupFree(&cgroup);
return 0; return 0;
cleanup: cleanup:
@ -668,11 +695,6 @@ cleanup:
virCgroupFree(&cgroup_vcpu); virCgroupFree(&cgroup_vcpu);
} }
if (cgroup) {
virCgroupRemove(cgroup);
virCgroupFree(&cgroup);
}
return -1; return -1;
} }
@ -682,33 +704,24 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
{ {
virBitmapPtr cpumask = NULL; virBitmapPtr cpumask = NULL;
virBitmapPtr cpumap = NULL; virBitmapPtr cpumap = NULL;
virCgroupPtr cgroup = NULL;
virCgroupPtr cgroup_emulator = NULL; virCgroupPtr cgroup_emulator = NULL;
virDomainDefPtr def = vm->def; virDomainDefPtr def = vm->def;
qemuDomainObjPrivatePtr priv = vm->privateData;
unsigned long long period = vm->def->cputune.emulator_period; unsigned long long period = vm->def->cputune.emulator_period;
long long quota = vm->def->cputune.emulator_quota; long long quota = vm->def->cputune.emulator_quota;
int rc; int rc;
if ((period || quota) && if ((period || quota) &&
(!driver->cgroup || !virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU))) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("cgroup cpu is required for scheduler tuning")); _("cgroup cpu is required for scheduler tuning"));
return -1; return -1;
} }
if (driver->cgroup == NULL) if (priv->cgroup == NULL)
return 0; /* Not supported, so claim success */ return 0; /* Not supported, so claim success */
rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0); rc = virCgroupForEmulator(priv->cgroup, &cgroup_emulator, 1);
if (rc != 0) {
virReportSystemError(-rc,
_("Unable to find cgroup for %s"),
vm->def->name);
goto cleanup;
}
rc = virCgroupForEmulator(cgroup, &cgroup_emulator, 1);
if (rc < 0) { if (rc < 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to create emulator cgroup for %s"), _("Unable to create emulator cgroup for %s"),
@ -716,7 +729,7 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
rc = virCgroupMoveTask(cgroup, cgroup_emulator); rc = virCgroupMoveTask(priv->cgroup, cgroup_emulator);
if (rc < 0) { if (rc < 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to move tasks from domain cgroup to " _("Unable to move tasks from domain cgroup to "
@ -736,7 +749,7 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
} }
if (cpumask) { if (cpumask) {
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
rc = qemuSetupCgroupEmulatorPin(cgroup_emulator, cpumask); rc = qemuSetupCgroupEmulatorPin(cgroup_emulator, cpumask);
if (rc < 0) if (rc < 0)
goto cleanup; goto cleanup;
@ -745,7 +758,7 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
} }
if (period || quota) { if (period || quota) {
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPU)) {
if ((rc = qemuSetupCgroupVcpuBW(cgroup_emulator, period, if ((rc = qemuSetupCgroupVcpuBW(cgroup_emulator, period,
quota)) < 0) quota)) < 0)
goto cleanup; goto cleanup;
@ -753,7 +766,6 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
} }
virCgroupFree(&cgroup_emulator); virCgroupFree(&cgroup_emulator);
virCgroupFree(&cgroup);
virBitmapFree(cpumap); virBitmapFree(cpumap);
return 0; return 0;
@ -765,67 +777,34 @@ cleanup:
virCgroupFree(&cgroup_emulator); virCgroupFree(&cgroup_emulator);
} }
if (cgroup) {
virCgroupRemove(cgroup);
virCgroupFree(&cgroup);
}
return rc; return rc;
} }
int qemuRemoveCgroup(virQEMUDriverPtr driver, int qemuRemoveCgroup(virDomainObjPtr vm)
virDomainObjPtr vm,
int quiet)
{ {
virCgroupPtr cgroup; qemuDomainObjPrivatePtr priv = vm->privateData;
int rc;
if (driver->cgroup == NULL) if (priv->cgroup == NULL)
return 0; /* Not supported, so claim success */ return 0; /* Not supported, so claim success */
rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0); return virCgroupRemove(priv->cgroup);
if (rc != 0) {
if (!quiet)
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to find cgroup for %s"),
vm->def->name);
return rc;
}
rc = virCgroupRemove(cgroup);
virCgroupFree(&cgroup);
return rc;
} }
int qemuAddToCgroup(virQEMUDriverPtr driver, int qemuAddToCgroup(virDomainObjPtr vm)
virDomainDefPtr def)
{ {
virCgroupPtr cgroup = NULL; qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
int rc; int rc;
if (driver->cgroup == NULL) if (priv->cgroup == NULL)
return 0; /* Not supported, so claim success */ return 0; /* Not supported, so claim success */
rc = virCgroupForDomain(driver->cgroup, def->name, &cgroup, 0); rc = virCgroupAddTask(priv->cgroup, getpid());
if (rc != 0) {
virReportSystemError(-rc,
_("unable to find cgroup for domain %s"),
def->name);
goto cleanup;
}
rc = virCgroupAddTask(cgroup, getpid());
if (rc != 0) { if (rc != 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("unable to add domain %s task %d to cgroup"), _("unable to add domain %s task %d to cgroup"),
def->name, getpid()); vm->def->name, getpid());
goto cleanup; return -1;
} }
ret = 0; return 0;
cleanup:
virCgroupFree(&cgroup);
return ret;
} }

View File

@ -25,26 +25,19 @@
# define __QEMU_CGROUP_H__ # define __QEMU_CGROUP_H__
# include "virusb.h" # include "virusb.h"
# include "vircgroup.h"
# include "domain_conf.h" # include "domain_conf.h"
# include "qemu_conf.h" # include "qemu_conf.h"
struct _qemuCgroupData {
virDomainObjPtr vm;
virCgroupPtr cgroup;
};
typedef struct _qemuCgroupData qemuCgroupData;
bool qemuCgroupControllerActive(virQEMUDriverPtr driver,
int controller);
int qemuSetupDiskCgroup(virDomainObjPtr vm, int qemuSetupDiskCgroup(virDomainObjPtr vm,
virCgroupPtr cgroup,
virDomainDiskDefPtr disk); virDomainDiskDefPtr disk);
int qemuTeardownDiskCgroup(virDomainObjPtr vm, int qemuTeardownDiskCgroup(virDomainObjPtr vm,
virCgroupPtr cgroup,
virDomainDiskDefPtr disk); virDomainDiskDefPtr disk);
int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev, int qemuSetupHostUsbDeviceCgroup(virUSBDevicePtr dev,
const char *path, const char *path,
void *opaque); void *opaque);
int qemuInitCgroup(virQEMUDriverPtr driver,
virDomainObjPtr vm);
int qemuSetupCgroup(virQEMUDriverPtr driver, int qemuSetupCgroup(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virBitmapPtr nodemask); virBitmapPtr nodemask);
@ -56,14 +49,11 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup,
int nvcpupin, int nvcpupin,
int vcpuid); int vcpuid);
int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, virBitmapPtr cpumask); int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, virBitmapPtr cpumask);
int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm); int qemuSetupCgroupForVcpu(virDomainObjPtr vm);
int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver, int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
virBitmapPtr nodemask); virBitmapPtr nodemask);
int qemuRemoveCgroup(virQEMUDriverPtr driver, int qemuRemoveCgroup(virDomainObjPtr vm);
virDomainObjPtr vm, int qemuAddToCgroup(virDomainObjPtr vm);
int quiet);
int qemuAddToCgroup(virQEMUDriverPtr driver,
virDomainDefPtr def);
#endif /* __QEMU_CGROUP_H__ */ #endif /* __QEMU_CGROUP_H__ */

View File

@ -34,7 +34,6 @@
# include "domain_event.h" # include "domain_event.h"
# include "virthread.h" # include "virthread.h"
# include "security/security_manager.h" # include "security/security_manager.h"
# include "vircgroup.h"
# include "virpci.h" # include "virpci.h"
# include "virusb.h" # include "virusb.h"
# include "cpu_conf.h" # include "cpu_conf.h"
@ -164,9 +163,6 @@ struct _virQEMUDriver {
/* Atomic increment only */ /* Atomic increment only */
int nextvmid; int nextvmid;
/* Immutable pointer. Immutable object */
virCgroupPtr cgroup;
/* Atomic inc/dec only */ /* Atomic inc/dec only */
unsigned int nactive; unsigned int nactive;

View File

@ -235,6 +235,7 @@ qemuDomainObjPrivateFree(void *data)
virObjectUnref(priv->qemuCaps); virObjectUnref(priv->qemuCaps);
virCgroupFree(&priv->cgroup);
qemuDomainPCIAddressSetFree(priv->pciaddrs); qemuDomainPCIAddressSetFree(priv->pciaddrs);
qemuDomainCCWAddressSetFree(priv->ccwaddrs); qemuDomainCCWAddressSetFree(priv->ccwaddrs);
virDomainChrSourceDefFree(priv->monConfig); virDomainChrSourceDefFree(priv->monConfig);

View File

@ -25,6 +25,7 @@
# define __QEMU_DOMAIN_H__ # define __QEMU_DOMAIN_H__
# include "virthread.h" # include "virthread.h"
# include "vircgroup.h"
# include "domain_conf.h" # include "domain_conf.h"
# include "snapshot_conf.h" # include "snapshot_conf.h"
# include "qemu_monitor.h" # include "qemu_monitor.h"
@ -165,6 +166,8 @@ struct _qemuDomainObjPrivate {
qemuDomainCleanupCallback *cleanupCallbacks; qemuDomainCleanupCallback *cleanupCallbacks;
size_t ncleanupCallbacks; size_t ncleanupCallbacks;
size_t ncleanupCallbacks_max; size_t ncleanupCallbacks_max;
virCgroupPtr cgroup;
}; };
struct qemuDomainWatchdogEvent struct qemuDomainWatchdogEvent

File diff suppressed because it is too large Load Diff

View File

@ -1136,27 +1136,16 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver,
goto error; goto error;
} }
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) {
virCgroupPtr cgroup = NULL;
virUSBDevicePtr usb; virUSBDevicePtr usb;
qemuCgroupData data;
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to find cgroup for %s"),
vm->def->name);
goto error;
}
if ((usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus, if ((usb = virUSBDeviceNew(hostdev->source.subsys.u.usb.bus,
hostdev->source.subsys.u.usb.device, hostdev->source.subsys.u.usb.device,
NULL)) == NULL) NULL)) == NULL)
goto error; goto error;
data.vm = vm;
data.cgroup = cgroup;
if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, if (virUSBDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup,
&data) < 0) { vm) < 0) {
virUSBDeviceFree(usb); virUSBDeviceFree(usb);
goto error; goto error;
} }
@ -2032,7 +2021,6 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
int i, ret = -1; int i, ret = -1;
virDomainDiskDefPtr detach = NULL; virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
char *drivestr = NULL; char *drivestr = NULL;
i = qemuFindDisk(vm->def, dev->data.disk->dst); i = qemuFindDisk(vm->def, dev->data.disk->dst);
@ -2052,15 +2040,6 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to find cgroup for %s"),
vm->def->name);
goto cleanup;
}
}
if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) && if (STREQLEN(vm->def->os.machine, "s390-ccw", 8) &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) { virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) {
if (!virDomainDeviceAddressIsValid(&detach->info, if (!virDomainDeviceAddressIsValid(&detach->info,
@ -2130,11 +2109,9 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
vm->def, dev->data.disk) < 0) vm->def, dev->data.disk) < 0)
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) { if (qemuTeardownDiskCgroup(vm, dev->data.disk) < 0)
if (qemuTeardownDiskCgroup(vm, cgroup, dev->data.disk) < 0) VIR_WARN("Failed to teardown cgroup for disk path %s",
VIR_WARN("Failed to teardown cgroup for disk path %s", NULLSTR(dev->data.disk->src));
NULLSTR(dev->data.disk->src));
}
if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0) if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0)
VIR_WARN("Unable to release lock on %s", dev->data.disk->src); VIR_WARN("Unable to release lock on %s", dev->data.disk->src);
@ -2142,7 +2119,6 @@ int qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
ret = 0; ret = 0;
cleanup: cleanup:
virCgroupFree(&cgroup);
VIR_FREE(drivestr); VIR_FREE(drivestr);
return ret; return ret;
} }
@ -2154,7 +2130,6 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
int i, ret = -1; int i, ret = -1;
virDomainDiskDefPtr detach = NULL; virDomainDiskDefPtr detach = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
char *drivestr = NULL; char *drivestr = NULL;
i = qemuFindDisk(vm->def, dev->data.disk->dst); i = qemuFindDisk(vm->def, dev->data.disk->dst);
@ -2181,15 +2156,6 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
goto cleanup; goto cleanup;
} }
if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) {
if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to find cgroup for %s"),
vm->def->name);
goto cleanup;
}
}
/* build the actual drive id string as the disk->info.alias doesn't /* build the actual drive id string as the disk->info.alias doesn't
* contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */ * contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */
if (virAsprintf(&drivestr, "%s%s", if (virAsprintf(&drivestr, "%s%s",
@ -2222,11 +2188,9 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
vm->def, dev->data.disk) < 0) vm->def, dev->data.disk) < 0)
VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); VIR_WARN("Unable to restore security label on %s", dev->data.disk->src);
if (cgroup != NULL) { if (qemuTeardownDiskCgroup(vm, dev->data.disk) < 0)
if (qemuTeardownDiskCgroup(vm, cgroup, dev->data.disk) < 0) VIR_WARN("Failed to teardown cgroup for disk path %s",
VIR_WARN("Failed to teardown cgroup for disk path %s", NULLSTR(dev->data.disk->src));
NULLSTR(dev->data.disk->src));
}
if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0) if (virDomainLockDiskDetach(driver->lockManager, vm, dev->data.disk) < 0)
VIR_WARN("Unable to release lock on disk %s", dev->data.disk->src); VIR_WARN("Unable to release lock on disk %s", dev->data.disk->src);
@ -2235,7 +2199,6 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
cleanup: cleanup:
VIR_FREE(drivestr); VIR_FREE(drivestr);
virCgroupFree(&cgroup);
return ret; return ret;
} }

View File

@ -4186,7 +4186,6 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
enum qemuDomainAsyncJob asyncJob) enum qemuDomainAsyncJob asyncJob)
{ {
qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainObjPrivatePtr priv = vm->privateData;
virCgroupPtr cgroup = NULL;
int ret = -1; int ret = -1;
int rc; int rc;
bool restoreLabel = false; bool restoreLabel = false;
@ -4220,21 +4219,13 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
* given cgroup ACL permission. We might also stumble on * given cgroup ACL permission. We might also stumble on
* a race present in some qemu versions where it does a wait() * a race present in some qemu versions where it does a wait()
* that botches pclose. */ * that botches pclose. */
if (qemuCgroupControllerActive(driver, if (virCgroupHasController(priv->cgroup,
VIR_CGROUP_CONTROLLER_DEVICES)) { VIR_CGROUP_CONTROLLER_DEVICES)) {
if (virCgroupForDomain(driver->cgroup, vm->def->name, rc = virCgroupAllowDevicePath(priv->cgroup, path,
&cgroup, 0) != 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Unable to find cgroup for %s"),
vm->def->name);
goto cleanup;
}
rc = virCgroupAllowDevicePath(cgroup, path,
VIR_CGROUP_DEVICE_RW); VIR_CGROUP_DEVICE_RW);
virDomainAuditCgroupPath(vm, cgroup, "allow", path, "rw", rc); virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path, "rw", rc);
if (rc == 1) { if (rc == 1) {
/* path was not a device, no further need for cgroup */ /* path was not a device, no further need for cgroup */
virCgroupFree(&cgroup);
} else if (rc < 0) { } else if (rc < 0) {
virReportSystemError(-rc, virReportSystemError(-rc,
_("Unable to allow device %s for %s"), _("Unable to allow device %s for %s"),
@ -4335,14 +4326,14 @@ cleanup:
vm->def, path) < 0) vm->def, path) < 0)
VIR_WARN("failed to restore save state label on %s", path); VIR_WARN("failed to restore save state label on %s", path);
if (cgroup != NULL) { if (virCgroupHasController(priv->cgroup,
rc = virCgroupDenyDevicePath(cgroup, path, VIR_CGROUP_CONTROLLER_DEVICES)) {
rc = virCgroupDenyDevicePath(priv->cgroup, path,
VIR_CGROUP_DEVICE_RWM); VIR_CGROUP_DEVICE_RWM);
virDomainAuditCgroupPath(vm, cgroup, "deny", path, "rwm", rc); virDomainAuditCgroupPath(vm, priv->cgroup, "deny", path, "rwm", rc);
if (rc < 0) if (rc < 0)
VIR_WARN("Unable to deny device %s for %s %d", VIR_WARN("Unable to deny device %s for %s %d",
path, vm->def->name, rc); path, vm->def->name, rc);
virCgroupFree(&cgroup);
} }
return ret; return ret;
} }

View File

@ -1395,6 +1395,7 @@ qemuProcessReadLogOutput(virDomainObjPtr vm,
/* Filter out debug messages from intermediate libvirt process */ /* Filter out debug messages from intermediate libvirt process */
while ((eol = strchr(filter_next, '\n'))) { while ((eol = strchr(filter_next, '\n'))) {
*eol = '\0'; *eol = '\0';
VIR_ERROR("<<<<<<<<<<<<%s>>>>>>>>>>", filter_next);
if (virLogProbablyLogMessage(filter_next)) { if (virLogProbablyLogMessage(filter_next)) {
memmove(filter_next, eol + 1, got - (eol - buf)); memmove(filter_next, eol + 1, got - (eol - buf));
got -= eol + 1 - filter_next; got -= eol + 1 - filter_next;
@ -2529,7 +2530,7 @@ static int qemuProcessHook(void *data)
* memory allocation is on the correct NUMA node * memory allocation is on the correct NUMA node
*/ */
VIR_DEBUG("Moving process to cgroup"); VIR_DEBUG("Moving process to cgroup");
if (qemuAddToCgroup(h->driver, h->vm->def) < 0) if (qemuAddToCgroup(h->vm) < 0)
goto cleanup; goto cleanup;
/* This must be done after cgroup placement to avoid resetting CPU /* This must be done after cgroup placement to avoid resetting CPU
@ -3004,6 +3005,9 @@ qemuProcessReconnect(void *opaque)
if (qemuUpdateActiveUsbHostdevs(driver, obj->def) < 0) if (qemuUpdateActiveUsbHostdevs(driver, obj->def) < 0)
goto error; goto error;
if (qemuInitCgroup(driver, obj) < 0)
goto error;
/* XXX: Need to change as long as lock is introduced for /* XXX: Need to change as long as lock is introduced for
* qemu_driver->sharedDisks. * qemu_driver->sharedDisks.
*/ */
@ -3384,7 +3388,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(driver, vm, 1); qemuRemoveCgroup(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];
@ -3750,7 +3754,7 @@ int qemuProcessStart(virConnectPtr conn,
goto cleanup; goto cleanup;
VIR_DEBUG("Setting cgroup for each VCPU (if required)"); VIR_DEBUG("Setting cgroup for each VCPU (if required)");
if (qemuSetupCgroupForVcpu(driver, vm) < 0) if (qemuSetupCgroupForVcpu(vm) < 0)
goto cleanup; goto cleanup;
VIR_DEBUG("Setting cgroup for emulator (if required)"); VIR_DEBUG("Setting cgroup for emulator (if required)");
@ -4085,7 +4089,7 @@ void qemuProcessStop(virQEMUDriverPtr driver,
} }
retry: retry:
if ((ret = qemuRemoveCgroup(driver, vm, 0)) < 0) { if ((ret = qemuRemoveCgroup(vm)) < 0) {
if (ret == -EBUSY && (retries++ < 5)) { if (ret == -EBUSY && (retries++ < 5)) {
usleep(200*1000); usleep(200*1000);
goto retry; goto retry;
@ -4093,6 +4097,7 @@ retry:
VIR_WARN("Failed to remove cgroup for %s", VIR_WARN("Failed to remove cgroup for %s",
vm->def->name); vm->def->name);
} }
virCgroupFree(&priv->cgroup);
qemuProcessRemoveDomainStatus(driver, vm); qemuProcessRemoveDomainStatus(driver, vm);