CGROUP fixes
[fio.git] / cgroup.c
... / ...
CommitLineData
1/*
2 * Code related to setting up a blkio cgroup
3 */
4#include <stdio.h>
5#include <stdlib.h>
6#include "fio.h"
7#include "cgroup.h"
8
9/*
10 * Check if the given root appears valid
11 */
12static int cgroup_check_fs(struct thread_data *td)
13{
14 struct stat sb;
15 char tmp[256];
16
17 sprintf(tmp, "%s/tasks", td->o.cgroup_root);
18 return stat(tmp, &sb);
19}
20
21static char *get_cgroup_root(struct thread_data *td)
22{
23 char *str = malloc(64);
24
25 if (td->o.cgroup)
26 sprintf(str, "%s/%s", td->o.cgroup_root, td->o.cgroup);
27 else
28 sprintf(str, "%s/%s", td->o.cgroup_root, td->o.name);
29
30 return str;
31}
32
33/*
34 * Add pid to given class
35 */
36static int cgroup_add_pid(struct thread_data *td)
37{
38 char *root, tmp[256];
39 FILE *f;
40
41 root = get_cgroup_root(td);
42 sprintf(tmp, "%s/tasks", root);
43
44 f = fopen(tmp, "w");
45 if (!f) {
46 td_verror(td, errno, "cgroup open tasks");
47 return 1;
48 }
49
50 fprintf(f, "%d", td->pid);
51 fclose(f);
52 free(root);
53 return 0;
54}
55
56/*
57 * Move pid to root class
58 */
59static int cgroup_del_pid(struct thread_data *td)
60{
61 char tmp[256];
62 FILE *f;
63
64 sprintf(tmp, "%s/tasks", td->o.cgroup_root);
65 f = fopen(tmp, "w");
66 if (!f) {
67 td_verror(td, errno, "cgroup open tasks");
68 return 1;
69 }
70
71 fprintf(f, "%d", td->pid);
72 fclose(f);
73 return 0;
74}
75
76
77int cgroup_setup(struct thread_data *td)
78{
79 char *root, tmp[256];
80 FILE *f;
81
82 if (cgroup_check_fs(td)) {
83 log_err("fio: blkio cgroup mount point %s not valid\n",
84 td->o.cgroup_root);
85 return 1;
86 }
87
88 /*
89 * Create container, if it doesn't exist
90 */
91 root = get_cgroup_root(td);
92 if (mkdir(root, 0755) < 0) {
93 int __e = errno;
94
95 if (__e != EEXIST) {
96 td_verror(td, __e, "cgroup mkdir");
97 return 1;
98 }
99 } else
100 td->o.cgroup_was_created = 1;
101
102 sprintf(tmp, "%s/blkio.weight", root);
103 f = fopen(tmp, "w");
104 if (!f) {
105 td_verror(td, errno, "cgroup open weight");
106 return 1;
107 }
108
109 fprintf(f, "%d", td->o.cgroup_weight);
110 fclose(f);
111 free(root);
112
113 if (cgroup_add_pid(td))
114 return 1;
115
116 return 0;
117}
118
119void cgroup_shutdown(struct thread_data *td)
120{
121 if (cgroup_check_fs(td))
122 return;
123 if (!td->o.cgroup_weight)
124 return;
125
126 cgroup_del_pid(td);
127
128 if (td->o.cgroup_was_created) {
129 char *root;
130
131 root = get_cgroup_root(td);
132 rmdir(root);
133 free(root);
134 }
135}