1212import org .elasticsearch .common .settings .Settings ;
1313import org .elasticsearch .common .util .concurrent .EsExecutors ;
1414
15+ import java .io .IOException ;
16+ import java .nio .file .Files ;
17+ import java .nio .file .Path ;
1518import java .util .List ;
1619import java .util .Map ;
17- import java .util .stream .Collectors ;
1820import java .util .stream .Stream ;
1921
2022final class SystemJvmOptions {
2123
2224 static List <String > systemJvmOptions (Settings nodeSettings , final Map <String , String > sysprops ) {
2325 String distroType = sysprops .get ("es.distribution.type" );
2426 boolean isHotspot = sysprops .getOrDefault ("sun.management.compiler" , "" ).contains ("HotSpot" );
25-
26- return Stream .concat (
27+ boolean useEntitlements = Boolean . parseBoolean ( sysprops . getOrDefault ( "es.entitlements.enabled" , "false" ));
28+ return Stream .of (
2729 Stream .of (
2830 /*
2931 * Cache ttl in seconds for positive DNS lookups noting that this overrides the JDK security property
@@ -35,8 +37,6 @@ static List<String> systemJvmOptions(Settings nodeSettings, final Map<String, St
3537 * networkaddress.cache.negative ttl; set to -1 to cache forever.
3638 */
3739 "-Des.networkaddress.cache.negative.ttl=10" ,
38- // Allow to set the security manager.
39- "-Djava.security.manager=allow" ,
4040 // pre-touch JVM emory pages during initialization
4141 "-XX:+AlwaysPreTouch" ,
4242 // explicitly set the stack size
@@ -61,15 +61,17 @@ static List<String> systemJvmOptions(Settings nodeSettings, final Map<String, St
6161 "-Dlog4j2.disable.jmx=true" ,
6262 "-Dlog4j2.formatMsgNoLookups=true" ,
6363 "-Djava.locale.providers=CLDR" ,
64- maybeEnableNativeAccess (),
65- maybeOverrideDockerCgroup (distroType ),
66- maybeSetActiveProcessorCount (nodeSettings ),
67- setReplayFile (distroType , isHotspot ),
6864 // Pass through distribution type
6965 "-Des.distribution.type=" + distroType
7066 ),
71- maybeWorkaroundG1Bug ()
72- ).filter (e -> e .isEmpty () == false ).collect (Collectors .toList ());
67+ maybeEnableNativeAccess (),
68+ maybeOverrideDockerCgroup (distroType ),
69+ maybeSetActiveProcessorCount (nodeSettings ),
70+ maybeSetReplayFile (distroType , isHotspot ),
71+ maybeWorkaroundG1Bug (),
72+ maybeAllowSecurityManager (),
73+ maybeAttachEntitlementAgent (useEntitlements )
74+ ).flatMap (s -> s ).toList ();
7375 }
7476
7577 /*
@@ -86,42 +88,42 @@ static List<String> systemJvmOptions(Settings nodeSettings, final Map<String, St
8688 * that cgroup statistics are available for the container this process
8789 * will run in.
8890 */
89- private static String maybeOverrideDockerCgroup (String distroType ) {
91+ private static Stream < String > maybeOverrideDockerCgroup (String distroType ) {
9092 if ("docker" .equals (distroType )) {
91- return "-Des.cgroups.hierarchy.override=/" ;
93+ return Stream . of ( "-Des.cgroups.hierarchy.override=/" ) ;
9294 }
93- return "" ;
95+ return Stream . empty () ;
9496 }
9597
96- private static String setReplayFile (String distroType , boolean isHotspot ) {
98+ private static Stream < String > maybeSetReplayFile (String distroType , boolean isHotspot ) {
9799 if (isHotspot == false ) {
98100 // the replay file option is only guaranteed for hotspot vms
99- return "" ;
101+ return Stream . empty () ;
100102 }
101103 String replayDir = "logs" ;
102104 if ("rpm" .equals (distroType ) || "deb" .equals (distroType )) {
103105 replayDir = "/var/log/elasticsearch" ;
104106 }
105- return "-XX:ReplayDataFile=" + replayDir + "/replay_pid%p.log" ;
107+ return Stream . of ( "-XX:ReplayDataFile=" + replayDir + "/replay_pid%p.log" ) ;
106108 }
107109
108110 /*
109111 * node.processors determines thread pool sizes for Elasticsearch. When it
110112 * is set, we need to also tell the JVM to respect a different value
111113 */
112- private static String maybeSetActiveProcessorCount (Settings nodeSettings ) {
114+ private static Stream < String > maybeSetActiveProcessorCount (Settings nodeSettings ) {
113115 if (EsExecutors .NODE_PROCESSORS_SETTING .exists (nodeSettings )) {
114116 int allocated = EsExecutors .allocatedProcessors (nodeSettings );
115- return "-XX:ActiveProcessorCount=" + allocated ;
117+ return Stream . of ( "-XX:ActiveProcessorCount=" + allocated ) ;
116118 }
117- return "" ;
119+ return Stream . empty () ;
118120 }
119121
120- private static String maybeEnableNativeAccess () {
122+ private static Stream < String > maybeEnableNativeAccess () {
121123 if (Runtime .version ().feature () >= 21 ) {
122- return "--enable-native-access=org.elasticsearch.nativeaccess,org.apache.lucene.core" ;
124+ return Stream . of ( "--enable-native-access=org.elasticsearch.nativeaccess,org.apache.lucene.core" ) ;
123125 }
124- return "" ;
126+ return Stream . empty () ;
125127 }
126128
127129 /*
@@ -134,4 +136,37 @@ private static Stream<String> maybeWorkaroundG1Bug() {
134136 }
135137 return Stream .of ();
136138 }
139+
140+ private static Stream <String > maybeAllowSecurityManager () {
141+ // Will become conditional on useEntitlements once entitlements can run without SM
142+ return Stream .of ("-Djava.security.manager=allow" );
143+ }
144+
145+ private static Stream <String > maybeAttachEntitlementAgent (boolean useEntitlements ) {
146+ if (useEntitlements == false ) {
147+ return Stream .empty ();
148+ }
149+
150+ Path dir = Path .of ("lib" , "entitlement-bridge" );
151+ if (Files .exists (dir ) == false ) {
152+ throw new IllegalStateException ("Directory for entitlement bridge jar does not exist: " + dir );
153+ }
154+ String bridgeJar ;
155+ try (var s = Files .list (dir )) {
156+ var candidates = s .limit (2 ).toList ();
157+ if (candidates .size () != 1 ) {
158+ throw new IllegalStateException ("Expected one jar in " + dir + "; found " + candidates .size ());
159+ }
160+ bridgeJar = candidates .get (0 ).toString ();
161+ } catch (IOException e ) {
162+ throw new IllegalStateException ("Failed to list entitlement jars in: " + dir , e );
163+ }
164+ return Stream .of (
165+ "-Des.entitlements.enabled=true" ,
166+ "-XX:+EnableDynamicAgentLoading" ,
167+ "-Djdk.attach.allowAttachSelf=true" ,
168+ "--patch-module=java.base=" + bridgeJar ,
169+ "--add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement"
170+ );
171+ }
137172}
0 commit comments