Skip to content

Commit 7b9f904

Browse files
committed
FreeBSD Native Access
1 parent 8d6faef commit 7b9f904

File tree

9 files changed

+159
-4
lines changed

9 files changed

+159
-4
lines changed
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.nativeaccess;
11+
12+
import org.elasticsearch.nativeaccess.lib.BsdCLibrary;
13+
import org.elasticsearch.nativeaccess.lib.NativeLibraryProvider;
14+
import org.elasticsearch.nativeaccess.lib.PosixCLibrary;
15+
16+
public class FreebsdNativeAccess extends PosixNativeAccess {
17+
18+
private final BsdCLibrary bsdLibc;
19+
static final int RLIMIT_NPROC = 7;
20+
21+
// https://github.com/freebsd/freebsd-src/blob/release/14.2.0/sys/sys/resource.h#L123
22+
// https://man.freebsd.org/cgi/man.cgi?stat(2)
23+
// https://github.com/freebsd/freebsd-src/blob/release/14.2.0/sys/sys/stat.h#L159
24+
// Offset of st_size: 112 bytes
25+
// Offset of st_blocks: 120 bytes
26+
FreebsdNativeAccess(NativeLibraryProvider libraryProvider) {
27+
super("FreeBSD", libraryProvider,
28+
new PosixConstants(
29+
-1L,
30+
10,
31+
1,
32+
6,
33+
512,
34+
144,
35+
112,
36+
120
37+
)
38+
);
39+
40+
this.bsdLibc = libraryProvider.getLibrary(BsdCLibrary.class);
41+
}
42+
43+
// https://github.com/freebsd/freebsd-src/blob/release/14.2.0/sys/sys/resource.h#L110
44+
@Override
45+
protected long getMaxThreads() {
46+
return getRLimit(RLIMIT_NPROC, "max number of threads");
47+
}
48+
49+
@Override
50+
protected void logMemoryLimitInstructions() {
51+
logger.warn("You can allow ElasticSearch to lock large amounts of RAM by setting the following in /etc/sysctl.conf:");
52+
logger.warn("security.bsd.unprivileged_mlock=1\n");
53+
logger.warn("You can also run the following command to modify the value immediately:");
54+
logger.warn("sysctl security.bsd.unprivileged_mlock=1\n");
55+
logger.warn("When running within a Jail, it's highly advisable to set:");
56+
logger.warn("enforce_statfs = 1");
57+
}
58+
59+
@Override
60+
protected boolean nativePreallocate(int fd, long currentSize, long newSize) {
61+
final int rc = bsdLibc.posix_fallocate(fd, currentSize, newSize - currentSize);
62+
if (rc != 0) {
63+
logger.warn("posix_fallocate failed: " + libc.strerror(libc.errno()));
64+
return false;
65+
}
66+
return true;
67+
}
68+
69+
// https://github.com/elastic/elasticsearch/blob/v8.15.5/server/src/main/java/org/elasticsearch/bootstrap/SystemCallFilter.java#L556
70+
@Override
71+
public void tryInstallExecSandbox() {
72+
PosixCLibrary.RLimit limit = libc.newRLimit();
73+
limit.rlim_cur(0);
74+
limit.rlim_max(0);
75+
if (libc.setrlimit(RLIMIT_NPROC, limit) != 0) {
76+
throw new UnsupportedOperationException("RLIMIT_NPROC unavailable: " + libc.strerror(libc.errno()));
77+
}
78+
79+
logger.debug("FreeBSD RLIMIT_NPROC initialization successful");
80+
81+
execSandboxState = ExecSandboxState.ALL_THREADS;
82+
}
83+
}

libs/native/src/main/java/org/elasticsearch/nativeaccess/NativeAccessHolder.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ class NativeAccessHolder {
3131
inst = new MacNativeAccess(libProvider);
3232
} else if (os.startsWith("Windows")) {
3333
inst = new WindowsNativeAccess(libProvider);
34+
} else if (os.startsWith("FreeBSD")) {
35+
inst = new FreebsdNativeAccess(libProvider);
3436
} else {
3537
logger.warn("Unsupported OS [" + os + "]. Native methods will be disabled.");
3638
}

libs/native/src/main/java/org/elasticsearch/nativeaccess/PosixNativeAccess.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ String rlimitToString(long value) {
200200
}
201201

202202
static boolean isNativeVectorLibSupported() {
203-
return Runtime.version().feature() >= 21 && (isMacOrLinuxAarch64() || isLinuxAmd64()) && checkEnableSystemProperty();
203+
return Runtime.version().feature() >= 21 && (isMacOrLinuxAarch64() || isLinuxAmd64() || isFreebsdAmd64()) &&
204+
checkEnableSystemProperty();
204205
}
205206

206207
/**
@@ -217,6 +218,12 @@ static boolean isMacOrLinuxAarch64() {
217218
return (name.startsWith("Mac") || name.startsWith("Linux")) && System.getProperty("os.arch").equals("aarch64");
218219
}
219220

221+
/** Returns true if the OS is FreeBSD, and the architecture is x64. */
222+
static boolean isFreebsdAmd64() {
223+
String name = System.getProperty("os.name");
224+
return (name.startsWith("FreeBSD")) && System.getProperty("os.arch").equals("amd64");
225+
}
226+
220227
/** -Dorg.elasticsearch.nativeaccess.enableVectorLibrary=false to disable.*/
221228
static final String ENABLE_JDK_VECTOR_LIBRARY = "org.elasticsearch.nativeaccess.enableVectorLibrary";
222229

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.nativeaccess.lib;
11+
12+
public non-sealed interface BsdCLibrary extends NativeLibrary {
13+
14+
int posix_fallocate(int fd, long offset, long length);
15+
}

libs/native/src/main/java/org/elasticsearch/nativeaccess/lib/LoaderHelper.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ private static Path findPlatformLibDir() {
4646
os = "linux";
4747
} else if (osname.startsWith("Mac OS")) {
4848
os = "darwin";
49+
} else if (osname.startsWith("FreeBSD")) {
50+
os = "freebsd";
4951
} else {
5052
os = "unsupported_os[" + osname + "]";
5153
}

libs/native/src/main/java/org/elasticsearch/nativeaccess/lib/NativeLibrary.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111

1212
/** A marker interface for libraries that can be loaded by {@link org.elasticsearch.nativeaccess.lib.NativeLibraryProvider} */
1313
public sealed interface NativeLibrary permits JavaLibrary, PosixCLibrary, LinuxCLibrary, MacCLibrary, Kernel32Library, VectorLibrary,
14-
ZstdLibrary {}
14+
ZstdLibrary, BsdCLibrary {}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.nativeaccess.jdk;
11+
12+
import org.elasticsearch.nativeaccess.lib.BsdCLibrary;
13+
14+
import java.lang.foreign.FunctionDescriptor;
15+
import java.lang.invoke.MethodHandle;
16+
17+
import static java.lang.foreign.ValueLayout.JAVA_INT;
18+
import static java.lang.foreign.ValueLayout.JAVA_LONG;
19+
import static org.elasticsearch.nativeaccess.jdk.JdkPosixCLibrary.downcallHandleWithErrno;
20+
import static org.elasticsearch.nativeaccess.jdk.JdkPosixCLibrary.errnoState;
21+
22+
public class JdkFreebsdCLibrary implements BsdCLibrary {
23+
24+
private static final MethodHandle posix_allocate$mh = downcallHandleWithErrno(
25+
"posix_fallocate",
26+
FunctionDescriptor.of(JAVA_INT, JAVA_INT, JAVA_LONG, JAVA_LONG)
27+
);
28+
29+
// https://man.freebsd.org/cgi/man.cgi?query=posix_fallocate
30+
// https://github.com/freebsd/freebsd-src/blob/release/14.2.0/sys/sys/fcntl.h#L390
31+
@Override
32+
public int posix_fallocate(int fd, long offset, long length) {
33+
try {
34+
return (int) posix_allocate$mh.invokeExact(errnoState, fd, offset, length);
35+
} catch (Throwable t) {
36+
throw new AssertionError(t);
37+
}
38+
}
39+
}

libs/native/src/main21/java/org/elasticsearch/nativeaccess/jdk/JdkNativeLibraryProvider.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
package org.elasticsearch.nativeaccess.jdk;
1111

12+
import org.elasticsearch.nativeaccess.lib.BsdCLibrary;
1213
import org.elasticsearch.nativeaccess.lib.JavaLibrary;
1314
import org.elasticsearch.nativeaccess.lib.Kernel32Library;
1415
import org.elasticsearch.nativeaccess.lib.LinuxCLibrary;
@@ -39,7 +40,9 @@ public JdkNativeLibraryProvider() {
3940
ZstdLibrary.class,
4041
JdkZstdLibrary::new,
4142
VectorLibrary.class,
42-
JdkVectorLibrary::new
43+
JdkVectorLibrary::new,
44+
BsdCLibrary.class,
45+
JdkFreebsdCLibrary::new
4346
)
4447
);
4548
}

libs/native/src/main21/java/org/elasticsearch/nativeaccess/jdk/JdkPosixCLibrary.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,12 @@ class JdkPosixCLibrary implements PosixCLibrary {
7979
private static final MethodHandle fstat$mh;
8080
static {
8181
MethodHandle fstat;
82+
String fstatFunc = "fstat64";
8283
try {
83-
fstat = downcallHandleWithErrno("fstat64", FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS));
84+
if (System.getProperty("os.name").equals("FreeBSD")) {
85+
fstatFunc = "fstat";
86+
}
87+
fstat = downcallHandleWithErrno(fstatFunc, FunctionDescriptor.of(JAVA_INT, JAVA_INT, ADDRESS));
8488
} catch (LinkageError e) {
8589
// Due to different sizes of the stat structure for 32 vs 64 bit machines, on some systems fstat actually points to
8690
// an internal symbol. So we fall back to looking for that symbol.

0 commit comments

Comments
 (0)