]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
common: add Windows implementation for system info getter
authorLucian Petrut <lpetrut@cloudbasesolutions.com>
Mon, 28 Oct 2019 10:15:31 +0000 (10:15 +0000)
committerLucian Petrut <lpetrut@cloudbasesolutions.com>
Thu, 30 Jul 2020 06:41:52 +0000 (06:41 +0000)
common/util.cc provides some system info retrievers. This patch
covers the Windows implemention.

Signed-off-by: Lucian Petrut <lpetrut@cloudbasesolutions.com>
src/common/util.cc

index b4846328ce132542c1e212de8d4fe8ae7388e13e..6965ed1cf2a23c6531457f145755716c3a8f0f3a 100644 (file)
  * 
  */
 
+#ifndef _WIN32
 #include <sys/utsname.h>
+#endif
+
 #include <fstream>
 #include <boost/algorithm/string.hpp>
 
@@ -46,6 +49,7 @@ using std::string;
 using ceph::bufferlist;
 using ceph::Formatter;
 
+#ifndef _WIN32
 int get_fs_stats(ceph_data_stats_t &stats, const char *path)
 {
   if (!path)
@@ -63,6 +67,24 @@ int get_fs_stats(ceph_data_stats_t &stats, const char *path)
   stats.avail_percent = (((float)stats.byte_avail/stats.byte_total)*100);
   return 0;
 }
+#else
+int get_fs_stats(ceph_data_stats_t &stats, const char *path)
+{
+  ULARGE_INTEGER avail_bytes, total_bytes, total_free_bytes;
+
+  if (!GetDiskFreeSpaceExA(path, &avail_bytes,
+                           &total_bytes, &total_free_bytes)) {
+    return -EINVAL;
+  }
+
+  stats.byte_total = total_bytes.QuadPart;
+  stats.byte_used = total_bytes.QuadPart - total_free_bytes.QuadPart;
+  // may not be equal to total_free_bytes due to quotas
+  stats.byte_avail = avail_bytes.QuadPart;
+  stats.avail_percent = ((float)stats.byte_avail / stats.byte_total) * 100;
+  return 0;
+}
+#endif
 
 static char* value_sanitize(char *value)
 {
@@ -145,6 +167,7 @@ static void distro_detect(map<string, string> *m, CephContext *cct)
 
 int get_cgroup_memory_limit(uint64_t *limit)
 {
+#ifndef _WIN32
   // /sys/fs/cgroup/memory/memory.limit_in_bytes
 
   // the magic value 9223372036854771712 or 0x7ffffffffffff000
@@ -172,8 +195,35 @@ int get_cgroup_memory_limit(uint64_t *limit)
 out:
   fclose(f);
   return ret;
+#else
+  return 0;
+#endif
 }
 
+#ifdef _WIN32
+int get_windows_version(POSVERSIONINFOEXW ver) {
+  using  get_version_func_t = DWORD (WINAPI *)(OSVERSIONINFOEXW*);
+
+  // We'll load the library directly to avoid depending on the NTDDK.
+  HMODULE ntdll_lib = LoadLibraryW(L"Ntdll.dll");
+  if (!ntdll_lib) {
+    return -EINVAL;
+  }
+
+  // The standard "GetVersion" returned values depend on the application
+  // manifest. We'll get the "real" version by using the Rtl* version.
+  auto get_version_func = (
+    get_version_func_t)GetProcAddress(ntdll_lib, "RtlGetVersion");
+  int ret = 0;
+  if (!get_version_func || get_version_func(ver)) {
+    // RtlGetVersion returns non-zero values in case of errors.
+    ret = -EINVAL;
+  }
+
+  FreeLibrary(ntdll_lib);
+  return ret;
+}
+#endif
 
 void collect_sys_info(map<string, string> *m, CephContext *cct)
 {
@@ -182,6 +232,7 @@ void collect_sys_info(map<string, string> *m, CephContext *cct)
   (*m)["ceph_version_short"] = ceph_version_to_str();
   (*m)["ceph_release"] = ceph_release_to_str();
 
+  #ifndef _WIN32
   // kernel info
   struct utsname u;
   int r = uname(&u);
@@ -192,6 +243,44 @@ void collect_sys_info(map<string, string> *m, CephContext *cct)
     (*m)["hostname"] = u.nodename;
     (*m)["arch"] = u.machine;
   }
+  #else
+  OSVERSIONINFOEXW ver = {0};
+  ver.dwOSVersionInfoSize = sizeof(ver);
+  get_windows_version(&ver);
+
+  char version_str[64];
+  snprintf(version_str, 64, "%d.%d (%d)",
+           ver.dwMajorVersion, ver.dwMinorVersion, ver.dwBuildNumber);
+
+  char hostname[64];
+  DWORD hostname_sz = sizeof(hostname);
+  GetComputerNameA(hostname, &hostname_sz);
+
+  SYSTEM_INFO sys_info;
+  char* arch_str;
+  GetNativeSystemInfo(&sys_info);
+
+  switch (sys_info.wProcessorArchitecture) {
+    case PROCESSOR_ARCHITECTURE_AMD64:
+      arch_str = "x86_64";
+      break;
+    case PROCESSOR_ARCHITECTURE_INTEL:
+      arch_str = "x86";
+      break;
+    case PROCESSOR_ARCHITECTURE_ARM:
+      arch_str = "arm";
+      break;
+    default:
+      arch_str = "unknown";
+      break;
+  }
+
+  (*m)["os"] = "Windows";
+  (*m)["kernel_version"] = version_str;
+  (*m)["kernel_description"] = version_str;
+  (*m)["hostname"] = hostname;
+  (*m)["arch"] = arch_str;
+  #endif
 
   // but wait, am i in a container?
   bool in_container = false;
@@ -210,7 +299,7 @@ void collect_sys_info(map<string, string> *m, CephContext *cct)
   }
   if (in_container) {
     if (const char *node_name = getenv("NODE_NAME")) {
-      (*m)["container_hostname"] = u.nodename;
+      (*m)["container_hostname"] = (*m)["hostname"];
       (*m)["hostname"] = node_name;
     }
     if (const char *ns = getenv("POD_NAMESPACE")) {
@@ -246,7 +335,7 @@ void collect_sys_info(map<string, string> *m, CephContext *cct)
       (*m)["cpu"] = buf;
     }
   }
-#else
+#elif !defined(_WIN32)
   // memory
   if (std::ifstream f{PROCPREFIX "/proc/meminfo"}; !f.fail()) {
     for (std::string line; std::getline(f, line); ) {