548740a08e9bd0f12741def199e40dc8843cc50d
[fio.git] / cgroup.c
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  */
12 static 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
21 static 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  */
36 static 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  */
59 static 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
77 int 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
119 void 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 }