This patch deploys the newly introduced virCgroupItem and removes the old cgroup code. --- daemon/libvirtd.c | 4 + src/conf/domain_audit.c | 16 +- src/conf/domain_audit.h | 6 +- src/conf/domain_conf.h | 5 + src/libvirt_private.syms | 10 +- src/lxc/lxc_cgroup.c | 91 ++-- src/lxc/lxc_conf.h | 2 +- src/lxc/lxc_driver.c | 268 ++++------ src/lxc/lxc_process.c | 56 +-- src/qemu/qemu_cgroup.c | 287 ++++------- src/qemu/qemu_cgroup.h | 17 +- src/qemu/qemu_conf.h | 2 +- src/qemu/qemu_driver.c | 478 ++++++------------ src/qemu/qemu_hotplug.c | 44 +- src/qemu/qemu_migration.c | 36 +- src/qemu/qemu_process.c | 29 +- src/util/vircgroup.c | 1181 ++++++++++++--------------------------------- src/util/vircgroup.h | 94 ++-- 18 files changed, 813 insertions(+), 1813 deletions(-) diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c index 7cb99b1..92e3292 100644 --- a/daemon/libvirtd.c +++ b/daemon/libvirtd.c @@ -1442,6 +1442,9 @@ int main(int argc, char **argv) { VIR_FORCE_CLOSE(statuswrite); } + if (virCgroupInit() < 0) + goto cleanup; + /* Initialize drivers & then start accepting new clients from network */ if (daemonStateInit(srv) < 0) { ret = VIR_DAEMON_ERR_INIT; @@ -1501,6 +1504,7 @@ cleanup: daemonConfigFree(config); virStateCleanup(); + virCgroupUninit(); return ret; } diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index 7082804..6c7efe8 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -420,12 +420,12 @@ cleanup: * Log an audit message about an attempted cgroup device ACL change. */ void -virDomainAuditCgroup(virDomainObjPtr vm, virCgroupPtr cgroup, +virDomainAuditCgroup(virDomainObjPtr vm, virCgroupItemPtr cgroup, const char *reason, const char *extra, bool success) { char uuidstr[VIR_UUID_STRING_BUFLEN]; char *vmname; - char *controller = NULL; + char *path = NULL; char *detail; const char *virt; @@ -440,10 +440,8 @@ virDomainAuditCgroup(virDomainObjPtr vm, virCgroupPtr cgroup, virt = "?"; } - ignore_value(virCgroupPathOfController(cgroup, - VIR_CGROUP_CONTROLLER_DEVICES, - NULL, &controller)); - detail = virAuditEncode("cgroup", VIR_AUDIT_STR(controller)); + ignore_value(virCgroupItemPath(cgroup, false, &path)); + detail = virAuditEncode("cgroup", VIR_AUDIT_STR(path)); VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success, "virt=%s resrc=cgroup reason=%s %s uuid=%s %s class=%s", @@ -451,7 +449,7 @@ virDomainAuditCgroup(virDomainObjPtr vm, virCgroupPtr cgroup, detail ? detail : "cgroup=?", extra); VIR_FREE(vmname); - VIR_FREE(controller); + VIR_FREE(path); VIR_FREE(detail); } @@ -468,7 +466,7 @@ virDomainAuditCgroup(virDomainObjPtr vm, virCgroupPtr cgroup, * Log an audit message about an attempted cgroup device ACL change. */ void -virDomainAuditCgroupMajor(virDomainObjPtr vm, virCgroupPtr cgroup, +virDomainAuditCgroupMajor(virDomainObjPtr vm, virCgroupItemPtr cgroup, const char *reason, int maj, const char *name, const char *perms, bool success) { @@ -498,7 +496,7 @@ virDomainAuditCgroupMajor(virDomainObjPtr vm, virCgroupPtr cgroup, * a specific device. */ void -virDomainAuditCgroupPath(virDomainObjPtr vm, virCgroupPtr cgroup, +virDomainAuditCgroupPath(virDomainObjPtr vm, virCgroupItemPtr cgroup, const char *reason, const char *path, const char *perms, int rc) { diff --git a/src/conf/domain_audit.h b/src/conf/domain_audit.h index 381fe37..573f592 100644 --- a/src/conf/domain_audit.h +++ b/src/conf/domain_audit.h @@ -66,14 +66,14 @@ void virDomainAuditHostdev(virDomainObjPtr vm, bool success) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); void virDomainAuditCgroup(virDomainObjPtr vm, - virCgroupPtr group, + virCgroupItemPtr group, const char *reason, const char *extra, bool success) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4); void virDomainAuditCgroupMajor(virDomainObjPtr vm, - virCgroupPtr group, + virCgroupItemPtr group, const char *reason, int maj, const char *name, @@ -82,7 +82,7 @@ void virDomainAuditCgroupMajor(virDomainObjPtr vm, ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(5) ATTRIBUTE_NONNULL(6); void virDomainAuditCgroupPath(virDomainObjPtr vm, - virCgroupPtr group, + virCgroupItemPtr group, const char *reason, const char *path, const char *perms, diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2ac338c..23ff2c9 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -48,6 +48,7 @@ # include "device_conf.h" # include "virbitmap.h" # include "virstoragefile.h" +# include "vircgroup.h" /* forward declarations of all device types, required by * virDomainDeviceDef @@ -1843,6 +1844,10 @@ struct _virDomainDef { /* Application-specific custom metadata */ xmlNodePtr metadata; + + virCgroupItemPtr cgroup[VIR_CGROUP_CONTROLLER_LAST]; + virCgroupItemPtr (*vcpuCgroups)[VIR_CGROUP_CONTROLLER_LAST]; + virCgroupItemPtr emulatorCgroup[VIR_CGROUP_CONTROLLER_LAST]; }; enum virDomainTaintFlags { diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 636c49d..82621ab 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -72,8 +72,6 @@ virCapabilitiesSetMacPrefix; # cgroup.h -virCgroupAddTask; -virCgroupAddTaskController; virCgroupAllowDevice; virCgroupAllowDeviceMajor; virCgroupAllowDevicePath; @@ -83,10 +81,6 @@ virCgroupDenyAllDevices; virCgroupDenyDevice; virCgroupDenyDeviceMajor; virCgroupDenyDevicePath; -virCgroupForDomain; -virCgroupForDriver; -virCgroupForEmulator; -virCgroupForVcpu; virCgroupFree; virCgroupGetAppRoot; virCgroupGetBlkioWeight; @@ -105,6 +99,7 @@ virCgroupGetMemoryUsage; virCgroupGetMemSwapHardLimit; virCgroupGetMemSwapUsage; virCgroupInit; +virCgroupItemAddTask; virCgroupItemFree; virCgroupItemKeyPath; virCgroupItemNew; @@ -114,9 +109,8 @@ virCgroupKill; virCgroupKillPainfully; virCgroupKillRecursive; virCgroupMounted; -virCgroupMoveTask; +virCgroupNew; virCgroupPathOfController; -virCgroupRemove; virCgroupSetBlkioDeviceWeight; virCgroupSetBlkioWeight; virCgroupSetCpuCfsPeriod; diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c index 1984c5f..8363383 100644 --- a/src/lxc/lxc_cgroup.c +++ b/src/lxc/lxc_cgroup.c @@ -32,7 +32,7 @@ #define VIR_FROM_THIS VIR_FROM_LXC static int virLXCCgroupSetupCpuTune(virDomainDefPtr def, - virCgroupPtr cgroup) + virCgroupItemPtr cgroup) { int ret = -1; if (def->cputune.shares != 0) { @@ -69,7 +69,7 @@ cleanup: static int virLXCCgroupSetupBlkioTune(virDomainDefPtr def, - virCgroupPtr cgroup) + virCgroupItemPtr cgroup) { int ret = -1; @@ -90,7 +90,7 @@ cleanup: static int virLXCCgroupSetupMemTune(virDomainDefPtr def, - virCgroupPtr cgroup) + virCgroupItemPtr cgroup) { int ret = -1; int rc; @@ -139,21 +139,21 @@ cleanup: } -static int virLXCCgroupGetMemSwapUsage(virCgroupPtr cgroup, +static int virLXCCgroupGetMemSwapUsage(virCgroupItemPtr cgroup, virLXCMeminfoPtr meminfo) { return virCgroupGetMemSwapUsage(cgroup, &meminfo->swapusage); } -static int virLXCCgroupGetMemSwapTotal(virCgroupPtr cgroup, +static int virLXCCgroupGetMemSwapTotal(virCgroupItemPtr cgroup, virLXCMeminfoPtr meminfo) { return virCgroupGetMemSwapHardLimit(cgroup, &meminfo->swaptotal); } -static int virLXCCgroupGetMemUsage(virCgroupPtr cgroup, +static int virLXCCgroupGetMemUsage(virCgroupItemPtr cgroup, virLXCMeminfoPtr meminfo) { int ret; @@ -166,14 +166,14 @@ static int virLXCCgroupGetMemUsage(virCgroupPtr cgroup, } -static int virLXCCgroupGetMemTotal(virCgroupPtr cgroup, +static int virLXCCgroupGetMemTotal(virCgroupItemPtr cgroup, virLXCMeminfoPtr meminfo) { return virCgroupGetMemoryHardLimit(cgroup, &meminfo->memtotal); } -static int virLXCCgroupGetMemStat(virCgroupPtr cgroup, +static int virLXCCgroupGetMemStat(virCgroupItemPtr cgroup, virLXCMeminfoPtr meminfo) { int ret = 0; @@ -182,8 +182,7 @@ static int virLXCCgroupGetMemStat(virCgroupPtr cgroup, char *line = NULL; size_t n; - ret = virCgroupPathOfController(cgroup, VIR_CGROUP_CONTROLLER_MEMORY, - "memory.stat", &statFile); + ret = virCgroupItemKeyPath(cgroup, "memory.stat", &statFile); if (ret != 0) { virReportSystemError(-ret, "%s", _("cannot get the path of MEMORY cgroup controller")); @@ -240,13 +239,13 @@ cleanup: int virLXCCgroupGetMeminfo(virLXCMeminfoPtr meminfo) { int ret; - virCgroupPtr cgroup; + virCgroupItemPtr cgroup; - ret = virCgroupGetAppRoot(&cgroup); - if (ret < 0) { - virReportSystemError(-ret, "%s", + cgroup = virCgroupGetAppRoot(VIR_CGROUP_CONTROLLER_MEMORY, false); + if (!cgroup) { + virReportSystemError(-1, "%s", _("Unable to get cgroup for container")); - return ret; + return -1; } ret = virLXCCgroupGetMemStat(cgroup, meminfo); @@ -275,7 +274,6 @@ int virLXCCgroupGetMeminfo(virLXCMeminfoPtr meminfo) ret = 0; cleanup: - virCgroupFree(&cgroup); return ret; } @@ -296,7 +294,7 @@ virLXCSetupHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED, const char *path, void *opaque) { - virCgroupPtr cgroup = opaque; + virCgroupItemPtr cgroup = opaque; int rc; VIR_DEBUG("Process path '%s' for USB device", path); @@ -318,7 +316,7 @@ virLXCTeardownHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED, const char *path, void *opaque) { - virCgroupPtr cgroup = opaque; + virCgroupItemPtr cgroup = opaque; int rc; VIR_DEBUG("Process path '%s' for USB device", path); @@ -336,7 +334,7 @@ virLXCTeardownHostUsbDeviceCgroup(usbDevice *dev ATTRIBUTE_UNUSED, static int virLXCCgroupSetupDeviceACL(virDomainDefPtr def, - virCgroupPtr cgroup) + virCgroupItemPtr cgroup) { int ret = -1; int rc; @@ -471,51 +469,52 @@ cleanup: int virLXCCgroupSetup(virDomainDefPtr def) { - virCgroupPtr driver = NULL; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr driver[VIR_CGROUP_CONTROLLER_LAST]; int ret = -1; int rc; + int i; - rc = virCgroupForDriver("lxc", &driver, 1, 0); - if (rc != 0) { - virReportSystemError(-rc, "%s", - _("Unable to get cgroup for driver")); - goto cleanup; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + driver[i] = virCgroupItemNew(i, "lxc", virCgroupGetAppRoot(i, true)); + def->cgroup[i] = virCgroupItemNew(i, def->name, driver[i]); } - rc = virCgroupForDomain(driver, def->name, &cgroup, 1); - if (rc != 0) { - virReportSystemError(-rc, - _("Unable to create cgroup for domain %s"), - def->name); + if (virLXCCgroupSetupCpuTune(def, + def->cgroup[VIR_CGROUP_CONTROLLER_CPU]) < 0) goto cleanup; - } - if (virLXCCgroupSetupCpuTune(def, cgroup) < 0) + if (virLXCCgroupSetupBlkioTune(def, + def->cgroup[VIR_CGROUP_CONTROLLER_BLKIO]) < 0) goto cleanup; - if (virLXCCgroupSetupBlkioTune(def, cgroup) < 0) + if (virLXCCgroupSetupMemTune(def, + def->cgroup[VIR_CGROUP_CONTROLLER_MEMORY]) < 0) goto cleanup; - if (virLXCCgroupSetupMemTune(def, cgroup) < 0) + if (virLXCCgroupSetupDeviceACL(def, + def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]) < 0) goto cleanup; - if (virLXCCgroupSetupDeviceACL(def, cgroup) < 0) - goto cleanup; - - rc = virCgroupAddTask(cgroup, getpid()); - if (rc != 0) { - virReportSystemError(-rc, - _("Unable to add task %d to cgroup for domain %s"), - getpid(), def->name); - goto cleanup; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + rc = virCgroupItemAddTask(def->cgroup[i], getpid()); + if (rc != 0) { + virReportSystemError(-rc, + _("Unable to add task %d to cgroup for domain %s"), + getpid(), def->name); + goto cleanup; + } } ret = 0; cleanup: - virCgroupFree(&cgroup); - virCgroupFree(&driver); + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + if (ret != 0) { + virCgroupItemFree(def->cgroup[i]); + def->cgroup[i] = NULL; + } + virCgroupItemFree(driver[i]); + } return ret; } diff --git a/src/lxc/lxc_conf.h b/src/lxc/lxc_conf.h index d45e0a0..03d9ba3 100644 --- a/src/lxc/lxc_conf.h +++ b/src/lxc/lxc_conf.h @@ -52,7 +52,7 @@ struct _virLXCDriver { virCapsPtr caps; - virCgroupPtr cgroup; + virCgroupItemPtr cgroup[VIR_CGROUP_CONTROLLER_LAST]; size_t nactive; virStateInhibitCallback inhibitCallback; diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 8050ce6..d6d5a94 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -526,7 +526,7 @@ static int lxcDomainGetInfo(virDomainPtr dom, { virLXCDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = NULL; int ret = -1, rc; lxcDriverLock(driver); @@ -546,7 +546,8 @@ static int lxcDomainGetInfo(virDomainPtr dom, info->cpuTime = 0; info->memory = vm->def->mem.cur_balloon; } else { - if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) { + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPUACCT]; + if (!cgroup) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to get cgroup for %s"), vm->def->name); goto cleanup; @@ -557,6 +558,14 @@ static int lxcDomainGetInfo(virDomainPtr dom, "%s", _("Cannot read cputime for domain")); goto cleanup; } + + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_MEMORY]; + if (!cgroup) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Unable to get cgroup for %s"), vm->def->name); + goto cleanup; + } + if ((rc = virCgroupGetMemoryUsage(cgroup, &(info->memory))) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Cannot read memory usage for domain")); @@ -575,8 +584,6 @@ static int lxcDomainGetInfo(virDomainPtr dom, cleanup: lxcDriverUnlock(driver); - if (cgroup) - virCgroupFree(&cgroup); if (vm) virDomainObjUnlock(vm); return ret; @@ -707,7 +714,7 @@ cleanup: static int lxcDomainSetMemory(virDomainPtr dom, unsigned long newmem) { virLXCDriverPtr driver = dom->conn->privateData; virDomainObjPtr vm; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = NULL; int ret = -1; lxcDriverLock(driver); @@ -733,13 +740,8 @@ static int lxcDomainSetMemory(virDomainPtr dom, unsigned long newmem) { goto cleanup; } - if (driver->cgroup == NULL) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroups must be configured on the host")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) { + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_MEMORY]; + if (!cgroup) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to get cgroup for %s"), vm->def->name); goto cleanup; @@ -756,8 +758,6 @@ static int lxcDomainSetMemory(virDomainPtr dom, unsigned long newmem) { cleanup: if (vm) virDomainObjUnlock(vm); - if (cgroup) - virCgroupFree(&cgroup); return ret; } @@ -769,7 +769,7 @@ lxcDomainSetMemoryParameters(virDomainPtr dom, { virLXCDriverPtr driver = dom->conn->privateData; int i; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = NULL; virDomainObjPtr vm = NULL; int ret = -1; int rc; @@ -796,7 +796,8 @@ lxcDomainSetMemoryParameters(virDomainPtr dom, goto cleanup; } - if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) { + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_MEMORY]; + if (!cgroup) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -831,8 +832,6 @@ lxcDomainSetMemoryParameters(virDomainPtr dom, } cleanup: - if (cgroup) - virCgroupFree(&cgroup); if (vm) virDomainObjUnlock(vm); lxcDriverUnlock(driver); @@ -847,7 +846,7 @@ lxcDomainGetMemoryParameters(virDomainPtr dom, { virLXCDriverPtr driver = dom->conn->privateData; int i; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = NULL; virDomainObjPtr vm = NULL; unsigned long long val; int ret = -1; @@ -873,7 +872,8 @@ lxcDomainGetMemoryParameters(virDomainPtr dom, goto cleanup; } - if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) != 0) { + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_MEMORY]; + if (!cgroup) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to get cgroup for %s"), vm->def->name); goto cleanup; @@ -930,8 +930,6 @@ lxcDomainGetMemoryParameters(virDomainPtr dom, ret = 0; cleanup: - if (cgroup) - virCgroupFree(&cgroup); if (vm) virDomainObjUnlock(vm); lxcDriverUnlock(driver); @@ -1407,7 +1405,7 @@ static int lxcStartup(bool privileged, void *opaque ATTRIBUTE_UNUSED) { char *ld; - int rc; + int i; /* Valgrind gets very annoyed when we clone containers, so * disable LXC when under valgrind @@ -1450,14 +1448,9 @@ static int lxcStartup(bool privileged, lxc_driver->log_libvirtd = 0; /* by default log to container logfile */ lxc_driver->have_netns = lxcCheckNetNsSupport(); - rc = virCgroupForDriver("lxc", &lxc_driver->cgroup, privileged, 1); - if (rc < 0) { - char buf[1024] ATTRIBUTE_UNUSED; - VIR_DEBUG("Unable to create cgroup for LXC driver: %s", - virStrerror(-rc, buf, sizeof(buf))); - /* Don't abort startup. We will explicitly report to - * the user when they try to start a VM - */ + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + lxc_driver->cgroup[i] = virCgroupItemNew(i, "lxc", + virCgroupGetAppRoot(i, privileged)); } /* Call function to load lxc driver configuration information */ @@ -1592,7 +1585,7 @@ static int lxcVersion(virConnectPtr conn ATTRIBUTE_UNUSED, unsigned long *versio * Return 1 when CFS bandwidth is supported, 0 when CFS bandwidth is not * supported, -1 on error. */ -static int lxcGetCpuBWStatus(virCgroupPtr cgroup) +static int lxcGetCpuBWStatus(virCgroupItemPtr cgroup) { char *cfs_period_path = NULL; int ret = -1; @@ -1600,8 +1593,8 @@ static int lxcGetCpuBWStatus(virCgroupPtr cgroup) if (!cgroup) return 0; - if (virCgroupPathOfController(cgroup, VIR_CGROUP_CONTROLLER_CPU, - "cpu.cfs_period_us", &cfs_period_path) < 0) { + if (virCgroupItemKeyPath(cgroup, "cpu.cfs_period_us", + &cfs_period_path) < 0) { VIR_INFO("cannot get the path of cgroup CPU controller"); ret = 0; goto cleanup; @@ -1626,7 +1619,7 @@ static bool lxcCgroupControllerActive(virLXCDriverPtr driver, return false; if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST) return false; - if (!virCgroupMounted(driver->cgroup, controller)) + if (!virCgroupMounted(controller)) return false; #if 0 if (driver->cgroupControllers & (1 << controller)) @@ -1652,7 +1645,7 @@ static char *lxcGetSchedulerType(virDomainPtr domain, } if (nparams) { - rc = lxcGetCpuBWStatus(driver->cgroup); + rc = lxcGetCpuBWStatus(driver->cgroup[VIR_CGROUP_CONTROLLER_CPU]); if (rc < 0) goto cleanup; else if (rc == 0) @@ -1672,7 +1665,7 @@ cleanup: static int -lxcGetVcpuBWLive(virCgroupPtr cgroup, unsigned long long *period, +lxcGetVcpuBWLive(virCgroupItemPtr cgroup, unsigned long long *period, long long *quota) { int rc; @@ -1695,7 +1688,7 @@ lxcGetVcpuBWLive(virCgroupPtr cgroup, unsigned long long *period, } -static int lxcSetVcpuBWLive(virCgroupPtr cgroup, unsigned long long period, +static int lxcSetVcpuBWLive(virCgroupItemPtr cgroup, unsigned long long period, long long quota) { int rc; @@ -1752,7 +1745,7 @@ lxcSetSchedulerParametersFlags(virDomainPtr dom, { virLXCDriverPtr driver = dom->conn->privateData; int i; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr vmdef = NULL; int ret = -1; @@ -1791,18 +1784,12 @@ lxcSetSchedulerParametersFlags(virDomainPtr dom, goto cleanup; } - if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroup CPU controller is not mounted")); - goto cleanup; - } - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPU]; + if ((flags & VIR_DOMAIN_AFFECT_LIVE) && !group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; - } } for (i = 0; i < nparams; i++) { @@ -1869,7 +1856,6 @@ lxcSetSchedulerParametersFlags(virDomainPtr dom, cleanup: virDomainDefFree(vmdef); - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); lxcDriverUnlock(driver); @@ -1891,7 +1877,7 @@ lxcGetSchedulerParametersFlags(virDomainPtr dom, unsigned int flags) { virLXCDriverPtr driver = dom->conn->privateData; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr persistentDef; unsigned long long shares = 0; @@ -1908,7 +1894,7 @@ lxcGetSchedulerParametersFlags(virDomainPtr dom, lxcDriverLock(driver); if (*nparams > 1) { - rc = lxcGetCpuBWStatus(driver->cgroup); + rc = lxcGetCpuBWStatus(driver->cgroup[VIR_CGROUP_CONTROLLER_CPU]); if (rc < 0) goto cleanup; cpu_bw_status = !!rc; @@ -1935,13 +1921,8 @@ lxcGetSchedulerParametersFlags(virDomainPtr dom, goto out; } - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroup CPU controller is not mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPU]; + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -1988,7 +1969,6 @@ out: ret = 0; cleanup: - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); lxcDriverUnlock(driver); @@ -2012,7 +1992,7 @@ lxcDomainSetBlkioParameters(virDomainPtr dom, { virLXCDriverPtr driver = dom->conn->privateData; int i; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr persistentDef = NULL; int ret = -1; @@ -2039,14 +2019,9 @@ lxcDomainSetBlkioParameters(virDomainPtr dom, &persistentDef) < 0) goto cleanup; + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_BLKIO]; if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("blkio cgroup isn't mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -2097,7 +2072,6 @@ lxcDomainSetBlkioParameters(virDomainPtr dom, ret = 0; cleanup: - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); lxcDriverUnlock(driver); @@ -2114,7 +2088,7 @@ lxcDomainGetBlkioParameters(virDomainPtr dom, { virLXCDriverPtr driver = dom->conn->privateData; int i; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr persistentDef = NULL; unsigned int val; @@ -2144,14 +2118,10 @@ lxcDomainGetBlkioParameters(virDomainPtr dom, &persistentDef) < 0) goto cleanup; - if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("blkio cgroup isn't mounted")); - goto cleanup; - } + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_BLKIO]; - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + if (flags & VIR_DOMAIN_AFFECT_LIVE) { + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -2203,8 +2173,6 @@ lxcDomainGetBlkioParameters(virDomainPtr dom, ret = 0; cleanup: - if (group) - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); lxcDriverUnlock(driver); @@ -2374,7 +2342,7 @@ cleanup: return ret; } -static int lxcFreezeContainer(virLXCDriverPtr driver, virDomainObjPtr vm) +static int lxcFreezeContainer(virDomainObjPtr vm) { int timeout = 1000; /* In milliseconds */ int check_interval = 1; /* In milliseconds */ @@ -2382,10 +2350,9 @@ static int lxcFreezeContainer(virLXCDriverPtr driver, virDomainObjPtr vm) int waited_time = 0; int ret = -1; char *state = NULL; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_FREEZER]; - if (!(driver->cgroup && - virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0)) + if (!cgroup) return -1; /* From here on, we know that cgroup != NULL. */ @@ -2462,7 +2429,6 @@ error: ret = -1; cleanup: - virCgroupFree(&cgroup); VIR_FREE(state); return ret; } @@ -2492,7 +2458,7 @@ static int lxcDomainSuspend(virDomainPtr dom) } if (virDomainObjGetState(vm, NULL) != VIR_DOMAIN_PAUSED) { - if (lxcFreezeContainer(driver, vm) < 0) { + if (lxcFreezeContainer(vm) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Suspend operation failed")); goto cleanup; @@ -2517,18 +2483,16 @@ cleanup: return ret; } -static int lxcUnfreezeContainer(virLXCDriverPtr driver, virDomainObjPtr vm) +static int lxcUnfreezeContainer(virDomainObjPtr vm) { int ret; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_FREEZER]; - if (!(driver->cgroup && - virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0)) + if (!cgroup) return -1; ret = virCgroupSetFreezerState(cgroup, "THAWED"); - virCgroupFree(&cgroup); return ret; } @@ -2557,7 +2521,7 @@ static int lxcDomainResume(virDomainPtr dom) } if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) { - if (lxcUnfreezeContainer(driver, vm) < 0) { + if (lxcUnfreezeContainer(vm) < 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", _("Resume operation failed")); goto cleanup; @@ -3100,7 +3064,7 @@ lxcDomainAttachDeviceDiskLive(virLXCDriverPtr driver, { virLXCDomainObjPrivatePtr priv = vm->privateData; virDomainDiskDefPtr def = dev->data.disk; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; int ret = -1; char *dst; struct stat sb; @@ -3185,17 +3149,7 @@ lxcDomainAttachDeviceDiskLive(virLXCDriverPtr driver, vm->def, def) < 0) goto cleanup; - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("devices cgroup isn't mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find cgroup for domain %s"), vm->def->name); - goto cleanup; - } + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; if (virCgroupAllowDevicePath(group, def->src, (def->readonly ? @@ -3215,8 +3169,6 @@ lxcDomainAttachDeviceDiskLive(virLXCDriverPtr driver, cleanup: def->src = tmpsrc; virDomainAuditDisk(vm, NULL, def->src, "attach", ret == 0); - if (group) - virCgroupFree(&group); if (dst && created && ret < 0) unlink(dst); return ret; @@ -3370,7 +3322,7 @@ lxcDomainAttachDeviceHostdevSubsysUSBLive(virLXCDriverPtr driver, mode_t mode; bool created = false; usbDevice *usb = NULL; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; if (virDomainHostdevFind(vm->def, def, NULL) >= 0) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", @@ -3405,13 +3357,8 @@ lxcDomainAttachDeviceHostdevSubsysUSBLive(virLXCDriverPtr driver, goto cleanup; } - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("devices cgroup isn't mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -3469,7 +3416,6 @@ cleanup: unlink(dstfile); usbFreeDevice(usb); - virCgroupFree(&group); VIR_FREE(src); VIR_FREE(dstfile); VIR_FREE(dstdir); @@ -3485,7 +3431,7 @@ lxcDomainAttachDeviceHostdevStorageLive(virLXCDriverPtr driver, { virLXCDomainObjPrivatePtr priv = vm->privateData; virDomainHostdevDefPtr def = dev->data.hostdev; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; int ret = -1; char *dst = NULL; char *vroot = NULL; @@ -3554,13 +3500,9 @@ lxcDomainAttachDeviceHostdevStorageLive(virLXCDriverPtr driver, vm->def, def, vroot) < 0) goto cleanup; - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("devices cgroup isn't mounted")); - goto cleanup; - } + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -3581,8 +3523,6 @@ lxcDomainAttachDeviceHostdevStorageLive(virLXCDriverPtr driver, cleanup: virDomainAuditHostdev(vm, def, "attach", ret == 0); - if (group) - virCgroupFree(&group); if (dst && created && ret < 0) unlink(dst); VIR_FREE(dst); @@ -3598,7 +3538,7 @@ lxcDomainAttachDeviceHostdevMiscLive(virLXCDriverPtr driver, { virLXCDomainObjPrivatePtr priv = vm->privateData; virDomainHostdevDefPtr def = dev->data.hostdev; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; int ret = -1; char *dst = NULL; char *vroot = NULL; @@ -3667,13 +3607,8 @@ lxcDomainAttachDeviceHostdevMiscLive(virLXCDriverPtr driver, vm->def, def, vroot) < 0) goto cleanup; - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("devices cgroup isn't mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -3694,8 +3629,6 @@ lxcDomainAttachDeviceHostdevMiscLive(virLXCDriverPtr driver, cleanup: virDomainAuditHostdev(vm, def, "attach", ret == 0); - if (group) - virCgroupFree(&group); if (dst && created && ret < 0) unlink(dst); VIR_FREE(dst); @@ -3812,13 +3745,12 @@ lxcDomainAttachDeviceLive(virConnectPtr conn, static int -lxcDomainDetachDeviceDiskLive(virLXCDriverPtr driver, - virDomainObjPtr vm, +lxcDomainDetachDeviceDiskLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev) { virLXCDomainObjPrivatePtr priv = vm->privateData; virDomainDiskDefPtr def = NULL; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; int i, ret = -1; char *dst; @@ -3844,13 +3776,8 @@ lxcDomainDetachDeviceDiskLive(virLXCDriverPtr driver, goto cleanup; } - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("devices cgroup isn't mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -3876,8 +3803,6 @@ lxcDomainDetachDeviceDiskLive(virLXCDriverPtr driver, cleanup: VIR_FREE(dst); - if (group) - virCgroupFree(&group); return ret; } @@ -3955,7 +3880,7 @@ lxcDomainDetachDeviceHostdevUSBLive(virLXCDriverPtr driver, { virLXCDomainObjPrivatePtr priv = vm->privateData; virDomainHostdevDefPtr def = NULL; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; int idx, ret = -1; char *dst; char *vroot; @@ -3983,13 +3908,8 @@ lxcDomainDetachDeviceHostdevUSBLive(virLXCDriverPtr driver, goto cleanup; } - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("devices cgroup isn't mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -4024,19 +3944,17 @@ lxcDomainDetachDeviceHostdevUSBLive(virLXCDriverPtr driver, cleanup: usbFreeDevice(usb); VIR_FREE(dst); - virCgroupFree(&group); return ret; } static int -lxcDomainDetachDeviceHostdevStorageLive(virLXCDriverPtr driver, - virDomainObjPtr vm, +lxcDomainDetachDeviceHostdevStorageLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev) { virLXCDomainObjPrivatePtr priv = vm->privateData; virDomainHostdevDefPtr def = NULL; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; int i, ret = -1; char *dst = NULL; @@ -4062,13 +3980,8 @@ lxcDomainDetachDeviceHostdevStorageLive(virLXCDriverPtr driver, goto cleanup; } - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("devices cgroup isn't mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -4094,20 +4007,17 @@ lxcDomainDetachDeviceHostdevStorageLive(virLXCDriverPtr driver, cleanup: VIR_FREE(dst); - if (group) - virCgroupFree(&group); return ret; } static int -lxcDomainDetachDeviceHostdevMiscLive(virLXCDriverPtr driver, - virDomainObjPtr vm, +lxcDomainDetachDeviceHostdevMiscLive(virDomainObjPtr vm, virDomainDeviceDefPtr dev) { virLXCDomainObjPrivatePtr priv = vm->privateData; virDomainHostdevDefPtr def = NULL; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; int i, ret = -1; char *dst = NULL; @@ -4133,13 +4043,8 @@ lxcDomainDetachDeviceHostdevMiscLive(virLXCDriverPtr driver, goto cleanup; } - if (!lxcCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("devices cgroup isn't mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -4165,8 +4070,6 @@ lxcDomainDetachDeviceHostdevMiscLive(virLXCDriverPtr driver, cleanup: VIR_FREE(dst); - if (group) - virCgroupFree(&group); return ret; } @@ -4190,16 +4093,15 @@ lxcDomainDetachDeviceHostdevSubsysLive(virLXCDriverPtr driver, static int -lxcDomainDetachDeviceHostdevCapsLive(virLXCDriverPtr driver, - virDomainObjPtr vm, - virDomainDeviceDefPtr dev) +lxcDomainDetachDeviceHostdevCapsLive(virDomainObjPtr vm, + virDomainDeviceDefPtr dev) { switch (dev->data.hostdev->source.caps.type) { case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_STORAGE: - return lxcDomainDetachDeviceHostdevStorageLive(driver, vm, dev); + return lxcDomainDetachDeviceHostdevStorageLive(vm, dev); case VIR_DOMAIN_HOSTDEV_CAPS_TYPE_MISC: - return lxcDomainDetachDeviceHostdevMiscLive(driver, vm, dev); + return lxcDomainDetachDeviceHostdevMiscLive(vm, dev); default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -4228,7 +4130,7 @@ lxcDomainDetachDeviceHostdevLive(virLXCDriverPtr driver, return lxcDomainDetachDeviceHostdevSubsysLive(driver, vm, dev); case VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES: - return lxcDomainDetachDeviceHostdevCapsLive(driver, vm, dev); + return lxcDomainDetachDeviceHostdevCapsLive(vm, dev); default: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -4248,7 +4150,7 @@ lxcDomainDetachDeviceLive(virLXCDriverPtr driver, switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: - ret = lxcDomainDetachDeviceDiskLive(driver, vm, dev); + ret = lxcDomainDetachDeviceDiskLive(vm, dev); break; case VIR_DOMAIN_DEVICE_NET: diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 1a89e4a..30c8a89 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -218,7 +218,6 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver, virDomainObjPtr vm, virDomainShutoffReason reason) { - virCgroupPtr cgroup; int i; virLXCDomainObjPrivatePtr priv = vm->privateData; virNetDevVPortProfilePtr vport = NULL; @@ -274,11 +273,8 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver, virDomainConfVMNWFilterTeardown(vm); - if (driver->cgroup && - virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) == 0) { - virCgroupRemove(cgroup); - virCgroupFree(&cgroup); - } + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) + virCgroupItemFree(vm->def->cgroup[i]); /* now that we know it's stopped call the hook if present */ if (virHookPresent(VIR_HOOK_DRIVER_LXC)) { @@ -683,8 +679,8 @@ int virLXCProcessStop(virLXCDriverPtr driver, virDomainObjPtr vm, virDomainShutoffReason reason) { - virCgroupPtr group = NULL; int rc; + int i; VIR_DEBUG("Stopping VM name=%s pid=%d reason=%d", vm->def->name, (int)vm->pid, (int)reason); @@ -705,24 +701,26 @@ int virLXCProcessStop(virLXCDriverPtr driver, VIR_FREE(vm->def->seclabels[0]->imagelabel); } - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) == 0) { - rc = virCgroupKillPainfully(group); - if (rc < 0) { - virReportSystemError(-rc, "%s", - _("Failed to kill container PIDs")); - rc = -1; - goto cleanup; - } - if (rc == 1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Some container PIDs refused to die")); - rc = -1; - goto cleanup; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + if (vm->def->cgroup[i]) { + rc = virCgroupKillPainfully(vm->def->cgroup[i]); + if (rc < 0) { + virReportSystemError(-rc, "%s", + _("Failed to kill container PIDs")); + rc = -1; + goto cleanup; + } + if (rc == 1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Some container PIDs refused to die")); + rc = -1; + goto cleanup; + } + } else { + /* If cgroup doesn't exist, the VM pids must have already + * died and so we're just cleaning up stale state + */ } - } else { - /* If cgroup doesn't exist, the VM pids must have already - * died and so we're just cleaning up stale state - */ } virLXCProcessCleanup(driver, vm, reason); @@ -730,7 +728,6 @@ int virLXCProcessStop(virLXCDriverPtr driver, rc = 0; cleanup: - virCgroupFree(&group); return rc; } @@ -924,20 +921,17 @@ int virLXCProcessStart(virConnectPtr conn, return -1; } - if (!virCgroupMounted(lxc_driver->cgroup, - VIR_CGROUP_CONTROLLER_CPUACCT)) { + if (!virCgroupMounted(VIR_CGROUP_CONTROLLER_CPUACCT)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to find 'cpuacct' cgroups controller mount")); return -1; } - if (!virCgroupMounted(lxc_driver->cgroup, - VIR_CGROUP_CONTROLLER_DEVICES)) { + if (!virCgroupMounted(VIR_CGROUP_CONTROLLER_DEVICES)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to find 'devices' cgroups controller mount")); return -1; } - if (!virCgroupMounted(lxc_driver->cgroup, - VIR_CGROUP_CONTROLLER_MEMORY)) { + if (!virCgroupMounted(VIR_CGROUP_CONTROLLER_MEMORY)) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Unable to find 'memory' cgroups controller mount")); return -1; diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 6527146..c409323 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -48,11 +48,9 @@ static const char *const defaultDeviceACL[] = { bool qemuCgroupControllerActive(virQEMUDriverPtr driver, int controller) { - if (driver->cgroup == NULL) - return false; if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST) return false; - if (!virCgroupMounted(driver->cgroup, controller)) + if (driver->cgroup[controller] == NULL) return false; if (driver->cgroupControllers & (1 << controller)) return true; @@ -89,7 +87,7 @@ qemuSetupDiskPathAllow(virDomainDiskDefPtr disk, int qemuSetupDiskCgroup(virDomainObjPtr vm, - virCgroupPtr cgroup, + virCgroupItemPtr cgroup, virDomainDiskDefPtr disk) { qemuCgroupData data = { vm, cgroup }; @@ -128,7 +126,7 @@ qemuTeardownDiskPathDeny(virDomainDiskDefPtr disk ATTRIBUTE_UNUSED, int qemuTeardownDiskCgroup(virDomainObjPtr vm, - virCgroupPtr cgroup, + virCgroupItemPtr cgroup, virDomainDiskDefPtr disk) { qemuCgroupData data = { vm, cgroup }; @@ -192,7 +190,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm, virBitmapPtr nodemask) { - virCgroupPtr cgroup = NULL; + char *path; + virCgroupItemPtr cgroup = NULL; int rc; unsigned int i; const char *const *deviceACL = @@ -200,17 +199,19 @@ int qemuSetupCgroup(virQEMUDriverPtr driver, (const char *const *)driver->cgroupDeviceACL : defaultDeviceACL; - if (driver->cgroup == NULL) - return 0; /* Not supported, so claim success */ - - rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 1); - if (rc != 0) { - virReportSystemError(-rc, - _("Unable to create cgroup for %s"), - vm->def->name); - goto cleanup; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + vm->def->cgroup[i] = virCgroupItemNew(i, vm->def->name, driver->cgroup[i]); + /* XXX: This is a dirty hack to create the cgroup item path before + * any qemu processes bring up. The reason to do so is virCgroup creates + * cgroup item path as needed, and maintains the information. But if the + * path is created by a sub-process(see qemuProcessHook), we can't know it + * and virCgroup will behave incorrectly. + */ + virCgroupItemPath(vm->def->cgroup[i], true, &path); } + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; + if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { qemuCgroupData data = { vm, cgroup }; rc = virCgroupDenyAllDevices(cgroup); @@ -300,6 +301,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver, } } + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_BLKIO]; + if (vm->def->blkio.weight != 0) { if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { rc = virCgroupSetBlkioWeight(cgroup, vm->def->blkio.weight); @@ -339,6 +342,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver, } } + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_MEMORY]; + if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) { unsigned long long hard_limit = vm->def->mem.hard_limit; @@ -392,6 +397,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver, VIR_WARN("Could not autoset a RSS limit for domain %s", vm->def->name); } + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPU]; + if (vm->def->cputune.shares != 0) { if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { rc = virCgroupSetCpuShares(cgroup, vm->def->cputune.shares); @@ -407,6 +414,8 @@ int qemuSetupCgroup(virQEMUDriverPtr driver, } } + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPUSET]; + if ((vm->def->numatune.memory.nodemask || (vm->def->numatune.memory.placement_mode == VIR_DOMAIN_NUMATUNE_MEM_PLACEMENT_MODE_AUTO)) && @@ -434,18 +443,13 @@ int qemuSetupCgroup(virQEMUDriverPtr driver, } } done: - virCgroupFree(&cgroup); return 0; cleanup: - if (cgroup) { - virCgroupRemove(cgroup); - virCgroupFree(&cgroup); - } return -1; } -int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup, unsigned long long period, +int qemuSetupCgroupVcpuBW(virCgroupItemPtr cgroup, unsigned long long period, long long quota) { int rc; @@ -493,7 +497,7 @@ cleanup: return -1; } -int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup, +int qemuSetupCgroupVcpuPin(virCgroupItemPtr cgroup, virDomainVcpuPinDefPtr *vcpupin, int nvcpupin, int vcpuid) @@ -509,7 +513,7 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup, return -1; } -int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, +int qemuSetupCgroupEmulatorPin(virCgroupItemPtr cgroup, virBitmapPtr cpumask) { int rc = 0; @@ -538,68 +542,48 @@ cleanup: int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm) { - virCgroupPtr cgroup = NULL; - virCgroupPtr cgroup_vcpu = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; virDomainDefPtr def = vm->def; int rc; unsigned int i, j; unsigned long long period = vm->def->cputune.period; long long quota = vm->def->cputune.quota; - - if ((period || quota) && - (!driver->cgroup || - !qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("cgroup cpu is required for scheduler tuning")); - return -1; - } - - /* We are trying to setup cgroups for CPU pinning, which can also be done - * with virProcessInfoSetAffinity, thus the lack of cgroups is not fatal - * here. - */ - if (driver->cgroup == NULL) - 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; - } + char *vcpuName = NULL; if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) { /* If we don't know VCPU<->PID mapping or all vcpu runs in the same * thread, we cannot control each vcpu. */ VIR_WARN("Unable to get vcpus' pids."); - virCgroupFree(&cgroup); return 0; } + if (VIR_ALLOC_N(vm->def->vcpuCgroups, priv->nvcpupids) < 0) { + virReportOOMError(); + goto cleanup; + } + for (i = 0; i < priv->nvcpupids; i++) { - rc = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 1); - if (rc < 0) { - virReportSystemError(-rc, - _("Unable to create vcpu cgroup for %s(vcpu:" - " %d)"), - vm->def->name, i); + if (virAsprintf(&vcpuName, "vcpu%d", i) < 0) goto cleanup; - } - /* move the thread for vcpu to sub dir */ - rc = virCgroupAddTask(cgroup_vcpu, priv->vcpupids[i]); - if (rc < 0) { - virReportSystemError(-rc, - _("unable to add vcpu %d task %d to cgroup"), - i, priv->vcpupids[i]); - goto cleanup; - } + for (j = 0; j < VIR_CGROUP_CONTROLLER_LAST; j++) + vm->def->vcpuCgroups[i][j] = virCgroupItemNew(j, + vcpuName, + vm->def->cgroup[j]); + + if ((period || quota) && vm->def->vcpuCgroups[i][VIR_CGROUP_CONTROLLER_CPU]) { + rc = virCgroupItemAddTask(vm->def->vcpuCgroups[i][VIR_CGROUP_CONTROLLER_CPU], + priv->vcpupids[i]); + if (rc < 0) { + virReportSystemError(-rc, + _("unable to add vcpu %d task %d to cgroup"), + i, priv->vcpupids[i]); + goto cleanup; + } - if (period || quota) { - if (qemuSetupCgroupVcpuBW(cgroup_vcpu, period, quota) < 0) + if (qemuSetupCgroupVcpuBW(vm->def->vcpuCgroups[i][VIR_CGROUP_CONTROLLER_CPU], + period, quota) < 0) goto cleanup; } @@ -611,7 +595,16 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm) if (def->cputune.vcpupin[j]->vcpuid != i) continue; - if (qemuSetupCgroupVcpuPin(cgroup_vcpu, + rc = virCgroupItemAddTask(vm->def->vcpuCgroups[i][VIR_CGROUP_CONTROLLER_CPUSET], + priv->vcpupids[i]); + if (rc < 0) { + virReportSystemError(-rc, + _("unable to add vcpu %d task %d to cgroup"), + i, priv->vcpupids[i]); + goto cleanup; + } + + if (qemuSetupCgroupVcpuPin(vm->def->vcpuCgroups[i][VIR_CGROUP_CONTROLLER_CPUSET], def->cputune.vcpupin, def->cputune.nvcpupin, i) < 0) @@ -620,24 +613,17 @@ int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm) break; } } - - virCgroupFree(&cgroup_vcpu); } - virCgroupFree(&cgroup); return 0; cleanup: - if (cgroup_vcpu) { - virCgroupRemove(cgroup_vcpu); - virCgroupFree(&cgroup_vcpu); - } - - if (cgroup) { - virCgroupRemove(cgroup); - virCgroupFree(&cgroup); + if (vm->def->vcpuCgroups) { + for (i = 0; i < priv->nvcpupids; i++) { + for (j = 0; j < VIR_CGROUP_CONTROLLER_LAST; j++) + virCgroupItemFree(vm->def->vcpuCgroups[i][j]); + } } - return -1; } @@ -647,52 +633,11 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver, { virBitmapPtr cpumask = NULL; virBitmapPtr cpumap = NULL; - virCgroupPtr cgroup = NULL; - virCgroupPtr cgroup_emulator = NULL; virDomainDefPtr def = vm->def; unsigned long long period = vm->def->cputune.emulator_period; long long quota = vm->def->cputune.emulator_quota; - int rc, i; - - if ((period || quota) && - (!driver->cgroup || - !qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU))) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("cgroup cpu is required for scheduler tuning")); - return -1; - } - - if (driver->cgroup == NULL) - return 0; /* Not supported, so claim success */ - - 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; - } - - rc = virCgroupForEmulator(cgroup, &cgroup_emulator, 1); - if (rc < 0) { - virReportSystemError(-rc, - _("Unable to create emulator cgroup for %s"), - vm->def->name); - goto cleanup; - } - - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { - if (!qemuCgroupControllerActive(driver, i)) - continue; - rc = virCgroupMoveTask(cgroup, cgroup_emulator, i); - if (rc < 0) { - virReportSystemError(-rc, - _("Unable to move tasks from domain cgroup to " - "emulator cgroup in controller %d for %s"), - i, vm->def->name); - goto cleanup; - } - } + int rc = -1; + int i; if (def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { if (!(cpumap = qemuPrepareCpumap(driver, nodemask))) @@ -704,97 +649,29 @@ int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver, cpumask = def->cpumask; } - if (cpumask) { - if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { - rc = qemuSetupCgroupEmulatorPin(cgroup_emulator, cpumask); - if (rc < 0) - goto cleanup; - } + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + def->emulatorCgroup[i] = virCgroupItemNew(i, "emulator", def->cgroup[i]); + } + + if (cpumask && def->emulatorCgroup[VIR_CGROUP_CONTROLLER_CPUSET]) { + rc = qemuSetupCgroupEmulatorPin(def->emulatorCgroup[VIR_CGROUP_CONTROLLER_CPUSET], + cpumask); + if (rc < 0) + goto cleanup; cpumask = NULL; /* sanity */ } - if (period || quota) { - if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { - if ((rc = qemuSetupCgroupVcpuBW(cgroup_emulator, period, - quota)) < 0) - goto cleanup; - } + if ((period || quota) && def->emulatorCgroup[VIR_CGROUP_CONTROLLER_CPU]) { + if ((rc = qemuSetupCgroupVcpuBW(def->emulatorCgroup[VIR_CGROUP_CONTROLLER_CPU], + period, quota)) < 0) + goto cleanup; } - virCgroupFree(&cgroup_emulator); - virCgroupFree(&cgroup); - virBitmapFree(cpumap); return 0; cleanup: - virBitmapFree(cpumap); - - if (cgroup_emulator) { - virCgroupRemove(cgroup_emulator); - virCgroupFree(&cgroup_emulator); - } - - if (cgroup) { - virCgroupRemove(cgroup); - virCgroupFree(&cgroup); - } - - return rc; -} - -int qemuRemoveCgroup(virQEMUDriverPtr driver, - virDomainObjPtr vm, - int quiet) -{ - virCgroupPtr cgroup; - int rc; - - if (driver->cgroup == NULL) - return 0; /* Not supported, so claim success */ - - rc = virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0); - if (rc != 0) { - if (!quiet) - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unable to find cgroup for %s"), - vm->def->name); - return rc; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + virCgroupItemFree(def->emulatorCgroup[i]); } - - rc = virCgroupRemove(cgroup); - virCgroupFree(&cgroup); return rc; } - -int qemuAddToCgroup(virQEMUDriverPtr driver, - virDomainDefPtr def) -{ - virCgroupPtr cgroup = NULL; - int ret = -1; - int rc; - - if (driver->cgroup == NULL) - return 0; /* Not supported, so claim success */ - - rc = virCgroupForDomain(driver->cgroup, def->name, &cgroup, 0); - if (rc != 0) { - virReportSystemError(-rc, - _("unable to find cgroup for domain %s"), - def->name); - goto cleanup; - } - - rc = virCgroupAddTask(cgroup, getpid()); - if (rc != 0) { - virReportSystemError(-rc, - _("unable to add domain %s task %d to cgroup"), - def->name, getpid()); - goto cleanup; - } - - ret = 0; - -cleanup: - virCgroupFree(&cgroup); - return ret; -} diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h index 75ef514..6444c2a 100644 --- a/src/qemu/qemu_cgroup.h +++ b/src/qemu/qemu_cgroup.h @@ -30,17 +30,17 @@ struct _qemuCgroupData { virDomainObjPtr vm; - virCgroupPtr cgroup; + virCgroupItemPtr cgroup; }; typedef struct _qemuCgroupData qemuCgroupData; bool qemuCgroupControllerActive(virQEMUDriverPtr driver, int controller); int qemuSetupDiskCgroup(virDomainObjPtr vm, - virCgroupPtr cgroup, + virCgroupItemPtr cgroup, virDomainDiskDefPtr disk); int qemuTeardownDiskCgroup(virDomainObjPtr vm, - virCgroupPtr cgroup, + virCgroupItemPtr cgroup, virDomainDiskDefPtr disk); int qemuSetupHostUsbDeviceCgroup(usbDevice *dev, const char *path, @@ -48,22 +48,17 @@ int qemuSetupHostUsbDeviceCgroup(usbDevice *dev, int qemuSetupCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm, virBitmapPtr nodemask); -int qemuSetupCgroupVcpuBW(virCgroupPtr cgroup, +int qemuSetupCgroupVcpuBW(virCgroupItemPtr cgroup, unsigned long long period, long long quota); -int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup, +int qemuSetupCgroupVcpuPin(virCgroupItemPtr cgroup, virDomainVcpuPinDefPtr *vcpupin, int nvcpupin, int vcpuid); -int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, virBitmapPtr cpumask); +int qemuSetupCgroupEmulatorPin(virCgroupItemPtr cgroup, virBitmapPtr cpumask); int qemuSetupCgroupForVcpu(virQEMUDriverPtr driver, virDomainObjPtr vm); int qemuSetupCgroupForEmulator(virQEMUDriverPtr driver, virDomainObjPtr vm, virBitmapPtr nodemask); -int qemuRemoveCgroup(virQEMUDriverPtr driver, - virDomainObjPtr vm, - int quiet); -int qemuAddToCgroup(virQEMUDriverPtr driver, - virDomainDefPtr def); #endif /* __QEMU_CGROUP_H__ */ diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h index 965eff7..9162914 100644 --- a/src/qemu/qemu_conf.h +++ b/src/qemu/qemu_conf.h @@ -69,7 +69,7 @@ struct _virQEMUDriver { unsigned int qemuVersion; int nextvmid; - virCgroupPtr cgroup; + virCgroupItemPtr cgroup[VIR_CGROUP_CONTROLLER_LAST]; int cgroupControllers; char **cgroupDeviceACL; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 39175f4..d795abe 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -650,11 +650,11 @@ qemuStartup(bool privileged, { char *base; char *driverConf = NULL; - int rc; virConnectPtr conn = NULL; char ebuf[1024]; char *membase = NULL; char *mempath = NULL; + int i; if (VIR_ALLOC(qemu_driver) < 0) return -1; @@ -795,17 +795,16 @@ qemuStartup(bool privileged, virAsprintf(&qemu_driver->autostartDir, "%s/qemu/autostart", base) < 0) goto out_of_memory; - rc = virCgroupForDriver("qemu", &qemu_driver->cgroup, privileged, 1); - if (rc < 0) { - VIR_INFO("Unable to create cgroup for driver: %s", - virStrerror(-rc, ebuf, sizeof(ebuf))); - } - if (qemuLoadDriverConfig(qemu_driver, driverConf) < 0) { goto error; } VIR_FREE(driverConf); + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + qemu_driver->cgroup[i] = virCgroupItemNew(i, "qemu", + virCgroupGetAppRoot(i, privileged)); + } + /* Allocate bitmap for remote display port reservations. We cannot * do this before the config is loaded properly, since the port * numbers are configurable now */ @@ -1146,10 +1145,14 @@ qemuShutdown(void) { /* Free domain callback list */ virDomainEventStateFree(qemu_driver->domainEventState); - virCgroupFree(&qemu_driver->cgroup); + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) + virCgroupItemFree(qemu_driver->cgroup[i]); virLockManagerPluginUnref(qemu_driver->lockManager); + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) + virCgroupItemFree(qemu_driver->cgroup[i]); + qemuDriverUnlock(qemu_driver); virMutexDestroy(&qemu_driver->lock); virThreadPoolFree(qemu_driver->workerPool); @@ -3652,7 +3655,7 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver, int ncpupids; virCgroupPtr cgroup = NULL; virCgroupPtr cgroup_vcpu = NULL; - bool cgroup_available = false; + //bool cgroup_available = false; qemuDomainObjEnterMonitor(driver, vm); @@ -3697,6 +3700,7 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver, goto cleanup; } +#if 0 /* XXX */ if (ncpupids != vcpus) { virReportError(VIR_ERR_INTERNAL_ERROR, _("got wrong number of vCPU pids from QEMU monitor. " @@ -3808,6 +3812,7 @@ static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver, } } } +#endif priv->nvcpupids = ncpupids; VIR_FREE(priv->vcpupids); @@ -4014,15 +4019,13 @@ qemuDomainPinVcpuFlags(virDomainPtr dom, } /* Configure the corresponding cpuset cgroup before set affinity. */ - if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { - if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup_dom, 0) == 0 && - virCgroupForVcpu(cgroup_dom, vcpu, &cgroup_vcpu, 0) == 0 && - qemuSetupCgroupVcpuPin(cgroup_vcpu, newVcpuPin, newVcpuPinNum, vcpu) < 0) { - virReportError(VIR_ERR_OPERATION_INVALID, - _("failed to set cpuset.cpus in cgroup" - " for vcpu %d"), vcpu); - goto cleanup; - } + if (vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPUSET] && + qemuSetupCgroupVcpuPin(vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPUSET], + newVcpuPin, newVcpuPinNum, vcpu) < 0) { + virReportError(VIR_ERR_OPERATION_INVALID, + _("failed to set cpuset.cpus in cgroup" + " for vcpu %d"), vcpu); + goto cleanup; } else { if (virProcessSetAffinity(priv->vcpupids[vcpu], pcpumap) < 0) { virReportError(VIR_ERR_SYSTEM_ERROR, @@ -4255,23 +4258,13 @@ qemuDomainPinEmulator(virDomainPtr dom, goto cleanup; } - if (qemuCgroupControllerActive(driver, - VIR_CGROUP_CONTROLLER_CPUSET)) { - /* - * Configure the corresponding cpuset cgroup. - * If no cgroup for domain or hypervisor exists, do nothing. - */ - if (virCgroupForDomain(driver->cgroup, vm->def->name, - &cgroup_dom, 0) == 0) { - if (virCgroupForEmulator(cgroup_dom, &cgroup_emulator, 0) == 0) { - if (qemuSetupCgroupEmulatorPin(cgroup_emulator, - newVcpuPin[0]->cpumask) < 0) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("failed to set cpuset.cpus in cgroup" - " for emulator threads")); - goto cleanup; - } - } + if (vm->def->emulatorCgroup[VIR_CGROUP_CONTROLLER_CPUSET]) { + if (qemuSetupCgroupEmulatorPin(vm->def->emulatorCgroup[VIR_CGROUP_CONTROLLER_CPUSET], + newVcpuPin[0]->cpumask) < 0) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("failed to set cpuset.cpus in cgroup" + " for emulator threads")); + goto cleanup; } } else { if (virProcessSetAffinity(pid, pcpumap) < 0) { @@ -5804,7 +5797,7 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn, virDomainDeviceDefPtr dev) { virDomainDiskDefPtr disk = dev->data.disk; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; int ret = -1; if (disk->driverName != NULL && !STREQ(disk->driverName, "qemu")) { @@ -5822,16 +5815,10 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn, if (qemuDomainDetermineDiskChain(driver, disk, false) < 0) goto end; - if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unable to find cgroup for %s"), - vm->def->name); - goto end; - } + if (cgroup) if (qemuSetupDiskCgroup(vm, cgroup, disk) < 0) goto end; - } + switch (disk->device) { case VIR_DOMAIN_DISK_DEVICE_CDROM: case VIR_DOMAIN_DISK_DEVICE_FLOPPY: @@ -5882,8 +5869,6 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn, } end: - if (cgroup) - virCgroupFree(&cgroup); return ret; } @@ -6067,23 +6052,15 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm, bool force) { virDomainDiskDefPtr disk = dev->data.disk; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; int ret = -1; if (qemuDomainDetermineDiskChain(driver, disk, false) < 0) goto end; - 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 end; - } + if (cgroup) if (qemuSetupDiskCgroup(vm, cgroup, disk) < 0) goto end; - } switch (disk->device) { case VIR_DOMAIN_DISK_DEVICE_CDROM: @@ -6105,8 +6082,6 @@ qemuDomainChangeDiskMediaLive(virDomainObjPtr vm, NULLSTR(disk->src)); } end: - if (cgroup) - virCgroupFree(&cgroup); return ret; } @@ -6693,39 +6668,6 @@ cleanup: } -/* - * check whether the host supports CFS bandwidth - * - * Return 1 when CFS bandwidth is supported, 0 when CFS bandwidth is not - * supported, -1 on error. - */ -static int qemuGetCpuBWStatus(virCgroupPtr cgroup) -{ - char *cfs_period_path = NULL; - int ret = -1; - - if (!cgroup) - return 0; - - if (virCgroupPathOfController(cgroup, VIR_CGROUP_CONTROLLER_CPU, - "cpu.cfs_period_us", &cfs_period_path) < 0) { - VIR_INFO("cannot get the path of cgroup CPU controller"); - ret = 0; - goto cleanup; - } - - if (access(cfs_period_path, F_OK) < 0) { - ret = 0; - } else { - ret = 1; - } - -cleanup: - VIR_FREE(cfs_period_path); - return ret; -} - - static char *qemuGetSchedulerType(virDomainPtr dom, int *nparams) { @@ -6741,10 +6683,10 @@ static char *qemuGetSchedulerType(virDomainPtr dom, } if (nparams) { - rc = qemuGetCpuBWStatus(driver->cgroup); + rc = virCgroupItemKeyPath(driver->cgroup[VIR_CGROUP_CONTROLLER_CPU], + "cpu.cfs_period_us", + NULL); if (rc < 0) - goto cleanup; - else if (rc == 0) *nparams = 1; else *nparams = 5; @@ -6895,7 +6837,7 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, { virQEMUDriverPtr driver = dom->conn->privateData; int i; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr persistentDef = NULL; int ret = -1; @@ -6923,23 +6865,14 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, &persistentDef) < 0) goto cleanup; + ret = 0; if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("blkio cgroup isn't mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find cgroup for domain %s"), - vm->def->name); + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_BLKIO]; + if (!group) { + ret = -1; goto cleanup; } - } - ret = 0; - if (flags & VIR_DOMAIN_AFFECT_LIVE) { for (i = 0; i < nparams; i++) { int rc; virTypedParameterPtr param = ¶ms[i]; @@ -7033,7 +6966,6 @@ qemuDomainSetBlkioParameters(virDomainPtr dom, } cleanup: - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -7048,7 +6980,7 @@ qemuDomainGetBlkioParameters(virDomainPtr dom, { virQEMUDriverPtr driver = dom->conn->privateData; int i, j; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr persistentDef = NULL; unsigned int val; @@ -7084,21 +7016,12 @@ qemuDomainGetBlkioParameters(virDomainPtr dom, &persistentDef) < 0) goto cleanup; - if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("blkio cgroup isn't mounted")); - goto cleanup; - } + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_BLKIO]; - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find cgroup for domain %s"), vm->def->name); + if (flags & VIR_DOMAIN_AFFECT_LIVE) { + if (!group) goto cleanup; - } - } - if (flags & VIR_DOMAIN_AFFECT_LIVE) { for (i = 0; i < *nparams && i < QEMU_NB_BLKIO_PARAM; i++) { virTypedParameterPtr param = ¶ms[i]; val = 0; @@ -7218,8 +7141,6 @@ qemuDomainGetBlkioParameters(virDomainPtr dom, ret = 0; cleanup: - if (group) - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -7235,7 +7156,7 @@ qemuDomainSetMemoryParameters(virDomainPtr dom, virQEMUDriverPtr driver = dom->conn->privateData; int i; virDomainDefPtr persistentDef = NULL; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virTypedParameterPtr hard_limit = NULL; virTypedParameterPtr swap_hard_limit = NULL; @@ -7273,19 +7194,9 @@ qemuDomainSetMemoryParameters(virDomainPtr dom, &persistentDef) < 0) goto cleanup; - if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroup memory controller is not mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find cgroup for domain %s"), vm->def->name); - goto cleanup; - } - } + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_MEMORY]; + if (!group) + goto cleanup; for (i = 0; i < nparams; i++) { if (STREQ(params[i].field, VIR_DOMAIN_MEMORY_HARD_LIMIT)) { @@ -7388,7 +7299,6 @@ qemuDomainSetMemoryParameters(virDomainPtr dom, } cleanup: - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -7403,7 +7313,7 @@ qemuDomainGetMemoryParameters(virDomainPtr dom, { virQEMUDriverPtr driver = dom->conn->privateData; int i; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr persistentDef = NULL; int ret = -1; @@ -7430,19 +7340,9 @@ qemuDomainGetMemoryParameters(virDomainPtr dom, &persistentDef) < 0) goto cleanup; - if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroup memory controller is not mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find cgroup for domain %s"), vm->def->name); - goto cleanup; - } - } + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_MEMORY]; + if (!group) + goto cleanup; if ((*nparams) == 0) { /* Current number of memory parameters supported by cgroups */ @@ -7547,8 +7447,6 @@ out: ret = 0; cleanup: - if (group) - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -7564,7 +7462,7 @@ qemuDomainSetNumaParameters(virDomainPtr dom, virQEMUDriverPtr driver = dom->conn->privateData; int i; virDomainDefPtr persistentDef = NULL; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; int ret = -1; @@ -7593,18 +7491,9 @@ qemuDomainSetNumaParameters(virDomainPtr dom, goto cleanup; if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroup cpuset controller is not mounted")); + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPUSET]; + if (!group) goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find cgroup for domain %s"), - vm->def->name); - goto cleanup; - } } ret = 0; @@ -7697,7 +7586,6 @@ qemuDomainSetNumaParameters(virDomainPtr dom, } cleanup: - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -7712,7 +7600,7 @@ qemuDomainGetNumaParameters(virDomainPtr dom, { virQEMUDriverPtr driver = dom->conn->privateData; int i; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr persistentDef = NULL; char *nodeset = NULL; @@ -7749,18 +7637,9 @@ qemuDomainGetNumaParameters(virDomainPtr dom, } if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_MEMORY)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroup memory controller is not mounted")); + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_MEMORY]; + if (!group) goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find cgroup for domain %s"), - vm->def->name); - goto cleanup; - } } for (i = 0; i < QEMU_NB_NUMA_PARAM && i < *nparams; i++) { @@ -7810,7 +7689,6 @@ qemuDomainGetNumaParameters(virDomainPtr dom, cleanup: VIR_FREE(nodeset); - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -7818,13 +7696,13 @@ cleanup: } static int -qemuSetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup, - unsigned long long period, long long quota) +qemuSetVcpusBWLive(virDomainObjPtr vm, + unsigned long long period, + long long quota) { int i; qemuDomainObjPrivatePtr priv = vm->privateData; - virCgroupPtr cgroup_vcpu = NULL; - int rc; + virCgroupItemPtr cgroup = NULL; if (period == 0 && quota == 0) return 0; @@ -7835,36 +7713,30 @@ qemuSetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup, */ if (priv->nvcpupids != 0 && priv->vcpupids[0] != vm->pid) { for (i = 0; i < priv->nvcpupids; i++) { - rc = virCgroupForVcpu(cgroup, i, &cgroup_vcpu, 0); - if (rc < 0) { - virReportSystemError(-rc, - _("Unable to find vcpu cgroup for %s(vcpu:" - " %d)"), - vm->def->name, i); - goto cleanup; - } + if (vm->def->vcpuCgroups && + vm->def->vcpuCgroups[i]) + cgroup = vm->def->vcpuCgroups[i][VIR_CGROUP_CONTROLLER_CPU]; - if (qemuSetupCgroupVcpuBW(cgroup_vcpu, period, quota) < 0) - goto cleanup; + if (!cgroup) + goto cleanup; - virCgroupFree(&cgroup_vcpu); + if (qemuSetupCgroupVcpuBW(cgroup, period, quota) < 0) + goto cleanup; } } return 0; cleanup: - virCgroupFree(&cgroup_vcpu); return -1; } static int -qemuSetEmulatorBandwidthLive(virDomainObjPtr vm, virCgroupPtr cgroup, +qemuSetEmulatorBandwidthLive(virDomainObjPtr vm, unsigned long long period, long long quota) { qemuDomainObjPrivatePtr priv = vm->privateData; - virCgroupPtr cgroup_emulator = NULL; - int rc; + virCgroupItemPtr cgroup = vm->def->emulatorCgroup[VIR_CGROUP_CONTROLLER_CPU]; if (period == 0 && quota == 0) return 0; @@ -7873,22 +7745,15 @@ qemuSetEmulatorBandwidthLive(virDomainObjPtr vm, virCgroupPtr cgroup, return 0; } - rc = virCgroupForEmulator(cgroup, &cgroup_emulator, 0); - if (rc < 0) { - virReportSystemError(-rc, - _("Unable to find emulator cgroup for %s"), - vm->def->name); + if (!cgroup) goto cleanup; - } - if (qemuSetupCgroupVcpuBW(cgroup_emulator, period, quota) < 0) + if (qemuSetupCgroupVcpuBW(cgroup, period, quota) < 0) goto cleanup; - virCgroupFree(&cgroup_emulator); return 0; cleanup: - virCgroupFree(&cgroup_emulator); return -1; } @@ -7909,7 +7774,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, { virQEMUDriverPtr driver = dom->conn->privateData; int i; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; virDomainDefPtr vmdef = NULL; unsigned long long value_ul; @@ -7954,18 +7819,12 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, goto cleanup; } - if (flags & VIR_DOMAIN_AFFECT_LIVE) { - if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroup CPU controller is not mounted")); - goto cleanup; - } - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find cgroup for domain %s"), - vm->def->name); - goto cleanup; - } + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPU]; + if ((flags & VIR_DOMAIN_AFFECT_LIVE) && !group) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find cgroup for domain %s"), + vm->def->name); + goto cleanup; } for (i = 0; i < nparams; i++) { @@ -7991,7 +7850,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD); if (flags & VIR_DOMAIN_AFFECT_LIVE && value_ul) { - if ((rc = qemuSetVcpusBWLive(vm, group, value_ul, 0))) + if ((rc = qemuSetVcpusBWLive(vm, value_ul, 0))) goto cleanup; vm->def->cputune.period = value_ul; @@ -8005,7 +7864,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA); if (flags & VIR_DOMAIN_AFFECT_LIVE && value_l) { - if ((rc = qemuSetVcpusBWLive(vm, group, 0, value_l))) + if ((rc = qemuSetVcpusBWLive(vm, 0, value_l))) goto cleanup; vm->def->cputune.quota = value_l; @@ -8019,7 +7878,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, QEMU_SCHED_MIN_PERIOD, QEMU_SCHED_MAX_PERIOD); if (flags & VIR_DOMAIN_AFFECT_LIVE && value_ul) { - if ((rc = qemuSetEmulatorBandwidthLive(vm, group, value_ul, 0))) + if ((rc = qemuSetEmulatorBandwidthLive(vm, value_ul, 0))) goto cleanup; vm->def->cputune.emulator_period = value_ul; @@ -8033,7 +7892,7 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, QEMU_SCHED_MIN_QUOTA, QEMU_SCHED_MAX_QUOTA); if (flags & VIR_DOMAIN_AFFECT_LIVE && value_l) { - if ((rc = qemuSetEmulatorBandwidthLive(vm, group, 0, value_l))) + if ((rc = qemuSetEmulatorBandwidthLive(vm, 0, value_l))) goto cleanup; vm->def->cputune.emulator_quota = value_l; @@ -8061,7 +7920,6 @@ qemuSetSchedulerParametersFlags(virDomainPtr dom, cleanup: virDomainDefFree(vmdef); - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -8081,7 +7939,7 @@ qemuSetSchedulerParameters(virDomainPtr dom, } static int -qemuGetVcpuBWLive(virCgroupPtr cgroup, unsigned long long *period, +qemuGetVcpuBWLive(virCgroupItemPtr cgroup, unsigned long long *period, long long *quota) { int rc; @@ -8104,10 +7962,10 @@ qemuGetVcpuBWLive(virCgroupPtr cgroup, unsigned long long *period, } static int -qemuGetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup, +qemuGetVcpusBWLive(virDomainObjPtr vm, unsigned long long *period, long long *quota) { - virCgroupPtr cgroup_vcpu = NULL; + virCgroupItemPtr cgroup = NULL; qemuDomainObjPrivatePtr priv = NULL; int rc; int ret = -1; @@ -8115,41 +7973,30 @@ qemuGetVcpusBWLive(virDomainObjPtr vm, virCgroupPtr cgroup, priv = vm->privateData; if (priv->nvcpupids == 0 || priv->vcpupids[0] == vm->pid) { /* We do not create sub dir for each vcpu */ - rc = qemuGetVcpuBWLive(cgroup, period, quota); - if (rc < 0) - goto cleanup; - - if (*quota > 0) - *quota /= vm->def->vcpus; - goto out; - } - - /* get period and quota for vcpu0 */ - rc = virCgroupForVcpu(cgroup, 0, &cgroup_vcpu, 0); - if (!cgroup_vcpu) { - virReportSystemError(-rc, - _("Unable to find vcpu cgroup for %s(vcpu: 0)"), - vm->def->name); - goto cleanup; + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPU]; + } else { + /* get period and quota for vcpu0 */ + cgroup = vm->def->vcpuCgroups[0][VIR_CGROUP_CONTROLLER_CPU]; } - rc = qemuGetVcpuBWLive(cgroup_vcpu, period, quota); + rc = qemuGetVcpuBWLive(cgroup, period, quota); if (rc < 0) goto cleanup; -out: + if (*quota > 0) + *quota /= vm->def->vcpus; + ret = 0; cleanup: - virCgroupFree(&cgroup_vcpu); return ret; } static int -qemuGetEmulatorBandwidthLive(virDomainObjPtr vm, virCgroupPtr cgroup, +qemuGetEmulatorBandwidthLive(virDomainObjPtr vm, unsigned long long *period, long long *quota) { - virCgroupPtr cgroup_emulator = NULL; + virCgroupItemPtr cgroup = NULL; qemuDomainObjPrivatePtr priv = NULL; int rc; int ret = -1; @@ -8162,23 +8009,23 @@ qemuGetEmulatorBandwidthLive(virDomainObjPtr vm, virCgroupPtr cgroup, return 0; } + cgroup = vm->def->emulatorCgroup[VIR_CGROUP_CONTROLLER_CPU]; + /* get period and quota for emulator */ - rc = virCgroupForEmulator(cgroup, &cgroup_emulator, 0); - if (!cgroup_emulator) { - virReportSystemError(-rc, + if (!cgroup) { + virReportSystemError(VIR_ERR_INTERNAL_ERROR, _("Unable to find emulator cgroup for %s"), vm->def->name); goto cleanup; } - rc = qemuGetVcpuBWLive(cgroup_emulator, period, quota); + rc = qemuGetVcpuBWLive(cgroup, period, quota); if (rc < 0) goto cleanup; ret = 0; cleanup: - virCgroupFree(&cgroup_emulator); return ret; } @@ -8189,7 +8036,7 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom, unsigned int flags) { virQEMUDriverPtr driver = dom->conn->privateData; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; unsigned long long shares; unsigned long long period; @@ -8212,10 +8059,12 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom, flags &= ~VIR_TYPED_PARAM_STRING_OKAY; if (*nparams > 1) { - rc = qemuGetCpuBWStatus(driver->cgroup); + rc = virCgroupItemKeyPath(driver->cgroup[VIR_CGROUP_CONTROLLER_CPU], + "cpu.cfs_period_us", + NULL); if (rc < 0) - goto cleanup; - cpu_bw_status = !!rc; + cpu_bw_status = 0; + cpu_bw_status = 1; } vm = virDomainFindByUUID(&driver->domains, dom->uuid); @@ -8241,13 +8090,8 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom, goto out; } - if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPU)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroup CPU controller is not mounted")); - goto cleanup; - } - - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPU]; + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -8261,13 +8105,13 @@ qemuGetSchedulerParametersFlags(virDomainPtr dom, } if (*nparams > 1 && cpu_bw_status) { - rc = qemuGetVcpusBWLive(vm, group, &period, "a); + rc = qemuGetVcpusBWLive(vm, &period, "a); if (rc != 0) goto cleanup; } if (*nparams > 3 && cpu_bw_status) { - rc = qemuGetEmulatorBandwidthLive(vm, group, &emulator_period, + rc = qemuGetEmulatorBandwidthLive(vm, &emulator_period, &emulator_quota); if (rc != 0) goto cleanup; @@ -8320,7 +8164,6 @@ out: ret = 0; cleanup: - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); @@ -10373,7 +10216,6 @@ typedef enum { static int qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver, virDomainObjPtr vm, - virCgroupPtr cgroup, virDomainDiskDefPtr disk, const char *file, qemuDomainDiskChainMode mode) @@ -10386,6 +10228,7 @@ qemuDomainPrepareDiskChainElement(virQEMUDriverPtr driver, virStorageFileMetadataPtr origchain = disk->backingChain; bool origreadonly = disk->readonly; int ret = -1; + virCgroupItemPtr cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; disk->src = (char *) file; /* casting away const is safe here */ disk->format = VIR_STORAGE_FILE_RAW; @@ -10840,7 +10683,6 @@ cleanup: static int qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, virDomainObjPtr vm, - virCgroupPtr cgroup, virDomainSnapshotDiskDefPtr snap, virDomainDiskDefPtr disk, virDomainDiskDefPtr persistDisk, @@ -10890,9 +10732,9 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver, virStorageFileFreeMetadata(disk->backingChain); disk->backingChain = NULL; - if (qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, source, + if (qemuDomainPrepareDiskChainElement(driver, vm, disk, source, VIR_DISK_CHAIN_READ_WRITE) < 0) { - qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, source, + qemuDomainPrepareDiskChainElement(driver, vm, disk, source, VIR_DISK_CHAIN_NO_ACCESS); goto cleanup; } @@ -10934,7 +10776,6 @@ cleanup: static void qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver, virDomainObjPtr vm, - virCgroupPtr cgroup, virDomainDiskDefPtr origdisk, virDomainDiskDefPtr disk, virDomainDiskDefPtr persistDisk, @@ -10951,7 +10792,7 @@ qemuDomainSnapshotUndoSingleDiskActive(virQEMUDriverPtr driver, goto cleanup; } - qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, origdisk->src, + qemuDomainPrepareDiskChainElement(driver, vm, disk, origdisk->src, VIR_DISK_CHAIN_NO_ACCESS); if (need_unlink && stat(disk->src, &st) == 0 && S_ISREG(st.st_mode) && unlink(disk->src) < 0) @@ -10988,7 +10829,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, int i; bool persist = false; bool reuse = (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REUSE_EXT) != 0; - virCgroupPtr cgroup = NULL; if (!virDomainObjIsActive(vm)) { virReportError(VIR_ERR_OPERATION_INVALID, @@ -10997,7 +10837,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, } if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) && - virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0)) { + !vm->def->cgroup) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to find cgroup for %s"), vm->def->name); @@ -11040,7 +10880,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, } } - ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm, cgroup, + ret = qemuDomainSnapshotCreateSingleDiskActive(driver, vm, &snap->def->disks[i], vm->def->disks[i], persistDisk, actions, @@ -11069,7 +10909,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, persistDisk = vm->newDef->disks[indx]; } - qemuDomainSnapshotUndoSingleDiskActive(driver, vm, cgroup, + qemuDomainSnapshotUndoSingleDiskActive(driver, vm, snap->def->dom->disks[i], vm->def->disks[i], persistDisk, @@ -11080,8 +10920,6 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver, qemuDomainObjExitMonitorWithDriver(driver, vm); cleanup: - virCgroupFree(&cgroup); - if (ret == 0 || !qemuCapsGet(priv->caps, QEMU_CAPS_TRANSACTION)) { if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0 || (persist && virDomainSaveConfig(driver->configDir, vm->newDef) < 0)) @@ -12769,7 +12607,7 @@ qemuDomainBlockPivot(virConnectPtr conn, virDomainBlockJobInfo info; const char *format = virStorageFileFormatTypeToString(disk->mirrorFormat); bool resume = false; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; char *oldsrc = NULL; int oldformat; virStorageFileMetadataPtr oldchain = NULL; @@ -12830,7 +12668,7 @@ qemuDomainBlockPivot(virConnectPtr conn, * we know for sure that there is a backing chain. */ if (disk->mirrorFormat && disk->mirrorFormat != VIR_STORAGE_FILE_RAW && qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) && - virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) < 0) { + !cgroup < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to find cgroup for %s"), vm->def->name); @@ -12895,8 +12733,6 @@ qemuDomainBlockPivot(virConnectPtr conn, disk->mirroring = false; cleanup: - if (cgroup) - virCgroupFree(&cgroup); if (resume && virDomainObjIsActive(vm) && qemuProcessStartCPUs(driver, vm, conn, VIR_DOMAIN_RUNNING_UNPAUSED, @@ -13127,7 +12963,7 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path, struct stat st; bool need_unlink = false; char *mirror = NULL; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = NULL; /* Preliminaries: find the disk we are editing, sanity checks */ virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW | @@ -13142,8 +12978,10 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path, _("domain is not running")); goto cleanup; } + + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) && - virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) < 0) { + !cgroup) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to find cgroup for %s"), vm->def->name); @@ -13250,9 +13088,9 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path, goto endjob; } - if (qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, dest, + if (qemuDomainPrepareDiskChainElement(driver, vm, disk, dest, VIR_DISK_CHAIN_READ_WRITE) < 0) { - qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, dest, + qemuDomainPrepareDiskChainElement(driver, vm, disk, dest, VIR_DISK_CHAIN_NO_ACCESS); goto endjob; } @@ -13264,7 +13102,7 @@ qemuDomainBlockCopy(virDomainPtr dom, const char *path, virDomainAuditDisk(vm, NULL, dest, "mirror", ret >= 0); qemuDomainObjExitMonitor(driver, vm); if (ret < 0) { - qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, dest, + qemuDomainPrepareDiskChainElement(driver, vm, disk, dest, VIR_DISK_CHAIN_NO_ACCESS); goto endjob; } @@ -13286,8 +13124,6 @@ endjob: } cleanup: - if (cgroup) - virCgroupFree(&cgroup); VIR_FREE(device); if (vm) virDomainObjUnlock(vm); @@ -13342,7 +13178,7 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base, virStorageFileMetadataPtr top_meta = NULL; const char *top_parent = NULL; const char *base_canon = NULL; - virCgroupPtr cgroup = NULL; + virCgroupItemPtr cgroup = NULL; bool clean_access = false; virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW, -1); @@ -13419,6 +13255,8 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base, goto endjob; } + cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; + /* For the commit to succeed, we must allow qemu to open both the * 'base' image and the parent of 'top' as read/write; 'top' might * not have a parent, or might already be read-write. XXX It @@ -13427,17 +13265,17 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base, * operation succeeds, but doing that requires tracking the * operation in XML across libvirtd restarts. */ if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES) && - virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup, 0) < 0) { + !cgroup) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Unable to find cgroup for %s"), vm->def->name); goto endjob; } clean_access = true; - if (qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, base_canon, + if (qemuDomainPrepareDiskChainElement(driver, vm, disk, base_canon, VIR_DISK_CHAIN_READ_WRITE) < 0 || (top_parent && top_parent != disk->src && - qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, + qemuDomainPrepareDiskChainElement(driver, vm, disk, top_parent, VIR_DISK_CHAIN_READ_WRITE) < 0)) goto endjob; @@ -13451,15 +13289,13 @@ qemuDomainBlockCommit(virDomainPtr dom, const char *path, const char *base, endjob: if (ret < 0 && clean_access) { /* Revert access to read-only, if possible. */ - qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, base_canon, + qemuDomainPrepareDiskChainElement(driver, vm, disk, base_canon, VIR_DISK_CHAIN_READ_ONLY); if (top_parent && top_parent != disk->src) - qemuDomainPrepareDiskChainElement(driver, vm, cgroup, disk, + qemuDomainPrepareDiskChainElement(driver, vm, disk, top_parent, VIR_DISK_CHAIN_READ_ONLY); } - if (cgroup) - virCgroupFree(&cgroup); if (qemuDomainObjEndJob(driver, vm) == 0) { vm = NULL; goto cleanup; @@ -14081,7 +13917,7 @@ cleanup: /* qemuDomainGetCPUStats() with start_cpu == -1 */ static int -qemuDomainGetTotalcpuStats(virCgroupPtr group, +qemuDomainGetTotalcpuStats(virCgroupItemPtr group, virTypedParameterPtr params, int nparams) { @@ -14143,28 +13979,24 @@ qemuDomainGetTotalcpuStats(virCgroupPtr group, * s3 = t03 + t13 */ static int -getSumVcpuPercpuStats(virCgroupPtr group, - unsigned int nvcpu, +getSumVcpuPercpuStats(virDomainObjPtr vm, unsigned long long *sum_cpu_time, unsigned int num) { int ret = -1; int i; char *buf = NULL; - virCgroupPtr group_vcpu = NULL; + virCgroupItemPtr group = NULL; + qemuDomainObjPrivatePtr priv = vm->privateData; - for (i = 0; i < nvcpu; i++) { + for (i = 0; i < priv->nvcpupids; i++) { char *pos; unsigned long long tmp; int j; - if (virCgroupForVcpu(group, i, &group_vcpu, 0) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("error accessing cgroup cpuacct for vcpu")); - goto cleanup; - } + group = vm->def->vcpuCgroups[i][VIR_CGROUP_CONTROLLER_CPUACCT]; - if (virCgroupGetCpuacctPercpuUsage(group_vcpu, &buf) < 0) + if (virCgroupGetCpuacctPercpuUsage(group, &buf) < 0) goto cleanup; pos = buf; @@ -14177,20 +14009,17 @@ getSumVcpuPercpuStats(virCgroupPtr group, sum_cpu_time[j] += tmp; } - virCgroupFree(&group_vcpu); VIR_FREE(buf); } ret = 0; cleanup: - virCgroupFree(&group_vcpu); VIR_FREE(buf); return ret; } static int qemuDomainGetPercpuStats(virDomainObjPtr vm, - virCgroupPtr group, virTypedParameterPtr params, unsigned int nparams, int start_cpu, @@ -14203,7 +14032,6 @@ qemuDomainGetPercpuStats(virDomainObjPtr vm, unsigned long long *sum_cpu_time = NULL; unsigned long long *sum_cpu_pos; unsigned int n = 0; - qemuDomainObjPrivatePtr priv = vm->privateData; virTypedParameterPtr ent; int param_idx; unsigned long long cpu_time; @@ -14230,7 +14058,8 @@ qemuDomainGetPercpuStats(virDomainObjPtr vm, } /* we get percpu cputime accounting info. */ - if (virCgroupGetCpuacctPercpuUsage(group, &buf)) + if (virCgroupGetCpuacctPercpuUsage(vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPUACCT], + &buf)) goto cleanup; pos = buf; memset(params, 0, nparams * ncpus); @@ -14270,7 +14099,7 @@ qemuDomainGetPercpuStats(virDomainObjPtr vm, virReportOOMError(); goto cleanup; } - if (getSumVcpuPercpuStats(group, priv->nvcpupids, sum_cpu_time, n) < 0) + if (getSumVcpuPercpuStats(vm, sum_cpu_time, n) < 0) goto cleanup; sum_cpu_pos = sum_cpu_time; @@ -14303,7 +14132,7 @@ qemuDomainGetCPUStats(virDomainPtr domain, unsigned int flags) { virQEMUDriverPtr driver = domain->conn->privateData; - virCgroupPtr group = NULL; + virCgroupItemPtr group = NULL; virDomainObjPtr vm = NULL; int ret = -1; bool isActive; @@ -14326,13 +14155,9 @@ qemuDomainGetCPUStats(virDomainPtr domain, goto cleanup; } - if (!qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUACCT)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cgroup CPUACCT controller is not mounted")); - goto cleanup; - } + group = vm->def->cgroup[VIR_CGROUP_CONTROLLER_CPUACCT]; - if (virCgroupForDomain(driver->cgroup, vm->def->name, &group, 0) != 0) { + if (!group) { virReportError(VIR_ERR_INTERNAL_ERROR, _("cannot find cgroup for domain %s"), vm->def->name); goto cleanup; @@ -14341,10 +14166,9 @@ qemuDomainGetCPUStats(virDomainPtr domain, if (start_cpu == -1) ret = qemuDomainGetTotalcpuStats(group, params, nparams); else - ret = qemuDomainGetPercpuStats(vm, group, params, nparams, + ret = qemuDomainGetPercpuStats(vm, params, nparams, start_cpu, ncpus); cleanup: - virCgroupFree(&group); if (vm) virDomainObjUnlock(vm); qemuDriverUnlock(driver); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 19172e1..3007f06 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1093,24 +1093,16 @@ int qemuDomainAttachHostUsbDevice(virQEMUDriverPtr driver, } if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_DEVICES)) { - virCgroupPtr cgroup = NULL; usbDevice *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 = usbGetDevice(hostdev->source.subsys.u.usb.bus, hostdev->source.subsys.u.usb.device, NULL)) == NULL) goto error; data.vm = vm; - data.cgroup = cgroup; + data.cgroup = vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]; if (usbDeviceFileIterate(usb, qemuSetupHostUsbDeviceCgroup, &data) < 0) goto error; } @@ -1981,7 +1973,6 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver, int i, ret = -1; virDomainDiskDefPtr detach = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; - virCgroupPtr cgroup = NULL; char *drivestr = NULL; i = qemuFindDisk(vm->def, dev->data.disk->dst); @@ -2001,15 +1992,6 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver, 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 (!virDomainDeviceAddressIsValid(&detach->info, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)) { virReportError(VIR_ERR_OPERATION_FAILED, "%s", @@ -2063,8 +2045,10 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver, vm->def, dev->data.disk) < 0) VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); - if (cgroup != NULL) { - if (qemuTeardownDiskCgroup(vm, cgroup, dev->data.disk) < 0) + if (vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]) { + if (qemuTeardownDiskCgroup(vm, + vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES], + dev->data.disk) < 0) VIR_WARN("Failed to teardown cgroup for disk path %s", NULLSTR(dev->data.disk->src)); } @@ -2075,7 +2059,6 @@ int qemuDomainDetachPciDiskDevice(virQEMUDriverPtr driver, ret = 0; cleanup: - virCgroupFree(&cgroup); VIR_FREE(drivestr); return ret; } @@ -2087,7 +2070,6 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, int i, ret = -1; virDomainDiskDefPtr detach = NULL; qemuDomainObjPrivatePtr priv = vm->privateData; - virCgroupPtr cgroup = NULL; char *drivestr = NULL; i = qemuFindDisk(vm->def, dev->data.disk->dst); @@ -2114,15 +2096,6 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, 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 * contain the QEMU_DRIVE_HOST_PREFIX that is passed to qemu */ if (virAsprintf(&drivestr, "%s%s", @@ -2155,8 +2128,10 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, vm->def, dev->data.disk) < 0) VIR_WARN("Unable to restore security label on %s", dev->data.disk->src); - if (cgroup != NULL) { - if (qemuTeardownDiskCgroup(vm, cgroup, dev->data.disk) < 0) + if (vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]) { + if (qemuTeardownDiskCgroup(vm, + vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES], + dev->data.disk) < 0) VIR_WARN("Failed to teardown cgroup for disk path %s", NULLSTR(dev->data.disk->src)); } @@ -2168,7 +2143,6 @@ int qemuDomainDetachDiskDevice(virQEMUDriverPtr driver, cleanup: VIR_FREE(drivestr); - virCgroupFree(&cgroup); return ret; } diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index f17c7ff..cb6f6c7 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -3590,7 +3590,6 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, enum qemuDomainAsyncJob asyncJob) { qemuDomainObjPrivatePtr priv = vm->privateData; - virCgroupPtr cgroup = NULL; int ret = -1; int rc; bool restoreLabel = false; @@ -3623,22 +3622,17 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm, * given cgroup ACL permission. We might also stumble on * a race present in some qemu versions where it does a wait() * that botches pclose. */ - 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; - } - rc = virCgroupAllowDevicePath(cgroup, path, + if (vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]) { + rc = virCgroupAllowDevicePath(vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES], + path, VIR_CGROUP_DEVICE_RW); - virDomainAuditCgroupPath(vm, cgroup, "allow", path, "rw", rc); - if (rc == 1) { - /* path was not a device, no further need for cgroup */ - virCgroupFree(&cgroup); - } else if (rc < 0) { + virDomainAuditCgroupPath(vm, + vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES], + "allow", + path, + "rw", + rc); + if (rc < 0) { virReportSystemError(-rc, _("Unable to allow device %s for %s"), path, vm->def->name); @@ -3732,14 +3726,16 @@ cleanup: vm->def, path) < 0) VIR_WARN("failed to restore save state label on %s", path); - if (cgroup != NULL) { - rc = virCgroupDenyDevicePath(cgroup, path, + if (vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES]) { + rc = virCgroupDenyDevicePath(vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES], + path, VIR_CGROUP_DEVICE_RWM); - virDomainAuditCgroupPath(vm, cgroup, "deny", path, "rwm", rc); + virDomainAuditCgroupPath(vm, + vm->def->cgroup[VIR_CGROUP_CONTROLLER_DEVICES], + "deny", path, "rwm", rc); if (rc < 0) VIR_WARN("Unable to deny device %s for %s %d", path, vm->def->name, rc); - virCgroupFree(&cgroup); } return ret; } diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 713670e..95cec7c 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2737,6 +2737,7 @@ static int qemuProcessHook(void *data) struct qemuProcessHookData *h = data; int ret = -1; int fd; + int i; /* Some later calls want pid present */ h->vm->pid = getpid(); @@ -2768,8 +2769,9 @@ static int qemuProcessHook(void *data) * memory allocation is on the correct NUMA node */ VIR_DEBUG("Moving process to cgroup"); - if (qemuAddToCgroup(h->driver, h->vm->def) < 0) - goto cleanup; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + virCgroupItemAddTask(h->vm->def->cgroup[i], getpid()); + } /* This must be done after cgroup placement to avoid resetting CPU * affinity */ @@ -3655,11 +3657,6 @@ 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(driver, vm, 1); - for (i = 0 ; i < vm->def->ngraphics; ++i) { virDomainGraphicsDefPtr graphics = vm->def->graphics[i]; if (graphics->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && @@ -4175,13 +4172,11 @@ void qemuProcessStop(virQEMUDriverPtr driver, virDomainShutoffReason reason, unsigned int flags) { - int ret; - int retries = 0; qemuDomainObjPrivatePtr priv = vm->privateData; virErrorPtr orig_err; virDomainDefPtr def; virNetDevVPortProfilePtr vport = NULL; - int i; + int i, j; int logfile = -1; char *timestamp; char ebuf[1024]; @@ -4344,14 +4339,14 @@ void qemuProcessStop(virQEMUDriverPtr driver, networkReleaseActualDevice(net); } -retry: - if ((ret = qemuRemoveCgroup(driver, vm, 0)) < 0) { - if (ret == -EBUSY && (retries++ < 5)) { - usleep(200*1000); - goto retry; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + virCgroupItemFree(vm->def->cgroup[i]); + virCgroupItemFree(vm->def->emulatorCgroup[i]); + if (vm->def->vcpuCgroups) { + for (j = 0; j < priv->nvcpupids; j++) { + virCgroupItemFree(vm->def->vcpuCgroups[j][i]); + } } - VIR_WARN("Failed to remove cgroup for %s", - vm->def->name); } qemuProcessRemoveDomainStatus(driver, vm); diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index baa0af7..c5af032 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -92,6 +92,7 @@ VIR_ONCE_GLOBAL_INIT(virCgroupItem); static struct virCgroupController cgroupControllers[VIR_CGROUP_CONTROLLER_LAST]; static virCgroupItemPtr rootCgroupItems[VIR_CGROUP_CONTROLLER_LAST]; +static virCgroupItemPtr appCgroupItems[2][VIR_CGROUP_CONTROLLER_LAST]; static virCgroupItemPtr virCgroupItemRootNew(int type); static int virCgroupDetectMounts(struct virCgroupController (*controllers)[VIR_CGROUP_CONTROLLER_LAST]); @@ -149,13 +150,21 @@ void virCgroupUninit(void) virCgroupItemFree(rootCgroupItems[i]); rootCgroupItems[i] = NULL; } + if (appCgroupItems[0][i]) { + virCgroupItemFree(appCgroupItems[0][i]); + appCgroupItems[0][i] = NULL; + } + if (appCgroupItems[1][i]) { + virCgroupItemFree(appCgroupItems[1][i]); + appCgroupItems[1][i] = NULL; + } } } -struct virCgroup { - char *path; +struct _virCgroup { + char *name; - struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; + virCgroupItemPtr items[VIR_CGROUP_CONTROLLER_LAST]; }; typedef enum { @@ -236,9 +245,6 @@ virCgroupItemPtr virCgroupItemNew(int type, return NULL; if (!parent) - parent = rootCgroupItems[type]; - - if (!parent) return NULL; cgroupItem = virCgroupHasChildByName(parent, name); @@ -406,6 +412,7 @@ static int virCgroupItemCpusetInherit(virCgroupItemPtr cgroupItem) } static int virCgroupRemoveRecursively(char *grppath); +static int virCgroupItemSetMemoryUseHierarchy(virCgroupItemPtr group); static int virCgroupItemMakePath(virCgroupItemPtr cgroupItem) { @@ -430,7 +437,11 @@ static int virCgroupItemMakePath(virCgroupItemPtr cgroupItem) return -errno; } - virCgroupItemCpusetInherit(cgroupItem); + if (cgroupItem->controller->type == VIR_CGROUP_CONTROLLER_CPUSET) + virCgroupItemCpusetInherit(cgroupItem); + + if (cgroupItem->controller->type == VIR_CGROUP_CONTROLLER_MEMORY) + virCgroupItemSetMemoryUseHierarchy(cgroupItem); } return ret; @@ -470,27 +481,6 @@ int virCgroupItemKeyPath(virCgroupItemPtr cgroupItem, } /** - * virCgroupFree: - * - * @group: The group structure to free - */ -void virCgroupFree(virCgroupPtr *group) -{ - int i; - - if (*group == NULL) - return; - - for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { - VIR_FREE((*group)->controllers[i].mountPoint); - VIR_FREE((*group)->controllers[i].placement); - } - - VIR_FREE((*group)->path); - VIR_FREE(*group); -} - -/** * virCgroupMounted: query whether a cgroup subsystem is mounted or not * * @cgroup: The group structure to be queried @@ -498,9 +488,9 @@ void virCgroupFree(virCgroupPtr *group) * * Returns true if a cgroup is subsystem is mounted. */ -bool virCgroupMounted(virCgroupPtr cgroup, int controller) +bool virCgroupMounted(int controller) { - return cgroup->controllers[controller].mountPoint != NULL; + return cgroupControllers[controller].mountPoint != NULL; } #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R @@ -627,54 +617,6 @@ no_memory: } -static int virCgroupDetect(virCgroupPtr group) -{ - int any = 0; - int rc; - int i; - - rc = virCgroupDetectMounts(&group->controllers); - if (rc < 0) { - VIR_ERROR(_("Failed to detect mounts for %s"), group->path); - return rc; - } - - /* Check that at least 1 controller is available */ - for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { - if (group->controllers[i].mountPoint != NULL) - any = 1; - } - if (!any) - return -ENXIO; - - - rc = virCgroupDetectPlacement(&group->controllers); - - if (rc == 0) { - /* Check that for every mounted controller, we found our placement */ - for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { - if (!group->controllers[i].mountPoint) - continue; - - if (!group->controllers[i].placement) { - VIR_ERROR(_("Could not find placement for controller %s at %s"), - virCgroupControllerTypeToString(i), - group->controllers[i].placement); - rc = -ENOENT; - break; - } - - VIR_DEBUG("Detected mount/mapping %i:%s at %s in %s", i, - virCgroupControllerTypeToString(i), - group->controllers[i].mountPoint, - group->controllers[i].placement); - } - } else { - VIR_ERROR(_("Failed to detect mapping for %s"), group->path); - } - - return rc; -} #endif @@ -683,99 +625,10 @@ int virCgroupPathOfController(virCgroupPtr group, const char *key, char **path) { - if (controller == -1) { - int i; - for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { - if (group->controllers[i].mountPoint && - group->controllers[i].placement) { - controller = i; - break; - } - } - } - if (controller == -1) - return -ENOSYS; - - if (group->controllers[controller].mountPoint == NULL) - return -ENOENT; - - if (group->controllers[controller].placement == NULL) - return -ENOENT; - - if (virAsprintf(path, "%s%s%s/%s", - group->controllers[controller].mountPoint, - group->controllers[controller].placement, - STREQ(group->path, "/") ? "" : group->path, - key ? key : "") == -1) - return -ENOMEM; - - return 0; -} - - -static int virCgroupSetValueStr(virCgroupPtr group, - int controller, - const char *key, - const char *value) -{ - int rc = 0; - char *keypath = NULL; - - rc = virCgroupPathOfController(group, controller, key, &keypath); - if (rc != 0) - return rc; - - VIR_DEBUG("Set value '%s' to '%s'", keypath, value); - rc = virFileWriteStr(keypath, value, 0); - if (rc < 0) { - rc = -errno; - VIR_DEBUG("Failed to write value '%s': %m", value); - } else { - rc = 0; - } - - VIR_FREE(keypath); - - return rc; -} - -static int virCgroupGetValueStr(virCgroupPtr group, - int controller, - const char *key, - char **value) -{ - int rc; - char *keypath = NULL; - - *value = NULL; - - rc = virCgroupPathOfController(group, controller, key, &keypath); - if (rc != 0) { - VIR_DEBUG("No path of %s, %s", group->path, key); - return rc; - } - - VIR_DEBUG("Get value %s", keypath); - - rc = virFileReadAll(keypath, 1024*1024, value); - if (rc < 0) { - rc = -errno; - VIR_DEBUG("Failed to read %s: %m\n", keypath); - } else { - /* Terminated with '\n' has sometimes harmful effects to the caller */ - if ((*value)[rc - 1] == '\n') - (*value)[rc - 1] = '\0'; - - rc = 0; - } - - VIR_FREE(keypath); - - return rc; + return virCgroupItemKeyPath(group->items[controller], key, path); } -static int virCgroupSetValueU64(virCgroupPtr group, - int controller, +static int virCgroupItemSetValueU64(virCgroupItemPtr group, const char *key, unsigned long long int value) { @@ -785,17 +638,14 @@ static int virCgroupSetValueU64(virCgroupPtr group, if (virAsprintf(&strval, "%llu", value) == -1) return -ENOMEM; - rc = virCgroupSetValueStr(group, controller, key, strval); + rc = virCgroupItemSetValueStr(group, key, strval); VIR_FREE(strval); return rc; } - - -static int virCgroupSetValueI64(virCgroupPtr group, - int controller, +static int virCgroupItemSetValueI64(virCgroupItemPtr group, const char *key, long long int value) { @@ -805,22 +655,21 @@ static int virCgroupSetValueI64(virCgroupPtr group, if (virAsprintf(&strval, "%lld", value) == -1) return -ENOMEM; - rc = virCgroupSetValueStr(group, controller, key, strval); + rc = virCgroupItemSetValueStr(group, key, strval); VIR_FREE(strval); return rc; } -static int virCgroupGetValueI64(virCgroupPtr group, - int controller, +static int virCgroupItemGetValueI64(virCgroupItemPtr group, const char *key, long long int *value) { char *strval = NULL; int rc = 0; - rc = virCgroupGetValueStr(group, controller, key, &strval); + rc = virCgroupItemGetValueStr(group, key, &strval); if (rc != 0) goto out; @@ -832,15 +681,14 @@ out: return rc; } -static int virCgroupGetValueU64(virCgroupPtr group, - int controller, - const char *key, - unsigned long long int *value) +static int virCgroupItemGetValueU64(virCgroupItemPtr group, + const char *key, + unsigned long long int *value) { char *strval = NULL; int rc = 0; - rc = virCgroupGetValueStr(group, controller, key, &strval); + rc = virCgroupItemGetValueStr(group, key, &strval); if (rc != 0) goto out; @@ -852,58 +700,16 @@ out: return rc; } - -#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -static int virCgroupCpuSetInherit(virCgroupPtr parent, virCgroupPtr group) -{ - int i; - int rc = 0; - const char *inherit_values[] = { - "cpuset.cpus", - "cpuset.mems", - }; - - VIR_DEBUG("Setting up inheritance %s -> %s", parent->path, group->path); - for (i = 0; i < ARRAY_CARDINALITY(inherit_values) ; i++) { - char *value; - - rc = virCgroupGetValueStr(parent, - VIR_CGROUP_CONTROLLER_CPUSET, - inherit_values[i], - &value); - if (rc != 0) { - VIR_ERROR(_("Failed to get %s %d"), inherit_values[i], rc); - break; - } - - VIR_DEBUG("Inherit %s = %s", inherit_values[i], value); - - rc = virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_CPUSET, - inherit_values[i], - value); - VIR_FREE(value); - - if (rc != 0) { - VIR_ERROR(_("Failed to set %s %d"), inherit_values[i], rc); - break; - } - } - - return rc; -} - -static int virCgroupSetMemoryUseHierarchy(virCgroupPtr group) +static int virCgroupItemSetMemoryUseHierarchy(virCgroupItemPtr item) { int rc = 0; unsigned long long value; const char *filename = "memory.use_hierarchy"; - rc = virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - filename, &value); + rc = virCgroupItemGetValueU64(item, + filename, &value); if (rc != 0) { - VIR_ERROR(_("Failed to read %s/%s (%d)"), group->path, filename, rc); + VIR_ERROR(_("Failed to read %s/%s (%d)"), item->path, filename, rc); return rc; } @@ -911,109 +717,24 @@ static int virCgroupSetMemoryUseHierarchy(virCgroupPtr group) if (value == 1) return 0; - VIR_DEBUG("Setting up %s/%s", group->path, filename); - rc = virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - filename, 1); + VIR_DEBUG("Setting up %s/%s", item->path, filename); + rc = virCgroupItemSetValueU64(item, + filename, 1); if (rc != 0) { - VIR_ERROR(_("Failed to set %s/%s (%d)"), group->path, filename, rc); - } - - return rc; -} - -static int virCgroupMakeGroup(virCgroupPtr parent, - virCgroupPtr group, - bool create, - unsigned int flags) -{ - int i; - int rc = 0; - - VIR_DEBUG("Make group %s", group->path); - for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { - char *path = NULL; - - /* Skip over controllers that aren't mounted */ - if (!group->controllers[i].mountPoint) - continue; - - /* We need to control cpu bandwidth for each vcpu now */ - if ((flags & VIR_CGROUP_VCPU) && - (i != VIR_CGROUP_CONTROLLER_CPU && - i != VIR_CGROUP_CONTROLLER_CPUACCT && - i != VIR_CGROUP_CONTROLLER_CPUSET)) { - /* treat it as unmounted and we can use virCgroupAddTask */ - VIR_FREE(group->controllers[i].mountPoint); - continue; - } - - rc = virCgroupPathOfController(group, i, "", &path); - if (rc < 0) - return rc; - /* As of Feb 2011, clang can't see that the above function - * call did not modify group. */ - sa_assert(group->controllers[i].mountPoint); - - VIR_DEBUG("Make controller %s", path); - if (access(path, F_OK) != 0) { - if (!create || - mkdir(path, 0755) < 0) { - /* With a kernel that doesn't support multi-level directory - * for blkio controller, libvirt will fail and disable all - * other controllers even though they are available. So - * treat blkio as unmounted if mkdir fails. */ - if (i == VIR_CGROUP_CONTROLLER_BLKIO) { - rc = 0; - VIR_FREE(group->controllers[i].mountPoint); - VIR_FREE(path); - continue; - } else { - rc = -errno; - VIR_FREE(path); - break; - } - } - if (group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint != NULL && - (i == VIR_CGROUP_CONTROLLER_CPUSET || - STREQ(group->controllers[i].mountPoint, group->controllers[VIR_CGROUP_CONTROLLER_CPUSET].mountPoint))) { - rc = virCgroupCpuSetInherit(parent, group); - if (rc != 0) { - VIR_FREE(path); - break; - } - } - /* - * Note that virCgroupSetMemoryUseHierarchy should always be - * called prior to creating subcgroups and attaching tasks. - */ - if ((flags & VIR_CGROUP_MEM_HIERACHY) && - (group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint != NULL) && - (i == VIR_CGROUP_CONTROLLER_MEMORY || - STREQ(group->controllers[i].mountPoint, group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint))) { - rc = virCgroupSetMemoryUseHierarchy(group); - if (rc != 0) { - VIR_FREE(path); - break; - } - } - } - - VIR_FREE(path); + VIR_ERROR(_("Failed to set %s/%s (%d)"), item->path, filename, rc); } return rc; } - -static int virCgroupNew(const char *path, - virCgroupPtr *group) +int virCgroupNew(const char *name, + virCgroupPtr parent, + virCgroupPtr *group) { int rc = 0; - char *typpath = NULL; + int i; - VIR_DEBUG("New group %s", path); *group = NULL; if (VIR_ALLOC((*group)) != 0) { @@ -1021,66 +742,48 @@ static int virCgroupNew(const char *path, goto err; } - if (!((*group)->path = strdup(path))) { + if (!((*group)->name = strdup(name))) { rc = -ENOMEM; goto err; } - rc = virCgroupDetect(*group); - if (rc < 0) - goto err; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) + (*group)->items[i] = virCgroupItemNew(i, name, parent->items[i]); return rc; err: - virCgroupFree(group); + VIR_FREE(*group); *group = NULL; - VIR_FREE(typpath); - return rc; } -static int virCgroupAppRoot(bool privileged, - virCgroupPtr *group, - bool create) +/** + * virCgroupFree: + * + * @group: The group to be removed + * + * fre @group and its cgroup items. + * + */ +void virCgroupFree(virCgroupPtr *group) { - virCgroupPtr rootgrp = NULL; - int rc; + int i; - rc = virCgroupNew("/", &rootgrp); - if (rc != 0) - return rc; + if (!group) + return; - if (privileged) { - rc = virCgroupNew("/libvirt", group); - } else { - char *rootname; - char *username; - username = virGetUserName(getuid()); - if (!username) { - rc = -ENOMEM; - goto cleanup; - } - rc = virAsprintf(&rootname, "/libvirt-%s", username); - VIR_FREE(username); - if (rc < 0) { - rc = -ENOMEM; - goto cleanup; - } + if (!*group) + return; - rc = virCgroupNew(rootname, group); - VIR_FREE(rootname); - } - if (rc != 0) - goto cleanup; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) + virCgroupItemFree((*group)->items[i]); - rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE); + VIR_FREE((*group)->name); + VIR_FREE(*group); -cleanup: - virCgroupFree(&rootgrp); - return rc; + return; } -#endif #if defined _DIRENT_HAVE_D_TYPE static int virCgroupRemoveRecursively(char *grppath) @@ -1140,93 +843,22 @@ static int virCgroupRemoveRecursively(char *grppath ATTRIBUTE_UNUSED) #endif /** - * virCgroupRemove: - * - * @group: The group to be removed - * - * It first removes all child groups recursively - * in depth first order and then removes @group - * because the presence of the child groups - * prevents removing @group. + * virCgroupItemAddTask: * - * Returns: 0 on success - */ -int virCgroupRemove(virCgroupPtr group) -{ - int rc = 0; - int i; - char *grppath = NULL; - - for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { - /* Skip over controllers not mounted */ - if (!group->controllers[i].mountPoint) - continue; - - if (virCgroupPathOfController(group, - i, - NULL, - &grppath) != 0) - continue; - - VIR_DEBUG("Removing cgroup %s and all child cgroups", grppath); - rc = virCgroupRemoveRecursively(grppath); - VIR_FREE(grppath); - } - - return rc; -} - -/** - * virCgroupAddTask: - * - * @group: The cgroup to add a task to + * @item: The cgroup item to add a task to * @pid: The pid of the task to add * * Returns: 0 on success */ -int virCgroupAddTask(virCgroupPtr group, pid_t pid) -{ - int rc = 0; - int i; - - for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { - /* Skip over controllers not mounted */ - if (!group->controllers[i].mountPoint) - continue; - - rc = virCgroupSetValueU64(group, i, "tasks", (unsigned long long)pid); - if (rc != 0) - break; - } - - return rc; -} - -/** - * virCgroupAddTaskController: - * - * @group: The cgroup to add a task to - * @pid: The pid of the task to add - * @controller: The cgroup controller to be operated on - * - * Returns: 0 on success or -errno on failure - */ -int virCgroupAddTaskController(virCgroupPtr group, pid_t pid, int controller) +int virCgroupItemAddTask(virCgroupItemPtr item, pid_t pid) { - if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST) - return -EINVAL; - - if (!group->controllers[controller].mountPoint) - return -EINVAL; - - return virCgroupSetValueU64(group, controller, "tasks", - (unsigned long long)pid); + return virCgroupItemSetValueU64(item, "tasks", + (unsigned long long)pid); } -static int virCgroupAddTaskStrController(virCgroupPtr group, - const char *pidstr, - int controller) +static int virCgroupItemAddTaskStr(virCgroupItemPtr item, + const char *pidstr) { char *str = NULL, *cur = NULL, *next = NULL; unsigned long long p = 0; @@ -1242,7 +874,7 @@ static int virCgroupAddTaskStrController(virCgroupPtr group, if (rc != 0) goto cleanup; - rc = virCgroupAddTaskController(group, p, controller); + rc = virCgroupItemAddTask(item, p); if (rc != 0) goto cleanup; @@ -1261,35 +893,23 @@ cleanup: } /** - * virCgroupMoveTask: + * virCgroupItemMoveTask: * - * @src_group: The source cgroup where all tasks are removed from - * @dest_group: The destination where all tasks are added to - * @controller: The cgroup controller to be operated on + * @src: The source cgroup where all tasks are removed from + * @dest: The destination where all tasks are added to * * Returns: 0 on success or -errno on failure */ -int virCgroupMoveTask(virCgroupPtr src_group, virCgroupPtr dest_group, - int controller) +int virCgroupItemMoveTask(virCgroupItemPtr src, virCgroupItemPtr dest) { int rc = 0, err = 0; char *content = NULL; - if (controller < VIR_CGROUP_CONTROLLER_CPU || - controller > VIR_CGROUP_CONTROLLER_BLKIO) - return -EINVAL; - - if (!src_group->controllers[controller].mountPoint || - !dest_group->controllers[controller].mountPoint) { - VIR_WARN("no vm cgroup in controller %d", controller); - return 0; - } - - rc = virCgroupGetValueStr(src_group, controller, "tasks", &content); + rc = virCgroupItemGetValueStr(src, "tasks", &content); if (rc != 0) return rc; - rc = virCgroupAddTaskStrController(dest_group, content, controller); + rc = virCgroupItemAddTaskStr(dest, content); if (rc != 0) goto cleanup; @@ -1302,229 +922,56 @@ cleanup: * We don't need to recover dest_cgroup because cgroup will make sure * that one task only resides in one cgroup of the same controller. */ - err = virCgroupAddTaskStrController(src_group, content, controller); + err = virCgroupItemAddTaskStr(src, content); if (err != 0) VIR_ERROR(_("Cannot recover cgroup %s from %s"), - src_group->controllers[controller].mountPoint, - dest_group->controllers[controller].mountPoint); + src->path, + dest->path); VIR_FREE(content); return rc; } /** - * virCgroupForDriver: - * - * @name: name of this driver (e.g., xen, qemu, lxc) - * @group: Pointer to returned virCgroupPtr - * - * Returns 0 on success - */ -#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -int virCgroupForDriver(const char *name, - virCgroupPtr *group, - bool privileged, - bool create) -{ - int rc; - char *path = NULL; - virCgroupPtr rootgrp = NULL; - - rc = virCgroupAppRoot(privileged, &rootgrp, create); - if (rc != 0) - goto out; - - if (virAsprintf(&path, "%s/%s", rootgrp->path, name) < 0) { - rc = -ENOMEM; - goto out; - } - - rc = virCgroupNew(path, group); - VIR_FREE(path); - - if (rc == 0) { - rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE); - if (rc != 0) - virCgroupFree(group); - } - -out: - virCgroupFree(&rootgrp); - - return rc; -} -#else -int virCgroupForDriver(const char *name ATTRIBUTE_UNUSED, - virCgroupPtr *group ATTRIBUTE_UNUSED, - bool privileged ATTRIBUTE_UNUSED, - bool create ATTRIBUTE_UNUSED) -{ - /* Claim no support */ - return -ENXIO; -} -#endif - -/** * virCgroupGetAppRoot: * -* @group: Pointer to returned virCgroupPtr +* @type: the type of app cgroup item * -* Returns 0 on success +* Returns the app cgroup item of type, or NULL on error */ -#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -int virCgroupGetAppRoot(virCgroupPtr *group) -{ - return virCgroupNew("/", group); -} -#else -int virCgroupGetAppRoot(virCgroupPtr *group ATTRIBUTE_UNUSED) -{ - return -ENXIO; -} -#endif - -/** - * virCgroupForDomain: - * - * @driver: group for driver owning the domain - * @name: name of the domain - * @group: Pointer to returned virCgroupPtr - * - * Returns 0 on success - */ -#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -int virCgroupForDomain(virCgroupPtr driver, - const char *name, - virCgroupPtr *group, - bool create) +virCgroupItemPtr virCgroupGetAppRoot(int type, bool privileged) { + int p = privileged ? 1 : 0; + char *name; + char *userName; int rc; - char *path; - - if (driver == NULL) - return -EINVAL; - - if (virAsprintf(&path, "%s/%s", driver->path, name) < 0) - return -ENOMEM; - - rc = virCgroupNew(path, group); - VIR_FREE(path); - - if (rc == 0) { - /* - * Create a cgroup with memory.use_hierarchy enabled to - * surely account memory usage of lxc with ns subsystem - * enabled. (To be exact, memory and ns subsystems are - * enabled at the same time.) - * - * The reason why doing it here, not a upper group, say - * a group for driver, is to avoid overhead to track - * cumulative usage that we don't need. - */ - rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_MEM_HIERACHY); - if (rc != 0) - virCgroupFree(group); - } - - return rc; -} -#else -int virCgroupForDomain(virCgroupPtr driver ATTRIBUTE_UNUSED, - const char *name ATTRIBUTE_UNUSED, - virCgroupPtr *group ATTRIBUTE_UNUSED, - bool create ATTRIBUTE_UNUSED) -{ - return -ENXIO; -} -#endif -/** - * virCgroupForVcpu: - * - * @driver: group for the domain - * @vcpuid: id of the vcpu - * @group: Pointer to returned virCgroupPtr - * - * Returns 0 on success - */ -#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -int virCgroupForVcpu(virCgroupPtr driver, - int vcpuid, - virCgroupPtr *group, - bool create) -{ - int rc; - char *path; - - if (driver == NULL) - return -EINVAL; - - if (virAsprintf(&path, "%s/vcpu%d", driver->path, vcpuid) < 0) - return -ENOMEM; + if (type < 0 || type >= VIR_CGROUP_CONTROLLER_LAST) + return NULL; - rc = virCgroupNew(path, group); - VIR_FREE(path); + if (virCgroupItemInitialize() < 0) + return NULL; - if (rc == 0) { - rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_VCPU); - if (rc != 0) - virCgroupFree(group); + if (privileged) { + rc = virAsprintf(&name, "libvirt"); + } else { + userName = virGetUserName(getuid()); + if (!userName) + return NULL; + rc = virAsprintf(&name, "libvirt-%s", userName); + VIR_FREE(userName); } - return rc; -} -#else -int virCgroupForVcpu(virCgroupPtr driver ATTRIBUTE_UNUSED, - int vcpuid ATTRIBUTE_UNUSED, - virCgroupPtr *group ATTRIBUTE_UNUSED, - bool create ATTRIBUTE_UNUSED) -{ - return -ENXIO; -} -#endif - -/** - * virCgroupForEmulator: - * - * @driver: group for the domain - * @group: Pointer to returned virCgroupPtr - * - * Returns: 0 on success or -errno on failure - */ -#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -int virCgroupForEmulator(virCgroupPtr driver, - virCgroupPtr *group, - bool create) -{ - int rc; - char *path; - - if (driver == NULL) - return -EINVAL; - - if (virAsprintf(&path, "%s/emulator", driver->path) < 0) - return -ENOMEM; - - rc = virCgroupNew(path, group); - VIR_FREE(path); + if (rc < 0) + return NULL; - if (rc == 0) { - rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_VCPU); - if (rc != 0) - virCgroupFree(group); - } + if (!appCgroupItems[p][type]) + appCgroupItems[p][type] = virCgroupItemNew(type, name, + rootCgroupItems[type]); - return rc; -} -#else -int virCgroupForEmulator(virCgroupPtr driver ATTRIBUTE_UNUSED, - virCgroupPtr *group ATTRIBUTE_UNUSED, - bool create ATTRIBUTE_UNUSED) -{ - return -ENXIO; + return appCgroupItems[p][type]; } -#endif /** * virCgroupSetBlkioWeight: * @@ -1533,15 +980,16 @@ int virCgroupForEmulator(virCgroupPtr driver ATTRIBUTE_UNUSED, * * Returns: 0 on success */ -int virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight) +int virCgroupSetBlkioWeight(virCgroupItemPtr group, unsigned int weight) { if (weight > 1000 || weight < 100) return -EINVAL; - return virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_BLKIO, - "blkio.weight", - weight); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_BLKIO); + + return virCgroupItemSetValueU64(group, + "blkio.weight", + weight); } /** @@ -1552,13 +1000,15 @@ int virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight) * * Returns: 0 on success */ -int virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight) +int virCgroupGetBlkioWeight(virCgroupItemPtr group, unsigned int *weight) { unsigned long long tmp; int ret; - ret = virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_BLKIO, - "blkio.weight", &tmp); + + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_BLKIO); + + ret = virCgroupItemGetValueU64(group, + "blkio.weight", &tmp); if (ret == 0) *weight = tmp; return ret; @@ -1577,7 +1027,7 @@ int virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight) * Returns: 0 on success, -errno on failure */ #if defined(major) && defined(minor) -int virCgroupSetBlkioDeviceWeight(virCgroupPtr group, +int virCgroupSetBlkioDeviceWeight(virCgroupItemPtr group, const char *path, unsigned int weight) { @@ -1585,6 +1035,8 @@ int virCgroupSetBlkioDeviceWeight(virCgroupPtr group, struct stat sb; int ret; + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_BLKIO); + if (weight && (weight > 1000 || weight < 100)) return -EINVAL; @@ -1598,10 +1050,9 @@ int virCgroupSetBlkioDeviceWeight(virCgroupPtr group, weight) < 0) return -errno; - ret = virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_BLKIO, - "blkio.weight_device", - str); + ret = virCgroupItemSetValueStr(group, + "blkio.weight_device", + str); VIR_FREE(str); return ret; } @@ -1623,22 +1074,22 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group ATTRIBUTE_UNUSED, * * Returns: 0 on success */ -int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb) +int virCgroupSetMemory(virCgroupItemPtr group, unsigned long long kb) { unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_MEMORY); + if (kb > maxkb) return -EINVAL; else if (kb == maxkb) - return virCgroupSetValueI64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.limit_in_bytes", - -1); + return virCgroupItemSetValueI64(group, + "memory.limit_in_bytes", + -1); else - return virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.limit_in_bytes", - kb << 10); + return virCgroupItemSetValueU64(group, + "memory.limit_in_bytes", + kb << 10); } /** @@ -1649,13 +1100,15 @@ int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb) * * Returns: 0 on success */ -int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) +int virCgroupGetMemoryUsage(virCgroupItemPtr group, unsigned long *kb) { long long unsigned int usage_in_bytes; int ret; - ret = virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.usage_in_bytes", &usage_in_bytes); + + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_MEMORY); + + ret = virCgroupItemGetValueU64(group, + "memory.usage_in_bytes", &usage_in_bytes); if (ret == 0) *kb = (unsigned long) usage_in_bytes >> 10; return ret; @@ -1669,7 +1122,7 @@ int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb) * * Returns: 0 on success */ -int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) +int virCgroupSetMemoryHardLimit(virCgroupItemPtr group, unsigned long long kb) { return virCgroupSetMemory(group, kb); } @@ -1682,13 +1135,15 @@ int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb) * * Returns: 0 on success */ -int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) +int virCgroupGetMemoryHardLimit(virCgroupItemPtr group, unsigned long long *kb) { long long unsigned int limit_in_bytes; int ret; - ret = virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.limit_in_bytes", &limit_in_bytes); + + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_MEMORY); + + ret = virCgroupItemGetValueU64(group, + "memory.limit_in_bytes", &limit_in_bytes); if (ret == 0) *kb = limit_in_bytes >> 10; return ret; @@ -1702,22 +1157,22 @@ int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb) * * Returns: 0 on success */ -int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) +int virCgroupSetMemorySoftLimit(virCgroupItemPtr group, unsigned long long kb) { unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_MEMORY); + if (kb > maxkb) return -EINVAL; else if (kb == maxkb) - return virCgroupSetValueI64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.soft_limit_in_bytes", - -1); + return virCgroupItemSetValueI64(group, + "memory.soft_limit_in_bytes", + -1); else - return virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.soft_limit_in_bytes", - kb << 10); + return virCgroupItemSetValueU64(group, + "memory.soft_limit_in_bytes", + kb << 10); } @@ -1729,13 +1184,15 @@ int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb) * * Returns: 0 on success */ -int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) +int virCgroupGetMemorySoftLimit(virCgroupItemPtr group, unsigned long long *kb) { long long unsigned int limit_in_bytes; int ret; - ret = virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.soft_limit_in_bytes", &limit_in_bytes); + + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_MEMORY); + + ret = virCgroupItemGetValueU64(group, + "memory.soft_limit_in_bytes", &limit_in_bytes); if (ret == 0) *kb = limit_in_bytes >> 10; return ret; @@ -1749,22 +1206,22 @@ int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb) * * Returns: 0 on success */ -int virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) +int virCgroupSetMemSwapHardLimit(virCgroupItemPtr group, unsigned long long kb) { unsigned long long maxkb = VIR_DOMAIN_MEMORY_PARAM_UNLIMITED; + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_MEMORY); + if (kb > maxkb) return -EINVAL; else if (kb == maxkb) - return virCgroupSetValueI64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.memsw.limit_in_bytes", - -1); + return virCgroupItemSetValueI64(group, + "memory.memsw.limit_in_bytes", + -1); else - return virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.memsw.limit_in_bytes", - kb << 10); + return virCgroupItemSetValueU64(group, + "memory.memsw.limit_in_bytes", + kb << 10); } /** @@ -1775,13 +1232,15 @@ int virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb) * * Returns: 0 on success */ -int virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) +int virCgroupGetMemSwapHardLimit(virCgroupItemPtr group, unsigned long long *kb) { long long unsigned int limit_in_bytes; int ret; - ret = virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.memsw.limit_in_bytes", &limit_in_bytes); + + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_MEMORY); + + ret = virCgroupItemGetValueU64(group, + "memory.memsw.limit_in_bytes", &limit_in_bytes); if (ret == 0) *kb = limit_in_bytes >> 10; return ret; @@ -1795,13 +1254,15 @@ int virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb) * * Returns: 0 on success */ -int virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb) +int virCgroupGetMemSwapUsage(virCgroupItemPtr group, unsigned long long *kb) { long long unsigned int usage_in_bytes; int ret; - ret = virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - "memory.memsw.usage_in_bytes", &usage_in_bytes); + + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_MEMORY); + + ret = virCgroupItemGetValueU64(group, + "memory.memsw.usage_in_bytes", &usage_in_bytes); if (ret == 0) *kb = usage_in_bytes >> 10; return ret; @@ -1815,12 +1276,13 @@ int virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb) * * Returns: 0 on success */ -int virCgroupSetCpusetMems(virCgroupPtr group, const char *mems) +int virCgroupSetCpusetMems(virCgroupItemPtr group, const char *mems) { - return virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_CPUSET, - "cpuset.mems", - mems); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPUSET); + + return virCgroupItemSetValueStr(group, + "cpuset.mems", + mems); } /** @@ -1831,12 +1293,13 @@ int virCgroupSetCpusetMems(virCgroupPtr group, const char *mems) * * Returns: 0 on success */ -int virCgroupGetCpusetMems(virCgroupPtr group, char **mems) +int virCgroupGetCpusetMems(virCgroupItemPtr group, char **mems) { - return virCgroupGetValueStr(group, - VIR_CGROUP_CONTROLLER_CPUSET, - "cpuset.mems", - mems); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPUSET); + + return virCgroupItemGetValueStr(group, + "cpuset.mems", + mems); } /** @@ -1847,12 +1310,13 @@ int virCgroupGetCpusetMems(virCgroupPtr group, char **mems) * * Retuens: 0 on success */ -int virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus) +int virCgroupSetCpusetCpus(virCgroupItemPtr group, const char *cpus) { - return virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_CPUSET, - "cpuset.cpus", - cpus); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPUSET); + + return virCgroupItemSetValueStr(group, + "cpuset.cpus", + cpus); } /** @@ -1863,10 +1327,11 @@ int virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus) * * Retuens: 0 on success */ -int virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus) +int virCgroupGetCpusetCpus(virCgroupItemPtr group, char **cpus) { - return virCgroupGetValueStr(group, - VIR_CGROUP_CONTROLLER_CPUSET, + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPUSET); + + return virCgroupItemGetValueStr(group, "cpuset.cpus", cpus); } @@ -1878,12 +1343,13 @@ int virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus) * * Returns: 0 on success */ -int virCgroupDenyAllDevices(virCgroupPtr group) +int virCgroupDenyAllDevices(virCgroupItemPtr group) { - return virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_DEVICES, - "devices.deny", - "a"); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_DEVICES); + + return virCgroupItemSetValueStr(group, + "devices.deny", + "a"); } /** @@ -1897,12 +1363,14 @@ int virCgroupDenyAllDevices(virCgroupPtr group) * * Returns: 0 on success */ -int virCgroupAllowDevice(virCgroupPtr group, char type, int major, int minor, +int virCgroupAllowDevice(virCgroupItemPtr group, char type, int major, int minor, int perms) { int rc; char *devstr = NULL; + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_DEVICES); + if (virAsprintf(&devstr, "%c %i:%i %s%s%s", type, major, minor, perms & VIR_CGROUP_DEVICE_READ ? "r" : "", perms & VIR_CGROUP_DEVICE_WRITE ? "w" : "", @@ -1911,10 +1379,9 @@ int virCgroupAllowDevice(virCgroupPtr group, char type, int major, int minor, goto out; } - rc = virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_DEVICES, - "devices.allow", - devstr); + rc = virCgroupItemSetValueStr(group, + "devices.allow", + devstr); out: VIR_FREE(devstr); @@ -1931,12 +1398,14 @@ out: * * Returns: 0 on success */ -int virCgroupAllowDeviceMajor(virCgroupPtr group, char type, int major, +int virCgroupAllowDeviceMajor(virCgroupItemPtr group, char type, int major, int perms) { int rc; char *devstr = NULL; + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_DEVICES); + if (virAsprintf(&devstr, "%c %i:* %s%s%s", type, major, perms & VIR_CGROUP_DEVICE_READ ? "r" : "", perms & VIR_CGROUP_DEVICE_WRITE ? "w" : "", @@ -1945,10 +1414,9 @@ int virCgroupAllowDeviceMajor(virCgroupPtr group, char type, int major, goto out; } - rc = virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_DEVICES, - "devices.allow", - devstr); + rc = virCgroupItemSetValueStr(group, + "devices.allow", + devstr); out: VIR_FREE(devstr); @@ -1969,7 +1437,7 @@ int virCgroupAllowDeviceMajor(virCgroupPtr group, char type, int major, * negative errno value on failure */ #if defined(major) && defined(minor) -int virCgroupAllowDevicePath(virCgroupPtr group, const char *path, int perms) +int virCgroupAllowDevicePath(virCgroupItemPtr group, const char *path, int perms) { struct stat sb; @@ -1986,7 +1454,7 @@ int virCgroupAllowDevicePath(virCgroupPtr group, const char *path, int perms) perms); } #else -int virCgroupAllowDevicePath(virCgroupPtr group ATTRIBUTE_UNUSED, +int virCgroupAllowDevicePath(virCgroupItemPtr group ATTRIBUTE_UNUSED, const char *path ATTRIBUTE_UNUSED, int perms ATTRIBUTE_UNUSED) { @@ -2006,12 +1474,14 @@ int virCgroupAllowDevicePath(virCgroupPtr group ATTRIBUTE_UNUSED, * * Returns: 0 on success */ -int virCgroupDenyDevice(virCgroupPtr group, char type, int major, int minor, +int virCgroupDenyDevice(virCgroupItemPtr group, char type, int major, int minor, int perms) { int rc; char *devstr = NULL; + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_DEVICES); + if (virAsprintf(&devstr, "%c %i:%i %s%s%s", type, major, minor, perms & VIR_CGROUP_DEVICE_READ ? "r" : "", perms & VIR_CGROUP_DEVICE_WRITE ? "w" : "", @@ -2020,10 +1490,9 @@ int virCgroupDenyDevice(virCgroupPtr group, char type, int major, int minor, goto out; } - rc = virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_DEVICES, - "devices.deny", - devstr); + rc = virCgroupItemSetValueStr(group, + "devices.deny", + devstr); out: VIR_FREE(devstr); @@ -2040,12 +1509,14 @@ out: * * Returns: 0 on success */ -int virCgroupDenyDeviceMajor(virCgroupPtr group, char type, int major, +int virCgroupDenyDeviceMajor(virCgroupItemPtr group, char type, int major, int perms) { int rc; char *devstr = NULL; + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_DEVICES); + if (virAsprintf(&devstr, "%c %i:* %s%s%s", type, major, perms & VIR_CGROUP_DEVICE_READ ? "r" : "", perms & VIR_CGROUP_DEVICE_WRITE ? "w" : "", @@ -2054,10 +1525,9 @@ int virCgroupDenyDeviceMajor(virCgroupPtr group, char type, int major, goto out; } - rc = virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_DEVICES, - "devices.deny", - devstr); + rc = virCgroupItemSetValueStr(group, + "devices.deny", + devstr); out: VIR_FREE(devstr); @@ -2065,7 +1535,7 @@ int virCgroupDenyDeviceMajor(virCgroupPtr group, char type, int major, } #if defined(major) && defined(minor) -int virCgroupDenyDevicePath(virCgroupPtr group, const char *path, int perms) +int virCgroupDenyDevicePath(virCgroupItemPtr group, const char *path, int perms) { struct stat sb; @@ -2082,7 +1552,7 @@ int virCgroupDenyDevicePath(virCgroupPtr group, const char *path, int perms) perms); } #else -int virCgroupDenyDevicePath(virCgroupPtr group ATTRIBUTE_UNUSED, +int virCgroupDenyDevicePath(virCgroupItemPtr group ATTRIBUTE_UNUSED, const char *path ATTRIBUTE_UNUSED, int perms ATTRIBUTE_UNUSED) { @@ -2090,18 +1560,20 @@ int virCgroupDenyDevicePath(virCgroupPtr group ATTRIBUTE_UNUSED, } #endif -int virCgroupSetCpuShares(virCgroupPtr group, unsigned long long shares) +int virCgroupSetCpuShares(virCgroupItemPtr group, unsigned long long shares) { - return virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_CPU, - "cpu.shares", shares); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPU); + + return virCgroupItemSetValueU64(group, + "cpu.shares", shares); } -int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares) +int virCgroupGetCpuShares(virCgroupItemPtr group, unsigned long long *shares) { - return virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_CPU, - "cpu.shares", shares); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPU); + + return virCgroupItemGetValueU64(group, + "cpu.shares", shares); } /** @@ -2112,16 +1584,17 @@ int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares) * * Returns: 0 on success */ -int virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period) +int virCgroupSetCpuCfsPeriod(virCgroupItemPtr group, unsigned long long cfs_period) { + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPU); + /* The cfs_period shoule be greater or equal than 1ms, and less or equal * than 1s. */ if (cfs_period < 1000 || cfs_period > 1000000) return -EINVAL; - return virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_CPU, + return virCgroupItemSetValueU64(group, "cpu.cfs_period_us", cfs_period); } @@ -2133,10 +1606,11 @@ int virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period) * * Returns: 0 on success */ -int virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period) +int virCgroupGetCpuCfsPeriod(virCgroupItemPtr group, unsigned long long *cfs_period) { - return virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_CPU, + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPU); + + return virCgroupItemGetValueU64(group, "cpu.cfs_period_us", cfs_period); } @@ -2149,8 +1623,10 @@ int virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period) * * Returns: 0 on success */ -int virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota) +int virCgroupSetCpuCfsQuota(virCgroupItemPtr group, long long cfs_quota) { + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPU); + if (cfs_quota >= 0) { /* The cfs_quota shoule be greater or equal than 1ms */ if (cfs_quota < 1000) @@ -2161,9 +1637,8 @@ int virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota) return -EINVAL; } - return virCgroupSetValueI64(group, - VIR_CGROUP_CONTROLLER_CPU, - "cpu.cfs_quota_us", cfs_quota); + return virCgroupItemSetValueI64(group, + "cpu.cfs_quota_us", cfs_quota); } /** @@ -2175,28 +1650,32 @@ int virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota) * * Returns: 0 on success */ -int virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota) +int virCgroupGetCpuCfsQuota(virCgroupItemPtr group, long long *cfs_quota) { - return virCgroupGetValueI64(group, - VIR_CGROUP_CONTROLLER_CPU, + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPU); + + return virCgroupItemGetValueI64(group, "cpu.cfs_quota_us", cfs_quota); } -int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage) +int virCgroupGetCpuacctUsage(virCgroupItemPtr group, unsigned long long *usage) { - return virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_CPUACCT, - "cpuacct.usage", usage); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPUACCT); + + return virCgroupItemGetValueU64(group, + "cpuacct.usage", usage); } -int virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage) +int virCgroupGetCpuacctPercpuUsage(virCgroupItemPtr group, char **usage) { - return virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT, - "cpuacct.usage_percpu", usage); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPUACCT); + + return virCgroupItemGetValueStr(group, + "cpuacct.usage_percpu", usage); } #ifdef _SC_CLK_TCK -int virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, +int virCgroupGetCpuacctStat(virCgroupItemPtr group, unsigned long long *user, unsigned long long *sys) { char *str; @@ -2204,8 +1683,10 @@ int virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, int ret; static double scale = -1.0; - if ((ret = virCgroupGetValueStr(group, VIR_CGROUP_CONTROLLER_CPUACCT, - "cpuacct.stat", &str)) < 0) + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_CPUACCT); + + if ((ret = virCgroupItemGetValueStr(group, + "cpuacct.stat", &str)) < 0) return ret; if (!(p = STRSKIP(str, "user ")) || virStrToLong_ull(p, &p, 10, user) < 0 || @@ -2234,7 +1715,7 @@ cleanup: return ret; } #else -int virCgroupGetCpuacctStat(virCgroupPtr group ATTRIBUTE_UNUSED, +int virCgroupGetCpuacctStat(virCgroupItemPtr group ATTRIBUTE_UNUSED, unsigned long long *user ATTRIBUTE_UNUSED, unsigned long long *sys ATTRIBUTE_UNUSED) { @@ -2242,33 +1723,33 @@ int virCgroupGetCpuacctStat(virCgroupPtr group ATTRIBUTE_UNUSED, } #endif -int virCgroupSetFreezerState(virCgroupPtr group, const char *state) +int virCgroupSetFreezerState(virCgroupItemPtr group, const char *state) { - return virCgroupSetValueStr(group, - VIR_CGROUP_CONTROLLER_FREEZER, - "freezer.state", state); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_FREEZER); + + return virCgroupItemSetValueStr(group, + "freezer.state", state); } -int virCgroupGetFreezerState(virCgroupPtr group, char **state) +int virCgroupGetFreezerState(virCgroupItemPtr group, char **state) { - return virCgroupGetValueStr(group, - VIR_CGROUP_CONTROLLER_FREEZER, - "freezer.state", state); + sa_assert(virCgroupItemType(group) == VIR_CGROUP_CONTROLLER_FREEZER); + + return virCgroupItemGetValueStr(group, + "freezer.state", state); } #if defined HAVE_KILL && defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -static int virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids) +static int virCgroupKillInternal(virCgroupItemPtr group, int signum, virHashTablePtr pids) { int rc; int killedAny = 0; char *keypath = NULL; bool done = false; FILE *fp = NULL; - VIR_DEBUG("group=%p path=%s signum=%d pids=%p", - group, group->path, signum, pids); - rc = virCgroupPathOfController(group, -1, "tasks", &keypath); + rc = virCgroupItemKeyPath(group, "tasks", &keypath); if (rc != 0) { VIR_DEBUG("No path of %s, tasks", group->path); return rc; @@ -2345,7 +1826,7 @@ static void *virCgroupPidCopy(const void *name) * 0 : no PIDs killed * 1 : at least one PID killed */ -int virCgroupKill(virCgroupPtr group, int signum) +int virCgroupKill(virCgroupItemPtr group, int signum) { VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum); int rc; @@ -2368,17 +1849,17 @@ int virCgroupKill(virCgroupPtr group, int signum) } -static int virCgroupKillRecursiveInternal(virCgroupPtr group, int signum, virHashTablePtr pids, bool dormdir) +static int virCgroupKillRecursiveInternal(virCgroupItemPtr group, + int signum, + virHashTablePtr pids) { int rc; - int killedAny = 0; char *keypath = NULL; - DIR *dp; - virCgroupPtr subgroup = NULL; - struct dirent *ent; - VIR_DEBUG("group=%p path=%s signum=%d pids=%p", group, group->path, signum, pids); + virCgroupItemPtr subgroup = NULL; + VIR_DEBUG("group=%p path=%s signum=%d pids=%p", + group,group->path, signum, pids); - rc = virCgroupPathOfController(group, -1, "", &keypath); + rc = virCgroupItemKeyPath(group, "", &keypath); if (rc != 0) { VIR_DEBUG("No path of %s, tasks", group->path); return rc; @@ -2387,52 +1868,18 @@ static int virCgroupKillRecursiveInternal(virCgroupPtr group, int signum, virHas if ((rc = virCgroupKillInternal(group, signum, pids)) != 0) return rc; - VIR_DEBUG("Iterate over children of %s", keypath); - if (!(dp = opendir(keypath))) { - rc = -errno; - return rc; - } - - while ((ent = readdir(dp))) { - char *subpath; - - if (STREQ(ent->d_name, ".")) - continue; - if (STREQ(ent->d_name, "..")) - continue; - if (ent->d_type != DT_DIR) - continue; - - VIR_DEBUG("Process subdir %s", ent->d_name); - if (virAsprintf(&subpath, "%s/%s", group->path, ent->d_name) < 0) { - rc = -ENOMEM; - goto cleanup; - } - - if ((rc = virCgroupNew(subpath, &subgroup)) != 0) - goto cleanup; - - if ((rc = virCgroupKillRecursiveInternal(subgroup, signum, pids, true)) < 0) - goto cleanup; - if (rc == 1) - killedAny = 1; - - if (dormdir) - virCgroupRemove(subgroup); - - virCgroupFree(&subgroup); + subgroup = group->children; + while (subgroup) { + rc = virCgroupKillRecursiveInternal(subgroup, signum, pids); + if (rc != 0) + return rc; + subgroup = subgroup->next; } - rc = killedAny; - -cleanup: - virCgroupFree(&subgroup); - closedir(dp); - return rc; } -int virCgroupKillRecursive(virCgroupPtr group, int signum) +int virCgroupKillRecursive(virCgroupItemPtr group, int signum) { int rc; VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum); @@ -2443,7 +1890,7 @@ int virCgroupKillRecursive(virCgroupPtr group, int signum) virCgroupPidCopy, NULL); - rc = virCgroupKillRecursiveInternal(group, signum, pids, false); + rc = virCgroupKillRecursiveInternal(group, signum, pids); virHashFree(pids); @@ -2451,7 +1898,7 @@ int virCgroupKillRecursive(virCgroupPtr group, int signum) } -int virCgroupKillPainfully(virCgroupPtr group) +int virCgroupKillPainfully(virCgroupItemPtr group) { int i; int rc; @@ -2478,18 +1925,18 @@ int virCgroupKillPainfully(virCgroupPtr group) } #else /* !(HAVE_KILL, HAVE_MNTENT_H, HAVE_GETMNTENT_R) */ -int virCgroupKill(virCgroupPtr group ATTRIBUTE_UNUSED, +int virCgroupKill(virCgroupItemPtr group ATTRIBUTE_UNUSED, int signum ATTRIBUTE_UNUSED) { return -ENOSYS; } -int virCgroupKillRecursive(virCgroupPtr group ATTRIBUTE_UNUSED, +int virCgroupKillRecursive(virCgroupItemPtr group ATTRIBUTE_UNUSED, int signum ATTRIBUTE_UNUSED) { return -ENOSYS; } -int virCgroupKillPainfully(virCgroupPtr group ATTRIBUTE_UNUSED) +int virCgroupKillPainfully(virCgroupItemPtr group ATTRIBUTE_UNUSED) { return -ENOSYS; } diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h index 0ba2430..a46b76e 100644 --- a/src/util/vircgroup.h +++ b/src/util/vircgroup.h @@ -27,8 +27,8 @@ #include "virutil.h" -struct virCgroup; -typedef struct virCgroup *virCgroupPtr; +typedef struct _virCgroup virCgroup; +typedef virCgroup *virCgroupPtr; typedef struct _virCgroupItem virCgroupItem; typedef virCgroupItem *virCgroupItemPtr; @@ -52,7 +52,7 @@ int virCgroupForDriver(const char *name, bool privileged, bool create); -int virCgroupGetAppRoot(virCgroupPtr *group); +virCgroupItemPtr virCgroupGetAppRoot(int type, bool privileged); int virCgroupForDomain(virCgroupPtr driver, const char *name, @@ -73,33 +73,28 @@ int virCgroupPathOfController(virCgroupPtr group, const char *key, char **path); -int virCgroupAddTask(virCgroupPtr group, pid_t pid); +int virCgroupItemAddTask(virCgroupItemPtr item, pid_t pid); -int virCgroupAddTaskController(virCgroupPtr group, - pid_t pid, - int controller); +int virCgroupItemMoveTask(virCgroupItemPtr src, + virCgroupItemPtr dest); -int virCgroupMoveTask(virCgroupPtr src_group, - virCgroupPtr dest_group, - int controller); +int virCgroupSetBlkioWeight(virCgroupItemPtr group, unsigned int weight); +int virCgroupGetBlkioWeight(virCgroupItemPtr group, unsigned int *weight); -int virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight); -int virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight); - -int virCgroupSetBlkioDeviceWeight(virCgroupPtr group, +int virCgroupSetBlkioDeviceWeight(virCgroupItemPtr group, const char *path, unsigned int weight); -int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb); -int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb); +int virCgroupSetMemory(virCgroupItemPtr group, unsigned long long kb); +int virCgroupGetMemoryUsage(virCgroupItemPtr group, unsigned long *kb); -int virCgroupSetMemoryHardLimit(virCgroupPtr group, unsigned long long kb); -int virCgroupGetMemoryHardLimit(virCgroupPtr group, unsigned long long *kb); -int virCgroupSetMemorySoftLimit(virCgroupPtr group, unsigned long long kb); -int virCgroupGetMemorySoftLimit(virCgroupPtr group, unsigned long long *kb); -int virCgroupSetMemSwapHardLimit(virCgroupPtr group, unsigned long long kb); -int virCgroupGetMemSwapHardLimit(virCgroupPtr group, unsigned long long *kb); -int virCgroupGetMemSwapUsage(virCgroupPtr group, unsigned long long *kb); +int virCgroupSetMemoryHardLimit(virCgroupItemPtr group, unsigned long long kb); +int virCgroupGetMemoryHardLimit(virCgroupItemPtr group, unsigned long long *kb); +int virCgroupSetMemorySoftLimit(virCgroupItemPtr group, unsigned long long kb); +int virCgroupGetMemorySoftLimit(virCgroupItemPtr group, unsigned long long *kb); +int virCgroupSetMemSwapHardLimit(virCgroupItemPtr group, unsigned long long kb); +int virCgroupGetMemSwapHardLimit(virCgroupItemPtr group, unsigned long long *kb); +int virCgroupGetMemSwapUsage(virCgroupItemPtr group, unsigned long long *kb); enum { VIR_CGROUP_DEVICE_READ = 1, @@ -109,65 +104,66 @@ enum { VIR_CGROUP_DEVICE_RWM = VIR_CGROUP_DEVICE_RW | VIR_CGROUP_DEVICE_MKNOD, }; -int virCgroupDenyAllDevices(virCgroupPtr group); +int virCgroupDenyAllDevices(virCgroupItemPtr group); -int virCgroupAllowDevice(virCgroupPtr group, +int virCgroupAllowDevice(virCgroupItemPtr group, char type, int major, int minor, int perms); -int virCgroupAllowDeviceMajor(virCgroupPtr group, +int virCgroupAllowDeviceMajor(virCgroupItemPtr group, char type, int major, int perms); -int virCgroupAllowDevicePath(virCgroupPtr group, +int virCgroupAllowDevicePath(virCgroupItemPtr group, const char *path, int perms); -int virCgroupDenyDevice(virCgroupPtr group, +int virCgroupDenyDevice(virCgroupItemPtr group, char type, int major, int minor, int perms); -int virCgroupDenyDeviceMajor(virCgroupPtr group, +int virCgroupDenyDeviceMajor(virCgroupItemPtr group, char type, int major, int perms); -int virCgroupDenyDevicePath(virCgroupPtr group, +int virCgroupDenyDevicePath(virCgroupItemPtr group, const char *path, int perms); -int virCgroupSetCpuShares(virCgroupPtr group, unsigned long long shares); -int virCgroupGetCpuShares(virCgroupPtr group, unsigned long long *shares); +int virCgroupSetCpuShares(virCgroupItemPtr group, unsigned long long shares); +int virCgroupGetCpuShares(virCgroupItemPtr group, unsigned long long *shares); -int virCgroupSetCpuCfsPeriod(virCgroupPtr group, unsigned long long cfs_period); -int virCgroupGetCpuCfsPeriod(virCgroupPtr group, unsigned long long *cfs_period); +int virCgroupSetCpuCfsPeriod(virCgroupItemPtr group, unsigned long long cfs_period); +int virCgroupGetCpuCfsPeriod(virCgroupItemPtr group, unsigned long long *cfs_period); -int virCgroupSetCpuCfsQuota(virCgroupPtr group, long long cfs_quota); -int virCgroupGetCpuCfsQuota(virCgroupPtr group, long long *cfs_quota); +int virCgroupSetCpuCfsQuota(virCgroupItemPtr group, long long cfs_quota); +int virCgroupGetCpuCfsQuota(virCgroupItemPtr group, long long *cfs_quota); -int virCgroupGetCpuacctUsage(virCgroupPtr group, unsigned long long *usage); -int virCgroupGetCpuacctPercpuUsage(virCgroupPtr group, char **usage); -int virCgroupGetCpuacctStat(virCgroupPtr group, unsigned long long *user, +int virCgroupGetCpuacctUsage(virCgroupItemPtr group, unsigned long long *usage); +int virCgroupGetCpuacctPercpuUsage(virCgroupItemPtr group, char **usage); +int virCgroupGetCpuacctStat(virCgroupItemPtr group, unsigned long long *user, unsigned long long *sys); -int virCgroupSetFreezerState(virCgroupPtr group, const char *state); -int virCgroupGetFreezerState(virCgroupPtr group, char **state); +int virCgroupSetFreezerState(virCgroupItemPtr group, const char *state); +int virCgroupGetFreezerState(virCgroupItemPtr group, char **state); -int virCgroupSetCpusetMems(virCgroupPtr group, const char *mems); -int virCgroupGetCpusetMems(virCgroupPtr group, char **mems); +int virCgroupSetCpusetMems(virCgroupItemPtr group, const char *mems); +int virCgroupGetCpusetMems(virCgroupItemPtr group, char **mems); -int virCgroupSetCpusetCpus(virCgroupPtr group, const char *cpus); -int virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus); +int virCgroupSetCpusetCpus(virCgroupItemPtr group, const char *cpus); +int virCgroupGetCpusetCpus(virCgroupItemPtr group, char **cpus); int virCgroupRemove(virCgroupPtr group); +int virCgroupNew(const char *name, virCgroupPtr parent, virCgroupPtr *group); void virCgroupFree(virCgroupPtr *group); -bool virCgroupMounted(virCgroupPtr cgroup, int controller); +bool virCgroupMounted(int controller); -int virCgroupKill(virCgroupPtr group, int signum); -int virCgroupKillRecursive(virCgroupPtr group, int signum); -int virCgroupKillPainfully(virCgroupPtr group); +int virCgroupKill(virCgroupItemPtr group, int signum); +int virCgroupKillRecursive(virCgroupItemPtr group, int signum); +int virCgroupKillPainfully(virCgroupItemPtr group); virCgroupItemPtr virCgroupItemNew(int type, const char *name, virCgroupItemPtr parent); void virCgroupItemFree(virCgroupItemPtr cgroupItem); -- 1.8.0.1.240.ge8a1f5a -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list