use of org.apache.hadoop.yarn.server.nodemanager.ContainerExecutor.DelayedProcessKiller in project hadoop by apache.
the class ContainerLaunch method cleanupContainer.
/**
* Cleanup the container.
* Cancels the launch if launch has not started yet or signals
* the executor to not execute the process if not already done so.
* Also, sends a SIGTERM followed by a SIGKILL to the process if
* the process id is available.
* @throws IOException
*/
// dispatcher not typed
@SuppressWarnings("unchecked")
public void cleanupContainer() throws IOException {
ContainerId containerId = container.getContainerId();
String containerIdStr = containerId.toString();
LOG.info("Cleaning up container " + containerIdStr);
try {
context.getNMStateStore().storeContainerKilled(containerId);
} catch (IOException e) {
LOG.error("Unable to mark container " + containerId + " killed in store", e);
}
// launch flag will be set to true if process already launched
boolean alreadyLaunched = !containerAlreadyLaunched.compareAndSet(false, true);
if (!alreadyLaunched) {
LOG.info("Container " + containerIdStr + " not launched." + " No cleanup needed to be done");
return;
}
if (LOG.isDebugEnabled()) {
LOG.debug("Marking container " + containerIdStr + " as inactive");
}
// this should ensure that if the container process has not launched
// by this time, it will never be launched
exec.deactivateContainer(containerId);
if (LOG.isDebugEnabled()) {
LOG.debug("Getting pid for container " + containerIdStr + " to kill" + " from pid file " + (pidFilePath != null ? pidFilePath.toString() : "null"));
}
// however the container process may have already started
try {
// get process id from pid file if available
// else if shell is still active, get it from the shell
String processId = null;
if (pidFilePath != null) {
processId = getContainerPid(pidFilePath);
}
// kill process
if (processId != null) {
String user = container.getUser();
if (LOG.isDebugEnabled()) {
LOG.debug("Sending signal to pid " + processId + " as user " + user + " for container " + containerIdStr);
}
final Signal signal = sleepDelayBeforeSigKill > 0 ? Signal.TERM : Signal.KILL;
boolean result = exec.signalContainer(new ContainerSignalContext.Builder().setContainer(container).setUser(user).setPid(processId).setSignal(signal).build());
if (LOG.isDebugEnabled()) {
LOG.debug("Sent signal " + signal + " to pid " + processId + " as user " + user + " for container " + containerIdStr + ", result=" + (result ? "success" : "failed"));
}
if (sleepDelayBeforeSigKill > 0) {
new DelayedProcessKiller(container, user, processId, sleepDelayBeforeSigKill, Signal.KILL, exec).start();
}
}
} catch (Exception e) {
String message = "Exception when trying to cleanup container " + containerIdStr + ": " + StringUtils.stringifyException(e);
LOG.warn(message);
dispatcher.getEventHandler().handle(new ContainerDiagnosticsUpdateEvent(containerId, message));
} finally {
// cleanup pid file if present
if (pidFilePath != null) {
FileContext lfs = FileContext.getLocalFSFileContext();
lfs.delete(pidFilePath, false);
lfs.delete(pidFilePath.suffix(EXIT_CODE_FILE_SUFFIX), false);
}
}
}
Aggregations