ARTEMIS-1417 Failback not working on NFSv4 With NFSv4 it is now necessary to lock/unlock the byte of the server lock file where the state information is written so that the information is then flushed to the other clients looking at the file.
(cherry picked from commit 2ec173bc708daca163c9356cf12440432abc61c4) Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/f5102350 Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/f5102350 Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/f5102350 Branch: refs/heads/1.x Commit: f51023506e20101cea87676df44337a019e24cc6 Parents: b4bbdff Author: Justin Bertram <jbert...@apache.org> Authored: Tue Sep 12 11:17:08 2017 -0500 Committer: Clebert Suconic <clebertsuco...@apache.org> Committed: Tue Sep 26 14:28:07 2017 -0400 ---------------------------------------------------------------------- .../core/server/impl/FileLockNodeManager.java | 74 ++++++++++++++------ 1 file changed, 53 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/f5102350/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java ---------------------------------------------------------------------- diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java index 694b112..92828bd 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/FileLockNodeManager.java @@ -33,11 +33,13 @@ public class FileLockNodeManager extends NodeManager { private static final Logger logger = Logger.getLogger(FileLockNodeManager.class); - private static final int LIVE_LOCK_POS = 1; + private static final long STATE_LOCK_POS = 0; - private static final int BACKUP_LOCK_POS = 2; + private static final long LIVE_LOCK_POS = 1; - private static final int LOCK_LENGTH = 1; + private static final long BACKUP_LOCK_POS = 2; + + private static final long LOCK_LENGTH = 1; private static final byte LIVE = 'L'; @@ -113,6 +115,7 @@ public class FileLockNodeManager extends NodeManager { @Override public void awaitLiveNode() throws Exception { + logger.debug("awaiting live node..."); do { byte state = getState(); while (state == FileLockNodeManager.NOT_STARTED || state == FIRST_TIME_START) { @@ -228,25 +231,52 @@ public class FileLockNodeManager extends NodeManager { * @param status * @throws IOException */ - private void writeFileLockStatus(byte status) throws IOException { + private void writeFileLockStatus(byte status) throws Exception { if (replicatedBackup && channel == null) return; + logger.debug("writing status: " + status); ByteBuffer bb = ByteBuffer.allocateDirect(1); bb.put(status); bb.position(0); - channel.write(bb, 0); - channel.force(true); + + if (!channel.isOpen()) { + setUpServerLockFile(); + } + FileLock lock = null; + try { + lock = lock(STATE_LOCK_POS); + channel.write(bb, 0); + channel.force(true); + } finally { + if (lock != null) { + lock.release(); + } + } } private byte getState() throws Exception { + byte result; + logger.debug("getting state..."); ByteBuffer bb = ByteBuffer.allocateDirect(1); int read; - read = channel.read(bb, 0); - if (read <= 0) { - return FileLockNodeManager.NOT_STARTED; - } else { - return bb.get(0); + FileLock lock = null; + try { + lock = lock(STATE_LOCK_POS); + read = channel.read(bb, 0); + if (read <= 0) { + result = FileLockNodeManager.NOT_STARTED; + } else { + result = bb.get(0); + } + } finally { + if (lock != null) { + lock.release(); + } } + + logger.debug("state: " + result); + + return result; } @Override @@ -263,25 +293,27 @@ public class FileLockNodeManager extends NodeManager { return getNodeId(); } - protected FileLock tryLock(final int lockPos) throws Exception { + protected FileLock tryLock(final long lockPos) throws IOException { try { - return channel.tryLock(lockPos, LOCK_LENGTH, false); + logger.debug("trying to lock position: " + lockPos); + FileLock lock = channel.tryLock(lockPos, LOCK_LENGTH, false); + if (lock != null) { + logger.debug("locked position: " + lockPos); + } else { + logger.debug("failed to lock position: " + lockPos); + } + return lock; } catch (java.nio.channels.OverlappingFileLockException ex) { // This just means that another object on the same JVM is holding the lock return null; } } - protected FileLock lock(final int liveLockPos) throws Exception { + protected FileLock lock(final long lockPosition) throws Exception { long start = System.currentTimeMillis(); while (!interrupted) { - FileLock lock = null; - try { - lock = channel.tryLock(liveLockPos, 1, false); - } catch (java.nio.channels.OverlappingFileLockException ex) { - // This just means that another object on the same JVM is holding the lock - } + FileLock lock = tryLock(lockPosition); if (lock == null) { try { @@ -302,7 +334,7 @@ public class FileLockNodeManager extends NodeManager { // need to investigate further and review FileLock lock; do { - lock = channel.tryLock(liveLockPos, 1, false); + lock = tryLock(lockPosition); if (lock == null) { try { Thread.sleep(500);