summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.c174
-rw-r--r--src/libcgroup.map1
-rw-r--r--src/tools/Makefile.am4
-rw-r--r--src/tools/cgclear.c37
4 files changed, 215 insertions, 1 deletions
diff --git a/src/config.c b/src/config.c
index 5706e1d..5d5155f 100644
--- a/src/config.c
+++ b/src/config.c
@@ -492,3 +492,177 @@ err_mnt:
fclose(yyin);
return error;
}
+
+static int cgroup_cleanup_cgroup_controller_files(struct cgroup_file_info info,
+ char *root_path, char *ctrl)
+{
+ void *task_handle;
+ pid_t pid;
+ char *rel_path = NULL;
+ int error;
+ int ret;
+
+
+ rel_path = info.full_path + strlen(root_path) - 1;
+
+ if (!strncmp(rel_path, "/", strlen(rel_path)))
+ return 0;
+
+ error = cgroup_get_task_begin(rel_path, ctrl,
+ &task_handle, &pid);
+
+ if (error && error != ECGEOF)
+ return error;
+
+ while (error != ECGEOF) {
+ ret = cgroup_attach_task_pid(NULL, pid);
+
+ if (ret) {
+ cgroup_get_task_end(&task_handle);
+ return ret;
+ }
+ error = cgroup_get_task_next(&task_handle, &pid);
+
+ if (error && error != ECGEOF) {
+ cgroup_get_task_end(&task_handle);
+ return error;
+ }
+ }
+
+ cgroup_get_task_end(&task_handle);
+
+ error = rmdir(info.full_path);
+ if (error) {
+ last_errno = errno;
+ return ECGOTHER;
+ }
+
+ return 0;
+}
+
+static int cgroup_config_unload_controller(struct cgroup_mount_point mount_info)
+{
+ struct cgroup_file_info info;
+ void *tree_handle;
+ int lvl;
+ int ret = 0, error;
+ char *root_path = NULL;
+
+ error = cgroup_walk_tree_begin(mount_info.name, "/", 0, &tree_handle,
+ &info, &lvl);
+
+ if (error && error != ECGEOF)
+ return error;
+
+ root_path = strdup(info.full_path);
+
+ if (!root_path) {
+ cgroup_walk_tree_end(&tree_handle);
+ last_errno = errno;
+ return ECGOTHER;
+ }
+
+ ret = cgroup_walk_tree_set_flags(&tree_handle,
+ CGROUP_WALK_TYPE_POST_DIR);
+
+ if (ret) {
+ cgroup_walk_tree_end(&tree_handle);
+ goto out_error;
+ }
+
+ while (error != ECGEOF) {
+ if (info.type == CGROUP_FILE_TYPE_DIR) {
+ ret = cgroup_cleanup_cgroup_controller_files(info,
+ root_path, mount_info.name);
+
+ if (ret) {
+ cgroup_walk_tree_end(&tree_handle);
+ goto out_error;
+ }
+ }
+
+ error = cgroup_walk_tree_next(0, &tree_handle, &info, lvl);
+
+ if (error && error != ECGEOF) {
+ ret = error;
+ cgroup_walk_tree_end(&tree_handle);
+ }
+ }
+ cgroup_walk_tree_end(&tree_handle);
+ error = umount(mount_info.path);
+
+ if (error) {
+ last_errno = errno;
+ ret = ECGOTHER;
+ goto out_error;
+ }
+
+ error = rmdir(mount_info.path);
+
+ if (error) {
+ last_errno = errno;
+ ret = ECGOTHER;
+ }
+
+out_error:
+ free(root_path);
+ return ret;
+}
+
+int cgroup_unload_cgroups(void)
+{
+ int error = 0;
+ void *ctrl_handle;
+ int ret = 0;
+ char *curr_path = NULL;
+ struct cgroup_mount_point info;
+
+ error = cgroup_init();
+
+ if (error) {
+ ret = error;
+ goto out_error;
+ }
+
+ error = cgroup_get_controller_begin(&ctrl_handle, &info);
+
+
+ if (error && error != ECGEOF) {
+ ret = error;
+ goto out_error;
+ }
+
+ while (error != ECGEOF) {
+ if (!curr_path || strcmp(info.path, curr_path) != 0) {
+ if (curr_path)
+ free(curr_path);
+
+ curr_path = strdup(info.path);
+ if (!curr_path)
+ goto out_errno;
+
+ ret = cgroup_config_unload_controller(info);
+
+ if (ret)
+ goto out_error;
+ }
+
+ error = cgroup_get_controller_next(&ctrl_handle, &info);
+
+ if (error && error != ECGEOF) {
+ ret = error;
+ goto out_error;
+ }
+ }
+
+out_error:
+ if (curr_path)
+ free(curr_path);
+ cgroup_get_controller_end(&ctrl_handle);
+ return ret;
+
+out_errno:
+ last_errno = errno;
+ cgroup_get_controller_end(&ctrl_handle);
+ return ECGOTHER;
+}
diff --git a/src/libcgroup.map b/src/libcgroup.map
index adcf905..5b088d4 100644
--- a/src/libcgroup.map
+++ b/src/libcgroup.map
@@ -66,6 +66,7 @@ global:
cgroup_get_controller_end;
cgroup_get_controller_next;
cgroup_get_controller_begin;
+ cgroup_unload_cgroups;
cgroup_get_controller;
cgroup_get_uid_gid_from_procfs;
} CGROUP_0.33;
diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am
index 2b4c9e7..f82916c 100644
--- a/src/tools/Makefile.am
+++ b/src/tools/Makefile.am
@@ -5,7 +5,7 @@ if WITH_TOOLS
bin_PROGRAMS = cgexec cgclassify cgcreate cgset
-sbin_PROGRAMS = cgconfigparser
+sbin_PROGRAMS = cgconfigparser cgclear
cgexec_SOURCES = cgexec.c tools-common.c tools-common.h
@@ -15,4 +15,6 @@ cgcreate_SOURCES = cgcreate.c tools-common.c tools-common.h
cgconfigparser_SOURCES = cgconfig.c
+cgclear_SOURCES = cgclear.c
+
endif
diff --git a/src/tools/cgclear.c b/src/tools/cgclear.c
new file mode 100644
index 0000000..1485768
--- /dev/null
+++ b/src/tools/cgclear.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright IBM Corporation. 2009
+ *
+ * Authors: Dhaval Giani <dhaval@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Code initiated and designed by Dhaval Giani. All faults are most likely
+ * his mistake.
+ */
+
+#include <libcgroup.h>
+#include <libcgroup-internal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+int main(int argc, char *argv[])
+{
+ int error;
+
+ error = cgroup_unload_cgroups();
+
+ if (error) {
+ printf("%s failed with %s\n", argv[0], cgroup_strerror(error));
+ exit(3);
+ }
+
+ return 0;
+}