|
@@ -23,6 +23,7 @@ import java.io.File;
|
|
|
import java.io.IOException;
|
|
|
import java.io.PrintStream;
|
|
|
import java.net.InetSocketAddress;
|
|
|
+import java.security.PrivilegedExceptionAction;
|
|
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
@@ -58,10 +59,10 @@ class Child {
|
|
|
public static void main(String[] args) throws Throwable {
|
|
|
LOG.debug("Child starting");
|
|
|
|
|
|
- JobConf defaultConf = new JobConf();
|
|
|
+ final JobConf defaultConf = new JobConf();
|
|
|
String host = args[0];
|
|
|
int port = Integer.parseInt(args[1]);
|
|
|
- InetSocketAddress address = new InetSocketAddress(host, port);
|
|
|
+ final InetSocketAddress address = new InetSocketAddress(host, port);
|
|
|
final TaskAttemptID firstTaskid = TaskAttemptID.forName(args[2]);
|
|
|
final int SLEEP_LONGER_COUNT = 5;
|
|
|
int jvmIdInt = Integer.parseInt(args[3]);
|
|
@@ -81,11 +82,21 @@ class Child {
|
|
|
UserGroupInformation current = UserGroupInformation.getCurrentUser();
|
|
|
current.addToken(jt);
|
|
|
|
|
|
- TaskUmbilicalProtocol umbilical =
|
|
|
- (TaskUmbilicalProtocol)RPC.getProxy(TaskUmbilicalProtocol.class,
|
|
|
- TaskUmbilicalProtocol.versionID,
|
|
|
- address,
|
|
|
- defaultConf);
|
|
|
+ UserGroupInformation taskOwner
|
|
|
+ = UserGroupInformation.createRemoteUser(firstTaskid.getJobID().toString());
|
|
|
+ taskOwner.addToken(jt);
|
|
|
+
|
|
|
+ final TaskUmbilicalProtocol umbilical =
|
|
|
+ taskOwner.doAs(new PrivilegedExceptionAction<TaskUmbilicalProtocol>() {
|
|
|
+ @Override
|
|
|
+ public TaskUmbilicalProtocol run() throws Exception {
|
|
|
+ return (TaskUmbilicalProtocol)RPC.getProxy(TaskUmbilicalProtocol.class,
|
|
|
+ TaskUmbilicalProtocol.versionID,
|
|
|
+ address,
|
|
|
+ defaultConf);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
int numTasksToExecute = -1; //-1 signifies "no limit"
|
|
|
int numTasksExecuted = 0;
|
|
|
Runtime.getRuntime().addShutdownHook(new Thread() {
|
|
@@ -127,6 +138,9 @@ class Child {
|
|
|
JvmContext context = new JvmContext(jvmId, pid);
|
|
|
int idleLoopCount = 0;
|
|
|
Task task = null;
|
|
|
+
|
|
|
+ UserGroupInformation childUGI = null;
|
|
|
+
|
|
|
try {
|
|
|
while (true) {
|
|
|
taskid = null;
|
|
@@ -156,7 +170,7 @@ class Child {
|
|
|
//create the index file so that the log files
|
|
|
//are viewable immediately
|
|
|
TaskLog.syncLogs(firstTaskid, taskid, isCleanup);
|
|
|
- JobConf job = new JobConf(task.getJobFile());
|
|
|
+ final JobConf job = new JobConf(task.getJobFile());
|
|
|
|
|
|
// set the jobTokenFile into task
|
|
|
task.setJobTokenSecret(JobTokenSecretManager.
|
|
@@ -181,11 +195,27 @@ class Child {
|
|
|
JvmMetrics.init(task.getPhase().toString(), job.getSessionId());
|
|
|
// use job-specified working directory
|
|
|
FileSystem.get(job).setWorkingDirectory(job.getWorkingDirectory());
|
|
|
- try {
|
|
|
- task.run(job, umbilical); // run the task
|
|
|
- } finally {
|
|
|
- TaskLog.syncLogs(firstTaskid, taskid, isCleanup);
|
|
|
+ LOG.debug("Creating remote user to execute task: " + job.get("user.name"));
|
|
|
+ childUGI = UserGroupInformation.createRemoteUser(job.get("user.name"));
|
|
|
+ // Add tokens to new user so that it may execute its task correctly.
|
|
|
+ for(Token<?> token : UserGroupInformation.getCurrentUser().getTokens()) {
|
|
|
+ childUGI.addToken(token);
|
|
|
}
|
|
|
+
|
|
|
+ // Create a final reference to the task for the doAs block
|
|
|
+ final Task taskFinal = task;
|
|
|
+ childUGI.doAs(new PrivilegedExceptionAction<Object>() {
|
|
|
+ @Override
|
|
|
+ public Object run() throws Exception {
|
|
|
+ try {
|
|
|
+ taskFinal.run(job, umbilical); // run the task
|
|
|
+ } finally {
|
|
|
+ TaskLog.syncLogs(firstTaskid, taskid, isCleanup);
|
|
|
+ }
|
|
|
+
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ });
|
|
|
if (numTasksToExecute > 0 && ++numTasksExecuted == numTasksToExecute) {
|
|
|
break;
|
|
|
}
|
|
@@ -198,7 +228,18 @@ class Child {
|
|
|
try {
|
|
|
if (task != null) {
|
|
|
// do cleanup for the task
|
|
|
- task.taskCleanup(umbilical);
|
|
|
+ if(childUGI == null) {
|
|
|
+ task.taskCleanup(umbilical);
|
|
|
+ } else {
|
|
|
+ final Task taskFinal = task;
|
|
|
+ childUGI.doAs(new PrivilegedExceptionAction<Object>() {
|
|
|
+ @Override
|
|
|
+ public Object run() throws Exception {
|
|
|
+ taskFinal.taskCleanup(umbilical);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
LOG.info("Error cleaning up", e);
|