From 078d38bc3738af7b27e60a5879d414185e044498 Mon Sep 17 00:00:00 2001 From: Dominik Pospisil Date: Mon, 21 Mar 2016 12:25:45 +0100 Subject: [PATCH] [ARTEMIS-444] Extend AIOSequentialFileFactory to check underlying FS --- .../core/io/aio/AIOSequentialFileFactory.java | 32 +++++++++++++++++++ .../artemis/jlibaio/LibaioContext.java | 2 +- .../core/server/ActiveMQServerLogger.java | 5 +++ .../core/server/impl/ActiveMQServerImpl.java | 12 +++++-- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java index b7bb47e924..93c09ee182 100644 --- a/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java +++ b/artemis-journal/src/main/java/org/apache/activemq/artemis/core/io/aio/AIOSequentialFileFactory.java @@ -50,6 +50,8 @@ public final class AIOSequentialFileFactory extends AbstractSequentialFileFactor private final AtomicBoolean running = new AtomicBoolean(false); + private static final String AIO_TEST_FILE = ".aio-test"; + // This method exists just to make debug easier. // I could replace log.trace by log.info temporarily while I was debugging // Journal @@ -114,6 +116,36 @@ public final class AIOSequentialFileFactory extends AbstractSequentialFileFactor return LibaioContext.isLoaded(); } + public static boolean isSupported(File journalPath) { + if (!isSupported()) { + return false; + } + + File aioTestFile = new File(journalPath, AIO_TEST_FILE); + try { + int fd = LibaioContext.open(aioTestFile.getAbsolutePath(), true); + LibaioContext.close(fd); + aioTestFile.delete(); + } + catch (Exception e) { + // try to handle the file using plain Java + // return false if and only if we can create/remove the file using + // plain Java but not using AIO + try { + if (!aioTestFile.exists()) { + if (!aioTestFile.createNewFile()) return true; + } + if (!aioTestFile.delete()) return true; + } + catch (Exception ie) { + // we can not even create the test file using plain java + return true; + } + return false; + } + return true; + } + @Override public ByteBuffer allocateDirectBuffer(final int size) { diff --git a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java index 75db50dc9f..df4c61ba95 100644 --- a/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java +++ b/artemis-native/src/main/java/org/apache/activemq/artemis/jlibaio/LibaioContext.java @@ -390,7 +390,7 @@ public class LibaioContext implements Closeable { */ public static native int open(String path, boolean direct); - static native void close(int fd); + public static native void close(int fd); /** */ diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java index 4f82f2e9c0..55f7268b59 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java @@ -1479,4 +1479,9 @@ public interface ActiveMQServerLogger extends BasicLogger { @LogMessage(level = Logger.Level.DEBUG) @Message(id = 224070, value = "Received Interrupt Exception whilst waiting for component to shutdown: {0}", format = Message.Format.MESSAGE_FORMAT) void interruptWhilstStoppingComponent(String componentClassName); + + @LogMessage(level = Logger.Level.INFO) + @Message(id = 224072, value = "libaio was found but the filesystem does not support AIO. Switching the configuration into NIO. Journal path: {0}", format = Message.Format.MESSAGE_FORMAT) + void switchingNIOonPath(String journalPath); + } diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java index 69d13bf627..d7eda4213c 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java @@ -1682,9 +1682,15 @@ public class ActiveMQServerImpl implements ActiveMQServer { // Create the pools - we have two pools - one for non scheduled - and another for scheduled initializeExecutorServices(); - if (configuration.getJournalType() == JournalType.ASYNCIO && !AIOSequentialFileFactory.isSupported()) { - ActiveMQServerLogger.LOGGER.switchingNIO(); - configuration.setJournalType(JournalType.NIO); + if (configuration.getJournalType() == JournalType.ASYNCIO) { + if (!AIOSequentialFileFactory.isSupported()) { + ActiveMQServerLogger.LOGGER.switchingNIO(); + configuration.setJournalType(JournalType.NIO); + } + else if (!AIOSequentialFileFactory.isSupported(configuration.getJournalLocation())) { + ActiveMQServerLogger.LOGGER.switchingNIOonPath(configuration.getJournalLocation().getAbsolutePath()); + configuration.setJournalType(JournalType.NIO); + } } managementService = new ManagementServiceImpl(mbeanServer, configuration);