]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
hostinfo: Identify Amazon Linux
authorOliver Kurth <okurth@vmware.com>
Wed, 7 Feb 2018 00:32:37 +0000 (16:32 -0800)
committerOliver Kurth <okurth@vmware.com>
Wed, 7 Feb 2018 00:32:37 +0000 (16:32 -0800)
Amazon Linux is not LSB compliant. Add a small amount of code such that
Amazon Linux can differentiated from all of other Linuxen and correctly
report its identifying data.

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

index 2184d1249b37be1cb247cbe9417655267262c00d..ffcce810f8db9b55151c90c71af71f6770625b63 100644 (file)
@@ -1,5 +1,5 @@
 /*********************************************************
- * Copyright (C) 1998-2017 VMware, Inc. All rights reserved.
+ * Copyright (C) 1998-2018 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
@@ -127,7 +127,7 @@ extern "C" {
 
 /* This list must be sorted alphabetically (non-case-sensitive) by gos name. */
 #define GUEST_OS_LIST_GEN                                                                             \
-   GOSL(STR_OS_AMAZON "2-64",                GUEST_OS_AMAZON2_64,             "linuxPreGlibc25.iso")  \
+   GOSL(STR_OS_AMAZON "2-64",                GUEST_OS_AMAZON2_64,             "linux.iso")            \
    GOSL(STR_OS_ASIANUX "3",                  GUEST_OS_OTHER26XLINUX,          "linuxPreGlibc25.iso")  \
    GOSL(STR_OS_ASIANUX "3-64",               GUEST_OS_OTHER26XLINUX_64,       "linuxPreGlibc25.iso")  \
    GOSL(STR_OS_ASIANUX "4",                  GUEST_OS_OTHER26XLINUX,          "linuxPreGlibc25.iso")  \
index 1f2965945250088c09bc0142c3a2a7589428cff6..e125382fc9116ac013d6d891a2c10751385dddfb 100644 (file)
@@ -157,9 +157,9 @@ static Atomic_Ptr hostinfoOSVersion;
 typedef struct {
    char *name;
    char *scanString;
-} DistoNameScan;
+} DistroNameScan;
 
-static const DistoNameScan lsbFields[] = {
+static const DistroNameScan lsbFields[] = {
    {"DISTRIB_ID=",          "DISTRIB_ID=%s"          },
    {"DISTRIB_RELEASE=",     "DISTRIB_RELEASE=%s"     },
    {"DISTRIB_CODENAME=",    "DISTRIB_CODENAME=%s"    },
@@ -167,6 +167,11 @@ static const DistoNameScan lsbFields[] = {
    {NULL,                   NULL                     },
 };
 
+static const DistroNameScan amazonFields[] = {
+   {"PRETTY_NAME=",        "PRETTY_NAME=%s"          },
+   {NULL,                   NULL                     },
+};
+
 typedef struct {
    char *name;
    char *filename;
@@ -881,9 +886,10 @@ HostinfoGetOSShortName(char *distro,         // IN: full distro name
  */
 
 static Bool
-HostinfoReadDistroFile(char *filename,  // IN: distro version file name
-                       int distroSize,  // IN: size of OS distro name buffer
-                       char *distro)    // OUT: full distro name
+HostinfoReadDistroFile(char *filename,                // IN: version file
+                       const DistroNameScan *values,  // IN: search strings
+                       int distroSize,                // IN: length of distro
+                       char *distro)                  // OUT: full distro name
 {
    int i;
    int buf_sz;
@@ -929,23 +935,23 @@ HostinfoReadDistroFile(char *filename,  // IN: distro version file name
    distroOrig[buf_sz - 1] = '\0';
 
    /*
-    * For the case where we do have a release file in the LSB format,
-    * but there is no LSB module, let's parse the LSB file for possible fields.
+    * Attempt to parse a file with one name=value pair per line. Values are
+    * expected to embedded in double quotes.
     */
 
    distro[0] = '\0';
 
-   for (i = 0; lsbFields[i].name != NULL; i++) {
-      const char *tmpDistroPos = strstr(distroOrig, lsbFields[i].name);
+   for (i = 0; values[i].name != NULL; i++) {
+      const char *tmpDistroPos = strstr(distroOrig, values[i].name);
 
       if (tmpDistroPos != NULL) {
          char distroPart[DISTRO_BUF_SIZE];
 
-         sscanf(tmpDistroPos, lsbFields[i].scanString, distroPart);
+         sscanf(tmpDistroPos, values[i].scanString, distroPart);
          if (distroPart[0] == '"') {
             char *tmpMakeNull;
 
-            tmpDistroPos += strlen(lsbFields[i].name) + 1;
+            tmpDistroPos += strlen(values[i].name) + 1;
             tmpMakeNull = strchr(tmpDistroPos + 1 , '"');
             if (tmpMakeNull != NULL) {
                *tmpMakeNull = '\0';
@@ -1144,8 +1150,8 @@ HostinfoLinux(struct utsname *buf)  // IN:
        */
 
       for (i = 0; distroArray[i].filename != NULL; i++) {
-         if (HostinfoReadDistroFile(distroArray[i].filename, distroSize,
-                                    distro)) {
+         if (HostinfoReadDistroFile(distroArray[i].filename, &lsbFields[0],
+                                    distroSize, distro)) {
             break;
          }
       }
@@ -1322,6 +1328,68 @@ HostinfoSun(struct utsname *buf)  // IN:
 
    return (len != -1);
 }
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * HostinfoAmazon --
+ *
+ *      Determine the specifics concerning Amazon Linux.
+ *
+ * Return value:
+ *      TRUE   Success
+ *      FALSE  Failure
+ *
+ * Side effects:
+ *      Cache values are set when returning TRUE
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static Bool
+HostinfoAmazon(struct utsname *buf)  // IN:
+{
+   int len;
+   char osName[MAX_OS_NAME_LEN];
+   char osNameFull[MAX_OS_FULLNAME_LEN] = { '\0' };
+
+   if (HostinfoReadDistroFile("/etc/os-release", &amazonFields[0],
+                              sizeof osNameFull, osNameFull)) {
+      len = strlen(osNameFull);
+   } else {
+      Log("%s: Using fallback\n", __FUNCTION__);
+
+      len = Str_Snprintf(osNameFull, sizeof osNameFull,
+                         "Amazon Linux x.y (kernel %d.%d)",
+                         Hostinfo_OSVersion(0),          // Kernel major
+                         Hostinfo_OSVersion(1));         // Kernel minor
+   }
+
+   if (len != -1) {
+      int amazonMinor = 0;
+      int amazonMajor = 0;
+
+      if (sscanf(osNameFull, "Amazon Linux %d.%d", &amazonMajor,
+                 &amazonMinor) != 2) {
+         /* Oldest known good release */
+         amazonMajor = 2;
+         amazonMinor = 0;
+      }
+
+      /* We are not offering a 32-bit version... or ever plan to. */
+      len = Str_Snprintf(osName, sizeof osName, "%s%d%s", STR_OS_AMAZON,
+                         amazonMajor, STR_OS_64BIT_SUFFIX);
+   }
+
+   if (len == -1) {
+      Warning("%s: Error: buffer too small\n", __FUNCTION__);
+   } else {
+      HostinfoPostData(osName, osNameFull);
+   }
+
+   return (len != -1);
+}
 #endif // !defined __APPLE__ && !defined USERWORLD
 
 
@@ -1364,7 +1432,13 @@ HostinfoOSData(void)
    success = HostinfoMacOS(&buf);
 #else
    if (strstr(buf.sysname, "Linux")) {
-      success = HostinfoLinux(&buf);
+      struct stat sb;
+
+      if (Posix_Stat("/etc/amazon", &sb) == 0) {
+         success = HostinfoAmazon(&buf);
+      } else {
+         success = HostinfoLinux(&buf);
+      }
    } else if (strstr(buf.sysname, "FreeBSD")) {
       success = HostinfoBSD(&buf);
    } else if (strstr(buf.sysname, "SunOS")) {