Platform.java revision 2745:9c8a884f35c1
1/*
2 * Copyright (c) 2013, 2016, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24package jdk.test.lib;
25
26import java.io.IOException;
27import java.nio.file.Files;
28import java.nio.file.Path;
29import java.nio.file.Paths;
30import java.util.regex.Pattern;
31
32public class Platform {
33    public  static final String vmName      = System.getProperty("java.vm.name");
34    public  static final String vmInfo      = System.getProperty("java.vm.info");
35    private static final String osVersion   = System.getProperty("os.version");
36    private static       int osVersionMajor = -1;
37    private static       int osVersionMinor = -1;
38    private static final String osName      = System.getProperty("os.name");
39    private static final String dataModel   = System.getProperty("sun.arch.data.model");
40    private static final String vmVersion   = System.getProperty("java.vm.version");
41    private static final String jdkDebug    = System.getProperty("jdk.debug");
42    private static final String osArch      = System.getProperty("os.arch");
43    private static final String userName    = System.getProperty("user.name");
44    private static final String compiler    = System.getProperty("sun.management.compiler");
45
46    public static boolean isClient() {
47        return vmName.endsWith(" Client VM");
48    }
49
50    public static boolean isServer() {
51        return vmName.endsWith(" Server VM");
52    }
53
54    public static boolean isGraal() {
55        return vmName.endsWith(" Graal VM");
56    }
57
58    public static boolean isZero() {
59        return vmName.endsWith(" Zero VM");
60    }
61
62    public static boolean isMinimal() {
63        return vmName.endsWith(" Minimal VM");
64    }
65
66    public static boolean isEmbedded() {
67        return vmName.contains("Embedded");
68    }
69
70    public static boolean isEmulatedClient() {
71        return vmInfo.contains(" emulated-client");
72    }
73
74    public static boolean isTieredSupported() {
75        return compiler.contains("Tiered Compilers");
76    }
77
78    public static boolean isInt() {
79        return vmInfo.contains("interpreted");
80    }
81
82    public static boolean isMixed() {
83        return vmInfo.contains("mixed");
84    }
85
86    public static boolean isComp() {
87        return vmInfo.contains("compiled");
88    }
89
90    public static boolean is32bit() {
91        return dataModel.equals("32");
92    }
93
94    public static boolean is64bit() {
95        return dataModel.equals("64");
96    }
97
98    public static boolean isAix() {
99        return isOs("aix");
100    }
101
102    public static boolean isLinux() {
103        return isOs("linux");
104    }
105
106    public static boolean isOSX() {
107        return isOs("mac");
108    }
109
110    public static boolean isSolaris() {
111        return isOs("sunos");
112    }
113
114    public static boolean isWindows() {
115        return isOs("win");
116    }
117
118    private static boolean isOs(String osname) {
119        return osName.toLowerCase().startsWith(osname.toLowerCase());
120    }
121
122    public static String getOsName() {
123        return osName;
124    }
125
126    // Os version support.
127    private static void init_version() {
128        try {
129            final String[] tokens = osVersion.split("\\.");
130            if (tokens.length > 0) {
131                osVersionMajor = Integer.parseInt(tokens[0]);
132                if (tokens.length > 1) {
133                    osVersionMinor = Integer.parseInt(tokens[1]);
134                }
135            }
136        } catch (NumberFormatException e) {
137            osVersionMajor = osVersionMinor = 0;
138        }
139    }
140
141    // Returns major version number from os.version system property.
142    // E.g. 5 on Solaris 10 and 3 on SLES 11.3 (for the linux kernel version).
143    public static int getOsVersionMajor() {
144        if (osVersionMajor == -1) init_version();
145        return osVersionMajor;
146    }
147
148    // Returns minor version number from os.version system property.
149    // E.g. 10 on Solaris 10 and 0 on SLES 11.3 (for the linux kernel version).
150    public static int getOsVersionMinor() {
151        if (osVersionMinor == -1) init_version();
152        return osVersionMinor;
153    }
154
155    public static boolean isDebugBuild() {
156        return (jdkDebug.toLowerCase().contains("debug"));
157    }
158
159    public static boolean isSlowDebugBuild() {
160        return (jdkDebug.toLowerCase().equals("slowdebug"));
161    }
162
163    public static boolean isFastDebugBuild() {
164        return (jdkDebug.toLowerCase().equals("fastdebug"));
165    }
166
167    public static String getVMVersion() {
168        return vmVersion;
169    }
170
171    public static boolean isAArch64() {
172        return isArch("aarch64");
173    }
174
175    public static boolean isARM() {
176        return isArch("arm.*");
177    }
178
179    public static boolean isPPC() {
180        return isArch("ppc.*");
181    }
182
183    // Returns true for IBM z System running linux.
184    public static boolean isS390x() {
185        return isArch("s390.*") || isArch("s/390.*") || isArch("zArch_64");
186    }
187
188    // Returns true for sparc and sparcv9.
189    public static boolean isSparc() {
190        return isArch("sparc.*");
191    }
192
193    public static boolean isX64() {
194        // On OSX it's 'x86_64' and on other (Linux, Windows and Solaris) platforms it's 'amd64'
195        return isArch("(amd64)|(x86_64)");
196    }
197
198    public static boolean isX86() {
199        // On Linux it's 'i386', Windows 'x86' without '_64' suffix.
200        return isArch("(i386)|(x86(?!_64))");
201    }
202
203    public static String getOsArch() {
204        return osArch;
205    }
206
207    /**
208     * Return a boolean for whether we expect to be able to attach
209     * the SA to our own processes on this system.
210     */
211    public static boolean shouldSAAttach() throws Exception {
212
213        if (isAix()) {
214            return false;   // SA not implemented.
215        } else if (isLinux()) {
216            if (isS390x()) { return false; }   // SA not implemented.
217            return canPtraceAttachLinux();
218        } else if (isOSX()) {
219            return canAttachOSX();
220        } else {
221            // Other platforms expected to work:
222            return true;
223        }
224    }
225
226    /**
227     * On Linux, first check the SELinux boolean "deny_ptrace" and return false
228     * as we expect to be denied if that is "1".  Then expect permission to attach
229     * if we are root, so return true.  Then return false for an expected denial
230     * if "ptrace_scope" is 1, and true otherwise.
231     */
232    public static boolean canPtraceAttachLinux() throws Exception {
233
234        // SELinux deny_ptrace:
235        String deny_ptrace = fileAsString("/sys/fs/selinux/booleans/deny_ptrace");
236        if (deny_ptrace != null && deny_ptrace.contains("1")) {
237            // ptrace will be denied:
238            return false;
239        }
240
241        // YAMA enhanced security ptrace_scope:
242        // 0 - a process can PTRACE_ATTACH to any other process running under the same uid
243        // 1 - restricted ptrace: a process must be a children of the inferior or user is root
244        // 2 - only processes with CAP_SYS_PTRACE may use ptrace or user is root
245        // 3 - no attach: no processes may use ptrace with PTRACE_ATTACH
246        String ptrace_scope = fileAsString("/proc/sys/kernel/yama/ptrace_scope");
247        if (ptrace_scope != null) {
248            if (ptrace_scope.startsWith("3")) {
249                return false;
250            }
251            if (!userName.equals("root") && !ptrace_scope.startsWith("0")) {
252                // ptrace will be denied:
253                return false;
254            }
255        }
256        // Otherwise expect to be permitted:
257        return true;
258    }
259
260    /**
261     * On OSX, expect permission to attach only if we are root.
262     */
263    public static boolean canAttachOSX() throws Exception {
264        return userName.equals("root");
265    }
266
267    private static boolean isArch(String archnameRE) {
268        return Pattern.compile(archnameRE, Pattern.CASE_INSENSITIVE)
269                      .matcher(osArch)
270                      .matches();
271    }
272
273    private static String fileAsString(String filename) throws IOException {
274        Path filePath = Paths.get(filename);
275        if (!Files.exists(filePath)) return null;
276        return new String(Files.readAllBytes(filePath));
277    }
278}
279