]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
GuestOS: Improve the guest OS identification code
authorOliver Kurth <okurth@vmware.com>
Tue, 19 Feb 2019 20:51:32 +0000 (12:51 -0800)
committerOliver Kurth <okurth@vmware.com>
Tue, 19 Feb 2019 20:51:32 +0000 (12:51 -0800)
Now that we often have an explicit, unambiguous version string for
a distro, use it. In the rare case we don't have one, search the
distro string for a digit and use that. If we can't find anything,
note this and let the code fall into the default appropriate to the
distro.

With this change, we stop using strings and so are no longer confused
by things like "7.5". For a few of the distros, we now no longer care
about the upper bound, we can report what we find. Anything above what
the release supports will be fixed by the GuestMapper.

open-vm-tools/lib/include/guest_os.h
open-vm-tools/lib/misc/hostinfoPosix.c

index 6d13ea680789de4df19e34e3a494c3c971ca5b9e..732b82c570174fb6a65b22c463ee2e11215f8abd 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 1998-2018 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2019 VMware, Inc. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published
@@ -250,7 +250,6 @@ Bool Gos_InSetArray(uint32 gos, const uint32 *set);
 #define STR_OS_DEBIAN_5            "debian5"
 #define STR_OS_DEBIAN_6            "debian6"
 #define STR_OS_DEBIAN_7            "debian7"
-#define STR_OS_DEBIAN_7_1          "debian7"
 #define STR_OS_DEBIAN_8            "debian8"
 #define STR_OS_DEBIAN_9            "debian9"
 #define STR_OS_DEBIAN_10           "debian10"
index 353f29f778a61c9d07ca38ff5e80caf63e28ae27..ef23368f0b69282be7e00cb9dd6fe7e10f659c3f 100644 (file)
@@ -188,6 +188,7 @@ static const DistroInfo distroArray[] = {
    { "Aurox",              "/etc/aurox-release"         },
    { "BlackCat",           "/etc/blackcat-release"      },
    { "Cobalt",             "/etc/cobalt-release"        },
+   { "CentOS",             "/etc/centos-release"        },
    { "Conectiva",          "/etc/conectiva-release"     },
    { "Debian",             "/etc/debian_release"        },
    { "Debian",             "/etc/debian_version"        },
@@ -783,39 +784,54 @@ HostinfoESX(struct utsname *buf)  // IN:
  */
 
 static void
-HostinfoGetOSShortName(char *distro,         // IN: full distro name
-                       char *distroShort,    // OUT: short distro name
-                       int distroShortSize)  // IN: size of short distro name
+HostinfoGetOSShortName(const char *distro,      // IN: full distro name
+                       const char *versionStr,  // IN/OPT: distro version
+                       char *distroShort,       // OUT: short distro name
+                       int distroShortSize)     // IN: size of short distro name
 
 {
-   char *distroLower = Util_SafeStrdup(distro);
+   uint32 version;
+   char *distroLower;
 
-   distroLower = Str_ToLower(distroLower);
+   ASSERT(distro != NULL);
+   ASSERT(distroShort != NULL);
 
-   if (strstr(distroLower, "red hat")) {
-      if (strstr(distroLower, "enterprise")) {
+   /* Come up with a distro version */
 
-         /*
-          * Looking for "release x" here instead of "x" as there could be
-          * build version which can be misleading. For example Red Hat
-          * Enterprise Linux ES release 4 (Nahant Update 3)
-          */
+   if (versionStr == NULL) {
+      const char *p = distro;
 
-         int release = 0;
-         char *releaseStart = strstr(distroLower, "release");
-
-         if (releaseStart != NULL) {
-            sscanf(releaseStart, "release %d", &release);
-            if (release > 0) {
-               snprintf(distroShort, distroShortSize, STR_OS_RED_HAT_EN"%d",
-                        release);
-            }
+      /* The first digit in the distro string is the version */
+      while (*p != '\0') {
+         if (isdigit(*p)) {
+            versionStr = p;
+            break;
          }
 
-         if (release <= 0) {
+         p++;
+      }
+   }
+
+   if (versionStr == NULL) {
+      version = 0;
+   } else {
+      if (sscanf(versionStr, "%u", &version) != 1) {
+         version = 0;
+      }
+   }
+
+   /* Normalize the distro string */
+   distroLower = Str_ToLower(Util_SafeStrdup(distro));
+
+   /* Attempt to match the distro against the "usual suspects". */
+   if (strstr(distroLower, "red hat")) {
+      if (strstr(distroLower, "enterprise")) {
+         if (version == 0) {
             Str_Strcpy(distroShort, STR_OS_RED_HAT_EN, distroShortSize);
+         } else {
+            Str_Sprintf(distroShort, distroShortSize, "%s%d",
+                        STR_OS_RED_HAT_EN, version);
          }
-
       } else {
          Str_Strcpy(distroShort, STR_OS_RED_HAT, distroShortSize);
       }
@@ -853,15 +869,12 @@ HostinfoGetOSShortName(char *distro,         // IN: full distro name
    } else if (strstr(distroLower, "sun")) {
       Str_Strcpy(distroShort, STR_OS_SUN_DESK, distroShortSize);
    } else if (strstr(distroLower, "amazon")) {
-      int amazonMajor = 0;
-
-      if (sscanf(distroLower, "amazon linux %d", &amazonMajor) != 1) {
-         /* Oldest known good release */
-         amazonMajor = 2;
+      if (version < 2) {
+         version = 2;
       }
 
       Str_Sprintf(distroShort, distroShortSize, "%s%d", STR_OS_AMAZON_LINUX,
-                  amazonMajor);
+                  version);
    } else if (strstr(distroLower, "annvix")) {
       Str_Strcpy(distroShort, STR_OS_ANNVIX, distroShortSize);
    } else if (strstr(distroLower, "arch")) {
@@ -890,32 +903,20 @@ HostinfoGetOSShortName(char *distro,         // IN: full distro name
    } else if (strstr(distroLower, "cobalt")) {
       Str_Strcpy(distroShort, STR_OS_COBALT, distroShortSize);
    } else if (StrUtil_StartsWith(distroLower, "centos")) {
-      if (strstr(distroLower, "6.")) {
-         Str_Strcpy(distroShort, STR_OS_CENTOS6, distroShortSize);
-      } else if (strstr(distroLower, "7.")) {
-         Str_Strcpy(distroShort, STR_OS_CENTOS7, distroShortSize);
-      } else if (strstr(distroLower, "8.")) {
-         Str_Strcpy(distroShort, STR_OS_CENTOS8, distroShortSize);
-      } else {
+      if (version < 6) {
          Str_Strcpy(distroShort, STR_OS_CENTOS, distroShortSize);
+      } else {
+         Str_Sprintf(distroShort, distroShortSize, "%s%d", STR_OS_CENTOS,
+                     version);
       }
    } else if (strstr(distroLower, "conectiva")) {
       Str_Strcpy(distroShort, STR_OS_CONECTIVA, distroShortSize);
    } else if (strstr(distroLower, "debian")) {
-      if (strstr(distroLower, "4.0")) {
+      if (version <= 4) {
          Str_Strcpy(distroShort, STR_OS_DEBIAN_4, distroShortSize);
-      } else if (strstr(distroLower, "5.0")) {
-         Str_Strcpy(distroShort, STR_OS_DEBIAN_5, distroShortSize);
-      } else if (strstr(distroLower, "6.0")) {
-         Str_Strcpy(distroShort, STR_OS_DEBIAN_6, distroShortSize);
-      } else if (strstr(distroLower, "7.")) {
-         Str_Strcpy(distroShort, STR_OS_DEBIAN_7, distroShortSize);
-      } else if (strstr(distroLower, "8.")) {
-         Str_Strcpy(distroShort, STR_OS_DEBIAN_8, distroShortSize);
-      } else if (strstr(distroLower, "9.")) {
-         Str_Strcpy(distroShort, STR_OS_DEBIAN_9, distroShortSize);
-      } else if (strstr(distroLower, "10.")) {
-         Str_Strcpy(distroShort, STR_OS_DEBIAN_10, distroShortSize);
+      } else {
+         Str_Sprintf(distroShort, distroShortSize, "%s%d", STR_OS_DEBIAN,
+                     version);
       }
    } else if (StrUtil_StartsWith(distroLower, "enterprise linux") ||
               StrUtil_StartsWith(distroLower, "oracle")) {
@@ -926,14 +927,11 @@ HostinfoGetOSShortName(char *distro,         // IN: full distro name
        * Not sure why they didn't brand their releases as "Oracle Enterprise
        * Linux". Oh well. It's fixed in 6.0, though.
        */
-      if (strstr(distroLower, "6.")) {
-         Str_Strcpy(distroShort, STR_OS_ORACLE6, distroShortSize);
-      } else if (strstr(distroLower, "7.")) {
-         Str_Strcpy(distroShort, STR_OS_ORACLE7, distroShortSize);
-      } else if (strstr(distroLower, "8.")) {
-         Str_Strcpy(distroShort, STR_OS_ORACLE8, distroShortSize);
-      } else {
+      if (version == 0) {
          Str_Strcpy(distroShort, STR_OS_ORACLE, distroShortSize);
+      } else {
+         Str_Sprintf(distroShort, distroShortSize, "%s%d", STR_OS_ORACLE,
+                     version);
       }
    } else if (strstr(distroLower, "fedora")) {
       Str_Strcpy(distroShort, STR_OS_FEDORA, distroShortSize);
@@ -1002,7 +1000,7 @@ HostinfoGetOSShortName(char *distro,         // IN: full distro name
 
 static char **
 HostinfoReadDistroFile(Bool osReleaseRules,           // IN: osRelease rules
-                       char *filename,                // IN: distro file
+                       const char *filename,          // IN: distro file
                        const DistroNameScan *values)  // IN: search strings
 {
    int i;
@@ -1236,7 +1234,7 @@ HostinfoGetCmdOutput(const char *cmd)  // IN:
  * HostinfoOsRelease --
  *
  *      Attempt to return the distro identification data we're interested in
- *      from the os-release standard file(s). Look for the os-release data in
+ *      from the os-release standard file(s). Look for the os-release data by
  *      following the priority order established by the os-release standard.
  *
  *      The fields of interest are found in osReleaseFields above.
@@ -1552,7 +1550,7 @@ HostinfoBestScore(char *distro,            // OUT:
       }
 
       HostinfoDefaultLinux(NULL, 0, distroShort, distroShortSize);
-      HostinfoGetOSShortName(distro, distroShort, distroShortSize);
+      HostinfoGetOSShortName(distro, lsbData[1], distroShort, distroShortSize);
 
       goto bail;
    }
@@ -1585,7 +1583,8 @@ HostinfoBestScore(char *distro,            // OUT:
       }
 
       HostinfoDefaultLinux(NULL, 0, distroShort, distroShortSize);
-      HostinfoGetOSShortName(distro, distroShort, distroShortSize);
+      HostinfoGetOSShortName(distro, osReleaseData[2],
+                             distroShort, distroShortSize);
 
       goto bail;
    }