bipinprasad commented on a change in pull request #3273:
URL: https://github.com/apache/storm/pull/3273#discussion_r434893532
##########
File path:
storm-server/src/main/java/org/apache/storm/daemon/supervisor/Container.java
##########
@@ -290,49 +301,368 @@ private boolean isWindowsProcessAlive(long pid, String
user) throws IOException
return ret;
}
- private boolean isPosixProcessAlive(long pid, String user) throws
IOException {
- boolean ret = false;
+ private static boolean isPosixProcessAlive(long pid, String user) throws
IOException {
+ LOG.debug("CMD: ps -o user -p {}", pid);
ProcessBuilder pb = new ProcessBuilder("ps", "-o", "user", "-p",
String.valueOf(pid));
- pb.redirectError(Redirect.INHERIT);
- Process p = pb.start();
- try (BufferedReader in = new BufferedReader(new
InputStreamReader(p.getInputStream()))) {
- String first = in.readLine();
- assert ("USER".equals(first));
- String processUser;
- while ((processUser = in.readLine()) != null) {
- if (user.equals(processUser)) {
- ret = true;
- break;
- } else {
- LOG.info("Found {} running as {}, but expected it to be
{}", pid, processUser, user);
+ pb.redirectError(ProcessBuilder.Redirect.INHERIT);
+ try (BufferedReader in = new BufferedReader(new
InputStreamReader(pb.start().getInputStream()))) {
+ int lineNo = 1;
+ String line = in.readLine();
+ LOG.debug("CMD-LINE#{}: {}", lineNo, line);
+ if (!"USER".equals(line.trim())) {
+ LOG.error("Expecting first line to contain USER, found
\"{}\"", line);
+ return false;
+ }
+ while ((line = in.readLine()) != null) {
+ lineNo++;
+ LOG.debug("CMD-LINE#{}: {}", lineNo, line);
+ line = line.trim();
+ if (user.equals(line)) {
+ return true;
}
+ LOG.info("Found {} running as {}, but expected it to be {}",
pid, line, user);
}
+ } catch (IOException ex) {
+ String err = String.format("Cannot read output of command \"ps -o
user -p %d\"", pid);
+ throw new IOException(err, ex);
}
- return ret;
+ return false;
+ }
+
+ /**
+ * Are any of the processes alive and running for the specified user. If
collection is empty or null
+ * then the return value is trivially false.
+ *
+ * @param pids the PIDs of the running processes
+ * @param user the user that is expected to own that process
+ * @return true if any one of the processes is owned by user and alive,
else false
+ * @throws IOException on I/O exception
+ */
+ public static boolean isAnyProcessAlive(Collection<Long> pids, String
user) throws IOException {
+ if (pids == null || pids.isEmpty()) {
+ return false;
+ }
+
+ if (ServerUtils.IS_ON_WINDOWS) {
+ return isAnyWindowsProcessAlive(pids, user);
+ }
+ return isAnyPosixProcessAlive(pids, user);
}
-
+
+ /**
+ * Are any of the processes alive and running for the specified userId. If
collection is empty or null
+ * then the return value is trivially false.
+ *
+ * @param pids the PIDs of the running processes
+ * @param uid the user that is expected to own that process
+ * @return true if any one of the processes is owned by user and alive,
else false
+ * @throws IOException on I/O exception
+ */
+ public static boolean isAnyProcessAlive(Collection<Long> pids, int uid)
throws IOException {
+ if (pids == null || pids.isEmpty()) {
+ return false;
+ }
+ if (ServerUtils.IS_ON_WINDOWS) {
+ return isAnyWindowsProcessAlive(pids, uid);
+ }
+ return isAnyPosixProcessAlive(pids, uid);
+ }
+
+ /**
+ * Find if any of the Windows processes are alive and owned by the
specified user.
+ * Command reference
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/tasklist.
+ *
+ * @param pids the PIDs of the running processes
+ * @param user the user that is expected to own that process
+ * @return true if any one of the processes is owned by user and alive,
else false
+ * @throws IOException on I/O exception
+ */
+ private static boolean isAnyWindowsProcessAlive(Collection<Long> pids,
String user) throws IOException {
+ List<String> cmdArgs = new ArrayList<>();
+ cmdArgs.add("tasklist");
+ cmdArgs.add("/fo");
+ cmdArgs.add("list");
+ pids.forEach(pid -> {
+ cmdArgs.add("/fi");
+ cmdArgs.add("pid eq " + pid);
+ });
+ cmdArgs.add("/v");
+ LOG.debug("CMD: {}", String.join(" ", cmdArgs));
+ ProcessBuilder pb = new ProcessBuilder(cmdArgs);
+ pb.redirectError(ProcessBuilder.Redirect.INHERIT);
+ List<String> unexpectedUsers = new ArrayList<>();
+ try (BufferedReader in = new BufferedReader(new
InputStreamReader(pb.start().getInputStream()))) {
+ int lineNo = 0;
+ String line;
+ while ((line = in.readLine()) != null) {
+ lineNo++;
+ LOG.debug("CMD-LINE#{}: {}", lineNo, line);
+ if (line.contains("User Name:")) { //Check for : in case
someone called their user "User Name"
+ //This line contains the user name for the pid we're
looking up
+ //Example line: "User Name: exampleDomain\exampleUser"
+ List<String> userNameLineSplitOnWhitespace =
Arrays.asList(line.split(":"));
+ if (userNameLineSplitOnWhitespace.size() == 2) {
+ List<String> userAndMaybeDomain =
Arrays.asList(userNameLineSplitOnWhitespace.get(1).trim().split("\\\\"));
+ String processUser = userAndMaybeDomain.size() == 2 ?
userAndMaybeDomain.get(1) : userAndMaybeDomain.get(0);
+ processUser = processUser.trim();
+ if (user.equals(processUser)) {
+ return true;
+ }
+ unexpectedUsers.add(processUser);
+ } else {
+ LOG.error("Received unexpected output from tasklist
command. Expected one colon in user name line. Line was {}",
+ line);
+ }
+ }
+ }
+ } catch (IOException ex) {
+ String err = String.format("Cannot read output of command \"%s\"",
String.join(" ", cmdArgs));
+ throw new IOException(err, ex);
+ }
+ String pidsAsStr =
pids.stream().map(String::valueOf).collect(Collectors.joining(","));
+ if (unexpectedUsers.isEmpty()) {
+ LOG.info("None of the processes {} are alive", pidsAsStr);
+ } else {
+ LOG.info("{} of the Processes {} are running as user(s) {}: but
expected user is {}",
+ unexpectedUsers.size(), pidsAsStr, String.join(",", new
TreeSet<>(unexpectedUsers)), user);
+ }
+ return false;
+ }
+
+ /**
+ * Find if any of the Windows processes are alive and owned by the
specified userId.
+ * This overridden method is provided for symmetry, but is not implemented.
+ *
+ * @param pids the PIDs of the running processes
+ * @param uid the user that is expected to own that process
+ * @return true if any one of the processes is owned by user and alive,
else false
+ * @throws IOException on I/O exception
+ */
+ private static boolean isAnyWindowsProcessAlive(Collection<Long> pids, int
uid) throws IOException {
+ throw new IllegalArgumentException("UID is not supported on Windows");
+ }
+
+ /**
+ * Are any of the processes alive and running for the specified user.
+ *
+ * @param pids the PIDs of the running processes
+ * @param user the user that is expected to own that process
+ * @return true if any one of the processes is owned by user and alive,
else false
+ * @throws IOException on I/O exception
+ */
+ private static boolean isAnyPosixProcessAlive(Collection<Long> pids,
String user) throws IOException {
+ String pidParams =
pids.stream().map(String::valueOf).collect(Collectors.joining(","));
Review comment:
changed
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]