@Override public void signalTask(String user, int taskPid, Signal signal) throws IOException { String[] command = new String[]{taskControllerExe, user, localStorage.getDirsString(), Integer.toString(Commands.SIGNAL_TASK.getValue()), Integer.toString(taskPid), Integer.toString(signal.getValue())}; ShellCommandExecutor shExec = new ShellCommandExecutor(command); if (LOG.isDebugEnabled()) { LOG.debug("signalTask: " + Arrays.toString(command)); } try { shExec.execute(); } catch (ExitCodeException e) { int ret_code = shExec.getExitCode(); if (ret_code != ResultCode.INVALID_TASK_PID.getValue()) { logOutput(shExec.getOutput()); throw new IOException("Problem signalling task " + taskPid + " with " + signal + "; exit = " + ret_code); } } }
synchronized void kill() throws IOException, InterruptedException { if (!killed) { TaskController controller = tracker.getTaskController(); // Check inital context before issuing a kill to prevent situations // where kill is issued before task is launched. String pidStr = jvmIdToPid.get(jvmId); if (pidStr != null) { String user = env.conf.getUser(); int pid = Integer.parseInt(pidStr); // start a thread that will kill the process dead if (sleeptimeBeforeSigkill > 0) { new DelayedProcessKiller(user, pid, sleeptimeBeforeSigkill, Signal.KILL).start(); controller.signalTask(user, pid, Signal.TERM); } else { controller.signalTask(user, pid, Signal.KILL); } } else { LOG.info(String.format("JVM Not killed %s but just removed", jvmId .toString())); } killed = true; } }
synchronized void kill() throws IOException, InterruptedException { if (!killed) { TaskController controller = tracker.getTaskController(); // Check inital context before issuing a kill to prevent situations // where kill is issued before task is launched. String pidStr = jvmIdToPid.get(jvmId); if (pidStr != null) { String user = env.conf.getUser(); int pid = Integer.parseInt(pidStr); // start a thread that will kill the process dead if (sleeptimeBeforeSigkill > 0) { LOG.info("jvm " + jvmId + " is Killed"); new DelayedProcessKiller(user, pid, sleeptimeBeforeSigkill, Signal.KILL).start(); controller.signalTask(user, pid, Signal.TERM); } else { controller.signalTask(user, pid, Signal.KILL); } } else { LOG.info(String.format("JVM Not killed %s but just removed", jvmId .toString())); } killed = true; } }
DelayedProcessKiller(String user, int pid, long delay, Signal signal) { this.user = user; this.pid = pid; this.delay = delay; this.signal = signal; setName("Task killer for " + pid); setDaemon(false); }
@Override public void signalTask(String user, int taskPid, Signal signal) { if (ProcessTree.isSetsidAvailable) { ProcessTree.killProcessGroup(Integer.toString(taskPid), signal); } else { ProcessTree.killProcess(Integer.toString(taskPid), signal); } }
synchronized void kill(boolean dumpStacksBefore) throws IOException, InterruptedException { if (!killed) { TaskController controller = tracker.getTaskController(); // Check inital context before issuing a kill to prevent situations // where kill is issued before task is launched. String pidStr = jvmIdToPid.get(jvmId); if (pidStr != null) { String user = env.conf.getUser(); int pid = Integer.parseInt(pidStr); // Send a signal and then start threads to send additional signals later. // In normal conditions, we send a SIGTERM immediately and a SIGKILL later. // If sleeptimeBeforeSigkill is 0, we don't send the SIGTERM and // instead send the SIGKILL immediately. // If dumpStacksBefore is true, we start with a SIGQUIT (to make the // child process dump its stacks) and then follow up with the // SIGTERM/SIGKILL later. if (dumpStacksBefore) { controller.signalTask(user, pid, Signal.QUIT); if (sleeptimeBeforeSigkill > 0) { new DelayedProcessKiller(user, pid, SLEEPTIME_AFTER_SIGQUIT, Signal.TERM).start(); new DelayedProcessKiller(user, pid, SLEEPTIME_AFTER_SIGQUIT + sleeptimeBeforeSigkill, Signal.KILL).start(); } else { new DelayedProcessKiller(user, pid, SLEEPTIME_AFTER_SIGQUIT, Signal.KILL).start(); } } else { if (sleeptimeBeforeSigkill > 0) { controller.signalTask(user, pid, Signal.TERM); new DelayedProcessKiller(user, pid, sleeptimeBeforeSigkill, Signal.KILL).start(); } else { controller.signalTask(user, pid, Signal.KILL); } } } else { LOG.info(String.format("JVM Not killed %s but just removed", jvmId .toString())); } killed = true; } }
/** * Send a signal to a task pid as the user. * @param user the user name * @param taskPid the pid of the task * @param signal the id of the signal to send */ public abstract void signalTask(String user, int taskPid, Signal signal) throws IOException;