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);

Reply via email to