Ver código fonte

HADOOP-14044. Synchronization issue in delegation token cancel functionality. Contributed by Hrishikesh Gadre.

(cherry picked from commit ba75bc759334c8987e5f7dd4b21d025f0cccbde7)
(cherry picked from commit 05ed48b75a53df9ad4456ecddc981250006540ae)
(cherry picked from commit e2e18501ab1a0a1ebee739fa825b6411b2350a26)
Xiao Chen 8 anos atrás
pai
commit
0ee637f849

+ 3 - 0
hadoop-common-project/hadoop-common/CHANGES.txt

@@ -159,6 +159,9 @@ Release 2.7.4 - UNRELEASED
     HADOOP-14474. Use OpenJDK 7 instead of Oracle JDK 7 to avoid
     oracle-java7-installer failures. (Akira Ajisaka via xiao)
 
+    HADOOP-14044. Synchronization issue in delegation token cancel
+    functionality. (Hrishikesh Gadre via xiao)
+
 Release 2.7.3 - 2016-08-25
 
   INCOMPATIBLE CHANGES

+ 23 - 10
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/token/delegation/ZKDelegationTokenSecretManager.java

@@ -627,6 +627,26 @@ public abstract class ZKDelegationTokenSecretManager<TokenIdent extends Abstract
     return tokenInfo;
   }
 
+  /**
+   * This method synchronizes the state of a delegation token information in
+   * local cache with its actual value in Zookeeper.
+   *
+   * @param ident Identifier of the token
+   */
+  private synchronized void syncLocalCacheWithZk(TokenIdent ident) {
+    try {
+      DelegationTokenInformation tokenInfo = getTokenInfoFromZK(ident);
+      if (tokenInfo != null && !currentTokens.containsKey(ident)) {
+        currentTokens.put(ident, tokenInfo);
+      } else if (tokenInfo == null && currentTokens.containsKey(ident)) {
+        currentTokens.remove(ident);
+      }
+    } catch (IOException e) {
+      LOG.error("Error retrieving tokenInfo [" + ident.getSequenceNumber()
+          + "] from ZK", e);
+    }
+  }
+
   private DelegationTokenInformation getTokenInfoFromZK(TokenIdent ident)
       throws IOException {
     return getTokenInfoFromZK(ident, false);
@@ -792,16 +812,9 @@ public abstract class ZKDelegationTokenSecretManager<TokenIdent extends Abstract
     DataInputStream in = new DataInputStream(buf);
     TokenIdent id = createIdentifier();
     id.readFields(in);
-    try {
-      if (!currentTokens.containsKey(id)) {
-        // See if token can be retrieved and placed in currentTokens
-        getTokenInfo(id);
-      }
-      return super.cancelToken(token, canceller);
-    } catch (Exception e) {
-      LOG.error("Exception while checking if token exist !!", e);
-      return id;
-    }
+
+    syncLocalCacheWithZk(id);
+    return super.cancelToken(token, canceller);
   }
 
   private void addOrUpdateToken(TokenIdent ident,