1 /* 2 * Copyright (c) 2018, 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.BufferedReader; 29 import java.io.IOException; 30 import java.math.BigInteger; 31 import java.nio.file.Files; 32 import java.nio.file.Path; 33 import java.nio.file.Paths; 34 import java.util.ArrayList; 35 import java.util.Optional; 36 import java.util.stream.Stream; 37 38 public class SubSystem { 39 String root; 40 String mountPoint; 41 String path; 42 43 public SubSystem(String root, String mountPoint) { 44 this.root = root; 45 this.mountPoint = mountPoint; 46 } 47 48 public void setPath(String cgroupPath) { 49 if (root != null && cgroupPath != null) { 50 if (root.equals("/")) { 51 if (!cgroupPath.equals("/")) { 52 path = mountPoint + cgroupPath; 53 } 54 else { 55 path = mountPoint; 56 } 57 } 58 else { 59 if (root.equals(cgroupPath)) { 60 path = mountPoint; 61 } 62 else { 63 if (root.indexOf(cgroupPath) == 0) { 64 if (cgroupPath.length() > root.length()) { 65 String cgroupSubstr = cgroupPath.substring(root.length()); 66 path = mountPoint + cgroupSubstr; 67 } 68 } 69 } 70 } 71 } 72 } 73 74 public String path() { 75 return path; 76 } 77 78 /** 79 * getSubSystemStringValue 80 * 81 * Return the first line of the file "parm" argument from the subsystem. 82 * 83 * TODO: Consider using weak references for caching BufferedReader object. 84 * 85 * @param subsystem 86 * @param parm 87 * @return Returns the contents of the file specified by param. 88 */ 89 public static String getStringValue(SubSystem subsystem, String parm) { 90 if (subsystem == null) return null; 91 92 try(BufferedReader bufferedReader = Files.newBufferedReader(Paths.get(subsystem.path(), parm))) { 93 String line = bufferedReader.readLine(); 94 return line; 95 } 96 catch (IOException e) { 97 return null; 98 } 99 100 } 101 102 public static long getLongValue(SubSystem subsystem, String parm) { 103 String strval = getStringValue(subsystem, parm); 104 long retval = 0; 105 106 if (strval == null) return 0L; 107 108 try { 109 retval = Long.parseLong(strval); 110 } catch (NumberFormatException e) { 111 // For some properties (e.g. memory.limit_in_bytes) we may overflow the range of signed long. 112 // In this case, return Long.max 113 BigInteger b = new BigInteger(strval); 114 if (b.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) { 115 return Long.MAX_VALUE; 116 } 117 } 118 return retval; 119 } 120 121 public static double getDoubleValue(SubSystem subsystem, String parm) { 122 String strval = getStringValue(subsystem, parm); 123 124 if (strval == null) return 0L; 125 126 double retval = Double.parseDouble(strval); 127 128 return retval; 129 } 130 131 /** 132 * getSubSystemlongEntry 133 * 134 * Return the long value from the line containing the string "entryname" 135 * within file "parm" in the "subsystem". 136 * 137 * TODO: Consider using weak references for caching BufferedReader object. 138 * 139 * @param subsystem 140 * @param parm 141 * @param entryname 142 * @return long value 143 */ 144 public static long getLongEntry(SubSystem subsystem, String parm, String entryname) { 145 String val = null; 146 147 if (subsystem == null) return 0L; 148 149 try (Stream<String> lines = Files.lines(Paths.get(subsystem.path(), parm))) { 150 151 Optional<String> result = lines.map(line -> line.split(" ")) 152 .filter(line -> (line.length == 2 && 153 line[0].equals(entryname))) 154 .map(line -> line[1]) 155 .findFirst(); 156 157 return result.isPresent() ? Long.parseLong(result.get()) : 0L; 158 } 159 catch (IOException e) { 160 return 0L; 161 } 162 } 163 164 public static int getIntValue(SubSystem subsystem, String parm) { 165 String val = getStringValue(subsystem, parm); 166 167 if (val == null) return 0; 168 169 return Integer.parseInt(val); 170 } 171 172 /** 173 * StringRangeToIntArray 174 * 175 * Convert a string in the form of 1,3-4,6 to an array of 176 * integers containing all the numbers in the range. 177 * 178 * @param range 179 * @return int[] containing a sorted list of processors or memory nodes 180 */ 181 public static int[] StringRangeToIntArray(String range) { 182 int[] ints = new int[0]; 183 184 if (range == null) return ints; 185 186 ArrayList<Integer> results = new ArrayList<>(); 187 String strs[] = range.split(","); 188 for (String str : strs) { 189 if (str.contains("-")) { 190 String lohi[] = str.split("-"); 191 // validate format 192 if (lohi.length != 2) { 193 continue; 194 } 195 int lo = Integer.parseInt(lohi[0]); 196 int hi = Integer.parseInt(lohi[1]); 197 for (int i = lo; i <= hi; i++) { 198 results.add(i); 199 } 200 } 201 else { 202 results.add(Integer.parseInt(str)); 203 } 204 } 205 206 // sort results 207 results.sort(null); 208 209 // convert ArrayList to primitive int array 210 ints = new int[results.size()]; 211 int i = 0; 212 for (Integer n : results) { 213 ints[i++] = n; 214 } 215 216 return ints; 217 } 218 }