diff --git a/pom.xml b/pom.xml
index 432aa22744e..8adf415700f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -635,6 +635,9 @@
${tests.security.manager}
${tests.compatibility}
true
+
+ true
${basedir}/src/main/resources/org/elasticsearch/bootstrap/security.policy
diff --git a/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
index d351a9d4ea2..d787ff84289 100644
--- a/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
+++ b/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
@@ -19,6 +19,7 @@
package org.elasticsearch.bootstrap;
+import org.apache.lucene.util.StringHelper;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.Version;
import org.elasticsearch.common.PidFile;
@@ -27,6 +28,7 @@ import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.inject.CreationException;
import org.elasticsearch.common.inject.spi.Message;
import org.elasticsearch.common.io.PathUtils;
+import org.elasticsearch.common.jna.Kernel32Library;
import org.elasticsearch.common.jna.Natives;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
@@ -38,6 +40,7 @@ import org.elasticsearch.monitor.process.JmxProcessProbe;
import org.elasticsearch.node.Node;
import org.elasticsearch.node.NodeBuilder;
import org.elasticsearch.node.internal.InternalSettingsPreparer;
+import org.hyperic.sigar.Sigar;
import java.util.Locale;
import java.util.Set;
@@ -57,24 +60,16 @@ public class Bootstrap {
private static volatile Thread keepAliveThread;
private static volatile CountDownLatch keepAliveLatch;
private static Bootstrap bootstrap;
-
- private void setup(boolean addShutdownHook, Settings settings, Environment environment) throws Exception {
- if (settings.getAsBoolean("bootstrap.mlockall", false)) {
+
+ /** initialize native resources */
+ public static void initializeNatives(boolean mlockAll, boolean ctrlHandler) {
+ // mlockall if requested
+ if (mlockAll) {
Natives.tryMlockall();
}
- NodeBuilder nodeBuilder = NodeBuilder.nodeBuilder().settings(settings).loadConfigSettings(false);
- node = nodeBuilder.build();
- if (addShutdownHook) {
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- node.close();
- }
- });
- }
-
- if (settings.getAsBoolean("bootstrap.ctrlhandler", true)) {
+ // listener for windows close event
+ if (ctrlHandler) {
Natives.addConsoleCtrlHandler(new ConsoleCtrlHandler() {
@Override
public boolean handle(int code) {
@@ -89,7 +84,36 @@ public class Bootstrap {
}
});
}
- // install SM after natives, JNA can require strange permissions
+ Kernel32Library.getInstance();
+
+ // initialize sigar explicitly
+ try {
+ Sigar.load();
+ Loggers.getLogger(Bootstrap.class).trace("sigar libraries loaded successfully");
+ } catch (Throwable t) {
+ Loggers.getLogger(Bootstrap.class).trace("failed to load sigar libraries", t);
+ }
+
+ // init lucene random seed. it will use /dev/urandom where available:
+ StringHelper.randomId();
+ }
+
+ private void setup(boolean addShutdownHook, Settings settings, Environment environment) throws Exception {
+ initializeNatives(settings.getAsBoolean("bootstrap.mlockall", false),
+ settings.getAsBoolean("bootstrap.ctrlhandler", true));
+
+ NodeBuilder nodeBuilder = NodeBuilder.nodeBuilder().settings(settings).loadConfigSettings(false);
+ node = nodeBuilder.build();
+ if (addShutdownHook) {
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ node.close();
+ }
+ });
+ }
+
+ // install SM after natives, shutdown hooks, etc.
setupSecurity(settings, environment);
}
diff --git a/src/main/java/org/elasticsearch/bootstrap/Security.java b/src/main/java/org/elasticsearch/bootstrap/Security.java
index a9eedb7816a..cdb79ab9b4e 100644
--- a/src/main/java/org/elasticsearch/bootstrap/Security.java
+++ b/src/main/java/org/elasticsearch/bootstrap/Security.java
@@ -19,7 +19,6 @@
package org.elasticsearch.bootstrap;
-import org.apache.lucene.util.StringHelper;
import org.elasticsearch.env.Environment;
import java.io.*;
@@ -49,9 +48,6 @@ class Security {
* Can only happen once!
*/
static void configure(Environment environment) throws Exception {
- // init lucene random seed. it will use /dev/urandom where available:
- StringHelper.randomId();
-
// enable security policy: union of template and environment-based paths.
URI template = Security.class.getResource(POLICY_RESOURCE).toURI();
Policy.setPolicy(new ESPolicy(template, createPermissions(environment)));
diff --git a/src/main/java/org/elasticsearch/common/jna/Kernel32Library.java b/src/main/java/org/elasticsearch/common/jna/Kernel32Library.java
index 386da4a5401..04549d78f1d 100644
--- a/src/main/java/org/elasticsearch/common/jna/Kernel32Library.java
+++ b/src/main/java/org/elasticsearch/common/jna/Kernel32Library.java
@@ -22,6 +22,8 @@ package org.elasticsearch.common.jna;
import com.google.common.collect.ImmutableList;
import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;
+
+import org.apache.lucene.util.Constants;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
@@ -46,13 +48,15 @@ public class Kernel32Library {
}
private Kernel32Library() {
- try {
- Native.register("kernel32");
- logger.debug("windows/Kernel32 library loaded");
- } catch (NoClassDefFoundError e) {
- logger.warn("JNA not found. native methods and handlers will be disabled.");
- } catch (UnsatisfiedLinkError e) {
- logger.warn("unable to link Windows/Kernel32 library. native methods and handlers will be disabled.");
+ if (Constants.WINDOWS) {
+ try {
+ Native.register("kernel32");
+ logger.debug("windows/Kernel32 library loaded");
+ } catch (NoClassDefFoundError e) {
+ logger.warn("JNA not found. native methods and handlers will be disabled.");
+ } catch (UnsatisfiedLinkError e) {
+ logger.warn("unable to link Windows/Kernel32 library. native methods and handlers will be disabled.");
+ }
}
}
diff --git a/src/main/resources/org/elasticsearch/bootstrap/security.policy b/src/main/resources/org/elasticsearch/bootstrap/security.policy
index 993868c18b3..f71105af7da 100644
--- a/src/main/resources/org/elasticsearch/bootstrap/security.policy
+++ b/src/main/resources/org/elasticsearch/bootstrap/security.policy
@@ -82,9 +82,6 @@ grant {
// needed by groovy scripting
permission java.lang.RuntimePermission "getProtectionDomain";
- // needed for natives calls
- permission java.lang.RuntimePermission "loadLibrary.*";
-
// reflection hacks:
// needed for Striped64 (what is this doing), also enables unmap hack
permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
diff --git a/src/test/java/org/elasticsearch/common/jna/NativesTests.java b/src/test/java/org/elasticsearch/common/jna/NativesTests.java
index 7a53b8d6895..72b973c0db9 100644
--- a/src/test/java/org/elasticsearch/common/jna/NativesTests.java
+++ b/src/test/java/org/elasticsearch/common/jna/NativesTests.java
@@ -20,83 +20,31 @@
package org.elasticsearch.common.jna;
import org.apache.lucene.util.Constants;
-import org.elasticsearch.common.jna.Kernel32Library.ConsoleCtrlHandler;
import org.elasticsearch.test.ElasticsearchTestCase;
-import org.junit.After;
-import org.junit.Before;
import org.junit.Test;
-import java.util.HashMap;
-import java.util.Map;
-
import static org.hamcrest.Matchers.equalTo;
public class NativesTests extends ElasticsearchTestCase {
- /**
- * Those properties are set by the JNA Api and if not ignored,
- * lead to tests failure (see AbstractRandomizedTest#IGNORED_INVARIANT_PROPERTIES)
- */
- private static final String[] JNA_INVARIANT_PROPERTIES = {
- "jna.platform.library.path",
- "jnidispatch.path"
- };
-
- private Map properties = new HashMap<>();
-
- @Before
- public void saveProperties() {
- assumeTrue("Natives can't load libraries from path if security manager is enabled.", System.getSecurityManager() == null);
- for (String p : JNA_INVARIANT_PROPERTIES) {
- properties.put(p, System.getProperty(p));
- }
- }
-
- @After
- public void restoreProperties() {
- for (String p : JNA_INVARIANT_PROPERTIES) {
- if (properties.get(p) != null) {
- System.setProperty(p, properties.get(p));
- } else {
- System.clearProperty(p);
- }
- }
- }
-
@Test
- public void testTryMlockall() {
- Natives.tryMlockall();
-
+ public void testMlockall() {
if (Constants.WINDOWS) {
assertFalse("Memory locking is not available on Windows platforms", Natives.LOCAL_MLOCKALL);
}
+ if (Constants.MAC_OS_X) {
+ assertFalse("Memory locking is not available on OS X platforms", Natives.LOCAL_MLOCKALL);
+ }
}
-
+
@Test
- public void testAddConsoleCtrlHandler() {
- ConsoleCtrlHandler handler = new ConsoleCtrlHandler() {
- @Override
- public boolean handle(int code) {
- return false;
- }
- };
-
- Natives.addConsoleCtrlHandler(handler);
-
+ public void testConsoleCtrlHandler() {
if (Constants.WINDOWS) {
assertNotNull(Kernel32Library.getInstance());
assertThat(Kernel32Library.getInstance().getCallbacks().size(), equalTo(1));
-
} else {
assertNotNull(Kernel32Library.getInstance());
assertThat(Kernel32Library.getInstance().getCallbacks().size(), equalTo(0));
-
- try {
- Kernel32Library.getInstance().addConsoleCtrlHandler(handler);
- fail("should have thrown an unsupported operation exception");
- } catch (UnsatisfiedLinkError e) {
- // UnsatisfiedLinkError is expected
- }
}
}
}
diff --git a/src/test/java/org/elasticsearch/monitor/SigarTests.java b/src/test/java/org/elasticsearch/monitor/SigarTests.java
new file mode 100644
index 00000000000..f582c2fdc1c
--- /dev/null
+++ b/src/test/java/org/elasticsearch/monitor/SigarTests.java
@@ -0,0 +1,42 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.elasticsearch.monitor;
+
+import org.elasticsearch.test.ElasticsearchTestCase;
+import org.hyperic.sigar.Sigar;
+
+public class SigarTests extends ElasticsearchTestCase {
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ assumeTrue("we can only ensure sigar is working when running from maven",
+ Boolean.parseBoolean(System.getProperty("tests.maven")));
+ }
+
+ public void testSigarLoads() throws Exception {
+ Sigar.load();
+ }
+
+ public void testSigarWorks() throws Exception {
+ Sigar sigar = new Sigar();
+ assertNotNull(sigar.getCpu());
+ }
+}
diff --git a/src/test/java/org/elasticsearch/test/SecurityHack.java b/src/test/java/org/elasticsearch/test/SecurityHack.java
index 092eda99f7d..90223ce4ac2 100644
--- a/src/test/java/org/elasticsearch/test/SecurityHack.java
+++ b/src/test/java/org/elasticsearch/test/SecurityHack.java
@@ -20,6 +20,7 @@
package org.elasticsearch.test;
import org.apache.lucene.util.TestSecurityManager;
+import org.elasticsearch.bootstrap.Bootstrap;
import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAsBoolean;
@@ -33,6 +34,8 @@ import static com.carrotsearch.randomizedtesting.RandomizedTest.systemPropertyAs
class SecurityHack {
static {
+ // just like bootstrap, initialize natives, then SM
+ Bootstrap.initializeNatives(true, true);
// for IDEs, we check that security.policy is set
if (systemPropertyAsBoolean("tests.security.manager", true) &&
System.getProperty("java.security.policy") != null) {