Add support for blkio cgroups on Linux
[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 static char *get_cgroup_root(struct thread_data *td)
10 {
11         char *str = malloc(64);
12
13         if (td->o.cgroup)
14                 sprintf(str, "%s/%s", td->o.cgroup_root, td->o.cgroup);
15         else
16                 sprintf(str, "%s/%s", td->o.cgroup_root, td->o.name);
17
18         return str;
19 }
20
21 /*
22  * Add pid to given class
23  */
24 static int cgroup_add_pid(struct thread_data *td)
25 {
26         char *root, tmp[256];
27         FILE *f;
28
29         root = get_cgroup_root(td);
30         sprintf(tmp, "%s/tasks", root);
31
32         f = fopen(tmp, "w");
33         if (!f) {
34                 td_verror(td, errno, "cgroup open tasks");
35                 return 1;
36         }
37
38         fprintf(f, "%d", td->pid);
39         fclose(f);
40         free(root);
41         return 0;
42 }
43
44 /*
45  * Move pid to root class
46  */
47 static int cgroup_del_pid(struct thread_data *td)
48 {
49         char tmp[256];
50         FILE *f;
51
52         sprintf(tmp, "%s/tasks", td->o.cgroup_root);
53         f = fopen(tmp, "w");
54         if (!f) {
55                 td_verror(td, errno, "cgroup open tasks");
56                 return 1;
57         }
58
59         fprintf(f, "%d", td->pid);
60         fclose(f);
61         return 0;
62 }
63
64
65 int cgroup_setup(struct thread_data *td)
66 {
67         char *root, tmp[256];
68         FILE *f;
69
70         /*
71          * Create container, if it doesn't exist
72          */
73         root = get_cgroup_root(td);
74         if (mkdir(root, 0755) < 0) {
75                 int __e = errno;
76
77                 if (__e != EEXIST) {
78                         td_verror(td, __e, "cgroup mkdir");
79                         return 1;
80                 }
81         } else
82                 td->o.cgroup_was_created = 1;
83
84         sprintf(tmp, "%s/blkio.weight", root);
85         f = fopen(tmp, "w");
86         if (!f) {
87                 td_verror(td, errno, "cgroup open weight");
88                 return 1;
89         }
90
91         fprintf(f, "%d", td->o.cgroup_weight);
92         fclose(f);
93         free(root);
94
95         if (cgroup_add_pid(td))
96                 return 1;
97
98         return 0;
99 }
100
101 void cgroup_shutdown(struct thread_data *td)
102 {
103         if (!td->o.cgroup_weight)
104                 return;
105
106         cgroup_del_pid(td);
107
108         if (td->o.cgroup_was_created) {
109                 char *root;
110
111                 root = get_cgroup_root(td);
112                 rmdir(root);
113                 free(root);
114         }
115 }