You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by an...@apache.org on 2017/12/01 00:05:57 UTC

[03/10] mesos git commit: Windows: Added `os::get_job_processes` to stout.

Windows: Added `os::get_job_processes` to stout.

Returns a `set<Process>` for all the processes in a job object.

Review: https://reviews.apache.org/r/63273


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/d11d6d2d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/d11d6d2d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/d11d6d2d

Branch: refs/heads/master
Commit: d11d6d2d08979a53183850e4665510799ed9b2d2
Parents: 7d1c580
Author: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Authored: Fri Oct 20 10:55:14 2017 -0700
Committer: Andrew Schwartzmeyer <an...@schwartzmeyer.com>
Committed: Thu Nov 30 15:54:53 2017 -0800

----------------------------------------------------------------------
 3rdparty/stout/include/stout/windows/os.hpp | 86 ++++++++++++++++++++++++
 1 file changed, 86 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/d11d6d2d/3rdparty/stout/include/stout/windows/os.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/stout/include/stout/windows/os.hpp b/3rdparty/stout/include/stout/windows/os.hpp
index 57481be..b0b1b8d 100644
--- a/3rdparty/stout/include/stout/windows/os.hpp
+++ b/3rdparty/stout/include/stout/windows/os.hpp
@@ -760,6 +760,92 @@ inline Try<JOBOBJECT_BASIC_ACCOUNTING_INFORMATION> get_job_info(pid_t pid)
 }
 
 
+template <size_t max_pids>
+Result<std::set<Process>> _get_job_processes(const SharedHandle& job_handle) {
+  // This is a statically allocated `JOBOBJECT_BASIC_PROCESS_ID_LIST`. We lie to
+  // the Windows API and construct our own struct to avoid (a) having to do
+  // hairy size calculations and (b) having to allocate dynamically, and then
+  // worry about deallocating.
+  struct {
+    DWORD     NumberOfAssignedProcesses;
+    DWORD     NumberOfProcessIdsInList;
+    ULONG_PTR ProcessIdList[max_pids];
+  } pid_list;
+
+  BOOL result = ::QueryInformationJobObject(
+    job_handle.get_handle(),
+    JobObjectBasicProcessIdList,
+    reinterpret_cast<JOBOBJECT_BASIC_PROCESS_ID_LIST*>(&pid_list),
+    sizeof(pid_list),
+    nullptr);
+
+  // `ERROR_MORE_DATA` indicates we need a larger `max_pids`.
+  if (result == FALSE && ::GetLastError() == ERROR_MORE_DATA) {
+    return None();
+  }
+
+  if (result == FALSE) {
+    return WindowsError(
+      "os::_get_job_processes: call to `QueryInformationJobObject` failed");
+  }
+
+  std::set<Process> processes;
+  for (DWORD i = 0; i < pid_list.NumberOfProcessIdsInList; ++i) {
+    Result<Process> process = os::process(pid_list.ProcessIdList[i]);
+    if (process.isSome()) {
+      processes.insert(process.get());
+    }
+  }
+
+  return processes;
+}
+
+
+inline Try<std::set<Process>> get_job_processes(pid_t pid)
+{
+  Try<std::wstring> name = os::name_job(pid);
+  if (name.isError()) {
+    return Error(name.error());
+  }
+
+  Try<SharedHandle> job_handle = os::open_job(
+    JOB_OBJECT_QUERY,
+    false,
+    name.get());
+  if (job_handle.isError()) {
+    return Error(job_handle.error());
+  }
+
+  // Try to enumerate the processes with three sizes: 32, 1K, and 32K.
+
+  Result<std::set<Process>> result =
+    os::_get_job_processes<32>(job_handle.get());
+  if (result.isError()) {
+    return Error(result.error());
+  } else if (result.isSome()) {
+    return result.get();
+  }
+
+  result = os::_get_job_processes<32*32>(job_handle.get());
+  if (result.isError()) {
+    return Error(result.error());
+  } else if (result.isSome()) {
+    return result.get();
+  }
+
+  result = os::_get_job_processes<32*32*32>(job_handle.get());
+  if (result.isError()) {
+    return Error(result.error());
+  } else if (result.isSome()) {
+    return result.get();
+  }
+
+  // If it was bigger than 32K, something else has gone wrong.
+
+  return Error("os::get_job_processes: failed to get processes");
+}
+
+
 // `set_job_cpu_limit` sets a CPU limit for the process represented by
 // `pid`, assuming it is assigned to a job object. This function will fail
 // otherwise. This limit is a hard cap enforced by the OS.