Commit | Line | Data |
---|---|---|
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" | |
7 | #include "cgroup.h" | |
8 | ||
ddf16fe4 JA |
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 | ||
a696fa2a JA |
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 | ||
ddf16fe4 JA |
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 | ||
a696fa2a JA |
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 | { | |
ddf16fe4 JA |
121 | if (cgroup_check_fs(td)) |
122 | return; | |
a696fa2a JA |
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 | } |