~ubuntu-branches/ubuntu/quantal/open-vm-tools/quantal-201210021442

« back to all changes in this revision

Viewing changes to lib/misc/hostinfoPosix.c

  • Committer: Bazaar Package Importer
  • Author(s): Serge Hallyn
  • Date: 2011-03-31 14:20:05 UTC
  • mfrom: (1.4.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110331142005-3n9red91p7ogkweo
Tags: 2011.03.28-387002-0ubuntu1
* Merge latest upstream git tag.  This has the unlocked_ioctl change
  needed to fix dkms build failures (LP: #727342)
* Changes in debian/rules:
  - work around a bug in toolbox/Makefile, where install-exec-hook is
    not happening.  This needs to get fixed the right way.
  - don't install 'vmware-user' which seems to no longer exist
  - move /etc/xdg into open-vm-toolbox (which should be done using .install)
* debian/open-vm-tools.init: add 'modprobe [-r] vmblock'. (LP: #332323)
* debian/rules and debian/open-vm-toolbox.lintian-overrides:
  - Make vmware-user-suid-wrapper suid-root (LP: #332323)

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 *
17
17
 *********************************************************/
18
18
 
 
19
#define _GNU_SOURCE
19
20
#include <stdio.h>
20
21
#include <stdlib.h>
21
22
#include <unistd.h>
65
66
#include <sys/vfs.h>
66
67
#endif
67
68
#if !defined(sun) && (!defined(USING_AUTOCONF) || (defined(HAVE_SYS_IO_H) && defined(HAVE_SYS_SYSINFO_H)))
68
 
#include <sys/io.h>
 
69
# ifndef __ANDROID__
 
70
# include <sys/io.h>
 
71
# endif
69
72
#include <sys/sysinfo.h>
70
73
#ifndef HAVE_SYSINFO
71
74
#define HAVE_SYSINFO 1
77
80
#include <paths.h>
78
81
#endif
79
82
 
 
83
#ifdef __linux__
 
84
#include <dlfcn.h>
 
85
#endif
 
86
 
80
87
#if !defined(_PATH_DEVNULL)
81
88
#define _PATH_DEVNULL "/dev/null"
82
89
#endif
140
147
} LSBDistroInfo;
141
148
 
142
149
 
143
 
static LSBDistroInfo lsbFields[] = {
 
150
static const LSBDistroInfo lsbFields[] = {
144
151
   {"DISTRIB_ID=",          "DISTRIB_ID=%s"},
145
152
   {"DISTRIB_RELEASE=",     "DISTRIB_RELEASE=%s"},
146
153
   {"DISTRIB_CODENAME=",    "DISTRIB_CODENAME=%s"},
154
161
   char *filename;
155
162
} DistroInfo;
156
163
 
157
 
 
158
 
static DistroInfo distroArray[] = {
 
164
static const DistroInfo distroArray[] = {
159
165
   {"RedHat",             "/etc/redhat-release"},
160
166
   {"RedHat",             "/etc/redhat_version"},
161
167
   {"Sun",                "/etc/sun-release"},
434
440
}
435
441
 
436
442
 
 
443
#if !defined __APPLE__
437
444
/*
438
445
 *-----------------------------------------------------------------------------
439
446
 *
499
506
      } else {
500
507
         Str_Strcpy(distroShort, STR_OS_RED_HAT, distroShortSize);
501
508
      }
 
509
   } else if (strstr(distroLower, "opensuse")) {
 
510
      Str_Strcpy(distroShort, STR_OS_OPENSUSE, distroShortSize);
502
511
   } else if (strstr(distroLower, "suse")) {
503
512
      if (strstr(distroLower, "enterprise")) {
504
 
         if (strstr(distroLower, "server 11")) {
 
513
         if (strstr(distroLower, "server 11") ||
 
514
             strstr(distroLower, "desktop 11")) {
505
515
            Str_Strcpy(distroShort, STR_OS_SLES_11, distroShortSize);
506
 
         } else if (strstr(distroLower, "server 10")) {
 
516
         } else if (strstr(distroLower, "server 10") ||
 
517
                    strstr(distroLower, "desktop 10")) {
507
518
            Str_Strcpy(distroShort, STR_OS_SLES_10, distroShortSize);
508
519
         } else {
509
 
            Str_Strcpy(distroShort, STR_OS_SUSE_EN, distroShortSize);
 
520
            Str_Strcpy(distroShort, STR_OS_SLES, distroShortSize);
510
521
         }
511
522
      } else if (strstr(distroLower, "sun")) {
512
523
         Str_Strcpy(distroShort, STR_OS_SUN_DESK, distroShortSize);
549
560
      } else if (strstr(distroLower, "5.0")) {
550
561
         Str_Strcpy(distroShort, STR_OS_DEBIAN_5, distroShortSize);
551
562
      }
552
 
   } else if (StrUtil_StartsWith(distroLower, "enterprise linux")) {
 
563
   } else if (StrUtil_StartsWith(distroLower, "enterprise linux") ||
 
564
              StrUtil_StartsWith(distroLower, "oracle")) {
553
565
      /*
554
566
       * [root@localhost ~]# lsb_release -sd
555
567
       * "Enterprise Linux Enterprise Linux Server release 5.4 (Carthage)"
556
568
       *
557
569
       * Not sure why they didn't brand their releases as "Oracle Enterprise
558
 
       * Linux".  Oh well.
 
570
       * Linux". Oh well. It's fixed in 6.0, though.
559
571
       */
560
572
      Str_Strcpy(distroShort, STR_OS_ORACLE, distroShortSize);
561
573
   } else if (strstr(distroLower, "fedora")) {
709
721
 
710
722
   return ret;
711
723
}
 
724
#endif
712
725
 
713
726
 
714
727
/*
795
808
 *
796
809
 *      Determine the OS short (.vmx format) and long names.
797
810
 *
798
 
 *      First retrieve OS information using uname, then look in
799
 
 *      /etc/xxx-release file to get the distro info.
800
 
 *
801
811
 * Return value:
802
812
 *      Returns TRUE on success and FALSE on failure.
803
813
 *
812
822
{
813
823
   struct utsname buf;
814
824
   unsigned int lastCharPos;
815
 
   const char *lsbCmd = "lsb_release -sd 2>/dev/null";
816
 
   char *lsbOutput = NULL;
817
 
 
818
825
   char osName[MAX_OS_NAME_LEN];
819
826
   char osNameFull[MAX_OS_FULLNAME_LEN];
820
 
 
821
827
   static Atomic_uint32 mutex = {0};
822
828
 
823
829
   /*
838
844
   }
839
845
 
840
846
   Str_Strcpy(osName, STR_OS_EMPTY, sizeof osName);
841
 
   Str_Sprintf(osNameFull, sizeof osNameFull, "%s %s", buf.sysname, buf.release);
842
 
 
843
 
   /*
844
 
    * Check to see if this is Linux
845
 
    * If yes, determine the distro by looking for /etc/xxx file.
846
 
    */
847
 
 
 
847
   Str_Sprintf(osNameFull, sizeof osNameFull, "%s %s", buf.sysname,
 
848
               buf.release);
 
849
 
 
850
#if defined __APPLE__
 
851
   {
 
852
      /*
 
853
       * The easiest way is to invoke "system_profiler" and hope that the
 
854
       * format of its unlocalized output will never change.
 
855
       *
 
856
       * Alternatively, we could do what system_profiler does and use the
 
857
       * CFPropertyList/CFDIctionary APIs to parse
 
858
       * /System/Library/CoreServices/{Server,System}Version.plist.
 
859
       *
 
860
       * On a MacBookPro4,1 (and possibly other models), invoking
 
861
       * "system_profiler" can take several seconds: it seems to spin up the CD
 
862
       * drive as a side-effect. So use "system_profiler SPSoftwareDataType"
 
863
       * instead.
 
864
       */
 
865
      SInt32 major;
 
866
      char *sysname = HostinfoGetCmdOutput(
 
867
                         "/usr/sbin/system_profiler SPSoftwareDataType"
 
868
                      " | /usr/bin/grep 'System Version:'"
 
869
                      " | /usr/bin/cut -d : -f 2");
 
870
 
 
871
      if (sysname) {
 
872
         char *trimmed = Unicode_Trim(sysname);
 
873
 
 
874
         ASSERT_MEM_ALLOC(trimmed);
 
875
         free(sysname);
 
876
         Str_Snprintf(osNameFull, sizeof osNameFull, "%s", trimmed);
 
877
         free(trimmed);
 
878
      } else {
 
879
         Log("%s: Failed to get output of system_profiler.\n", __FUNCTION__);
 
880
         /* Fall back to returning the original osNameFull. */
 
881
      }
 
882
 
 
883
      if (Gestalt(gestaltSystemVersionMajor, &major) == 0) {
 
884
         /*
 
885
          * XXX: some places in the code refer to Mac OS X Lion (10.7?)
 
886
          * as "darwin11", which is not what this code is doing. Once it's
 
887
          * released and we support it, this code may need some tweaking.
 
888
          */
 
889
         Str_Snprintf(osName, sizeof osName, "%s%d", STR_OS_MACOS, (int) major);
 
890
      } else if (Gestalt(gestaltSystemVersion, &major) == 0) {
 
891
         /* Pre 10.3 Mac OS doesn't have gestaltSystemVersionMajor. */
 
892
         NOT_TESTED();
 
893
         major = (major & 0xFF00) >> 8;
 
894
         Str_Snprintf(osName, sizeof osName, "%s%x", STR_OS_MACOS, (int) major);
 
895
      } else {
 
896
         Log("Call to Gestalt() failed!\n");
 
897
         Str_Snprintf(osName, sizeof osName, "%s", STR_OS_MACOS);
 
898
      }
 
899
   }
 
900
#else
 
901
   // XXX Use compile-time instead of run-time checks for these as well.
848
902
   if (strstr(osNameFull, "Linux")) {
849
903
      char distro[DISTRO_BUF_SIZE];
850
904
      char distroShort[DISTRO_BUF_SIZE];
851
 
      int i = 0;
852
 
      int distroSize = sizeof distro;
 
905
      static int const distroSize = sizeof distro;
 
906
      char *lsbOutput;
853
907
 
854
908
      /*
855
909
       * Write default distro string depending on the kernel version. If
871
925
       * Try to get OS detailed information from the lsb_release command.
872
926
       */
873
927
 
874
 
      lsbOutput = HostinfoGetCmdOutput(lsbCmd);
875
 
 
 
928
      lsbOutput = HostinfoGetCmdOutput("lsb_release -sd 2>/dev/null");
876
929
      if (!lsbOutput) {
 
930
         int i;
 
931
 
877
932
         /*
878
933
          * Try to get more detailed information from the version file.
879
934
          */
975
1030
      Str_Snprintf(osName, sizeof osName, "%s%s", STR_OS_SOLARIS,
976
1031
                   solarisRelease);
977
1032
   }
 
1033
#endif
978
1034
 
979
1035
   if (Hostinfo_GetSystemBitness() == 64) {
980
1036
      if (strlen(osName) + sizeof STR_OS_64BIT_SUFFIX > sizeof osName) {
1014
1070
}
1015
1071
 
1016
1072
 
1017
 
#if defined(VMX86_SERVER)
1018
1073
/*
1019
 
 *----------------------------------------------------------------------
1020
 
 *
1021
 
 * HostinfoReadProc --
1022
 
 *
1023
 
 *      Depending on what string is passed to it, this function parses the
1024
 
 *      /proc/vmware/sched/ncpus node and returns the requested value.
 
1074
 *-----------------------------------------------------------------------------
 
1075
 *
 
1076
 * Hostinfo_CPUCounts --
 
1077
 *
 
1078
 *      Get a count of CPUs for the host.
 
1079
 *        pkgs := total number of sockets/packages
 
1080
 *        cores := total number of actual cores (not including hyperthreads)
 
1081
 *        logical := total schedulable threads, as seen by host scheduler
 
1082
 *      Depending on available host OS interfaces, these numbers may be
 
1083
 *      either "active" or "possible", so do not depend upon them for
 
1084
 *      precision.
 
1085
 *
 
1086
 *      As an example, a 2 socket Nehalem (4 cores + HT) would return:
 
1087
 *        pkgs = 2, cores = 8, logical = 16
 
1088
 *
 
1089
 *      Again, this interface is generally not useful b/c of its potential
 
1090
 *      inaccuracy (especially with hotplug!) and because it is only implemented
 
1091
 *      for a few OSes.
 
1092
 *
 
1093
 *      If you are trying to use this interface, it probably means you are doing
 
1094
 *      something 'clever' with licensing.  Don't.
1025
1095
 *
1026
1096
 * Results:
1027
 
 *      A postive value on success, -1 (0xFFFFFFFF) on failure.
 
1097
 *      TRUE if sane numbers are populated, FALSE otherwise.
1028
1098
 *
1029
1099
 * Side effects:
1030
 
 *      None.
 
1100
 *      None
1031
1101
 *
1032
 
 *----------------------------------------------------------------------
 
1102
 *-----------------------------------------------------------------------------
1033
1103
 */
1034
1104
 
1035
 
static uint32
1036
 
HostinfoReadProc(const char *str)  // IN:
 
1105
Bool
 
1106
Hostinfo_CPUCounts(uint32 *logical,  // OUT
 
1107
                   uint32 *cores,    // OUT
 
1108
                   uint32 *pkgs)     // OUT
1037
1109
{
1038
 
   /* XXX this should use sysinfo!! (bug 59849)
 
1110
#if defined __APPLE__
 
1111
   /*
 
1112
    * Lame logic.  Because Apple doesn't really expose this info,
 
1113
    * we'd only use it for licensing anyway, and we just plain
 
1114
    * don't need it on Apple except that VMHS stuffs it somewhere
 
1115
    * and may result in a division-by-zero if we don't provide it.
1039
1116
    */
 
1117
   *logical = Hostinfo_NumCPUs();
 
1118
   *pkgs = *logical > 4 ? 2 : 1;
 
1119
   *cores = *logical / *pkgs;
 
1120
 
 
1121
   return TRUE;
 
1122
#elif defined __linux__
1040
1123
   FILE *f;
1041
1124
   char *line;
1042
 
   uint32 count;
1043
 
 
1044
 
   ASSERT(!strcmp("logical", str) || !strcmp("cores", str) ||
1045
 
          !strcmp("packages", str));
1046
 
 
1047
 
   ASSERT(!HostType_OSIsVMK()); // Don't use /proc/vmware
1048
 
 
1049
 
   f = Posix_Fopen("/proc/vmware/sched/ncpus", "r");
1050
 
 
1051
 
   if (f != NULL) {
1052
 
      while (StdIO_ReadNextLine(f, &line, 0, NULL) == StdIO_Success) {
1053
 
         if (strstr(line, str)) {
1054
 
            if (sscanf(line, "%d ", &count) == 1) {
1055
 
               free(line);
1056
 
               break;
1057
 
            }
1058
 
         }
1059
 
         free(line);
1060
 
      }
1061
 
      fclose(f);
1062
 
 
1063
 
      if (count > 0) {
1064
 
         return count;
1065
 
      }
1066
 
   }
1067
 
 
1068
 
   return -1;
1069
 
}
1070
 
 
1071
 
 
1072
 
/*
1073
 
 *----------------------------------------------------------------------
1074
 
 *
1075
 
 * Hostinfo_HTDisabled --
1076
 
 *
1077
 
 *      Figure out if hyperthreading is enabled
1078
 
 *
1079
 
 * Results:
1080
 
 *      TRUE if hyperthreading is disabled, FALSE otherwise
1081
 
 *
1082
 
 * Side effects:
1083
 
 *      None.
1084
 
 *
1085
 
 *----------------------------------------------------------------------
1086
 
 */
1087
 
 
1088
 
Bool
1089
 
Hostinfo_HTDisabled(void)
1090
 
{
1091
 
   static uint32 logical = 0, cores = 0;
1092
 
 
1093
 
   if (HostType_OSIsVMK()) {
1094
 
      return VMKernel_HTEnabledCPU() != VMK_OK;
1095
 
   }
1096
 
 
1097
 
   if (logical == 0 && cores == 0) {
1098
 
      logical = HostinfoReadProc("logical");
1099
 
      cores = HostinfoReadProc("cores");
1100
 
 
1101
 
      if (logical <= 0 || cores <= 0) {
1102
 
         logical = cores = 0;
1103
 
      }
1104
 
   }
1105
 
 
1106
 
   return logical == cores;
1107
 
}
1108
 
#endif /*ifdef VMX86_SERVER*/
 
1125
   unsigned count = 0, coresPerProc = 0, siblingsPerProc = 0;
 
1126
 
 
1127
   f = Posix_Fopen("/proc/cpuinfo", "r");
 
1128
   if (f == NULL) {
 
1129
      return FALSE;
 
1130
   }
 
1131
 
 
1132
   while (StdIO_ReadNextLine(f, &line, 0, NULL) == StdIO_Success) {
 
1133
      if (strncmp(line, "processor", strlen("processor")) == 0) {
 
1134
         count++;
 
1135
      }
 
1136
      /* Assume all processors are identical, so just read the first. */
 
1137
      if (coresPerProc == 0) {
 
1138
         sscanf(line, "cpu cores : %u", &coresPerProc);
 
1139
      }
 
1140
      if (siblingsPerProc == 0) {
 
1141
         sscanf(line, "siblings : %u", &siblingsPerProc);
 
1142
      }
 
1143
      free(line);
 
1144
   }
 
1145
 
 
1146
   fclose(f);
 
1147
 
 
1148
   *logical = count;
 
1149
   *pkgs = siblingsPerProc > 0 ? count / siblingsPerProc : count;
 
1150
   *cores = coresPerProc > 0 ? *pkgs * coresPerProc : *pkgs;
 
1151
 
 
1152
   Log(LGPFX" This machine has %u physical CPUS, %u total cores, and %u "
 
1153
            "logical CPUs.\n", *pkgs, *cores, *logical);
 
1154
 
 
1155
   return TRUE;
 
1156
#else
 
1157
   NOT_IMPLEMENTED();
 
1158
#endif
 
1159
}
1109
1160
 
1110
1161
 
1111
1162
/*
1194
1245
   static int count = 0;
1195
1246
 
1196
1247
   if (count <= 0) {
 
1248
      FILE *f;
 
1249
      char *line;
 
1250
 
1197
1251
#if defined(VMX86_SERVER)
1198
1252
      if (HostType_OSIsVMK()) {
1199
1253
         VMK_ReturnStatus status = VMKernel_GetNumCPUsUsed(&count);
1203
1257
 
1204
1258
            return -1;
1205
1259
         }
1206
 
      } else {
1207
 
         count = HostinfoReadProc("logical");
1208
 
 
1209
 
         if (count <= 0) {
1210
 
            count = 0;
1211
 
 
1212
 
            return -1;
1213
 
         }
 
1260
 
 
1261
         return count;
1214
1262
      }
1215
 
#else /* ifdef VMX86_SERVER */
1216
 
      FILE *f;
1217
 
      char *line;
1218
 
 
 
1263
#endif
1219
1264
      f = Posix_Fopen("/proc/cpuinfo", "r");
1220
1265
      if (f == NULL) {
1221
1266
         return -1;
1233
1278
      if (count == 0) {
1234
1279
         return -1;
1235
1280
      }
1236
 
#endif /* ifdef VMX86_SERVER */
1237
1281
   }
1238
1282
 
1239
1283
   return count;
1392
1436
                       float *avg1,  // IN/OUT:
1393
1437
                       float *avg2)  // IN/OUT:
1394
1438
{
1395
 
   /* getloadavg(3) was introduced with glibc 2.2 */
1396
 
#if defined(GLIBC_VERSION_22) || defined(__APPLE__)
 
1439
#if defined(__linux__) || defined(__APPLE__)
1397
1440
   double avg[3];
1398
1441
   int res;
1399
1442
 
1770
1813
/*
1771
1814
 *----------------------------------------------------------------------
1772
1815
 *
1773
 
 *  Hostinfo_TouchBackDoor --
1774
 
 *
1775
 
 *      Access the backdoor. This is used to determine if we are
1776
 
 *      running in a VM or on a physical host. On a physical host
1777
 
 *      this should generate a GP which we catch and thereby determine
1778
 
 *      that we are not in a VM. However some OSes do not handle the
1779
 
 *      GP correctly and the process continues running returning garbage.
1780
 
 *      In this case we check the EBX register which should be
1781
 
 *      BDOOR_MAGIC if the IN was handled in a VM. Based on this we
1782
 
 *      return either TRUE or FALSE.
1783
 
 *
1784
 
 * Results:
1785
 
 *      TRUE if we succesfully accessed the backdoor, FALSE or segfault
1786
 
 *      if not.
1787
 
 *
1788
 
 * Side effects:
1789
 
 *      Exception if not in a VM.
1790
 
 *
1791
 
 *----------------------------------------------------------------------
1792
 
 */
1793
 
 
1794
 
Bool
1795
 
Hostinfo_TouchBackDoor(void)
1796
 
{
1797
 
   /*
1798
 
    * XXX: This can cause Apple's Crash Reporter to erroneously display
1799
 
    * a crash, even though the process has caught the SIGILL and handled
1800
 
    * it.
1801
 
    */
1802
 
 
1803
 
#if !defined(__APPLE__) && (defined(__i386__) || defined(__x86_64__))
1804
 
   uint32 eax;
1805
 
   uint32 ebx;
1806
 
   uint32 ecx;
1807
 
 
1808
 
   __asm__ __volatile__(
1809
 
#   if defined __PIC__ && !vm_x86_64 // %ebx is reserved by the compiler.
1810
 
      "xchgl %%ebx, %1" "\n\t"
1811
 
      "inl %%dx, %%eax" "\n\t"
1812
 
      "xchgl %%ebx, %1"
1813
 
      : "=a" (eax),
1814
 
        "=&rm" (ebx),
1815
 
#   else
1816
 
      "inl %%dx, %%eax"
1817
 
      : "=a" (eax),
1818
 
        "=b" (ebx),
1819
 
#   endif
1820
 
        "=c" (ecx)
1821
 
      : "0" (BDOOR_MAGIC),
1822
 
        "1" (~BDOOR_MAGIC),
1823
 
        "2" (BDOOR_CMD_GETVERSION),
1824
 
        "d" (BDOOR_PORT)
1825
 
   );
1826
 
   if (ebx == BDOOR_MAGIC) {
1827
 
      return TRUE;
1828
 
   }
1829
 
#endif
1830
 
 
1831
 
   return FALSE;
1832
 
}
1833
 
 
1834
 
 
1835
 
/*
1836
 
 *----------------------------------------------------------------------
1837
 
 *
1838
 
 *  Hostinfo_TouchVirtualPC --
1839
 
 *
1840
 
 *      Access MS Virtual PC's backdoor. This is used to determine if 
1841
 
 *      we are running in a MS Virtual PC or on a physical host.  Works
1842
 
 *      the same as Hostinfo_TouchBackDoor, except the entry to MS VPC
1843
 
 *      is an invalid opcode instead or writing to a port.  Since
1844
 
 *      MS VPC is 32-bit only, the 64-bit path returns FALSE.
1845
 
 *      See: http://www.codeproject.com/KB/system/VmDetect.aspx
1846
 
 *
1847
 
 * Results:
1848
 
 *      TRUE if we succesfully accessed MS Virtual PC, FALSE or 
1849
 
 *      segfault if not.
1850
 
 *
1851
 
 * Side effects:
1852
 
 *      Exception if not in a VM.
1853
 
 *
1854
 
 *----------------------------------------------------------------------
1855
 
 */
1856
 
 
1857
 
Bool
1858
 
Hostinfo_TouchVirtualPC(void)
1859
 
{
1860
 
#if defined vm_x86_64
1861
 
   return FALSE;
1862
 
#else
1863
 
 
1864
 
   uint32 ebxval;
1865
 
 
1866
 
   __asm__ __volatile__ (
1867
 
#  if defined __PIC__        // %ebx is reserved by the compiler.
1868
 
     "xchgl %%ebx, %1" "\n\t"
1869
 
     ".long 0x0B073F0F" "\n\t"
1870
 
     "xchgl %%ebx, %1"
1871
 
     : "=&rm" (ebxval)
1872
 
     : "a" (1),
1873
 
       "0" (0)
1874
 
#  else
1875
 
     ".long 0x0B073F0F"
1876
 
     : "=b" (ebxval)
1877
 
     : "a" (1),
1878
 
       "b" (0)
1879
 
#  endif
1880
 
  );
1881
 
  return !ebxval; // %%ebx is zero if inside Virtual PC
1882
 
#endif
1883
 
}
1884
 
 
1885
 
 
1886
 
/*
1887
 
 *----------------------------------------------------------------------
1888
 
 *
1889
 
 *  Hostinfo_NestingSupported --
1890
 
 *
1891
 
 *      Access the backdoor with a nesting control query. This is used
1892
 
 *      to determine if we are running inside a VM that supports nesting.
1893
 
 *      This function should only be called after determining that the
1894
 
 *      backdoor is present with Hostinfo_TouchBackdoor().
1895
 
 *
1896
 
 * Results:
1897
 
 *      TRUE if the outer VM supports nesting.
1898
 
 *      FALSE otherwise.
1899
 
 *
1900
 
 * Side effects:
1901
 
 *      Exception if not in a VM, so don't do that!
1902
 
 *
1903
 
 *----------------------------------------------------------------------
1904
 
 */
1905
 
 
1906
 
Bool
1907
 
Hostinfo_NestingSupported(void)
1908
 
{
1909
 
#if defined(__i386__) || defined(__x86_64__)
1910
 
   uint32 cmd = NESTING_CONTROL_QUERY << 16 | BDOOR_CMD_NESTING_CONTROL;
1911
 
   uint32 result;
1912
 
 
1913
 
   __asm__ __volatile__(
1914
 
      "inl %%dx, %%eax"
1915
 
      : "=a" (result)
1916
 
      : "0"  (BDOOR_MAGIC),
1917
 
        "c"  (cmd),
1918
 
        "d"  (BDOOR_PORT)
1919
 
   );
1920
 
 
1921
 
   if (result >= NESTING_CONTROL_QUERY && result != ~0U) {
1922
 
      return TRUE;
1923
 
   }
1924
 
#endif
1925
 
 
1926
 
   return FALSE;
1927
 
}
1928
 
 
1929
 
 
1930
 
/*
1931
 
 *----------------------------------------------------------------------
1932
 
 *
1933
1816
 * Hostinfo_ResetProcessState --
1934
1817
 *
1935
1818
 *      Clean up signal handlers and file descriptors before an exec().
3113
2996
 * HostinfoGetLinuxMemoryInfoInPages --
3114
2997
 *
3115
2998
 *      Obtain the minimum memory to be maintained, total memory available,
3116
 
 *      and free memory available on the host (Linux or COS) in pages.
 
2999
 *      and free memory available on the host (Linux) in pages.
3117
3000
 *
3118
3001
 * Results:
3119
3002
 *      TRUE on success: '*minSize', '*maxSize' and '*currentSize' are set
3183
3066
 *
3184
3067
 * HostinfoGetSwapInfoInPages --
3185
3068
 *
3186
 
 *      Obtain the total swap and free swap on the host (Linux or COS) in
 
3069
 *      Obtain the total swap and free swap on the host (Linux) in
3187
3070
 *      pages.
3188
3071
 *
3189
3072
 * Results:
3311
3194
}
3312
3195
 
3313
3196
 
3314
 
#ifdef VMX86_SERVER
3315
 
/*
3316
 
 *-----------------------------------------------------------------------------
3317
 
 *
3318
 
 * Hostinfo_GetCOSMemoryInfoInPages --
3319
 
 *
3320
 
 *      Obtain the minimum memory to be maintained, total memory available, and
3321
 
 *      free memory available on the COS in pages.
3322
 
 *
3323
 
 * Results:
3324
 
 *      TRUE on success: '*minSize', '*maxSize' and '*currentSize' are set
3325
 
 *      FALSE on failure
3326
 
 *
3327
 
 * Side effects:
3328
 
 *      None
3329
 
 *
3330
 
 *-----------------------------------------------------------------------------
3331
 
 */
3332
 
 
3333
 
Bool
3334
 
Hostinfo_GetCOSMemoryInfoInPages(unsigned int *minSize,      // OUT:
3335
 
                                 unsigned int *maxSize,      // OUT:
3336
 
                                 unsigned int *currentSize)  // OUT:
3337
 
{
3338
 
   if (HostType_OSIsPureVMK()) {
3339
 
      return FALSE;
3340
 
   } else {
3341
 
      return HostinfoGetLinuxMemoryInfoInPages(minSize, maxSize, currentSize);
3342
 
   }
3343
 
}
3344
 
#endif
3345
 
 
3346
 
 
3347
3197
/*
3348
3198
 *-----------------------------------------------------------------------------
3349
3199
 *
3422
3272
 
3423
3273
   return path;
3424
3274
}
 
3275
 
 
3276
 
 
3277
/*
 
3278
 *----------------------------------------------------------------------
 
3279
 *
 
3280
 * Hostinfo_GetLibraryPath --
 
3281
 *
 
3282
 *      Try and deduce the path to the library where the specified
 
3283
 *      address resides. Expected usage is that the caller will pass
 
3284
 *      in the address of one of the caller's own functions.
 
3285
 *
 
3286
 *      Not implemented on MacOS.
 
3287
 *
 
3288
 * Results:
 
3289
 *      The path (which MAY OR MAY NOT BE ABSOLUTE) or NULL on failure.
 
3290
 *
 
3291
 * Side effects:
 
3292
 *      Memory is allocated.
 
3293
 *
 
3294
 *----------------------------------------------------------------------
 
3295
 */
 
3296
 
 
3297
char *
 
3298
Hostinfo_GetLibraryPath(void *addr)  // IN
 
3299
{
 
3300
#ifdef __linux__
 
3301
   Dl_info info;
 
3302
 
 
3303
   if (dladdr(addr, &info)) {
 
3304
      return Unicode_Alloc(info.dli_fname, STRING_ENCODING_DEFAULT);
 
3305
   }
 
3306
   return NULL;
 
3307
#else
 
3308
   return NULL;
 
3309
#endif
 
3310
}