HDFS-3972. Trash emptier fails in secure HA cluster. Contributed by Todd Lipcon

git-svn-id: https://svn.apache.org/repos/asf/hadoop/common/branches/branch-2@1390730 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eli Collins 2012-09-26 21:26:54 +00:00
parent bde1ba70c1
commit 31bd01c15d
4 changed files with 57 additions and 5 deletions

View File

@ -72,8 +72,9 @@ public class TrashPolicyDefault extends TrashPolicy {
public TrashPolicyDefault() { }
private TrashPolicyDefault(Path home, Configuration conf) throws IOException {
initialize(conf, home.getFileSystem(conf), home);
private TrashPolicyDefault(FileSystem fs, Path home, Configuration conf)
throws IOException {
initialize(conf, fs, home);
}
@Override
@ -279,7 +280,8 @@ public class TrashPolicyDefault extends TrashPolicy {
if (!home.isDirectory())
continue;
try {
TrashPolicyDefault trash = new TrashPolicyDefault(home.getPath(), conf);
TrashPolicyDefault trash = new TrashPolicyDefault(
fs, home.getPath(), conf);
trash.deleteCheckpoint();
trash.createCheckpoint();
} catch (IOException e) {

View File

@ -25,6 +25,7 @@ import java.net.URLConnection;
import java.net.UnknownHostException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.List;
import java.util.ServiceLoader;
@ -451,6 +452,41 @@ public class SecurityUtil {
return action.run();
}
}
/**
* Perform the given action as the daemon's login user. If an
* InterruptedException is thrown, it is converted to an IOException.
*
* @param action the action to perform
* @return the result of the action
* @throws IOException in the event of error
*/
public static <T> T doAsLoginUser(PrivilegedExceptionAction<T> action)
throws IOException {
return doAsUser(UserGroupInformation.getLoginUser(), action);
}
/**
* Perform the given action as the daemon's current user. If an
* InterruptedException is thrown, it is converted to an IOException.
*
* @param action the action to perform
* @return the result of the action
* @throws IOException in the event of error
*/
public static <T> T doAsCurrentUser(PrivilegedExceptionAction<T> action)
throws IOException {
return doAsUser(UserGroupInformation.getCurrentUser(), action);
}
private static <T> T doAsUser(UserGroupInformation ugi,
PrivilegedExceptionAction<T> action) throws IOException {
try {
return ugi.doAs(action);
} catch (InterruptedException ie) {
throw new IOException(ie);
}
}
/**
* Open a (if need be) secure connection to a URL in a secure environment

View File

@ -631,6 +631,8 @@ Release 2.0.2-alpha - 2012-09-07
HDFS-3938. remove current limitations from HttpFS docs. (tucu)
HDFS-3944. Httpfs resolveAuthority() is not resolving host correctly. (tucu)
HDFS-3972. Trash emptier fails in secure HA cluster. (todd via eli)
BREAKDOWN OF HDFS-3042 SUBTASKS

View File

@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.PrintStream;
import java.net.InetSocketAddress;
import java.net.URI;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -512,7 +513,7 @@ public class NameNode {
stopHttpServer();
}
private void startTrashEmptier(Configuration conf) throws IOException {
private void startTrashEmptier(final Configuration conf) throws IOException {
long trashInterval =
conf.getLong(FS_TRASH_INTERVAL_KEY, FS_TRASH_INTERVAL_DEFAULT);
if (trashInterval == 0) {
@ -521,7 +522,18 @@ public class NameNode {
throw new IOException("Cannot start tresh emptier with negative interval."
+ " Set " + FS_TRASH_INTERVAL_KEY + " to a positive value.");
}
this.emptier = new Thread(new Trash(conf).getEmptier(), "Trash Emptier");
// This may be called from the transitionToActive code path, in which
// case the current user is the administrator, not the NN. The trash
// emptier needs to run as the NN. See HDFS-3972.
FileSystem fs = SecurityUtil.doAsLoginUser(
new PrivilegedExceptionAction<FileSystem>() {
@Override
public FileSystem run() throws IOException {
return FileSystem.get(conf);
}
});
this.emptier = new Thread(new Trash(fs, conf).getEmptier(), "Trash Emptier");
this.emptier.setDaemon(true);
this.emptier.start();
}