/// <summary>Recover an already existing container.</summary> /// <remarks> /// Recover an already existing container. This is a blocking call and returns /// only when the container exits. Note that the container must have been /// activated prior to this call. /// </remarks> /// <param name="user">the user of the container</param> /// <param name="containerId">The ID of the container to reacquire</param> /// <returns>The exit code of the pre-existing container</returns> /// <exception cref="System.IO.IOException"/> /// <exception cref="System.Exception"></exception> public virtual int ReacquireContainer(string user, ContainerId containerId) { Path pidPath = GetPidFilePath(containerId); if (pidPath == null) { Log.Warn(containerId + " is not active, returning terminated error"); return(ContainerExecutor.ExitCode.Terminated.GetExitCode()); } string pid = null; pid = ProcessIdFileReader.GetProcessId(pidPath); if (pid == null) { throw new IOException("Unable to determine pid for " + containerId); } Log.Info("Reacquiring " + containerId + " with pid " + pid); while (IsContainerProcessAlive(user, pid)) { Sharpen.Thread.Sleep(1000); } // wait for exit code file to appear string exitCodeFile = ContainerLaunch.GetExitCodeFile(pidPath.ToString()); FilePath file = new FilePath(exitCodeFile); int sleepMsec = 100; int msecLeft = 2000; while (!file.Exists() && msecLeft >= 0) { if (!IsContainerActive(containerId)) { Log.Info(containerId + " was deactivated"); return(ContainerExecutor.ExitCode.Terminated.GetExitCode()); } Sharpen.Thread.Sleep(sleepMsec); msecLeft -= sleepMsec; } if (msecLeft < 0) { throw new IOException("Timeout while waiting for exit code from " + containerId); } try { return(System.Convert.ToInt32(FileUtils.ReadFileToString(file).Trim())); } catch (FormatException e) { throw new IOException("Error parsing exit code from pid " + pid, e); } }
/// <summary>Get the process-identifier for the container</summary> /// <param name="containerID"/> /// <returns> /// the processid of the container if it has already launched, /// otherwise return null /// </returns> public virtual string GetProcessId(ContainerId containerID) { string pid = null; Path pidFile = pidFiles[containerID]; if (pidFile == null) { // This container isn't even launched yet. return(pid); } try { pid = ProcessIdFileReader.GetProcessId(pidFile); } catch (IOException e) { Log.Error("Got exception reading pid from pid-file " + pidFile, e); } return(pid); }
/// <summary> /// Loop through for a time-bounded interval waiting to /// read the process id from a file generated by a running process. /// </summary> /// <param name="pidFilePath">File from which to read the process id</param> /// <returns>Process ID</returns> /// <exception cref="System.Exception"/> private string GetContainerPid(Path pidFilePath) { string containerIdStr = ConverterUtils.ToString(container.GetContainerId()); string processId = null; Log.Debug("Accessing pid for container " + containerIdStr + " from pid file " + pidFilePath ); int sleepCounter = 0; int sleepInterval = 100; // loop waiting for pid file to show up // until our timer expires in which case we admit defeat while (true) { processId = ProcessIdFileReader.GetProcessId(pidFilePath); if (processId != null) { Log.Debug("Got pid " + processId + " for container " + containerIdStr); break; } else { if ((sleepCounter * sleepInterval) > maxKillWaitTime) { Log.Info("Could not get pid for " + containerIdStr + ". Waited for " + maxKillWaitTime + " ms."); break; } else { ++sleepCounter; Sharpen.Thread.Sleep(sleepInterval); } } } return(processId); }