< prev index next >

src/java.base/linux/classes/jdk/internal/platform/cgroupv1/CgroupV1Subsystem.java

Print this page
@  rev 56863 : 8231111: Cgroups v2: Rework Metrics in java.base so as to recognize unified hierarchy
|  Reviewed-by: bobv
~


  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.util.stream.Stream;
  33 
  34 import jdk.internal.platform.cgroupv1.SubSystem.MemorySubSystem;

  35 
  36 public class Metrics implements jdk.internal.platform.Metrics {
  37     private MemorySubSystem memory;
  38     private SubSystem cpu;
  39     private SubSystem cpuacct;
  40     private SubSystem cpuset;
  41     private SubSystem blkio;
  42     private boolean activeSubSystems;
  43 
  44     // Values returned larger than this number are unlimited.
  45     static long unlimited_minimum = 0x7FFFFFFFFF000000L;
  46 
  47     private static final Metrics INSTANCE = initContainerSubSystems();
  48 
  49     private static final String PROVIDER_NAME = "cgroupv1";
  50 
  51     private Metrics() {
  52         activeSubSystems = false;
  53     }
  54 
  55     public static Metrics getInstance() {
  56         return INSTANCE;
  57     }
  58 
  59     private static Metrics initContainerSubSystems() {
  60         Metrics metrics = new Metrics();
  61 
  62         /**
  63          * Find the cgroup mount points for subsystems
  64          * by reading /proc/self/mountinfo
  65          *
  66          * Example for docker MemorySubSystem subsystem:
  67          * 219 214 0:29 /docker/7208cebd00fa5f2e342b1094f7bed87fa25661471a4637118e65f1c995be8a34 /sys/fs/cgroup/MemorySubSystem ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,MemorySubSystem
  68          *
  69          * Example for host:
  70          * 34 28 0:29 / /sys/fs/cgroup/MemorySubSystem rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,MemorySubSystem
  71          */
  72         try (Stream<String> lines =
  73              Files.lines(Paths.get("/proc/self/mountinfo"))) {
  74 
  75             lines.filter(line -> line.contains(" - cgroup "))
  76                  .map(line -> line.split(" "))
  77                  .forEach(entry -> createSubSystem(metrics, entry));
  78 
  79         } catch (IOException e) {
  80             return null;
  81         }
  82 
  83         /**
  84          * Read /proc/self/cgroup and map host mount point to
  85          * local one via /proc/self/mountinfo content above
  86          *
  87          * Docker example:
  88          * 5:memory:/docker/6558aed8fc662b194323ceab5b964f69cf36b3e8af877a14b80256e93aecb044
  89          *
  90          * Host example:
  91          * 5:memory:/user.slice
  92          *
  93          * Construct a path to the process specific memory and cpuset
  94          * cgroup directory.
  95          *
  96          * For a container running under Docker from memory example above
  97          * the paths would be:
  98          *
  99          * /sys/fs/cgroup/memory
 100          *
 101          * For a Host from memory example above the path would be:
 102          *
 103          * /sys/fs/cgroup/memory/user.slice
 104          *
 105          */
 106         try (Stream<String> lines =
 107              Files.lines(Paths.get("/proc/self/cgroup"))) {
 108 
 109             lines.map(line -> line.split(":"))
 110                  .filter(line -> (line.length >= 3))
 111                  .forEach(line -> setSubSystemPath(metrics, line));
 112 
 113         } catch (IOException e) {
 114             return null;
 115         }
 116 
 117         // Return Metrics object if we found any subsystems.
 118         if (metrics.activeSubSystems()) {
 119             return metrics;
 120         }
 121 
 122         return null;
 123     }
 124 
 125     /**
 126      * createSubSystem objects and initialize mount points
 127      */
 128     private static void createSubSystem(Metrics metric, String[] mountentry) {
 129         if (mountentry.length < 5) return;
 130 
 131         Path p = Paths.get(mountentry[4]);
 132         String[] subsystemNames = p.getFileName().toString().split(",");
 133 
 134         for (String subsystemName: subsystemNames) {
 135             switch (subsystemName) {
 136                 case "memory":
 137                     metric.setMemorySubSystem(new MemorySubSystem(mountentry[3], mountentry[4]));
 138                     break;
 139                 case "cpuset":
 140                     metric.setCpuSetSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 141                     break;
 142                 case "cpuacct":
 143                     metric.setCpuAcctSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 144                     break;
 145                 case "cpu":
 146                     metric.setCpuSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 147                     break;
 148                 case "blkio":
 149                     metric.setBlkIOSubSystem(new SubSystem(mountentry[3], mountentry[4]));
 150                     break;
 151                 default:
 152                     // Ignore subsystems that we don't support
 153                     break;
 154             }
 155         }
 156     }
 157 
 158     /**
 159      * setSubSystemPath based on the contents of /proc/self/cgroup
 160      */
 161     private static void setSubSystemPath(Metrics metric, String[] entry) {
 162         String controller;
 163         String base;
 164         SubSystem subsystem = null;
 165         SubSystem subsystem2 = null;
 166 
 167         controller = entry[1];
 168         base = entry[2];
 169         if (controller != null && base != null) {
 170             switch (controller) {
 171                 case "memory":
 172                     subsystem = metric.MemorySubSystem();
 173                     break;
 174                 case "cpuset":
 175                     subsystem = metric.CpuSetSubSystem();
 176                     break;
 177                 case "cpu,cpuacct":
 178                 case "cpuacct,cpu":
 179                     subsystem = metric.CpuSubSystem();
 180                     subsystem2 = metric.CpuAcctSubSystem();
 181                     break;
 182                 case "cpuacct":
 183                     subsystem = metric.CpuAcctSubSystem();
 184                     break;
 185                 case "cpu":
 186                     subsystem = metric.CpuSubSystem();
 187                     break;
 188                 case "blkio":
 189                     subsystem = metric.BlkIOSubSystem();
 190                     break;
 191                 // Ignore subsystems that we don't support
 192                 default:
 193                     break;
 194             }
 195         }
 196 
 197         if (subsystem != null) {
 198             subsystem.setPath(base);
 199             if (subsystem instanceof MemorySubSystem) {
 200                 MemorySubSystem memorySubSystem = (MemorySubSystem)subsystem;
 201                 boolean isHierarchial = getHierarchical(memorySubSystem);
 202                 memorySubSystem.setHierarchical(isHierarchial);
 203             }
 204             metric.setActiveSubSystems();
 205         }
 206         if (subsystem2 != null) {
 207             subsystem2.setPath(base);
 208         }
 209     }
 210 
 211 
 212     private static boolean getHierarchical(MemorySubSystem subsystem) {
 213         long hierarchical = SubSystem.getLongValue(subsystem, "memory.use_hierarchy");
 214         return hierarchical > 0;
 215     }
 216 
 217     private void setActiveSubSystems() {
 218         activeSubSystems = true;
 219     }
 220 
 221     private boolean activeSubSystems() {
 222         return activeSubSystems;
 223     }
 224 
 225     private void setMemorySubSystem(MemorySubSystem memory) {
 226         this.memory = memory;
 227     }
 228 
 229     private void setCpuSubSystem(SubSystem cpu) {
 230         this.cpu = cpu;
 231     }
 232 
 233     private void setCpuAcctSubSystem(SubSystem cpuacct) {
 234         this.cpuacct = cpuacct;
 235     }
 236 
 237     private void setCpuSetSubSystem(SubSystem cpuset) {
 238         this.cpuset = cpuset;
 239     }
 240 
 241     private void setBlkIOSubSystem(SubSystem blkio) {
 242         this.blkio = blkio;
 243     }
 244 
 245     private SubSystem MemorySubSystem() {
 246         return memory;
 247     }
 248 
 249     private SubSystem CpuSubSystem() {
 250         return cpu;
 251     }
 252 
 253     private SubSystem CpuAcctSubSystem() {
 254         return cpuacct;
 255     }
 256 
 257     private SubSystem CpuSetSubSystem() {
 258         return cpuset;
 259     }
 260 
 261     private SubSystem BlkIOSubSystem() {
 262         return blkio;
 263     }
 264 







 265     public String getProvider() {
 266         return PROVIDER_NAME;
 267     }
 268 
 269     /*****************************************************************
 270      * CPU Accounting Subsystem
 271      ****************************************************************/
 272 
 273 
 274     public long getCpuUsage() {
 275         return SubSystem.getLongValue(cpuacct, "cpuacct.usage");
 276     }
 277 
 278     public long[] getPerCpuUsage() {
 279         String usagelist = SubSystem.getStringValue(cpuacct, "cpuacct.usage_percpu");
 280         if (usagelist == null) {
 281             return new long[0];
 282         }
 283 
 284         String list[] = usagelist.split(" ");
 285         long percpu[] = new long[list.length];
 286         for (int i = 0; i < list.length; i++) {
 287             percpu[i] = Long.parseLong(list[i]);
 288         }
 289         return percpu;
 290     }
 291 
 292     public long getCpuUserUsage() {
 293         return SubSystem.getLongEntry(cpuacct, "cpuacct.stat", "user");
 294     }
 295 
 296     public long getCpuSystemUsage() {
 297         return SubSystem.getLongEntry(cpuacct, "cpuacct.stat", "system");
 298     }
 299 
 300 
 301     /*****************************************************************
 302      * CPU Subsystem
 303      ****************************************************************/
 304 
 305 
 306     public long getCpuPeriod() {
 307         return SubSystem.getLongValue(cpu, "cpu.cfs_period_us");
 308     }
 309 
 310     public long getCpuQuota() {
 311         return SubSystem.getLongValue(cpu, "cpu.cfs_quota_us");
 312     }
 313 
 314     public long getCpuShares() {
 315         long retval = SubSystem.getLongValue(cpu, "cpu.shares");
 316         if (retval == 0 || retval == 1024)
 317             return -1;
 318         else
 319             return retval;
 320     }
 321 
 322     public long getCpuNumPeriods() {
 323         return SubSystem.getLongEntry(cpu, "cpu.stat", "nr_periods");
 324     }
 325 
 326     public long getCpuNumThrottled() {
 327         return SubSystem.getLongEntry(cpu, "cpu.stat", "nr_throttled");
 328     }
 329 
 330     public long getCpuThrottledTime() {
 331         return SubSystem.getLongEntry(cpu, "cpu.stat", "throttled_time");
 332     }
 333 
 334     public long getEffectiveCpuCount() {
 335         return Runtime.getRuntime().availableProcessors();
 336     }
 337 
 338 
 339     /*****************************************************************
 340      * CPUSet Subsystem
 341      ****************************************************************/
 342 
 343     public int[] getCpuSetCpus() {
 344         return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.cpus"));
 345     }
 346 
 347     public int[] getEffectiveCpuSetCpus() {
 348         return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.effective_cpus"));
 349     }
 350 
 351     public int[] getCpuSetMems() {
 352         return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.mems"));
 353     }
 354 
 355     public int[] getEffectiveCpuSetMems() {
 356         return SubSystem.StringRangeToIntArray(SubSystem.getStringValue(cpuset, "cpuset.effective_mems"));
 357     }
 358 
 359     public double getCpuSetMemoryPressure() {
 360         return SubSystem.getDoubleValue(cpuset, "cpuset.memory_pressure");
 361     }
 362 
 363     public boolean isCpuSetMemoryPressureEnabled() {
 364         long val = SubSystem.getLongValue(cpuset, "cpuset.memory_pressure_enabled");
 365         return (val == 1);
 366     }
 367 
 368 
 369     /*****************************************************************
 370      * Memory Subsystem
 371      ****************************************************************/
 372 
 373 
 374     public long getMemoryFailCount() {
 375         return SubSystem.getLongValue(memory, "memory.failcnt");
 376     }
 377 
 378     public long getMemoryLimit() {
 379         long retval = SubSystem.getLongValue(memory, "memory.limit_in_bytes");
 380         if (retval > unlimited_minimum) {
 381             if (memory.isHierarchical()) {
 382                 // memory.limit_in_bytes returned unlimited, attempt
 383                 // hierarchical memory limit
 384                 String match = "hierarchical_memory_limit";
 385                 retval = SubSystem.getLongValueMatchingLine(memory,
 386                                                             "memory.stat",
 387                                                             match,
 388                                                             Metrics::convertHierachicalLimitLine);
 389             }
 390         }
 391         return retval > unlimited_minimum ? -1L : retval;
 392     }
 393 
 394     public static long convertHierachicalLimitLine(String line) {
 395         String[] tokens = line.split("\\s");
 396         if (tokens.length == 2) {
 397             String strVal = tokens[1];
 398             return SubSystem.convertStringToLong(strVal);
 399         }
 400         return unlimited_minimum + 1; // unlimited
 401     }
 402 
 403     public long getMemoryMaxUsage() {
 404         return SubSystem.getLongValue(memory, "memory.max_usage_in_bytes");
 405     }
 406 
 407     public long getMemoryUsage() {
 408         return SubSystem.getLongValue(memory, "memory.usage_in_bytes");
 409     }
 410 
 411     public long getKernelMemoryFailCount() {
 412         return SubSystem.getLongValue(memory, "memory.kmem.failcnt");
 413     }
 414 
 415     public long getKernelMemoryLimit() {
 416         long retval = SubSystem.getLongValue(memory, "memory.kmem.limit_in_bytes");
 417         return retval > unlimited_minimum ? -1L : retval;
 418     }
 419 
 420     public long getKernelMemoryMaxUsage() {
 421         return SubSystem.getLongValue(memory, "memory.kmem.max_usage_in_bytes");
 422     }
 423 
 424     public long getKernelMemoryUsage() {
 425         return SubSystem.getLongValue(memory, "memory.kmem.usage_in_bytes");
 426     }
 427 
 428     public long getTcpMemoryFailCount() {
 429         return SubSystem.getLongValue(memory, "memory.kmem.tcp.failcnt");
 430     }
 431 
 432     public long getTcpMemoryLimit() {
 433         long retval =  SubSystem.getLongValue(memory, "memory.kmem.tcp.limit_in_bytes");
 434         return retval > unlimited_minimum ? -1L : retval;
 435     }
 436 
 437     public long getTcpMemoryMaxUsage() {
 438         return SubSystem.getLongValue(memory, "memory.kmem.tcp.max_usage_in_bytes");
 439     }
 440 
 441     public long getTcpMemoryUsage() {
 442         return SubSystem.getLongValue(memory, "memory.kmem.tcp.usage_in_bytes");
 443     }
 444 
 445     public long getMemoryAndSwapFailCount() {
 446         return SubSystem.getLongValue(memory, "memory.memsw.failcnt");
 447     }
 448 
 449     public long getMemoryAndSwapLimit() {
 450         long retval = SubSystem.getLongValue(memory, "memory.memsw.limit_in_bytes");
 451         if (retval > unlimited_minimum) {
 452             if (memory.isHierarchical()) {
 453                 // memory.memsw.limit_in_bytes returned unlimited, attempt
 454                 // hierarchical memory limit
 455                 String match = "hierarchical_memsw_limit";
 456                 retval = SubSystem.getLongValueMatchingLine(memory,
 457                                                             "memory.stat",
 458                                                             match,
 459                                                             Metrics::convertHierachicalLimitLine);
 460             }
 461         }
 462         return retval > unlimited_minimum ? -1L : retval;
 463     }
 464 
 465     public long getMemoryAndSwapMaxUsage() {
 466         return SubSystem.getLongValue(memory, "memory.memsw.max_usage_in_bytes");
 467     }
 468 
 469     public long getMemoryAndSwapUsage() {
 470         return SubSystem.getLongValue(memory, "memory.memsw.usage_in_bytes");
 471     }
 472 
 473     public boolean isMemoryOOMKillEnabled() {
 474         long val = SubSystem.getLongEntry(memory, "memory.oom_control", "oom_kill_disable");
 475         return (val == 0);
 476     }
 477 
 478     public long getMemorySoftLimit() {
 479         long retval = SubSystem.getLongValue(memory, "memory.soft_limit_in_bytes");
 480         return retval > unlimited_minimum ? -1L : retval;
 481     }
 482 
 483 
 484     /*****************************************************************
 485      * BlKIO Subsystem
 486      ****************************************************************/
 487 
 488 
 489     public long getBlkIOServiceCount() {
 490         return SubSystem.getLongEntry(blkio, "blkio.throttle.io_service_bytes", "Total");
 491     }
 492 
 493     public long getBlkIOServiced() {
 494         return SubSystem.getLongEntry(blkio, "blkio.throttle.io_serviced", "Total");
 495     }
 496 
 497 }


  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.util.stream.Stream;
  33 
  34 import jdk.internal.platform.CgroupSubsystem;
  35 import jdk.internal.platform.CgroupSubsystemController;
  36 
  37 public class CgroupV1Subsystem implements CgroupSubsystem {
  38     private CgroupV1MemorySubSystemController memory;
  39     private CgroupV1SubsystemController cpu;
  40     private CgroupV1SubsystemController cpuacct;
  41     private CgroupV1SubsystemController cpuset;
  42     private CgroupV1SubsystemController blkio;
  43     private boolean activeSubSystems;
  44 
  45     private static final CgroupV1Subsystem INSTANCE = initSubSystem();



  46 
  47     private static final String PROVIDER_NAME = "cgroupv1";
  48 
  49     private CgroupV1Subsystem() {
  50         activeSubSystems = false;
  51     }
  52 
  53     public static CgroupV1Subsystem getInstance() {
  54         return INSTANCE;
  55     }
  56 
  57     private static CgroupV1Subsystem initSubSystem() {
  58         CgroupV1Subsystem subsystem = new CgroupV1Subsystem();
  59 
  60         /**
  61          * Find the cgroup mount points for subsystems
  62          * by reading /proc/self/mountinfo
  63          *
  64          * Example for docker MemorySubSystem subsystem:
  65          * 219 214 0:29 /docker/7208cebd00fa5f2e342b1094f7bed87fa25661471a4637118e65f1c995be8a34 /sys/fs/cgroup/MemorySubSystem ro,nosuid,nodev,noexec,relatime - cgroup cgroup rw,MemorySubSystem
  66          *
  67          * Example for host:
  68          * 34 28 0:29 / /sys/fs/cgroup/MemorySubSystem rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,MemorySubSystem
  69          */
  70         try (Stream<String> lines =
  71              Files.lines(Paths.get("/proc/self/mountinfo"))) {
  72 
  73             lines.filter(line -> line.contains(" - cgroup "))
  74                  .map(line -> line.split(" "))
  75                  .forEach(entry -> createSubSystemController(subsystem, entry));
  76 
  77         } catch (IOException e) {
  78             return null;
  79         }
  80 
  81         /**
  82          * Read /proc/self/cgroup and map host mount point to
  83          * local one via /proc/self/mountinfo content above
  84          *
  85          * Docker example:
  86          * 5:memory:/docker/6558aed8fc662b194323ceab5b964f69cf36b3e8af877a14b80256e93aecb044
  87          *
  88          * Host example:
  89          * 5:memory:/user.slice
  90          *
  91          * Construct a path to the process specific memory and cpuset
  92          * cgroup directory.
  93          *
  94          * For a container running under Docker from memory example above
  95          * the paths would be:
  96          *
  97          * /sys/fs/cgroup/memory
  98          *
  99          * For a Host from memory example above the path would be:
 100          *
 101          * /sys/fs/cgroup/memory/user.slice
 102          *
 103          */
 104         try (Stream<String> lines =
 105              Files.lines(Paths.get("/proc/self/cgroup"))) {
 106 
 107             lines.map(line -> line.split(":"))
 108                  .filter(line -> (line.length >= 3))
 109                  .forEach(line -> setSubSystemControllerPath(subsystem, line));
 110 
 111         } catch (IOException e) {
 112             return null;
 113         }
 114 
 115         // Return Metrics object if we found any subsystems.
 116         if (subsystem.activeSubSystems()) {
 117             return subsystem;
 118         }
 119 
 120         return null;
 121     }
 122 
 123     /**
 124      * createSubSystem objects and initialize mount points
 125      */
 126     private static void createSubSystemController(CgroupV1Subsystem subsystem, String[] mountentry) {
 127         if (mountentry.length < 5) return;
 128 
 129         Path p = Paths.get(mountentry[4]);
 130         String[] subsystemNames = p.getFileName().toString().split(",");
 131 
 132         for (String subsystemName: subsystemNames) {
 133             switch (subsystemName) {
 134                 case "memory":
 135                     subsystem.setMemorySubSystem(new CgroupV1MemorySubSystemController(mountentry[3], mountentry[4]));
 136                     break;
 137                 case "cpuset":
 138                     subsystem.setCpuSetController(new CgroupV1SubsystemController(mountentry[3], mountentry[4]));
 139                     break;
 140                 case "cpuacct":
 141                     subsystem.setCpuAcctController(new CgroupV1SubsystemController(mountentry[3], mountentry[4]));
 142                     break;
 143                 case "cpu":
 144                     subsystem.setCpuController(new CgroupV1SubsystemController(mountentry[3], mountentry[4]));
 145                     break;
 146                 case "blkio":
 147                     subsystem.setBlkIOController(new CgroupV1SubsystemController(mountentry[3], mountentry[4]));
 148                     break;
 149                 default:
 150                     // Ignore subsystems that we don't support
 151                     break;
 152             }
 153         }
 154     }
 155 
 156     /**
 157      * setSubSystemPath based on the contents of /proc/self/cgroup
 158      */
 159     private static void setSubSystemControllerPath(CgroupV1Subsystem subsystem, String[] entry) {
 160         String controllerName;
 161         String base;
 162         CgroupV1SubsystemController controller = null;
 163         CgroupV1SubsystemController controller2 = null;
 164 
 165         controllerName = entry[1];
 166         base = entry[2];
 167         if (controllerName != null && base != null) {
 168             switch (controllerName) {
 169                 case "memory":
 170                     controller = subsystem.memoryController();
 171                     break;
 172                 case "cpuset":
 173                     controller = subsystem.cpuSetController();
 174                     break;
 175                 case "cpu,cpuacct":
 176                 case "cpuacct,cpu":
 177                     controller = subsystem.cpuController();
 178                     controller2 = subsystem.cpuAcctController();
 179                     break;
 180                 case "cpuacct":
 181                     controller = subsystem.cpuAcctController();
 182                     break;
 183                 case "cpu":
 184                     controller = subsystem.cpuController();
 185                     break;
 186                 case "blkio":
 187                     controller = subsystem.blkIOController();
 188                     break;
 189                 // Ignore subsystems that we don't support
 190                 default:
 191                     break;
 192             }
 193         }
 194 
 195         if (controller != null) {
 196             controller.setPath(base);
 197             if (controller instanceof CgroupV1MemorySubSystemController) {
 198                 CgroupV1MemorySubSystemController memorySubSystem = (CgroupV1MemorySubSystemController)controller;
 199                 boolean isHierarchial = getHierarchical(memorySubSystem);
 200                 memorySubSystem.setHierarchical(isHierarchial);
 201             }
 202             subsystem.setActiveSubSystems();
 203         }
 204         if (controller2 != null) {
 205             controller2.setPath(base);
 206         }
 207     }
 208 
 209 
 210     private static boolean getHierarchical(CgroupV1MemorySubSystemController controller) {
 211         long hierarchical = getLongValue(controller, "memory.use_hierarchy");
 212         return hierarchical > 0;
 213     }
 214 
 215     private void setActiveSubSystems() {
 216         activeSubSystems = true;
 217     }
 218 
 219     private boolean activeSubSystems() {
 220         return activeSubSystems;
 221     }
 222 
 223     private void setMemorySubSystem(CgroupV1MemorySubSystemController memory) {
 224         this.memory = memory;
 225     }
 226 
 227     private void setCpuController(CgroupV1SubsystemController cpu) {
 228         this.cpu = cpu;
 229     }
 230 
 231     private void setCpuAcctController(CgroupV1SubsystemController cpuacct) {
 232         this.cpuacct = cpuacct;
 233     }
 234 
 235     private void setCpuSetController(CgroupV1SubsystemController cpuset) {
 236         this.cpuset = cpuset;
 237     }
 238 
 239     private void setBlkIOController(CgroupV1SubsystemController blkio) {
 240         this.blkio = blkio;
 241     }
 242 
 243     private CgroupV1SubsystemController memoryController() {
 244         return memory;
 245     }
 246 
 247     private CgroupV1SubsystemController cpuController() {
 248         return cpu;
 249     }
 250 
 251     private CgroupV1SubsystemController cpuAcctController() {
 252         return cpuacct;
 253     }
 254 
 255     private CgroupV1SubsystemController cpuSetController() {
 256         return cpuset;
 257     }
 258 
 259     private CgroupV1SubsystemController blkIOController() {
 260         return blkio;
 261     }
 262 
 263     private static long getLongValue(CgroupSubsystemController controller,
 264                               String parm) {
 265         return CgroupSubsystemController.getLongValue(controller,
 266                                                       parm,
 267                                                       CgroupV1SubsystemController::convertStringToLong);
 268     }
 269 
 270     public String getProvider() {
 271         return PROVIDER_NAME;
 272     }
 273 
 274     /*****************************************************************
 275      * CPU Accounting Subsystem
 276      ****************************************************************/
 277 
 278 
 279     public long getCpuUsage() {
 280         return getLongValue(cpuacct, "cpuacct.usage");
 281     }
 282 
 283     public long[] getPerCpuUsage() {
 284         String usagelist = CgroupSubsystemController.getStringValue(cpuacct, "cpuacct.usage_percpu");
 285         if (usagelist == null) {
 286             return new long[0];
 287         }
 288 
 289         String list[] = usagelist.split(" ");
 290         long percpu[] = new long[list.length];
 291         for (int i = 0; i < list.length; i++) {
 292             percpu[i] = Long.parseLong(list[i]);
 293         }
 294         return percpu;
 295     }
 296 
 297     public long getCpuUserUsage() {
 298         return CgroupSubsystemController.getLongEntry(cpuacct, "cpuacct.stat", "user");
 299     }
 300 
 301     public long getCpuSystemUsage() {
 302         return CgroupSubsystemController.getLongEntry(cpuacct, "cpuacct.stat", "system");
 303     }
 304 
 305 
 306     /*****************************************************************
 307      * CPU Subsystem
 308      ****************************************************************/
 309 
 310 
 311     public long getCpuPeriod() {
 312         return getLongValue(cpu, "cpu.cfs_period_us");
 313     }
 314 
 315     public long getCpuQuota() {
 316         return getLongValue(cpu, "cpu.cfs_quota_us");
 317     }
 318 
 319     public long getCpuShares() {
 320         long retval = getLongValue(cpu, "cpu.shares");
 321         if (retval == 0 || retval == 1024)
 322             return -1;
 323         else
 324             return retval;
 325     }
 326 
 327     public long getCpuNumPeriods() {
 328         return CgroupSubsystemController.getLongEntry(cpu, "cpu.stat", "nr_periods");
 329     }
 330 
 331     public long getCpuNumThrottled() {
 332         return CgroupSubsystemController.getLongEntry(cpu, "cpu.stat", "nr_throttled");
 333     }
 334 
 335     public long getCpuThrottledTime() {
 336         return CgroupSubsystemController.getLongEntry(cpu, "cpu.stat", "throttled_time");
 337     }
 338 
 339     public long getEffectiveCpuCount() {
 340         return Runtime.getRuntime().availableProcessors();
 341     }
 342 
 343 
 344     /*****************************************************************
 345      * CPUSet Subsystem
 346      ****************************************************************/
 347 
 348     public int[] getCpuSetCpus() {
 349         return CgroupSubsystemController.stringRangeToIntArray(CgroupSubsystemController.getStringValue(cpuset, "cpuset.cpus"));
 350     }
 351 
 352     public int[] getEffectiveCpuSetCpus() {
 353         return CgroupSubsystemController.stringRangeToIntArray(CgroupSubsystemController.getStringValue(cpuset, "cpuset.effective_cpus"));
 354     }
 355 
 356     public int[] getCpuSetMems() {
 357         return CgroupSubsystemController.stringRangeToIntArray(CgroupSubsystemController.getStringValue(cpuset, "cpuset.mems"));
 358     }
 359 
 360     public int[] getEffectiveCpuSetMems() {
 361         return CgroupSubsystemController.stringRangeToIntArray(CgroupSubsystemController.getStringValue(cpuset, "cpuset.effective_mems"));
 362     }
 363 
 364     public double getCpuSetMemoryPressure() {
 365         return CgroupSubsystemController.getDoubleValue(cpuset, "cpuset.memory_pressure");
 366     }
 367 
 368     public boolean isCpuSetMemoryPressureEnabled() {
 369         long val = getLongValue(cpuset, "cpuset.memory_pressure_enabled");
 370         return (val == 1);
 371     }
 372 
 373 
 374     /*****************************************************************
 375      * Memory Subsystem
 376      ****************************************************************/
 377 
 378 
 379     public long getMemoryFailCount() {
 380         return getLongValue(memory, "memory.failcnt");
 381     }
 382 
 383     public long getMemoryLimit() {
 384         long retval = getLongValue(memory, "memory.limit_in_bytes");
 385         if (retval > CgroupV1SubsystemController.UNLIMITED_MIN) {
 386             if (memory.isHierarchical()) {
 387                 // memory.limit_in_bytes returned unlimited, attempt
 388                 // hierarchical memory limit
 389                 String match = "hierarchical_memory_limit";
 390                 retval = CgroupSubsystemController.getLongValueMatchingLine(memory,
 391                                                             "memory.stat",
 392                                                             match,
 393                                                             CgroupV1Subsystem::convertHierachicalLimitLine);
 394             }
 395         }
 396         return CgroupV1SubsystemController.longValOrUnlimited(retval);
 397     }
 398 
 399     public static long convertHierachicalLimitLine(String line) {
 400         String[] tokens = line.split("\\s");
 401         if (tokens.length == 2) {
 402             String strVal = tokens[1];
 403             return CgroupV1SubsystemController.convertStringToLong(strVal);
 404         }
 405         return CgroupV1SubsystemController.UNLIMITED_MIN + 1; // unlimited
 406     }
 407 
 408     public long getMemoryMaxUsage() {
 409         return getLongValue(memory, "memory.max_usage_in_bytes");
 410     }
 411 
 412     public long getMemoryUsage() {
 413         return getLongValue(memory, "memory.usage_in_bytes");
 414     }
 415 
 416     public long getKernelMemoryFailCount() {
 417         return getLongValue(memory, "memory.kmem.failcnt");
 418     }
 419 
 420     public long getKernelMemoryLimit() {
 421         return CgroupV1SubsystemController.longValOrUnlimited(getLongValue(memory, "memory.kmem.limit_in_bytes"));

 422     }
 423 
 424     public long getKernelMemoryMaxUsage() {
 425         return getLongValue(memory, "memory.kmem.max_usage_in_bytes");
 426     }
 427 
 428     public long getKernelMemoryUsage() {
 429         return getLongValue(memory, "memory.kmem.usage_in_bytes");
 430     }
 431 
 432     public long getTcpMemoryFailCount() {
 433         return getLongValue(memory, "memory.kmem.tcp.failcnt");
 434     }
 435 
 436     public long getTcpMemoryLimit() {
 437         return CgroupV1SubsystemController.longValOrUnlimited(getLongValue(memory, "memory.kmem.tcp.limit_in_bytes"));

 438     }
 439 
 440     public long getTcpMemoryMaxUsage() {
 441         return getLongValue(memory, "memory.kmem.tcp.max_usage_in_bytes");
 442     }
 443 
 444     public long getTcpMemoryUsage() {
 445         return getLongValue(memory, "memory.kmem.tcp.usage_in_bytes");
 446     }
 447 
 448     public long getMemoryAndSwapFailCount() {
 449         return getLongValue(memory, "memory.memsw.failcnt");
 450     }
 451 
 452     public long getMemoryAndSwapLimit() {
 453         long retval = getLongValue(memory, "memory.memsw.limit_in_bytes");
 454         if (retval > CgroupV1SubsystemController.UNLIMITED_MIN) {
 455             if (memory.isHierarchical()) {
 456                 // memory.memsw.limit_in_bytes returned unlimited, attempt
 457                 // hierarchical memory limit
 458                 String match = "hierarchical_memsw_limit";
 459                 retval = CgroupSubsystemController.getLongValueMatchingLine(memory,
 460                                                             "memory.stat",
 461                                                             match,
 462                                                             CgroupV1Subsystem::convertHierachicalLimitLine);
 463             }
 464         }
 465         return CgroupV1SubsystemController.longValOrUnlimited(retval);
 466     }
 467 
 468     public long getMemoryAndSwapMaxUsage() {
 469         return getLongValue(memory, "memory.memsw.max_usage_in_bytes");
 470     }
 471 
 472     public long getMemoryAndSwapUsage() {
 473         return getLongValue(memory, "memory.memsw.usage_in_bytes");
 474     }
 475 
 476     public boolean isMemoryOOMKillEnabled() {
 477         long val = CgroupSubsystemController.getLongEntry(memory, "memory.oom_control", "oom_kill_disable");
 478         return (val == 0);
 479     }
 480 
 481     public long getMemorySoftLimit() {
 482         return CgroupV1SubsystemController.longValOrUnlimited(getLongValue(memory, "memory.soft_limit_in_bytes"));

 483     }
 484 
 485 
 486     /*****************************************************************
 487      * BlKIO Subsystem
 488      ****************************************************************/
 489 
 490 
 491     public long getBlkIOServiceCount() {
 492         return CgroupSubsystemController.getLongEntry(blkio, "blkio.throttle.io_service_bytes", "Total");
 493     }
 494 
 495     public long getBlkIOServiced() {
 496         return CgroupSubsystemController.getLongEntry(blkio, "blkio.throttle.io_serviced", "Total");
 497     }
 498 
 499 }
< prev index next >