cgroup cleanups/fixes
[fio.git] / cgroup.c
CommitLineData
a696fa2a
JA
1/*
2 * Code related to setting up a blkio cgroup
3 */
4#include <stdio.h>
5#include <stdlib.h>
6#include "fio.h"
39f22027 7#include "flist.h"
a696fa2a 8#include "cgroup.h"
39f22027
JA
9#include "smalloc.h"
10
11static struct flist_head *cgroup_list;
12static struct fio_mutex *lock;
13
14struct cgroup_member {
15 struct flist_head list;
16 char *root;
17};
18
19static void add_cgroup(const char *name)
20{
21 struct cgroup_member *cm;
22
23 cm = smalloc(sizeof(*cm));
24 INIT_FLIST_HEAD(&cm->list);
25 cm->root = smalloc_strdup(name);
26
27 fio_mutex_down(lock);
28
29 if (!cgroup_list) {
30 cgroup_list = smalloc(sizeof(struct flist_head));
31 INIT_FLIST_HEAD(cgroup_list);
32 }
33
34 flist_add_tail(&cm->list, cgroup_list);
35 fio_mutex_up(lock);
36}
37
38void cgroup_kill(void)
39{
40 struct flist_head *n, *tmp;
41 struct cgroup_member *cm;
42
43 fio_mutex_down(lock);
44 if (!cgroup_list)
45 goto out;
46
47 flist_for_each_safe(n, tmp, cgroup_list) {
48 cm = flist_entry(n, struct cgroup_member, list);
49 rmdir(cm->root);
50 flist_del(&cm->list);
51 sfree(cm->root);
52 sfree(cm);
53 }
54
55 sfree(cgroup_list);
56 cgroup_list = NULL;
57out:
58 fio_mutex_up(lock);
59}
a696fa2a 60
ddf16fe4
JA
61/*
62 * Check if the given root appears valid
63 */
64static int cgroup_check_fs(struct thread_data *td)
65{
66 struct stat sb;
67 char tmp[256];
68
69 sprintf(tmp, "%s/tasks", td->o.cgroup_root);
70 return stat(tmp, &sb);
71}
72
a696fa2a
JA
73static char *get_cgroup_root(struct thread_data *td)
74{
75 char *str = malloc(64);
76
77 if (td->o.cgroup)
78 sprintf(str, "%s/%s", td->o.cgroup_root, td->o.cgroup);
79 else
80 sprintf(str, "%s/%s", td->o.cgroup_root, td->o.name);
81
82 return str;
83}
84
3858bf9e 85static int cgroup_write_pid(struct thread_data *td, const char *root)
a696fa2a 86{
3858bf9e 87 char tmp[256];
a696fa2a 88 FILE *f;
3858bf9e 89
a696fa2a 90 sprintf(tmp, "%s/tasks", root);
a696fa2a
JA
91 f = fopen(tmp, "w");
92 if (!f) {
93 td_verror(td, errno, "cgroup open tasks");
94 return 1;
95 }
96
97 fprintf(f, "%d", td->pid);
98 fclose(f);
a696fa2a 99 return 0;
3858bf9e 100
a696fa2a
JA
101}
102
103/*
3858bf9e 104 * Add pid to given class
a696fa2a 105 */
3858bf9e 106static int cgroup_add_pid(struct thread_data *td)
a696fa2a 107{
3858bf9e
JA
108 char *root;
109 int ret;
a696fa2a 110
3858bf9e
JA
111 root = get_cgroup_root(td);
112 ret = cgroup_write_pid(td, root);
113 free(root);
114 return ret;
a696fa2a
JA
115}
116
3858bf9e
JA
117/*
118 * Move pid to root class
119 */
120static int cgroup_del_pid(struct thread_data *td)
121{
122 return cgroup_write_pid(td, td->o.cgroup_root);
123}
a696fa2a
JA
124
125int cgroup_setup(struct thread_data *td)
126{
127 char *root, tmp[256];
128 FILE *f;
129
ddf16fe4
JA
130 if (cgroup_check_fs(td)) {
131 log_err("fio: blkio cgroup mount point %s not valid\n",
132 td->o.cgroup_root);
133 return 1;
134 }
135
a696fa2a
JA
136 /*
137 * Create container, if it doesn't exist
138 */
139 root = get_cgroup_root(td);
140 if (mkdir(root, 0755) < 0) {
141 int __e = errno;
142
143 if (__e != EEXIST) {
144 td_verror(td, __e, "cgroup mkdir");
3858bf9e 145 goto err;
a696fa2a
JA
146 }
147 } else
39f22027 148 add_cgroup(root);
a696fa2a 149
39f22027
JA
150 if (td->o.cgroup_weight) {
151 sprintf(tmp, "%s/blkio.weight", root);
152 f = fopen(tmp, "w");
153 if (!f) {
154 td_verror(td, errno, "cgroup open weight");
3858bf9e 155 goto err;
39f22027
JA
156 }
157
158 fprintf(f, "%d", td->o.cgroup_weight);
159 fclose(f);
a696fa2a
JA
160 }
161
a696fa2a
JA
162 free(root);
163
164 if (cgroup_add_pid(td))
165 return 1;
166
167 return 0;
3858bf9e
JA
168err:
169 free(root);
170 return 1;
a696fa2a
JA
171}
172
173void cgroup_shutdown(struct thread_data *td)
174{
ddf16fe4
JA
175 if (cgroup_check_fs(td))
176 return;
39f22027 177 if (!td->o.cgroup_weight && td->o.cgroup)
a696fa2a
JA
178 return;
179
180 cgroup_del_pid(td);
39f22027 181}
a696fa2a 182
a696fa2a 183
39f22027
JA
184static void fio_init cgroup_init(void)
185{
186 lock = fio_mutex_init(1);
187}
188
189static void fio_exit cgroup_exit(void)
190{
191 fio_mutex_remove(lock);
a696fa2a 192}