YARN-4834. ProcfsBasedProcessTree doesn't track daemonized processes. Contributed by Nathan Roberts

(cherry picked from commit c6b4839168)
This commit is contained in:
Jason Lowe 2016-05-03 17:27:28 +00:00
parent 4f1c198881
commit 8013529746
2 changed files with 41 additions and 17 deletions

View File

@ -216,7 +216,16 @@ public class ProcfsBasedProcessTree extends ResourceCalculatorProcessTree {
String pID = entry.getKey(); String pID = entry.getKey();
if (!pID.equals("1")) { if (!pID.equals("1")) {
ProcessInfo pInfo = entry.getValue(); ProcessInfo pInfo = entry.getValue();
ProcessInfo parentPInfo = allProcessInfo.get(pInfo.getPpid()); String ppid = pInfo.getPpid();
// If parent is init and process is not session leader,
// attach to sessionID
if (ppid.equals("1")) {
String sid = pInfo.getSessionId().toString();
if (!pID.equals(sid)) {
ppid = sid;
}
}
ProcessInfo parentPInfo = allProcessInfo.get(ppid);
if (parentPInfo != null) { if (parentPInfo != null) {
parentPInfo.addChild(pInfo); parentPInfo.addChild(pInfo);
} }
@ -573,6 +582,14 @@ public class ProcfsBasedProcessTree extends ResourceCalculatorProcessTree {
return pTree.substring(0, pTree.length()) + "]"; return pTree.substring(0, pTree.length()) + "]";
} }
/**
* Returns boolean indicating whether pid
* is in process tree.
*/
public boolean contains(String pid) {
return processTree.containsKey(pid);
}
/** /**
* *
* Class containing information of a process. * Class containing information of a process.

View File

@ -36,6 +36,7 @@ import java.util.Vector;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.conf.Configuration;
@ -65,7 +66,7 @@ public class TestProcfsBasedProcessTree {
TestProcfsBasedProcessTree.class.getName() + "-localDir"); TestProcfsBasedProcessTree.class.getName() + "-localDir");
private ShellCommandExecutor shexec = null; private ShellCommandExecutor shexec = null;
private String pidFile, lowestDescendant; private String pidFile, lowestDescendant, lostDescendant;
private String shellScript; private String shellScript;
private static final int N = 6; // Controls the RogueTask private static final int N = 6; // Controls the RogueTask
@ -144,19 +145,17 @@ public class TestProcfsBasedProcessTree {
lowestDescendant = lowestDescendant =
TEST_ROOT_DIR + File.separator + "lowestDescendantPidFile"; TEST_ROOT_DIR + File.separator + "lowestDescendantPidFile";
lostDescendant =
TEST_ROOT_DIR + File.separator + "lostDescendantPidFile";
// write to shell-script // write to shell-script
try { File file = new File(shellScript);
FileWriter fWriter = new FileWriter(shellScript); FileUtils.writeStringToFile(file, "# rogue task\n" + "sleep 1\n" + "echo hello\n"
fWriter.write("# rogue task\n" + "sleep 1\n" + "echo hello\n" + "if [ $1 -ne 0 ]\n" + "then\n" + " sh " + shellScript
+ "if [ $1 -ne 0 ]\n" + "then\n" + " sh " + shellScript + " $(($1-1))\n" + "else\n" + " echo $$ > " + lowestDescendant + "\n"
+ " $(($1-1))\n" + "else\n" + " echo $$ > " + lowestDescendant + "\n" + "(sleep 300&\n"
+ " while true\n do\n" + " sleep 5\n" + " done\n" + "fi"); + "echo $! > " + lostDescendant + ")\n"
fWriter.close(); + " while true\n do\n" + " sleep 5\n" + " done\n" + "fi");
} catch (IOException ioe) {
LOG.info("Error: " + ioe);
return;
}
Thread t = new RogueTaskThread(); Thread t = new RogueTaskThread();
t.start(); t.start();
@ -179,6 +178,12 @@ public class TestProcfsBasedProcessTree {
p.updateProcessTree(); // reconstruct p.updateProcessTree(); // reconstruct
LOG.info("ProcessTree: " + p.toString()); LOG.info("ProcessTree: " + p.toString());
// Verify the orphaned pid is In process tree
String lostpid = getPidFromPidFile(lostDescendant);
LOG.info("Orphaned pid: " + lostpid);
Assert.assertTrue("Child process owned by init escaped process tree.",
p.contains(lostpid));
// Get the process-tree dump // Get the process-tree dump
String processTreeDump = p.getProcessTreeDump(); String processTreeDump = p.getProcessTreeDump();
@ -230,10 +235,12 @@ public class TestProcfsBasedProcessTree {
Assert.assertTrue( Assert.assertTrue(
"vmem for the gone-process is " + p.getVirtualMemorySize() "vmem for the gone-process is " + p.getVirtualMemorySize()
+ " . It should be zero.", p.getVirtualMemorySize() == 0); + " . It should be UNAVAILABLE(-1).",
p.getVirtualMemorySize() == UNAVAILABLE);
Assert.assertTrue( Assert.assertTrue(
"vmem (old API) for the gone-process is " + p.getCumulativeVmem() "vmem (old API) for the gone-process is " + p.getCumulativeVmem()
+ " . It should be zero.", p.getCumulativeVmem() == 0); + " . It should be UNAVAILABLE(-1).",
p.getCumulativeVmem() == UNAVAILABLE);
Assert.assertTrue(p.toString().equals("[ ]")); Assert.assertTrue(p.toString().equals("[ ]"));
} }
@ -247,7 +254,7 @@ public class TestProcfsBasedProcessTree {
} }
protected void destroyProcessTree(String pid) throws IOException { protected void destroyProcessTree(String pid) throws IOException {
sendSignal(pid, 9); sendSignal("-"+pid, 9);
} }
/** /**
@ -917,7 +924,7 @@ public class TestProcfsBasedProcessTree {
private static void sendSignal(String pid, int signal) throws IOException { private static void sendSignal(String pid, int signal) throws IOException {
ShellCommandExecutor shexec = null; ShellCommandExecutor shexec = null;
String[] arg = { "kill", "-" + signal, pid }; String[] arg = { "kill", "-" + signal, "--", pid };
shexec = new ShellCommandExecutor(arg); shexec = new ShellCommandExecutor(arg);
shexec.execute(); shexec.execute();
} }