Path: blob/master/src/java.base/linux/classes/jdk/internal/platform/CgroupSubsystemController.java
40948 views
/*1* Copyright (c) 2020, Red Hat Inc.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package jdk.internal.platform;2627import java.io.IOException;28import java.io.UncheckedIOException;29import java.math.BigInteger;30import java.nio.file.Path;31import java.nio.file.Paths;32import java.util.ArrayList;33import java.util.List;34import java.util.Optional;35import java.util.function.Function;36import java.util.stream.Stream;3738/**39* Cgroup version agnostic controller logic40*41*/42public interface CgroupSubsystemController {4344public static final String EMPTY_STR = "";4546public String path();4748/**49* getStringValue50*51* Return the first line of the file "param" argument from the controller.52*53* TODO: Consider using weak references for caching BufferedReader object.54*55* @param controller56* @param param57* @return Returns the contents of the file specified by param or null if58* an error occurs.59*/60public static String getStringValue(CgroupSubsystemController controller, String param) {61if (controller == null) return null;6263try {64return CgroupUtil.readStringValue(controller, param);65}66catch (IOException e) {67return null;68}6970}7172/**73* Get an entry from file "param" within the "controller" directory path74* which matches string "match". Applies "conversion" to the matching line.75*76* @param controller77* @param param78* @param match79* @param conversion80* @param defaultRetval81* @return The long value as derived by applying "conversion" to the matching82* line or "defaultRetval" if there was an error or no match found.83*/84public static long getLongValueMatchingLine(CgroupSubsystemController controller,85String param,86String match,87Function<String, Long> conversion,88long defaultRetval) {89long retval = defaultRetval;90if (controller == null) {91return retval;92}93try {94Path filePath = Paths.get(controller.path(), param);95List<String> lines = CgroupUtil.readAllLinesPrivileged(filePath);96for (String line : lines) {97if (line.startsWith(match)) {98retval = conversion.apply(line);99break;100}101}102} catch (IOException e) {103// Ignore. Default is unlimited.104}105return retval;106}107108/**109* Get a long value from directory "controller" and file "param", by110* applying "conversion" to the string value within the file.111*112* @param controller113* @param param114* @param conversion115* @param defaultRetval116* @return The converted long value or "defaultRetval" if there was an117* error.118*/119public static long getLongValue(CgroupSubsystemController controller,120String param,121Function<String, Long> conversion,122long defaultRetval) {123String strval = getStringValue(controller, param);124if (strval == null) return defaultRetval;125return conversion.apply(strval);126}127128/**129* Get a double value from file "param" within "controller".130*131* @param controller132* @param param133* @param defaultRetval134* @return The double value or "defaultRetval" if there was an error.135*/136public static double getDoubleValue(CgroupSubsystemController controller, String param, double defaultRetval) {137String strval = getStringValue(controller, param);138139if (strval == null) return defaultRetval;140141double retval = Double.parseDouble(strval);142143return retval;144}145146/**147* getLongEntry148*149* Return the long value from the line containing the string "entryname"150* within file "param" in the "controller".151*152* TODO: Consider using weak references for caching BufferedReader object.153*154* @param controller155* @param param156* @param entryname157* @return long value or "defaultRetval" if there was an error or no match158* was found.159*/160public static long getLongEntry(CgroupSubsystemController controller, String param, String entryname, long defaultRetval) {161if (controller == null) return defaultRetval;162163try (Stream<String> lines = CgroupUtil.readFilePrivileged(Paths.get(controller.path(), param))) {164165Optional<String> result = lines.map(line -> line.split(" "))166.filter(line -> (line.length == 2 &&167line[0].equals(entryname)))168.map(line -> line[1])169.findFirst();170171return result.isPresent() ? Long.parseLong(result.get()) : defaultRetval;172} catch (UncheckedIOException e) {173return defaultRetval;174} catch (IOException e) {175return defaultRetval;176}177}178179/**180* stringRangeToIntArray181*182* Convert a string in the form of 1,3-4,6 to an array of183* integers containing all the numbers in the range.184*185* @param range186* @return int[] containing a sorted list of numbers as represented by187* the string range. Returns null if there was an error or the input188* was an empty string.189*/190public static int[] stringRangeToIntArray(String range) {191if (range == null || EMPTY_STR.equals(range)) return null;192193ArrayList<Integer> results = new ArrayList<>();194String strs[] = range.split(",");195for (String str : strs) {196if (str.contains("-")) {197String lohi[] = str.split("-");198// validate format199if (lohi.length != 2) {200continue;201}202int lo = Integer.parseInt(lohi[0]);203int hi = Integer.parseInt(lohi[1]);204for (int i = lo; i <= hi; i++) {205results.add(i);206}207}208else {209results.add(Integer.parseInt(str));210}211}212213// sort results214results.sort(null);215216// convert ArrayList to primitive int array217int[] ints = new int[results.size()];218int i = 0;219for (Integer n : results) {220ints[i++] = n;221}222223return ints;224}225226/**227* Convert a number from its string representation to a long.228*229* @param strval230* @param overflowRetval231* @param defaultRetval232* @return The converted long value. "overflowRetval" is returned if the233* string representation exceeds the range of type long.234* "defaultRetval" is returned if another type of error occurred235* during conversion.236*/237public static long convertStringToLong(String strval, long overflowRetval, long defaultRetval) {238long retval = defaultRetval;239if (strval == null) return retval;240241try {242retval = Long.parseLong(strval);243} catch (NumberFormatException e) {244// For some properties (e.g. memory.limit_in_bytes, cgroups v1) we may overflow245// the range of signed long. In this case, return overflowRetval246BigInteger b = new BigInteger(strval);247if (b.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {248return overflowRetval;249}250}251return retval;252}253254}255256257