--- src/libvirt_private.syms | 9 +- src/util/vircgroup.c | 812 +++++++---------------------------------------- src/util/vircgroup.h | 25 +- 3 files changed, 112 insertions(+), 734 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f5138af..78e387d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -73,8 +73,6 @@ virCapabilitiesSetMacPrefix; # cgroup.h -virCgroup2Free; -virCgroup2New; virCgroupAddTask; virCgroupAddTaskController; virCgroupAllowDevice; @@ -86,10 +84,6 @@ virCgroupDenyAllDevices; virCgroupDenyDevice; virCgroupDenyDeviceMajor; virCgroupDenyDevicePath; -virCgroupForDomain; -virCgroupForDriver; -virCgroupForEmulator; -virCgroupForVcpu; virCgroupFree; virCgroupGetAppRoot; virCgroupGetBlkioWeight; @@ -110,10 +104,11 @@ virCgroupGetMemSwapUsage; virCgroupKill; virCgroupKillPainfully; virCgroupKillRecursive; +virCgroupMakePath; virCgroupMounted; virCgroupMoveTask; +virCgroupNew; virCgroupPathOfController; -virCgroupRemove; virCgroupSetBlkioDeviceWeight; virCgroupSetBlkioWeight; virCgroupSetCpuCfsPeriod; diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index dbc9688..90ff97c 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -80,7 +80,7 @@ struct _virCgroupItem { struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; }; -struct virCgroup2 { +struct virCgroup { virCgroupItemPtr items[VIR_CGROUP_CONTROLLER_LAST]; }; @@ -145,12 +145,6 @@ static int virCgroupControllersInit(struct virCgroupController (*controllers)[VI return rc; } -struct virCgroup { - char *path; - - struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; -}; - typedef enum { VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */ VIR_CGROUP_MEM_HIERACHY = 1 << 0, /* call virCgroupSetMemoryUseHierarchy @@ -447,9 +441,21 @@ static int virCgroupItemKeyPath(virCgroupItemPtr cgroupItem, return ret; } -int virCgroup2New(const char *name, virCgroup2Ptr parent, virCgroup2Ptr *cgroup) +int virCgroupMakePath(virCgroupPtr cgroup) { - virCgroup2Ptr newCgroup = NULL; + int i; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + if (virCgroupItemPath(cgroup->items[i], true, NULL) != 0) + return -1; + } + + return 0; +} + +int virCgroupNew(const char *name, virCgroupPtr parent, virCgroupPtr *cgroup) +{ + virCgroupPtr newCgroup = NULL; virCgroupItemPtr *parentCgroupItems; int ret = -1; int i = 0; @@ -502,40 +508,24 @@ error: return ret; } -void virCgroup2Free(virCgroup2Ptr *cgroup) -{ - int i; - - if (!cgroup || !*cgroup) - return; - - for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { - virCgroupItemFree(&(*cgroup)->items[i]); - } - - VIR_FREE(*cgroup); - *cgroup = NULL; -} - /** * virCgroupFree: * * @group: The group structure to free */ -void virCgroupFree(virCgroupPtr *group) +void virCgroupFree(virCgroupPtr *cgroup) { int i; - if (*group == NULL) + if (!cgroup || !*cgroup) return; - for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { - VIR_FREE((*group)->controllers[i].mountPoint); - VIR_FREE((*group)->controllers[i].placement); + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + virCgroupItemFree(&(*cgroup)->items[i]); } - VIR_FREE((*group)->path); - VIR_FREE(*group); + VIR_FREE(*cgroup); + *cgroup = NULL; } /** @@ -546,9 +536,13 @@ void virCgroupFree(virCgroupPtr *group) * * Returns true if a cgroup is subsystem is mounted. */ -bool virCgroupMounted(virCgroupPtr cgroup, int controller) +bool virCgroupMounted(virCgroupPtr cgroup ATTRIBUTE_UNUSED, + int controller) { - return cgroup->controllers[controller].mountPoint != NULL; + if (rootCgroupItems[controller] && + rootCgroupItems[controller]->controllers[controller].mountPoint) + return true; + return false; } #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R @@ -675,58 +669,8 @@ 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 - int virCgroupPathOfController(virCgroupPtr group, int controller, const char *key, @@ -735,8 +679,7 @@ int virCgroupPathOfController(virCgroupPtr group, if (controller == -1) { int i; for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { - if (group->controllers[i].mountPoint && - group->controllers[i].placement) { + if (virCgroupMounted(group, i)) { controller = i; break; } @@ -745,64 +688,22 @@ int virCgroupPathOfController(virCgroupPtr group, 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, + if (virAsprintf(path, "%s%s%s", + group->items[controller]->path, + key ? "/" : "", key ? key : "") == -1) return -ENOMEM; return 0; } -static int virCgroup2SetValueStr(virCgroup2Ptr group, - int controller, - const char *key, - const char *value) -{ - return virCgroupItemSetValueStr(group->items[controller], - key, value); -} - -static int virCgroup2GetValueStr(virCgroup2Ptr group, - int controller, - const char *key, - char **value) -{ - return virCgroupItemGetValueStr(group->items[controller], - key, value); -} - 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; + return virCgroupItemSetValueStr(group->items[controller], + key, value); } static int virCgroupGetValueStr(virCgroupPtr group, @@ -810,34 +711,8 @@ static int virCgroupGetValueStr(virCgroupPtr group, 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 virCgroupItemGetValueStr(group->items[controller], + key, value); } static int virCgroupSetValueU64(virCgroupPtr group, @@ -858,8 +733,6 @@ static int virCgroupSetValueU64(virCgroupPtr group, return rc; } - - static int virCgroupSetValueI64(virCgroupPtr group, int controller, const char *key, @@ -919,45 +792,6 @@ out: } #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 virCgroupItemCpusetInherit(virCgroupItemPtr cgroupItem) { int i; @@ -993,36 +827,6 @@ static int virCgroupItemCpusetInherit(virCgroupItemPtr cgroupItem) return rc; } -static int virCgroupSetMemoryUseHierarchy(virCgroupPtr group) -{ - int rc = 0; - unsigned long long value; - const char *filename = "memory.use_hierarchy"; - - rc = virCgroupGetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - filename, &value); - if (rc != 0) { - VIR_ERROR(_("Failed to read %s/%s (%d)"), group->path, filename, rc); - return rc; - } - - /* Setting twice causes error, so if already enabled, skip setting */ - if (value == 1) - return 0; - - VIR_DEBUG("Setting up %s/%s", group->path, filename); - rc = virCgroupSetValueU64(group, - VIR_CGROUP_CONTROLLER_MEMORY, - filename, 1); - - if (rc != 0) { - VIR_ERROR(_("Failed to set %s/%s (%d)"), group->path, filename, rc); - } - - return rc; -} - static int virCgroupItemSetMemoryUseHierarchy(virCgroupItemPtr item) { int rc = 0; @@ -1055,163 +859,6 @@ out: 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); - } - - return rc; -} - - -static int virCgroupNew(const char *path, - virCgroupPtr *group) -{ - int rc = 0; - char *typpath = NULL; - - VIR_DEBUG("New group %s", path); - *group = NULL; - - if (VIR_ALLOC((*group)) != 0) { - rc = -ENOMEM; - goto err; - } - - if (!((*group)->path = strdup(path))) { - rc = -ENOMEM; - goto err; - } - - rc = virCgroupDetect(*group); - if (rc < 0) - goto err; - - return rc; -err: - virCgroupFree(group); - *group = NULL; - - VIR_FREE(typpath); - - return rc; -} - -static int virCgroupAppRoot(bool privileged, - virCgroupPtr *group, - bool create) -{ - virCgroupPtr rootgrp = NULL; - int rc; - - rc = virCgroupNew("/", &rootgrp); - if (rc != 0) - return rc; - - 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; - } - - rc = virCgroupNew(rootname, group); - VIR_FREE(rootname); - } - if (rc != 0) - goto cleanup; - - rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE); - -cleanup: - virCgroupFree(&rootgrp); - return rc; -} #endif #if defined _DIRENT_HAVE_D_TYPE @@ -1272,43 +919,6 @@ 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. - * - * 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 @@ -1323,7 +933,7 @@ int virCgroupAddTask(virCgroupPtr group, pid_t pid) for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { /* Skip over controllers not mounted */ - if (!group->controllers[i].mountPoint) + if (!virCgroupMounted(group, i)) continue; rc = virCgroupSetValueU64(group, i, "tasks", (unsigned long long)pid); @@ -1348,7 +958,7 @@ int virCgroupAddTaskController(virCgroupPtr group, pid_t pid, int controller) if (controller < 0 || controller >= VIR_CGROUP_CONTROLLER_LAST) return -EINVAL; - if (!group->controllers[controller].mountPoint) + if (!virCgroupMounted(group, controller)) return -EINVAL; return virCgroupSetValueU64(group, controller, "tasks", @@ -1411,12 +1021,6 @@ int virCgroupMoveTask(virCgroupPtr src_group, virCgroupPtr dest_group, 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); if (rc != 0) return rc; @@ -1437,226 +1041,39 @@ cleanup: err = virCgroupAddTaskStrController(src_group, content, controller); if (err != 0) VIR_ERROR(_("Cannot recover cgroup %s from %s"), - src_group->controllers[controller].mountPoint, - dest_group->controllers[controller].mountPoint); + src_group->items[controller]->path, + dest_group->items[controller]->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 -* -* Returns 0 on success -*/ -#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) -{ - 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 virCgroupGetAppRoot(virCgroupPtr *cgroup, bool privileged) { + char *name = NULL; + char *user = NULL; int rc; - char *path; - if (driver == NULL) - return -EINVAL; - - if (virAsprintf(&path, "%s/vcpu%d", driver->path, vcpuid) < 0) - return -ENOMEM; - - rc = virCgroupNew(path, group); - VIR_FREE(path); + if (privileged) + name = strdup("libvirt"); + else { + user = virGetUserName(getuid()); + if (!user) { + return -ENOMEM; + } - if (rc == 0) { - rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_VCPU); - if (rc != 0) - virCgroupFree(group); + if (virAsprintf(&name, "libvirt-%s", user) < 0) { + VIR_FREE(user); + return -ENOMEM; + } } - 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) { - rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_VCPU); - if (rc != 0) - virCgroupFree(group); - } + rc = virCgroupNew(name, NULL, cgroup); + VIR_FREE(name); return rc; } -#else -int virCgroupForEmulator(virCgroupPtr driver ATTRIBUTE_UNUSED, - virCgroupPtr *group ATTRIBUTE_UNUSED, - bool create ATTRIBUTE_UNUSED) -{ - return -ENXIO; -} -#endif /** * virCgroupSetBlkioWeight: * @@ -2390,21 +1807,20 @@ int virCgroupGetFreezerState(virCgroupPtr group, char **state) #if defined HAVE_KILL && defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R -static int virCgroupKillInternal(virCgroupPtr group, int signum, virHashTablePtr pids) +static int virCgroupItemKillInternal(virCgroupItemPtr item, + int signum, + virHashTablePtr pids) { - int rc; + int rc = -1; 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); + VIR_DEBUG("cgroupItem=%p signum=%d pids=%p", + item, signum, pids); - rc = virCgroupPathOfController(group, -1, "tasks", &keypath); - if (rc != 0) { - VIR_DEBUG("No path of %s, tasks", group->path); + if (virAsprintf(&keypath, "%s/tasks", item->path) < 0) return rc; - } /* PIDs may be forking as we kill them, so loop * until there are no new PIDs found @@ -2456,7 +1872,6 @@ cleanup: return rc; } - static uint32_t virCgroupPidCode(const void *name, uint32_t seed) { unsigned long pid_value = (unsigned long)(intptr_t)name; @@ -2471,15 +1886,8 @@ static void *virCgroupPidCopy(const void *name) return (void*)name; } -/* - * Returns - * < 0 : errno that occurred - * 0 : no PIDs killed - * 1 : at least one PID killed - */ -int virCgroupKill(virCgroupPtr group, int signum) +static int virCgroupItemKill(virCgroupItemPtr item, int signum) { - VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum); int rc; /* The 'tasks' file in cgroups can contain duplicated * pids, so we use a hash to track which we've already @@ -2492,82 +1900,65 @@ int virCgroupKill(virCgroupPtr group, int signum) virCgroupPidCopy, NULL); - rc = virCgroupKillInternal(group, signum, pids); + rc = virCgroupItemKillInternal(item, signum, pids); virHashFree(pids); return rc; } - -static int virCgroupKillRecursiveInternal(virCgroupPtr group, int signum, virHashTablePtr pids, bool dormdir) +/* + * Returns + * < 0 : errno that occurred + * 0 : no PIDs killed + * 1 : at least one PID killed + */ +int virCgroupKill(virCgroupPtr group, int signum) { 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); - - rc = virCgroupPathOfController(group, -1, "", &keypath); - if (rc != 0) { - VIR_DEBUG("No path of %s, tasks", group->path); - return rc; - } + int i; - if ((rc = virCgroupKillInternal(group, signum, pids)) != 0) - return rc; + VIR_DEBUG("group=%p signum=%d", group, signum); - VIR_DEBUG("Iterate over children of %s", keypath); - if (!(dp = opendir(keypath))) { - rc = -errno; - return rc; + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + rc = virCgroupItemKill(group->items[i], signum); + if (rc < 0) + break; } - while ((ent = readdir(dp))) { - char *subpath; + return rc; +} - if (STREQ(ent->d_name, ".")) - continue; - if (STREQ(ent->d_name, "..")) - continue; - if (ent->d_type != DT_DIR) - continue; +static int virCgroupItemKillRecursiveInternal(virCgroupItemPtr item, + int signum, + virHashTablePtr pids) +{ + int rc; + int killedAny = 0; + virCgroupItemPtr child = NULL; - 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 = virCgroupItemKillInternal(item, signum, pids)) < 0) + return rc; - if ((rc = virCgroupNew(subpath, &subgroup)) != 0) - goto cleanup; + VIR_DEBUG("Iterate over children of %s", item->path); - if ((rc = virCgroupKillRecursiveInternal(subgroup, signum, pids, true)) < 0) - goto cleanup; + child = item->children; + while (child) { + rc = virCgroupItemKillRecursiveInternal(child, signum, pids); if (rc == 1) killedAny = 1; - if (dormdir) - virCgroupRemove(subgroup); - - virCgroupFree(&subgroup); + child = child->next; } rc = killedAny; -cleanup: - virCgroupFree(&subgroup); - closedir(dp); - return rc; } -int virCgroupKillRecursive(virCgroupPtr group, int signum) +static int virCgroupItemKillRecursive(virCgroupItemPtr item, int signum) { int rc; - VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum); virHashTablePtr pids = virHashCreateFull(100, NULL, virCgroupPidCode, @@ -2575,19 +1966,30 @@ int virCgroupKillRecursive(virCgroupPtr group, int signum) virCgroupPidCopy, NULL); - rc = virCgroupKillRecursiveInternal(group, signum, pids, false); + rc = virCgroupItemKillRecursiveInternal(item, signum, pids); virHashFree(pids); return rc; } +int virCgroupKillRecursive(virCgroupPtr group, int signum) +{ + int rc; + int i; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { + rc = virCgroupItemKillRecursive(group->items[i], signum); + } + + return rc; +} int virCgroupKillPainfully(virCgroupPtr group) { int i; int rc; - VIR_DEBUG("cgroup=%p path=%s", group, group->path); + VIR_DEBUG("cgroup=%p", group); for (i = 0 ; i < 15 ; i++) { int signum; if (i == 0) diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h index f93c185..0ccca23 100644 --- a/src/util/vircgroup.h +++ b/src/util/vircgroup.h @@ -30,10 +30,6 @@ struct virCgroup; typedef struct virCgroup *virCgroupPtr; -struct virCgroup2; -typedef struct virCgroup2 virCgroup2; -typedef virCgroup2 *virCgroup2Ptr; - enum { VIR_CGROUP_CONTROLLER_CPU, VIR_CGROUP_CONTROLLER_CPUACCT, @@ -53,21 +49,7 @@ int virCgroupForDriver(const char *name, bool privileged, bool create); -int virCgroupGetAppRoot(virCgroupPtr *group); - -int virCgroupForDomain(virCgroupPtr driver, - const char *name, - virCgroupPtr *group, - bool create); - -int virCgroupForVcpu(virCgroupPtr driver, - int vcpuid, - virCgroupPtr *group, - bool create); - -int virCgroupForEmulator(virCgroupPtr driver, - virCgroupPtr *group, - bool create); +int virCgroupGetAppRoot(virCgroupPtr *group, bool privileged); int virCgroupPathOfController(virCgroupPtr group, int controller, @@ -163,6 +145,7 @@ int virCgroupGetCpusetCpus(virCgroupPtr group, char **cpus); int virCgroupRemove(virCgroupPtr group); +int virCgroupNew(const char *name, virCgroupPtr parent, virCgroupPtr *cgroup); void virCgroupFree(virCgroupPtr *group); bool virCgroupMounted(virCgroupPtr cgroup, int controller); @@ -170,8 +153,6 @@ int virCgroupKill(virCgroupPtr group, int signum); int virCgroupKillRecursive(virCgroupPtr group, int signum); int virCgroupKillPainfully(virCgroupPtr group); - -int virCgroup2New(const char *name, virCgroup2Ptr parent, virCgroup2Ptr *cgroup); -void virCgroup2Free(virCgroup2Ptr *cgroup); +int virCgroupMakePath(virCgroupPtr cgroup); #endif /* __VIR_CGROUP_H__ */ -- 1.8.0.1.240.ge8a1f5a -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list