HADOOP-12441. Fixed shell-kill command behaviour to work correctly on some Linux distributions after HADOOP-12317. Contributed by Wangda Tan.
This commit is contained in:
parent
b925cf1006
commit
f1c19b9365
@ -1185,6 +1185,9 @@ Release 2.8.0 - UNRELEASED
|
|||||||
HADOOP-12442. Display help if the command option to 'hdfs dfs' is not valid
|
HADOOP-12442. Display help if the command option to 'hdfs dfs' is not valid
|
||||||
(nijel via vinayakumarb)
|
(nijel via vinayakumarb)
|
||||||
|
|
||||||
|
HADOOP-12441. Fixed shell-kill command behaviour to work correctly on some
|
||||||
|
Linux distributions after HADOOP-12317. (Wangda Tan via vinodkv)
|
||||||
|
|
||||||
Release 2.7.2 - UNRELEASED
|
Release 2.7.2 - UNRELEASED
|
||||||
|
|
||||||
INCOMPATIBLE CHANGES
|
INCOMPATIBLE CHANGES
|
||||||
|
@ -210,20 +210,26 @@ public static String[] getReadlinkCommand(String link) {
|
|||||||
|
|
||||||
/** Return a command for determining if process with specified pid is alive. */
|
/** Return a command for determining if process with specified pid is alive. */
|
||||||
public static String[] getCheckProcessIsAliveCommand(String pid) {
|
public static String[] getCheckProcessIsAliveCommand(String pid) {
|
||||||
return Shell.WINDOWS ?
|
return getSignalKillCommand(0, pid);
|
||||||
new String[] { Shell.WINUTILS, "task", "isAlive", pid } :
|
|
||||||
isSetsidAvailable ?
|
|
||||||
new String[] { "kill", "-0", "--", "-" + pid } :
|
|
||||||
new String[] { "kill", "-0", pid };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return a command to send a signal to a given pid */
|
/** Return a command to send a signal to a given pid */
|
||||||
public static String[] getSignalKillCommand(int code, String pid) {
|
public static String[] getSignalKillCommand(int code, String pid) {
|
||||||
return Shell.WINDOWS ?
|
// Code == 0 means check alive
|
||||||
new String[] { Shell.WINUTILS, "task", "kill", pid } :
|
if (Shell.WINDOWS) {
|
||||||
isSetsidAvailable ?
|
if (0 == code) {
|
||||||
new String[] { "kill", "-" + code, "--", "-" + pid } :
|
return new String[] { Shell.WINUTILS, "task", "isAlive", pid };
|
||||||
new String[] { "kill", "-" + code, pid };
|
} else {
|
||||||
|
return new String[] { Shell.WINUTILS, "task", "kill", pid };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSetsidAvailable) {
|
||||||
|
// Use the shell-builtin as it support "--" in all Hadoop supported OSes
|
||||||
|
return new String[] { "bash", "-c", "kill -" + code + " -- -" + pid };
|
||||||
|
} else {
|
||||||
|
return new String[] { "bash", "-c", "kill -" + code + " " + pid };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final String ENV_NAME_REGEX = "[A-Za-z_][A-Za-z0-9_]*";
|
public static final String ENV_NAME_REGEX = "[A-Za-z_][A-Za-z0-9_]*";
|
||||||
@ -386,6 +392,26 @@ public static final String getWinUtilsPath() {
|
|||||||
return winUtilsPath;
|
return winUtilsPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final boolean isBashSupported = checkIsBashSupported();
|
||||||
|
private static boolean checkIsBashSupported() {
|
||||||
|
if (Shell.WINDOWS) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ShellCommandExecutor shexec;
|
||||||
|
boolean supported = true;
|
||||||
|
try {
|
||||||
|
String[] args = {"bash", "-c", "echo 1000"};
|
||||||
|
shexec = new ShellCommandExecutor(args);
|
||||||
|
shexec.execute();
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
LOG.warn("Bash is not supported by the OS", ioe);
|
||||||
|
supported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return supported;
|
||||||
|
}
|
||||||
|
|
||||||
public static final boolean isSetsidAvailable = isSetsidSupported();
|
public static final boolean isSetsidAvailable = isSetsidSupported();
|
||||||
private static boolean isSetsidSupported() {
|
private static boolean isSetsidSupported() {
|
||||||
if (Shell.WINDOWS) {
|
if (Shell.WINDOWS) {
|
||||||
|
@ -163,9 +163,9 @@ public void testGetCheckProcessIsAliveCommand() throws Exception {
|
|||||||
expectedCommand =
|
expectedCommand =
|
||||||
new String[]{ Shell.WINUTILS, "task", "isAlive", anyPid };
|
new String[]{ Shell.WINUTILS, "task", "isAlive", anyPid };
|
||||||
} else if (Shell.isSetsidAvailable) {
|
} else if (Shell.isSetsidAvailable) {
|
||||||
expectedCommand = new String[]{ "kill", "-0", "--", "-" + anyPid };
|
expectedCommand = new String[] { "bash", "-c", "kill -0 -- -" + anyPid };
|
||||||
} else {
|
} else {
|
||||||
expectedCommand = new String[]{"kill", "-0", anyPid};
|
expectedCommand = new String[]{ "bash", "-c", "kill -0 " + anyPid };
|
||||||
}
|
}
|
||||||
Assert.assertArrayEquals(expectedCommand, checkProcessAliveCommand);
|
Assert.assertArrayEquals(expectedCommand, checkProcessAliveCommand);
|
||||||
}
|
}
|
||||||
@ -177,15 +177,14 @@ public void testGetSignalKillCommand() throws Exception {
|
|||||||
anyPid);
|
anyPid);
|
||||||
|
|
||||||
String[] expectedCommand;
|
String[] expectedCommand;
|
||||||
|
|
||||||
if (Shell.WINDOWS) {
|
if (Shell.WINDOWS) {
|
||||||
expectedCommand =
|
expectedCommand =
|
||||||
new String[]{ Shell.WINUTILS, "task", "kill", anyPid };
|
new String[]{ Shell.WINUTILS, "task", "isAlive", anyPid };
|
||||||
} else if (Shell.isSetsidAvailable) {
|
} else if (Shell.isSetsidAvailable) {
|
||||||
expectedCommand =
|
expectedCommand = new String[] { "bash", "-c", "kill -9 -- -" + anyPid };
|
||||||
new String[]{ "kill", "-" + anySignal, "--", "-" + anyPid };
|
|
||||||
} else {
|
} else {
|
||||||
expectedCommand =
|
expectedCommand = new String[]{ "bash", "-c", "kill -9 " + anyPid };
|
||||||
new String[]{ "kill", "-" + anySignal, anyPid };
|
|
||||||
}
|
}
|
||||||
Assert.assertArrayEquals(expectedCommand, checkProcessAliveCommand);
|
Assert.assertArrayEquals(expectedCommand, checkProcessAliveCommand);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
import org.apache.hadoop.util.JvmPauseMonitor;
|
import org.apache.hadoop.util.JvmPauseMonitor;
|
||||||
import org.apache.hadoop.util.NodeHealthScriptRunner;
|
import org.apache.hadoop.util.NodeHealthScriptRunner;
|
||||||
import org.apache.hadoop.util.ReflectionUtils;
|
import org.apache.hadoop.util.ReflectionUtils;
|
||||||
|
import org.apache.hadoop.util.Shell;
|
||||||
import org.apache.hadoop.util.ShutdownHookManager;
|
import org.apache.hadoop.util.ShutdownHookManager;
|
||||||
import org.apache.hadoop.util.StringUtils;
|
import org.apache.hadoop.util.StringUtils;
|
||||||
import org.apache.hadoop.yarn.YarnUncaughtExceptionHandler;
|
import org.apache.hadoop.yarn.YarnUncaughtExceptionHandler;
|
||||||
@ -595,6 +596,17 @@ public NodeHealthCheckerService getNodeHealthChecker() {
|
|||||||
|
|
||||||
private void initAndStartNodeManager(Configuration conf, boolean hasToReboot) {
|
private void initAndStartNodeManager(Configuration conf, boolean hasToReboot) {
|
||||||
try {
|
try {
|
||||||
|
// Failed to start if we're a Unix based system but we don't have bash.
|
||||||
|
// Bash is necessary to launch containers under Unix-based systems.
|
||||||
|
if (!Shell.WINDOWS) {
|
||||||
|
if (!Shell.isBashSupported) {
|
||||||
|
String message =
|
||||||
|
"Failing NodeManager start since we're on a "
|
||||||
|
+ "Unix-based system but bash doesn't seem to be available.";
|
||||||
|
LOG.fatal(message);
|
||||||
|
throw new YarnRuntimeException(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove the old hook if we are rebooting.
|
// Remove the old hook if we are rebooting.
|
||||||
if (hasToReboot && null != nodeManagerShutdownHook) {
|
if (hasToReboot && null != nodeManagerShutdownHook) {
|
||||||
|
Loading…
Reference in New Issue
Block a user