diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java
index aa18bfbb6f1..e55e08e39b6 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java
@@ -569,6 +569,12 @@ public class CommonConfigurationKeysPublic {
/** Only used by HttpServer. */
public static final boolean HADOOP_SSL_ENABLED_DEFAULT = false;
+ /** See core-default.xml */
+ public static final String HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN =
+ "hadoop.kerberos.min.seconds.before.relogin";
+ /** Default value for HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN */
+ public static final int HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN_DEFAULT =
+ 60;
// HTTP policies to be used in configuration
// Use HttpPolicy.name() instead
diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
index 33066db9795..e1f77ece530 100644
--- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
+++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/security/UserGroupInformation.java
@@ -17,6 +17,8 @@
*/
package org.apache.hadoop.security;
+import static org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN;
+import static org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN_DEFAULT;
import static org.apache.hadoop.fs.CommonConfigurationKeys.HADOOP_USER_GROUP_METRICS_PERCENTILES_INTERVALS;
import static org.apache.hadoop.util.PlatformName.IBM_JAVA;
@@ -240,13 +242,11 @@ public class UserGroupInformation {
private static AuthenticationMethod authenticationMethod;
/** Server-side groups fetching service */
private static Groups groups;
+ /** Min time (in seconds) before relogin for Kerberos */
+ private static long kerberosMinSecondsBeforeRelogin;
/** The configuration to use */
private static Configuration conf;
-
- /** Leave 10 minutes between relogin attempts. */
- private static final long MIN_TIME_BEFORE_RELOGIN = 10 * 60 * 1000L;
-
/**Environment variable pointing to the token cache file*/
public static final String HADOOP_TOKEN_FILE_LOCATION =
"HADOOP_TOKEN_FILE_LOCATION";
@@ -280,6 +280,16 @@ public class UserGroupInformation {
"Problem with Kerberos auth_to_local name configuration", ioe);
}
}
+ try {
+ kerberosMinSecondsBeforeRelogin = 1000L * conf.getLong(
+ HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN,
+ HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN_DEFAULT);
+ }
+ catch(NumberFormatException nfe) {
+ throw new IllegalArgumentException("Invalid attribute value for " +
+ HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN + " of " +
+ conf.get(HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN));
+ }
// If we haven't set up testing groups, use the configuration to find it
if (!(groups instanceof TestingGroups)) {
groups = Groups.getUserToGroupsMappingService(conf);
@@ -936,7 +946,7 @@ public class UserGroupInformation {
return;
}
nextRefresh = Math.max(getRefreshTime(tgt),
- now + MIN_TIME_BEFORE_RELOGIN);
+ now + kerberosMinSecondsBeforeRelogin);
} catch (InterruptedException ie) {
LOG.warn("Terminating renewal thread");
return;
@@ -1217,10 +1227,10 @@ public class UserGroupInformation {
}
private boolean hasSufficientTimeElapsed(long now) {
- if (now - user.getLastLogin() < MIN_TIME_BEFORE_RELOGIN ) {
+ if (now - user.getLastLogin() < kerberosMinSecondsBeforeRelogin ) {
LOG.warn("Not attempting to re-login since the last re-login was " +
- "attempted less than " + (MIN_TIME_BEFORE_RELOGIN/1000) + " seconds"+
- " before. Last Login=" + user.getLastLogin());
+ "attempted less than " + (kerberosMinSecondsBeforeRelogin/1000) +
+ " seconds before. Last Login=" + user.getLastLogin());
return false;
}
return true;
diff --git a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
index b8d49043753..7ceee486358 100644
--- a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
+++ b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml
@@ -465,6 +465,14 @@
+
+ hadoop.kerberos.min.seconds.before.relogin
+ 60
+ The minimum time between relogin attempts for Kerberos, in
+ seconds.
+
+
+
hadoop.security.auth_to_local
diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java
index 06f14212b32..521ab4abe45 100644
--- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java
+++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/security/TestUserGroupInformation.java
@@ -38,6 +38,7 @@ import javax.security.auth.login.LoginContext;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.lang.reflect.Method;
import java.security.PrivilegedExceptionAction;
import java.util.Collection;
import java.util.ConcurrentModificationException;
@@ -927,4 +928,39 @@ public class TestUserGroupInformation {
});
}
+
+ /** Test hasSufficientTimeElapsed method */
+ @Test
+ public void testHasSufficientTimeElapsed() throws Exception {
+ // Make hasSufficientTimeElapsed public
+ Method method = UserGroupInformation.class
+ .getDeclaredMethod("hasSufficientTimeElapsed", long.class);
+ method.setAccessible(true);
+
+ UserGroupInformation ugi = UserGroupInformation.getCurrentUser();
+ User user = ugi.getSubject().getPrincipals(User.class).iterator().next();
+ long now = System.currentTimeMillis();
+
+ // Using default relogin time (1 minute)
+ user.setLastLogin(now - 2 * 60 * 1000); // 2 minutes before "now"
+ assertTrue((Boolean)method.invoke(ugi, now));
+ user.setLastLogin(now - 30 * 1000); // 30 seconds before "now"
+ assertFalse((Boolean)method.invoke(ugi, now));
+
+ // Using relogin time of 10 minutes
+ Configuration conf2 = new Configuration(conf);
+ conf2.setLong(
+ CommonConfigurationKeysPublic.HADOOP_KERBEROS_MIN_SECONDS_BEFORE_RELOGIN,
+ 10 * 60);
+ UserGroupInformation.setConfiguration(conf2);
+ user.setLastLogin(now - 15 * 60 * 1000); // 15 minutes before "now"
+ assertTrue((Boolean)method.invoke(ugi, now));
+ user.setLastLogin(now - 6 * 60 * 1000); // 6 minutes before "now"
+ assertFalse((Boolean)method.invoke(ugi, now));
+ // Restore original conf to UGI
+ UserGroupInformation.setConfiguration(conf);
+
+ // Restore hasSufficientTimElapsed back to private
+ method.setAccessible(false);
+ }
}