]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/java/src/main/java/org/rocksdb/util/Environment.java
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / java / src / main / java / org / rocksdb / util / Environment.java
1 // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
2 package org.rocksdb.util;
3
4 import java.io.File;
5 import java.io.IOException;
6
7 public class Environment {
8 private static String OS = System.getProperty("os.name").toLowerCase();
9 private static String ARCH = System.getProperty("os.arch").toLowerCase();
10 private static String MUSL_ENVIRONMENT = System.getenv("ROCKSDB_MUSL_LIBC");
11
12 /**
13 * Will be lazily initialised by {@link #isMuslLibc()} instead of the previous static
14 * initialisation. The lazy initialisation prevents Windows from reporting suspicious behaviour of
15 * the JVM attempting IO on Unix paths.
16 */
17 private static Boolean MUSL_LIBC = null;
18
19 public static boolean isAarch64() {
20 return ARCH.contains("aarch64");
21 }
22
23 public static boolean isPowerPC() {
24 return ARCH.contains("ppc");
25 }
26
27 public static boolean isS390x() {
28 return ARCH.contains("s390x");
29 }
30
31 public static boolean isWindows() {
32 return (OS.contains("win"));
33 }
34
35 public static boolean isFreeBSD() {
36 return (OS.contains("freebsd"));
37 }
38
39 public static boolean isMac() {
40 return (OS.contains("mac"));
41 }
42
43 public static boolean isAix() {
44 return OS.contains("aix");
45 }
46
47 public static boolean isUnix() {
48 return OS.contains("nix") ||
49 OS.contains("nux");
50 }
51
52 /**
53 * Determine if the environment has a musl libc.
54 *
55 * @return true if the environment has a musl libc, false otherwise.
56 */
57 public static boolean isMuslLibc() {
58 if (MUSL_LIBC == null) {
59 MUSL_LIBC = initIsMuslLibc();
60 }
61 return MUSL_LIBC;
62 }
63
64 /**
65 * Determine if the environment has a musl libc.
66 *
67 * The initialisation counterpart of {@link #isMuslLibc()}.
68 *
69 * Intentionally package-private for testing.
70 *
71 * @return true if the environment has a musl libc, false otherwise.
72 */
73 static boolean initIsMuslLibc() {
74 // consider explicit user setting from environment first
75 if ("true".equalsIgnoreCase(MUSL_ENVIRONMENT)) {
76 return true;
77 }
78 if ("false".equalsIgnoreCase(MUSL_ENVIRONMENT)) {
79 return false;
80 }
81
82 // check if ldd indicates a muslc lib
83 try {
84 final Process p =
85 new ProcessBuilder("/usr/bin/env", "sh", "-c", "ldd /usr/bin/env | grep -q musl").start();
86 if (p.waitFor() == 0) {
87 return true;
88 }
89 } catch (final IOException | InterruptedException e) {
90 // do nothing, and move on to the next check
91 }
92
93 final File lib = new File("/lib");
94 if (lib.exists() && lib.isDirectory() && lib.canRead()) {
95 // attempt the most likely musl libc name first
96 final String possibleMuslcLibName;
97 if (isPowerPC()) {
98 possibleMuslcLibName = "libc.musl-ppc64le.so.1";
99 } else if (isAarch64()) {
100 possibleMuslcLibName = "libc.musl-aarch64.so.1";
101 } else if (isS390x()) {
102 possibleMuslcLibName = "libc.musl-s390x.so.1";
103 } else {
104 possibleMuslcLibName = "libc.musl-x86_64.so.1";
105 }
106 final File possibleMuslcLib = new File(lib, possibleMuslcLibName);
107 if (possibleMuslcLib.exists() && possibleMuslcLib.canRead()) {
108 return true;
109 }
110
111 // fallback to scanning for a musl libc
112 final File[] libFiles = lib.listFiles();
113 if (libFiles == null) {
114 return false;
115 }
116 for (final File f : libFiles) {
117 if (f.getName().startsWith("libc.musl")) {
118 return true;
119 }
120 }
121 }
122
123 return false;
124 }
125
126 public static boolean isSolaris() {
127 return OS.contains("sunos");
128 }
129
130 public static boolean isOpenBSD() {
131 return (OS.contains("openbsd"));
132 }
133
134 public static boolean is64Bit() {
135 if (ARCH.indexOf("sparcv9") >= 0) {
136 return true;
137 }
138 return (ARCH.indexOf("64") > 0);
139 }
140
141 public static String getSharedLibraryName(final String name) {
142 return name + "jni";
143 }
144
145 public static String getSharedLibraryFileName(final String name) {
146 return appendLibOsSuffix("lib" + getSharedLibraryName(name), true);
147 }
148
149 /**
150 * Get the name of the libc implementation
151 *
152 * @return the name of the implementation,
153 * or null if the default for that platform (e.g. glibc on Linux).
154 */
155 public static /* @Nullable */ String getLibcName() {
156 if (isMuslLibc()) {
157 return "musl";
158 } else {
159 return null;
160 }
161 }
162
163 private static String getLibcPostfix() {
164 final String libcName = getLibcName();
165 if (libcName == null) {
166 return "";
167 }
168 return "-" + libcName;
169 }
170
171 public static String getJniLibraryName(final String name) {
172 if (isUnix()) {
173 final String arch = is64Bit() ? "64" : "32";
174 if (isPowerPC() || isAarch64()) {
175 return String.format("%sjni-linux-%s%s", name, ARCH, getLibcPostfix());
176 } else if (isS390x()) {
177 return String.format("%sjni-linux-%s", name, ARCH);
178 } else {
179 return String.format("%sjni-linux%s%s", name, arch, getLibcPostfix());
180 }
181 } else if (isMac()) {
182 if (is64Bit()) {
183 final String arch;
184 if (isAarch64()) {
185 arch = "arm64";
186 } else {
187 arch = "x86_64";
188 }
189 return String.format("%sjni-osx-%s", name, arch);
190 } else {
191 return String.format("%sjni-osx", name);
192 }
193 } else if (isFreeBSD()) {
194 return String.format("%sjni-freebsd%s", name, is64Bit() ? "64" : "32");
195 } else if (isAix() && is64Bit()) {
196 return String.format("%sjni-aix64", name);
197 } else if (isSolaris()) {
198 final String arch = is64Bit() ? "64" : "32";
199 return String.format("%sjni-solaris%s", name, arch);
200 } else if (isWindows() && is64Bit()) {
201 return String.format("%sjni-win64", name);
202 } else if (isOpenBSD()) {
203 return String.format("%sjni-openbsd%s", name, is64Bit() ? "64" : "32");
204 }
205
206 throw new UnsupportedOperationException(String.format("Cannot determine JNI library name for ARCH='%s' OS='%s' name='%s'", ARCH, OS, name));
207 }
208
209 public static /*@Nullable*/ String getFallbackJniLibraryName(final String name) {
210 if (isMac() && is64Bit()) {
211 return String.format("%sjni-osx", name);
212 }
213 return null;
214 }
215
216 public static String getJniLibraryFileName(final String name) {
217 return appendLibOsSuffix("lib" + getJniLibraryName(name), false);
218 }
219
220 public static /*@Nullable*/ String getFallbackJniLibraryFileName(final String name) {
221 final String fallbackJniLibraryName = getFallbackJniLibraryName(name);
222 if (fallbackJniLibraryName == null) {
223 return null;
224 }
225 return appendLibOsSuffix("lib" + fallbackJniLibraryName, false);
226 }
227
228 private static String appendLibOsSuffix(final String libraryFileName, final boolean shared) {
229 if (isUnix() || isAix() || isSolaris() || isFreeBSD() || isOpenBSD()) {
230 return libraryFileName + ".so";
231 } else if (isMac()) {
232 return libraryFileName + (shared ? ".dylib" : ".jnilib");
233 } else if (isWindows()) {
234 return libraryFileName + ".dll";
235 }
236 throw new UnsupportedOperationException();
237 }
238
239 public static String getJniLibraryExtension() {
240 if (isWindows()) {
241 return ".dll";
242 }
243 return (isMac()) ? ".jnilib" : ".so";
244 }
245 }