1 /*
2 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.internal.platform.cgroupv1;
27
28 import java.io.IOException;
29 import java.nio.file.Files;
30 import java.nio.file.Path;
31 import java.nio.file.Paths;
32 import java.security.AccessController;
33 import java.security.PrivilegedActionException;
34 import java.security.PrivilegedExceptionAction;
35 import java.util.stream.Stream;
36
37 import jdk.internal.platform.cgroupv1.SubSystem.MemorySubSystem;
38
39 public class Metrics implements jdk.internal.platform.Metrics {
40 private MemorySubSystem memory;
41 private SubSystem cpu;
42 private SubSystem cpuacct;
43 private SubSystem cpuset;
44 private SubSystem blkio;
45 private boolean activeSubSystems;
46
47 // Values returned larger than this number are unlimited.
48 static long unlimited_minimum = 0x7FFFFFFFFF000000L;
49
50 private static final Metrics INSTANCE = initContainerSubSystems();
51
52 private static final String PROVIDER_NAME = "cgroupv1";
53
54 private Metrics() {
55 activeSubSystems = false;
56 }
57
58 public static Metrics getInstance() {
59 return INSTANCE;
60 }
61
62 private static Metrics initContainerSubSystems() {
63 Metrics metrics = new Metrics();
64
65 /**
66 * Find the cgroup mount points for subsystems
67 * by reading /proc/self/mountinfo
68 *
69 * Example for docker MemorySubSystem subsystem:
70 * 219 214 0:29 /docker/7208cebd00fa5f2e342b1094f7bed87fa25661471a4637118e65f1c995be8a34 /sys/fs/cgroup/MemorySubSystem ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,MemorySubSystem
71 *
72 * Example for host:
73 * 34 28 0:29 / /sys/fs/cgroup/MemorySubSystem rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,MemorySubSystem
74 */
75 try (Stream<String> lines =
76 readFilePrivileged(Paths.get("/proc/self/mountinfo"))) {
77
78 lines.filter(line -> line.contains(" - cgroup "))
79 .map(line -> line.split(" "))
80 .forEach(entry -> createSubSystem(metrics, entry));
81
82 } catch (IOException e) {
83 return null;
84 }
85
86 /**
87 * Read /proc/self/cgroup and map host mount point to
88 * local one via /proc/self/mountinfo content above
89 *
90 * Docker example:
91 * 5:memory:/docker/6558aed8fc662b194323ceab5b964f69cf36b3e8af877a14b80256e93aecb044
92 *
93 * Host example:
94 * 5:memory:/user.slice
95 *
96 * Construct a path to the process specific memory and cpuset
97 * cgroup directory.
98 *
99 * For a container running under Docker from memory example above
100 * the paths would be:
101 *
102 * /sys/fs/cgroup/memory
103 *
104 * For a Host from memory example above the path would be:
105 *
106 * /sys/fs/cgroup/memory/user.slice
107 *
108 */
109 try (Stream<String> lines =
110 readFilePrivileged(Paths.get("/proc/self/cgroup"))) {
111
112 lines.map(line -> line.split(":"))
113 .filter(line -> (line.length >= 3))
114 .forEach(line -> setSubSystemPath(metrics, line));
115
116 } catch (IOException e) {
117 return null;
118 }
119
120 // Return Metrics object if we found any subsystems.
121 if (metrics.activeSubSystems()) {
122 return metrics;
123 }
124
125 return null;
126 }
127
128 static Stream<String> readFilePrivileged(Path path) throws IOException {
129 try {
130 PrivilegedExceptionAction<Stream<String>> pea = () -> Files.lines(path);
131 return AccessController.doPrivileged(pea);
132 } catch (PrivilegedActionException e) {
133 unwrapIOExceptionAndRethrow(e);
134 throw new InternalError(e.getCause());
135 }
136 }
137
138 static void unwrapIOExceptionAndRethrow(PrivilegedActionException pae) throws IOException {
139 Throwable x = pae.getCause();
140 if (x instanceof IOException)
141 throw (IOException) x;
142 if (x instanceof RuntimeException)
143 throw (RuntimeException) x;
144 if (x instanceof Error)
145 throw (Error) x;
146 }
147 /**
148 * createSubSystem objects and initialize mount points
149 */
150 private static void createSubSystem(Metrics metric, String[] mountentry) {
151 if (mountentry.length < 5) return;
152
153 Path p = Paths.get(mountentry[4]);
154 String[] subsystemNames = p.getFileName().toString().split(",");
155
156 for (String subsystemName: subsystemNames) {
157 switch (subsystemName) {
158 case "memory":
159 metric.setMemorySubSystem(new MemorySubSystem(mountentry[3], mountentry[4]));
160 break;
161 case "cpuset":
162 metric.setCpuSetSubSystem(new SubSystem(mountentry[3], mountentry[4]));
163 break;
164 case "cpuacct":
165 metric.setCpuAcctSubSystem(new SubSystem(mountentry[3], mountentry[4]));
166 break;
167 case "cpu":
168 metric.setCpuSubSystem(new SubSystem(mountentry[3], mountentry[4]));
169 break;
170 case "blkio":
171 metric.setBlkIOSubSystem(new SubSystem(mountentry[3], mountentry[4]));
172 break;
173 default:
174 // Ignore subsystems that we don't support
175 break;
176 }
177 }
178 }
179
180 /**
181 * setSubSystemPath based on the contents of /proc/self/cgroup
182 */
183 private static void setSubSystemPath(Metrics metric, String[] entry) {
184 String controller;
185 String base;
186 SubSystem subsystem = null;
187 SubSystem subsystem2 = null;
188
189 controller = entry[1];
190 base = entry[2];
191 if (controller != null && base != null) {
192 switch (controller) {
193 case "memory":
194 subsystem = metric.MemorySubSystem();
195 break;
196 case "cpuset":
197 subsystem = metric.CpuSetSubSystem();
198 break;
199 case "cpu,cpuacct":
200 case "cpuacct,cpu":
201 subsystem = metric.CpuSubSystem();
202 subsystem2 = metric.CpuAcctSubSystem();
203 break;
204 case "cpuacct":
205 subsystem = metric.CpuAcctSubSystem();
206 break;
207 case "cpu":
208 subsystem = metric.CpuSubSystem();
209 break;
210 case "blkio":
211 subsystem = metric.BlkIOSubSystem();
212 break;
213 // Ignore subsystems that we don't support
214 default:
215 break;
216 }
217 }
218
219 if (subsystem != null) {
220 subsystem.setPath(base);
221 if (subsystem instanceof MemorySubSystem) {
222 MemorySubSystem memorySubSystem = (MemorySubSystem)subsystem;
223 boolean isHierarchial = getHierarchical(memorySubSystem);
224 memorySubSystem.setHierarchical(isHierarchial);
225 }
226 metric.setActiveSubSystems();
227 }
228 if (subsystem2 != null) {
229 subsystem2.setPath(base);
230 }
231 }
232
233
234 private static boolean getHierarchical(MemorySubSystem subsystem) {
235 long hierarchical = SubSystem.getLongValue(subsystem, "memory.use_hierarchy");
236 return hierarchical > 0;
237 }
238
239 private void setActiveSubSystems() {
240 activeSubSystems = true;
241 }
242
243 private boolean activeSubSystems() {
244 return activeSubSystems;
245 }
246
247 private void setMemorySubSystem(MemorySubSystem memory) {
248 this.memory = memory;
249 }
250
251 private void setCpuSubSystem(SubSystem cpu) {
252 this.cpu = cpu;
253 }
254
255 private void setCpuAcctSubSystem(SubSystem cpuacct) {
256 this.cpuacct = cpuacct;
257 }
258
259 private void setCpuSetSubSystem(SubSystem cpuset) {
260 this.cpuset = cpuset;
261 }
262
263 private void setBlkIOSubSystem(SubSystem blkio) {
264 this.blkio = blkio;
265 }
266
267 private SubSystem MemorySubSystem() {
268 return memory;
269 }
270
271 private SubSystem CpuSubSystem() {
272 return cpu;
273 }
274
275 private SubSystem CpuAcctSubSystem() {
276 return cpuacct;
277 }
278
279 private SubSystem CpuSetSubSystem() {
280 return cpuset;
281 }
282
283 private SubSystem BlkIOSubSystem() {
284 return blkio;
285 }
286
287 public String getProvider() {
288 return PROVIDER_NAME;
289 }
290
291 /*****************************************************************
292 * CPU Accounting Subsystem
293 ****************************************************************/
294
295
296 public long getCpuUsage() {
297 return SubSystem.getLongValue(cpuacct, "cpuacct.usage");
298 }
299
300 public long[] getPerCpuUsage() {
301 String usagelist = SubSystem.getStringValue(cpuacct, "cpuacct.usage_percpu");
302 if (usagelist == null) {
303 return new long[0];
304 }
305
306 String list[] = usagelist.split(" ");
307 long percpu[] = new long[list.length];
308 for (int i = 0; i < list.length; i++) {
309 percpu[i] = Long.parseLong(list[i]);
310 }
311 return percpu;
312 }
313
314 public long getCpuUserUsage() {
315 return SubSystem.getLongEntry(cpuacct, "cpuacct.stat", "user");
316 }
317
318 public long getCpuSystemUsage() {
319 return SubSystem.getLongEntry(cpuacct, "cpuacct.stat", "system");
320 }
321
322
323 /*****************************************************************
324 * CPU Subsystem
325 ****************************************************************/
326
327
328 public long getCpuPeriod() {
329 return SubSystem.getLongValue(cpu, "cpu.cfs_period_us");
330 }
331
332 public long getCpuQuota() {
333 return SubSystem.getLongValue(cpu, "cpu.cfs_quota_us");
334 }
335
336 public long getCpuShares() {
337 long retval = SubSystem.getLongValue(cpu, "cpu.shares");
338 if (retval == 0 || retval == 1024)
339 return -1;
340 else
341 return retval;
342 }
343
344 public long getCpuNumPeriods() {
345 return SubSystem.getLongEntry(cpu, "cpu.stat", "nr_periods");
346 }
347
348 public long getCpuNumThrottled() {
349 return SubSystem.getLongEntry(cpu, "cpu.stat", "nr_throttled");
350 }
351
352 public long getCpuThrottledTime() {
353 return SubSystem.getLongEntry(cpu, "cpu.stat", "throttled_time");
354 }
355
356 public long getEffectiveCpuCount() {
357 return Runtime.getRuntime().availableProcessors();
358 }
359
360
361 /*****************************************************************
362 * CPUSet Subsystem
363 ****************************************************************/
364
365 public int[] getCpuSetCpus() {
366 return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.cpus"));
367 }
368
369 public int[] getEffectiveCpuSetCpus() {
370 return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.effective_cpus"));
371 }
372
373 public int[] getCpuSetMems() {
374 return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.mems"));
375 }
376
377 public int[] getEffectiveCpuSetMems() {
378 return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.effective_mems"));
379 }
380
381 public double getCpuSetMemoryPressure() {
382 return SubSystem.getDoubleValue(cpuset, "cpuset.memory_pressure");
383 }
384
385 public boolean isCpuSetMemoryPressureEnabled() {
386 long val = SubSystem.getLongValue(cpuset, "cpuset.memory_pressure_enabled");
387 return (val == 1);
388 }
389
390
391 /*****************************************************************
392 * Memory Subsystem
393 ****************************************************************/
394
395
396 public long getMemoryFailCount() {
397 return SubSystem.getLongValue(memory, "memory.failcnt");
398 }
399
400 public long getMemoryLimit() {
401 long retval = SubSystem.getLongValue(memory, "memory.limit_in_bytes");
402 if (retval > unlimited_minimum) {
403 if (memory.isHierarchical()) {
404 // memory.limit_in_bytes returned unlimited, attempt
405 // hierarchical memory limit
406 String match = "hierarchical_memory_limit";
407 retval = SubSystem.getLongValueMatchingLine(memory,
408 "memory.stat",
409 match,
410 Metrics::convertHierachicalLimitLine);
411 }
412 }
413 return retval > unlimited_minimum ? -1L : retval;
414 }
415
416 public static long convertHierachicalLimitLine(String line) {
417 String[] tokens = line.split("\\s");
418 if (tokens.length == 2) {
419 String strVal = tokens[1];
420 return SubSystem.convertStringToLong(strVal);
421 }
422 return unlimited_minimum + 1; // unlimited
423 }
424
425 public long getMemoryMaxUsage() {
426 return SubSystem.getLongValue(memory, "memory.max_usage_in_bytes");
427 }
428
429 public long getMemoryUsage() {
430 return SubSystem.getLongValue(memory, "memory.usage_in_bytes");
431 }
432
433 public long getKernelMemoryFailCount() {
434 return SubSystem.getLongValue(memory, "memory.kmem.failcnt");
435 }
436
437 public long getKernelMemoryLimit() {
438 long retval = SubSystem.getLongValue(memory, "memory.kmem.limit_in_bytes");
439 return retval > unlimited_minimum ? -1L : retval;
440 }
441
442 public long getKernelMemoryMaxUsage() {
443 return SubSystem.getLongValue(memory, "memory.kmem.max_usage_in_bytes");
444 }
445
446 public long getKernelMemoryUsage() {
447 return SubSystem.getLongValue(memory, "memory.kmem.usage_in_bytes");
448 }
449
450 public long getTcpMemoryFailCount() {
451 return SubSystem.getLongValue(memory, "memory.kmem.tcp.failcnt");
452 }
453
454 public long getTcpMemoryLimit() {
455 long retval = SubSystem.getLongValue(memory, "memory.kmem.tcp.limit_in_bytes");
456 return retval > unlimited_minimum ? -1L : retval;
457 }
458
459 public long getTcpMemoryMaxUsage() {
460 return SubSystem.getLongValue(memory, "memory.kmem.tcp.max_usage_in_bytes");
461 }
462
463 public long getTcpMemoryUsage() {
464 return SubSystem.getLongValue(memory, "memory.kmem.tcp.usage_in_bytes");
465 }
466
467 public long getMemoryAndSwapFailCount() {
468 return SubSystem.getLongValue(memory, "memory.memsw.failcnt");
469 }
470
471 public long getMemoryAndSwapLimit() {
472 long retval = SubSystem.getLongValue(memory, "memory.memsw.limit_in_bytes");
473 if (retval > unlimited_minimum) {
474 if (memory.isHierarchical()) {
475 // memory.memsw.limit_in_bytes returned unlimited, attempt
476 // hierarchical memory limit
477 String match = "hierarchical_memsw_limit";
478 retval = SubSystem.getLongValueMatchingLine(memory,
479 "memory.stat",
480 match,
481 Metrics::convertHierachicalLimitLine);
482 }
483 }
484 return retval > unlimited_minimum ? -1L : retval;
485 }
486
487 public long getMemoryAndSwapMaxUsage() {
488 return SubSystem.getLongValue(memory, "memory.memsw.max_usage_in_bytes");
489 }
490
491 public long getMemoryAndSwapUsage() {
492 return SubSystem.getLongValue(memory, "memory.memsw.usage_in_bytes");
493 }
494
495 public boolean isMemoryOOMKillEnabled() {
496 long val = SubSystem.getLongEntry(memory, "memory.oom_control", "oom_kill_disable");
497 return (val == 0);
498 }
499
500 public long getMemorySoftLimit() {
501 long retval = SubSystem.getLongValue(memory, "memory.soft_limit_in_bytes");
502 return retval > unlimited_minimum ? -1L : retval;
503 }
504
505
506 /*****************************************************************
507 * BlKIO Subsystem
508 ****************************************************************/
509
510
511 public long getBlkIOServiceCount() {
512 return SubSystem.getLongEntry(blkio, "blkio.throttle.io_service_bytes", "Total");
513 }
514
515 public long getBlkIOServiced() {
516 return SubSystem.getLongEntry(blkio, "blkio.throttle.io_serviced", "Total");
517 }
518
519 }
|
1 /*
2 * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package jdk.internal.platform.cgroupv1;
27
28 import java.io.IOException;
29 import java.nio.file.Path;
30 import java.nio.file.Paths;
31 import java.util.stream.Stream;
32
33 import jdk.internal.platform.CgroupSubsystem;
34 import jdk.internal.platform.CgroupSubsystemController;
35 import jdk.internal.platform.CgroupUtil;
36 import jdk.internal.platform.MetricsCgroupV1;
37
38 public class CgroupV1Subsystem implements CgroupSubsystem, MetricsCgroupV1 {
39 private CgroupV1MemorySubSystemController memory;
40 private CgroupV1SubsystemController cpu;
41 private CgroupV1SubsystemController cpuacct;
42 private CgroupV1SubsystemController cpuset;
43 private CgroupV1SubsystemController blkio;
44 private boolean activeSubSystems;
45
46 private static final CgroupV1Subsystem INSTANCE = initSubSystem();
47
48 private static final String PROVIDER_NAME = "cgroupv1";
49
50 private CgroupV1Subsystem() {
51 activeSubSystems = false;
52 }
53
54 public static CgroupV1Subsystem getInstance() {
55 return INSTANCE;
56 }
57
58 private static CgroupV1Subsystem initSubSystem() {
59 CgroupV1Subsystem subsystem = new CgroupV1Subsystem();
60
61 /**
62 * Find the cgroup mount points for subsystems
63 * by reading /proc/self/mountinfo
64 *
65 * Example for docker MemorySubSystem subsystem:
66 * 219 214 0:29 /docker/7208cebd00fa5f2e342b1094f7bed87fa25661471a4637118e65f1c995be8a34 /sys/fs/cgroup/MemorySubSystem ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,MemorySubSystem
67 *
68 * Example for host:
69 * 34 28 0:29 / /sys/fs/cgroup/MemorySubSystem rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,MemorySubSystem
70 */
71 try (Stream<String> lines =
72 CgroupUtil.readFilePrivileged(Paths.get("/proc/self/mountinfo"))) {
73
74 lines.filter(line -> line.contains(" - cgroup "))
75 .map(line -> line.split(" "))
76 .forEach(entry -> createSubSystemController(subsystem, entry));
77
78 } catch (IOException e) {
79 return null;
80 }
81
82 /**
83 * Read /proc/self/cgroup and map host mount point to
84 * local one via /proc/self/mountinfo content above
85 *
86 * Docker example:
87 * 5:memory:/docker/6558aed8fc662b194323ceab5b964f69cf36b3e8af877a14b80256e93aecb044
88 *
89 * Host example:
90 * 5:memory:/user.slice
91 *
92 * Construct a path to the process specific memory and cpuset
93 * cgroup directory.
94 *
95 * For a container running under Docker from memory example above
96 * the paths would be:
97 *
98 * /sys/fs/cgroup/memory
99 *
100 * For a Host from memory example above the path would be:
101 *
102 * /sys/fs/cgroup/memory/user.slice
103 *
104 */
105 try (Stream<String> lines =
106 CgroupUtil.readFilePrivileged(Paths.get("/proc/self/cgroup"))) {
107
108 lines.map(line -> line.split(":"))
109 .filter(line -> (line.length >= 3))
110 .forEach(line -> setSubSystemControllerPath(subsystem, line));
111
112 } catch (IOException e) {
113 return null;
114 }
115
116 // Return Metrics object if we found any subsystems.
117 if (subsystem.activeSubSystems()) {
118 return subsystem;
119 }
120
121 return null;
122 }
123
124 /**
125 * createSubSystem objects and initialize mount points
126 */
127 private static void createSubSystemController(CgroupV1Subsystem subsystem, String[] mountentry) {
128 if (mountentry.length < 5) return;
129
130 Path p = Paths.get(mountentry[4]);
131 String[] subsystemNames = p.getFileName().toString().split(",");
132
133 for (String subsystemName: subsystemNames) {
134 switch (subsystemName) {
135 case "memory":
136 subsystem.setMemorySubSystem(new CgroupV1MemorySubSystemController(mountentry[3], mountentry[4]));
137 break;
138 case "cpuset":
139 subsystem.setCpuSetController(new CgroupV1SubsystemController(mountentry[3], mountentry[4]));
140 break;
141 case "cpuacct":
142 subsystem.setCpuAcctController(new CgroupV1SubsystemController(mountentry[3], mountentry[4]));
143 break;
144 case "cpu":
145 subsystem.setCpuController(new CgroupV1SubsystemController(mountentry[3], mountentry[4]));
146 break;
147 case "blkio":
148 subsystem.setBlkIOController(new CgroupV1SubsystemController(mountentry[3], mountentry[4]));
149 break;
150 default:
151 // Ignore subsystems that we don't support
152 break;
153 }
154 }
155 }
156
157 /**
158 * setSubSystemPath based on the contents of /proc/self/cgroup
159 */
160 private static void setSubSystemControllerPath(CgroupV1Subsystem subsystem, String[] entry) {
161 String controllerName;
162 String base;
163 CgroupV1SubsystemController controller = null;
164 CgroupV1SubsystemController controller2 = null;
165
166 controllerName = entry[1];
167 base = entry[2];
168 if (controllerName != null && base != null) {
169 switch (controllerName) {
170 case "memory":
171 controller = subsystem.memoryController();
172 break;
173 case "cpuset":
174 controller = subsystem.cpuSetController();
175 break;
176 case "cpu,cpuacct":
177 case "cpuacct,cpu":
178 controller = subsystem.cpuController();
179 controller2 = subsystem.cpuAcctController();
180 break;
181 case "cpuacct":
182 controller = subsystem.cpuAcctController();
183 break;
184 case "cpu":
185 controller = subsystem.cpuController();
186 break;
187 case "blkio":
188 controller = subsystem.blkIOController();
189 break;
190 // Ignore subsystems that we don't support
191 default:
192 break;
193 }
194 }
195
196 if (controller != null) {
197 controller.setPath(base);
198 if (controller instanceof CgroupV1MemorySubSystemController) {
199 CgroupV1MemorySubSystemController memorySubSystem = (CgroupV1MemorySubSystemController)controller;
200 boolean isHierarchial = getHierarchical(memorySubSystem);
201 memorySubSystem.setHierarchical(isHierarchial);
202 }
203 subsystem.setActiveSubSystems();
204 }
205 if (controller2 != null) {
206 controller2.setPath(base);
207 }
208 }
209
210
211 private static boolean getHierarchical(CgroupV1MemorySubSystemController controller) {
212 long hierarchical = getLongValue(controller, "memory.use_hierarchy");
213 return hierarchical > 0;
214 }
215
216 private void setActiveSubSystems() {
217 activeSubSystems = true;
218 }
219
220 private boolean activeSubSystems() {
221 return activeSubSystems;
222 }
223
224 private void setMemorySubSystem(CgroupV1MemorySubSystemController memory) {
225 this.memory = memory;
226 }
227
228 private void setCpuController(CgroupV1SubsystemController cpu) {
229 this.cpu = cpu;
230 }
231
232 private void setCpuAcctController(CgroupV1SubsystemController cpuacct) {
233 this.cpuacct = cpuacct;
234 }
235
236 private void setCpuSetController(CgroupV1SubsystemController cpuset) {
237 this.cpuset = cpuset;
238 }
239
240 private void setBlkIOController(CgroupV1SubsystemController blkio) {
241 this.blkio = blkio;
242 }
243
244 private CgroupV1SubsystemController memoryController() {
245 return memory;
246 }
247
248 private CgroupV1SubsystemController cpuController() {
249 return cpu;
250 }
251
252 private CgroupV1SubsystemController cpuAcctController() {
253 return cpuacct;
254 }
255
256 private CgroupV1SubsystemController cpuSetController() {
257 return cpuset;
258 }
259
260 private CgroupV1SubsystemController blkIOController() {
261 return blkio;
262 }
263
264 private static long getLongValue(CgroupSubsystemController controller,
265 String parm) {
266 return CgroupSubsystemController.getLongValue(controller,
267 parm,
268 CgroupV1SubsystemController::convertStringToLong,
269 CgroupSubsystem.LONG_RETVAL_UNLIMITED);
270 }
271
272 public String getProvider() {
273 return PROVIDER_NAME;
274 }
275
276 /*****************************************************************
277 * CPU Accounting Subsystem
278 ****************************************************************/
279
280
281 public long getCpuUsage() {
282 return getLongValue(cpuacct, "cpuacct.usage");
283 }
284
285 public long[] getPerCpuUsage() {
286 String usagelist = CgroupSubsystemController.getStringValue(cpuacct, "cpuacct.usage_percpu");
287 if (usagelist == null) {
288 return null;
289 }
290
291 String list[] = usagelist.split(" ");
292 long percpu[] = new long[list.length];
293 for (int i = 0; i < list.length; i++) {
294 percpu[i] = Long.parseLong(list[i]);
295 }
296 return percpu;
297 }
298
299 public long getCpuUserUsage() {
300 return CgroupV1SubsystemController.getLongEntry(cpuacct, "cpuacct.stat", "user");
301 }
302
303 public long getCpuSystemUsage() {
304 return CgroupV1SubsystemController.getLongEntry(cpuacct, "cpuacct.stat", "system");
305 }
306
307
308 /*****************************************************************
309 * CPU Subsystem
310 ****************************************************************/
311
312
313 public long getCpuPeriod() {
314 return getLongValue(cpu, "cpu.cfs_period_us");
315 }
316
317 public long getCpuQuota() {
318 return getLongValue(cpu, "cpu.cfs_quota_us");
319 }
320
321 public long getCpuShares() {
322 long retval = getLongValue(cpu, "cpu.shares");
323 if (retval == 0 || retval == 1024)
324 return CgroupSubsystem.LONG_RETVAL_UNLIMITED;
325 else
326 return retval;
327 }
328
329 public long getCpuNumPeriods() {
330 return CgroupV1SubsystemController.getLongEntry(cpu, "cpu.stat", "nr_periods");
331 }
332
333 public long getCpuNumThrottled() {
334 return CgroupV1SubsystemController.getLongEntry(cpu, "cpu.stat", "nr_throttled");
335 }
336
337 public long getCpuThrottledTime() {
338 return CgroupV1SubsystemController.getLongEntry(cpu, "cpu.stat", "throttled_time");
339 }
340
341 public long getEffectiveCpuCount() {
342 return Runtime.getRuntime().availableProcessors();
343 }
344
345
346 /*****************************************************************
347 * CPUSet Subsystem
348 ****************************************************************/
349
350 public int[] getCpuSetCpus() {
351 return CgroupSubsystemController.stringRangeToIntArray(CgroupSubsystemController.getStringValue(cpuset, "cpuset.cpus"));
352 }
353
354 public int[] getEffectiveCpuSetCpus() {
355 return CgroupSubsystemController.stringRangeToIntArray(CgroupSubsystemController.getStringValue(cpuset, "cpuset.effective_cpus"));
356 }
357
358 public int[] getCpuSetMems() {
359 return CgroupSubsystemController.stringRangeToIntArray(CgroupSubsystemController.getStringValue(cpuset, "cpuset.mems"));
360 }
361
362 public int[] getEffectiveCpuSetMems() {
363 return CgroupSubsystemController.stringRangeToIntArray(CgroupSubsystemController.getStringValue(cpuset, "cpuset.effective_mems"));
364 }
365
366 public double getCpuSetMemoryPressure() {
367 return CgroupV1SubsystemController.getDoubleValue(cpuset, "cpuset.memory_pressure");
368 }
369
370 public Boolean isCpuSetMemoryPressureEnabled() {
371 long val = getLongValue(cpuset, "cpuset.memory_pressure_enabled");
372 return (val == 1);
373 }
374
375
376 /*****************************************************************
377 * Memory Subsystem
378 ****************************************************************/
379
380
381 public long getMemoryFailCount() {
382 return getLongValue(memory, "memory.failcnt");
383 }
384
385 public long getMemoryLimit() {
386 long retval = getLongValue(memory, "memory.limit_in_bytes");
387 if (retval > CgroupV1SubsystemController.UNLIMITED_MIN) {
388 if (memory.isHierarchical()) {
389 // memory.limit_in_bytes returned unlimited, attempt
390 // hierarchical memory limit
391 String match = "hierarchical_memory_limit";
392 retval = CgroupV1SubsystemController.getLongValueMatchingLine(memory,
393 "memory.stat",
394 match);
395 }
396 }
397 return CgroupV1SubsystemController.longValOrUnlimited(retval);
398 }
399
400 public long getMemoryMaxUsage() {
401 return getLongValue(memory, "memory.max_usage_in_bytes");
402 }
403
404 public long getMemoryUsage() {
405 return getLongValue(memory, "memory.usage_in_bytes");
406 }
407
408 public long getKernelMemoryFailCount() {
409 return getLongValue(memory, "memory.kmem.failcnt");
410 }
411
412 public long getKernelMemoryLimit() {
413 return CgroupV1SubsystemController.longValOrUnlimited(getLongValue(memory, "memory.kmem.limit_in_bytes"));
414 }
415
416 public long getKernelMemoryMaxUsage() {
417 return getLongValue(memory, "memory.kmem.max_usage_in_bytes");
418 }
419
420 public long getKernelMemoryUsage() {
421 return getLongValue(memory, "memory.kmem.usage_in_bytes");
422 }
423
424 public long getTcpMemoryFailCount() {
425 return getLongValue(memory, "memory.kmem.tcp.failcnt");
426 }
427
428 public long getTcpMemoryLimit() {
429 return CgroupV1SubsystemController.longValOrUnlimited(getLongValue(memory, "memory.kmem.tcp.limit_in_bytes"));
430 }
431
432 public long getTcpMemoryMaxUsage() {
433 return getLongValue(memory, "memory.kmem.tcp.max_usage_in_bytes");
434 }
435
436 public long getTcpMemoryUsage() {
437 return getLongValue(memory, "memory.kmem.tcp.usage_in_bytes");
438 }
439
440 public long getMemoryAndSwapFailCount() {
441 return getLongValue(memory, "memory.memsw.failcnt");
442 }
443
444 public long getMemoryAndSwapLimit() {
445 long retval = getLongValue(memory, "memory.memsw.limit_in_bytes");
446 if (retval > CgroupV1SubsystemController.UNLIMITED_MIN) {
447 if (memory.isHierarchical()) {
448 // memory.memsw.limit_in_bytes returned unlimited, attempt
449 // hierarchical memory limit
450 String match = "hierarchical_memsw_limit";
451 retval = CgroupV1SubsystemController.getLongValueMatchingLine(memory,
452 "memory.stat",
453 match);
454 }
455 }
456 return CgroupV1SubsystemController.longValOrUnlimited(retval);
457 }
458
459 public long getMemoryAndSwapMaxUsage() {
460 return getLongValue(memory, "memory.memsw.max_usage_in_bytes");
461 }
462
463 public long getMemoryAndSwapUsage() {
464 return getLongValue(memory, "memory.memsw.usage_in_bytes");
465 }
466
467 public Boolean isMemoryOOMKillEnabled() {
468 long val = CgroupV1SubsystemController.getLongEntry(memory, "memory.oom_control", "oom_kill_disable");
469 return (val == 0);
470 }
471
472 public long getMemorySoftLimit() {
473 return CgroupV1SubsystemController.longValOrUnlimited(getLongValue(memory, "memory.soft_limit_in_bytes"));
474 }
475
476
477 /*****************************************************************
478 * BlKIO Subsystem
479 ****************************************************************/
480
481
482 public long getBlkIOServiceCount() {
483 return CgroupV1SubsystemController.getLongEntry(blkio, "blkio.throttle.io_service_bytes", "Total");
484 }
485
486 public long getBlkIOServiced() {
487 return CgroupV1SubsystemController.getLongEntry(blkio, "blkio.throttle.io_serviced", "Total");
488 }
489
490 }
|