~ubuntu-branches/ubuntu/trusty/cgmanager/trusty-proposed

« back to all changes in this revision

Viewing changes to debian/patches/0005-allow-passing-in-extra-mounts.patch

  • Committer: Package Import Robot
  • Author(s): Serge Hallyn
  • Date: 2014-02-24 16:38:37 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20140224163837-ur8o2a6byf3gvjy6
Tags: 0.20-0ubuntu1
MergeĀ upstreamĀ v0.20

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
From 3f2044cb5764c6cf568f7b016a5a1e639dcab129 Mon Sep 17 00:00:00 2001
2
 
From: Serge Hallyn <serge.hallyn@ubuntu.com>
3
 
Date: Mon, 17 Feb 2014 15:01:05 -0600
4
 
Subject: [PATCH 1/1] allow passing in extra mounts
5
 
 
6
 
cgroup mounts like the 'none,name=systemd' mount do not show up in
7
 
/proc/cgroups.  So allow the user to specify a list of such unbound
8
 
cgroup subsystems to mount.  I.e.
9
 
 
10
 
cgmanager -m name=systemd,name=yyy
11
 
 
12
 
Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
13
 
---
14
 
 cgmanager.c |  13 +++++-
15
 
 fs.c        | 149 ++++++++++++++++++++++++++++++++++++++++++------------------
16
 
 fs.h        |   2 +-
17
 
 3 files changed, 117 insertions(+), 47 deletions(-)
18
 
 
19
 
diff --git a/cgmanager.c b/cgmanager.c
20
 
index e203da1..6fe428a 100644
21
 
--- a/cgmanager.c
22
 
+++ b/cgmanager.c
23
 
@@ -604,6 +604,15 @@ int get_tasks_main(void *parent, const char *controller, const char *cgroup,
24
 
        return file_read_pids(parent, path, pids);
25
 
 }
26
 
 
27
 
+char *extra_cgroup_mounts;
28
 
+
29
 
+static int
30
 
+my_setter (NihOption *option, const char *arg)
31
 
+{
32
 
+       extra_cgroup_mounts = NIH_MUST( strdup(arg) );
33
 
+
34
 
+       return 0;
35
 
+}
36
 
 
37
 
 /**
38
 
  * options:
39
 
@@ -611,6 +620,8 @@ int get_tasks_main(void *parent, const char *controller, const char *cgroup,
40
 
  * Command-line options accepted by this program.
41
 
  **/
42
 
 static NihOption options[] = {
43
 
+       { 'm', "mount", N_("Extra subsystems to mount"),
44
 
+               NULL, "subsystems to mount", NULL, my_setter },
45
 
        { 0, "daemon", N_("Detach and run in the background"),
46
 
                NULL, NULL, &daemonise, NULL },
47
 
 
48
 
@@ -708,7 +719,7 @@ main (int argc, char *argv[])
49
 
                                  client_disconnect);
50
 
        nih_assert (server != NULL);
51
 
 
52
 
-       if (setup_cgroup_mounts() < 0) {
53
 
+       if (setup_cgroup_mounts(extra_cgroup_mounts) < 0) {
54
 
                nih_fatal ("Failed to set up cgroup mounts");
55
 
                exit(1);
56
 
        }
57
 
diff --git a/fs.c b/fs.c
58
 
index 313a6c2..b6dd4fd 100644
59
 
--- a/fs.c
60
 
+++ b/fs.c
61
 
@@ -122,6 +122,79 @@ static void set_use_hierarchy(const char *path)
62
 
        fclose(f);
63
 
 }
64
 
 
65
 
+static bool do_mount_subsys(char *s)
66
 
+{
67
 
+       struct controller_mounts *tmp;
68
 
+       char *src, dest[MAXPATHLEN], *controller;
69
 
+       int ret;
70
 
+       size_t len = strlen(s);
71
 
+
72
 
+       if (len > MAXPATHLEN) {
73
 
+               nih_fatal("bad controller type: %s", s);
74
 
+               return false;
75
 
+       }
76
 
+       if ((controller = strchr(s, '='))) {
77
 
+               /* this is something like 'name=systemd' */
78
 
+               src = alloca(len+6);
79
 
+               /* so for controller we want 'systemd' */
80
 
+               controller++;
81
 
+               /* and for source we want "none,name=systemd" */
82
 
+               snprintf(src, len+6, "none,%s", s);
83
 
+       } else {
84
 
+               controller = s;
85
 
+               src = s;
86
 
+       }
87
 
+
88
 
+       ret = snprintf(dest, MAXPATHLEN, "%s/%s", base_path, src);
89
 
+       if (ret < 0 || ret >= MAXPATHLEN) {
90
 
+               nih_fatal("Error calculating pathname for %s and %s", base_path, src);
91
 
+               ret = -1;
92
 
+               goto out;
93
 
+       }
94
 
+       if (mkdir(dest, 0755) < 0 && errno != EEXIST) {
95
 
+               nih_fatal("Failed to create %s: %s", dest, strerror(errno));
96
 
+               ret = -1;
97
 
+               goto out;
98
 
+       }
99
 
+       if ((ret = mount(src, dest, "cgroup", 0, src)) < 0) {
100
 
+               nih_fatal("Failed mounting %s: %s", s, strerror(errno));
101
 
+               goto out;
102
 
+       }
103
 
+       ret = -1;
104
 
+       tmp = realloc(all_mounts, (num_controllers+1) * sizeof(*all_mounts));
105
 
+       if (!tmp) {
106
 
+               nih_fatal("Out of memory mounting controllers");
107
 
+               goto out;
108
 
+       }
109
 
+       all_mounts = tmp;
110
 
+       all_mounts[num_controllers].controller = strdup(controller);
111
 
+       if (!all_mounts[num_controllers].controller) {
112
 
+               nih_fatal("Out of memory mounting controllers");
113
 
+               goto out;
114
 
+       }
115
 
+       all_mounts[num_controllers].options = NULL;
116
 
+       all_mounts[num_controllers].path = strdup(dest);
117
 
+       if (!all_mounts[num_controllers].path) {
118
 
+               nih_fatal("Out of memory mounting controllers");
119
 
+               goto out;
120
 
+       }
121
 
+       nih_info(_("Mounted %s onto %s"),
122
 
+                       all_mounts[num_controllers].controller,
123
 
+                       all_mounts[num_controllers].path);
124
 
+       if (strcmp(all_mounts[num_controllers].controller, "cpuset") == 0) {
125
 
+               set_clone_children(dest); // TODO make this optional?
126
 
+               nih_info(_("set clone_children"));
127
 
+       } else if (strcmp(all_mounts[num_controllers].controller, "memory") == 0) {
128
 
+               set_use_hierarchy(dest);  // TODO make this optional?
129
 
+               nih_info(_("set memory.use_hierarchy"));
130
 
+       }
131
 
+       num_controllers++;
132
 
+       return true;
133
 
+
134
 
+out:
135
 
+       return false;
136
 
+}
137
 
+
138
 
 /**
139
 
  * Mount the cgroup filesystems and record the information.
140
 
  * This should take configuration data from /etc.  For now,
141
 
@@ -134,7 +207,7 @@ static void set_use_hierarchy(const char *path)
142
 
  * . any mount options (per-controller)
143
 
  * . values for sane_behavior, use_hierarchy, and clone_children
144
 
  */
145
 
-int setup_cgroup_mounts(void)
146
 
+int setup_cgroup_mounts(char *extra_mounts)
147
 
 {
148
 
        FILE *cgf;
149
 
        int ret;
150
 
@@ -148,14 +221,23 @@ int setup_cgroup_mounts(void)
151
 
                nih_fatal("Error setting up base cgroup path");
152
 
                return -1;
153
 
        }
154
 
+
155
 
+       if (extra_mounts) {
156
 
+               char *e;
157
 
+               for (e = strtok(extra_mounts, ","); e; e = strtok(NULL, ",")) {
158
 
+                       if (!do_mount_subsys(e)) {
159
 
+                               nih_fatal("Error loading subsystem \"%s\"", e);
160
 
+                               return -1;
161
 
+                       }
162
 
+               }
163
 
+       }
164
 
+
165
 
        if ((cgf = fopen("/proc/cgroups", "r")) == NULL) {
166
 
                nih_fatal ("Error opening /proc/cgroups: %s", strerror(errno));
167
 
                return -1;
168
 
        }
169
 
        while (fgets(line, 400, cgf)) {
170
 
                char *p;
171
 
-               struct controller_mounts *tmp;
172
 
-               char dest[MAXPATHLEN];
173
 
                unsigned long h;
174
 
 
175
 
                if (line[0] == '#')
176
 
@@ -172,50 +254,12 @@ int setup_cgroup_mounts(void)
177
 
                        goto out;
178
 
 #endif
179
 
                }
180
 
-               ret = snprintf(dest, MAXPATHLEN, "%s/%s", base_path, line);
181
 
-               if (ret < 0 || ret >= MAXPATHLEN) {
182
 
-                       nih_fatal("Error calculating pathname for %s and %s", base_path, line);
183
 
-                       ret = -1;
184
 
-                       goto out;
185
 
-               }
186
 
-               if (mkdir(dest, 0755) < 0 && errno != EEXIST) {
187
 
-                       nih_fatal("Failed to create %s: %s", dest, strerror(errno));
188
 
+
189
 
+               if (!do_mount_subsys(line)) {
190
 
+                       nih_fatal("Error mounting subsystem %s", line);
191
 
                        ret = -1;
192
 
                        goto out;
193
 
                }
194
 
-               if ((ret = mount(line, dest, "cgroup", 0, line)) < 0) {
195
 
-                       nih_fatal("Failed mounting %s: %s", line, strerror(errno));
196
 
-                       goto out;
197
 
-               }
198
 
-               ret = -1;
199
 
-               tmp = realloc(all_mounts, (num_controllers+1) * sizeof(*all_mounts));
200
 
-               if (!tmp) {
201
 
-                       nih_fatal("Out of memory mounting controllers");
202
 
-                       goto out;
203
 
-               }
204
 
-               all_mounts = tmp;
205
 
-               all_mounts[num_controllers].controller = strdup(line);
206
 
-               if (!all_mounts[num_controllers].controller) {
207
 
-                       nih_fatal("Out of memory mounting controllers");
208
 
-                       goto out;
209
 
-               }
210
 
-               all_mounts[num_controllers].options = NULL;
211
 
-               all_mounts[num_controllers].path = strdup(dest);
212
 
-               if (!all_mounts[num_controllers].path) {
213
 
-                       nih_fatal("Out of memory mounting controllers");
214
 
-                       goto out;
215
 
-               }
216
 
-               nih_info(_("Mounted %s onto %s"),
217
 
-                       all_mounts[num_controllers].controller,
218
 
-                       all_mounts[num_controllers].path);
219
 
-               if (strcmp(all_mounts[num_controllers].controller, "cpuset") == 0) {
220
 
-                       set_clone_children(dest); // TODO make this optional?
221
 
-                       nih_info(_("set clone_children"));
222
 
-               } else if (strcmp(all_mounts[num_controllers].controller, "memory") == 0) {
223
 
-                       set_use_hierarchy(dest);  // TODO make this optional?
224
 
-                       nih_info(_("set memory.use_hierarchy"));
225
 
-               }
226
 
-               num_controllers++;
227
 
        }
228
 
        nih_info(_("mounted %d controllers"), num_controllers);
229
 
        ret = 0;
230
 
@@ -233,6 +277,21 @@ static inline void drop_newlines(char *s)
231
 
 }
232
 
 
233
 
 /*
234
 
+ * The user will pass in 'cpuset' or 'systemd'.  /proc/self/cgroup will
235
 
+ * show 'cpuset:' or 'name=systemd:'.  We have to account for that.
236
 
+ */
237
 
+static bool is_same_controller(const char *cmp, const char *cnt)
238
 
+{
239
 
+       if (strcmp(cmp, cnt) == 0)
240
 
+               return true;
241
 
+       if (strncmp(cmp, "name=", 5) != 0)
242
 
+               return false;
243
 
+       if (strcmp(cmp+5, cnt) == 0)
244
 
+               return true;
245
 
+       return false;
246
 
+}
247
 
+
248
 
+/*
249
 
  * pid_cgroup: return the cgroup of @pid for @controller.
250
 
  * retv must be a (at least) MAXPATHLEN size buffer into
251
 
  * which the answer will be copied.
252
 
@@ -258,7 +317,7 @@ static inline char *pid_cgroup(pid_t pid, const char *controller, char *retv)
253
 
                        continue;
254
 
                *c2 = '\0';
255
 
                for (; (token = strtok_r(c1, ",", &saveptr)); c1 = NULL) {
256
 
-                       if (strcmp(token, controller) != 0)
257
 
+                       if (!is_same_controller(token, controller))
258
 
                                continue;
259
 
                        if (strlen(c2+1) + 1 > MAXPATHLEN) {
260
 
                                nih_error("cgroup name too long");
261
 
diff --git a/fs.h b/fs.h
262
 
index 3322e62..b5d3868 100644
263
 
--- a/fs.h
264
 
+++ b/fs.h
265
 
@@ -24,7 +24,7 @@
266
 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
267
 
  */
268
 
 
269
 
-int setup_cgroup_mounts(void);
270
 
+int setup_cgroup_mounts(char *extra_mounts);
271
 
 bool compute_pid_cgroup(pid_t pid, const char *controller, const char *cgroup, char *path);
272
 
 bool may_access(pid_t pid, uid_t uid, gid_t gid, const char *path, int mode);
273
 
 void get_pid_creds(pid_t pid, uid_t *uid, gid_t *gid);
274
 
1.9.rc1
275