diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/ProcfsBasedProcessTree.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/ProcfsBasedProcessTree.java index 55be001443b..e8fedde753f 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/ProcfsBasedProcessTree.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/util/ProcfsBasedProcessTree.java @@ -515,58 +515,54 @@ private static String getValidPID(String pid) { * @return updated ProcessInfo, null on errors. */ private static ProcessInfo constructProcessInfo(ProcessInfo pinfo, - String procfsDir) { - ProcessInfo ret = null; + String procfsDir) { // Read "procfsDir//stat" file - typically /proc//stat - BufferedReader in = null; - InputStreamReader fReader = null; - try { - File pidDir = new File(procfsDir, pinfo.getPid()); - fReader = new InputStreamReader( - new FileInputStream( - new File(pidDir, PROCFS_STAT_FILE)), Charset.forName("UTF-8")); - in = new BufferedReader(fReader); - } catch (FileNotFoundException f) { - // The process vanished in the interim! - return ret; + final File pidDir = new File(procfsDir, pinfo.getPid()); + final File procFsStatFile = new File(pidDir, PROCFS_STAT_FILE); + if (!procFsStatFile.exists() || !procFsStatFile.canRead()) { + return null; } - ret = pinfo; + String str; try { - String str = in.readLine(); // only one line - Matcher m = PROCFS_STAT_FILE_FORMAT.matcher(str); - boolean mat = m.find(); - if (mat) { - String processName = "(" + m.group(2) + ")"; - // Set (name) (ppid) (pgrpId) (session) (utime) (stime) (vsize) (rss) - pinfo.updateProcessInfo(processName, m.group(3), - Integer.parseInt(m.group(4)), Integer.parseInt(m.group(5)), - Long.parseLong(m.group(7)), new BigInteger(m.group(8)), - Long.parseLong(m.group(10)), Long.parseLong(m.group(11))); - } else { - LOG.warn("Unexpected: procfs stat file is not in the expected format" - + " for process with pid " + pinfo.getPid()); - ret = null; - } + str = readFirstLineFromFile(procFsStatFile); } catch (IOException io) { LOG.warn("Error reading the stream", io); - ret = null; - } finally { - // Close the streams - try { - fReader.close(); - try { - in.close(); - } catch (IOException i) { - LOG.warn("Error closing the stream", i); - } - } catch (IOException i) { - LOG.warn("Error closing the stream", i); - } + return null; + } + + if (str.isEmpty()) { + LOG.warn("Unexpected: procfs stat file is empty for process with pid " + + pinfo.getPid()); + return null; } - return ret; + Matcher m = PROCFS_STAT_FILE_FORMAT.matcher(str); + boolean mat = m.find(); + if (mat) { + String processName = "(" + m.group(2) + ")"; + // Set (name) (ppid) (pgrpId) (session) (utime) (stime) (vsize) (rss) + pinfo.updateProcessInfo(processName, m.group(3), + Integer.parseInt(m.group(4)), Integer.parseInt(m.group(5)), + Long.parseLong(m.group(7)), new BigInteger(m.group(8)), + Long.parseLong(m.group(10)), Long.parseLong(m.group(11))); + return pinfo; + } else { + LOG.warn("Unexpected: procfs stat file is not in the expected format" + + " for process with pid " + pinfo.getPid()); + return null; + } + } + + private static String readFirstLineFromFile(File file) throws IOException { + try (final InputStreamReader fReader = new InputStreamReader( + new FileInputStream(file), Charset.forName("UTF-8"))) { + try (final BufferedReader in = new BufferedReader(fReader)) { + return in.readLine(); + } + } } + /** * Returns a string printing PIDs of process present in the * ProcfsBasedProcessTree. Output format : [pid pid ..]