]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Changes in shared code that don't affect open-vm-tools functionality.
authorVMware, Inc <>
Wed, 18 Sep 2013 03:25:16 +0000 (20:25 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Mon, 23 Sep 2013 05:06:58 +0000 (22:06 -0700)
Signed-off-by: Dmitry Torokhov <dtor@vmware.com>
open-vm-tools/lib/asyncsocket/asyncSocketInt.h
open-vm-tools/lib/asyncsocket/asyncsocket.c
open-vm-tools/lib/file/filePosix.c
open-vm-tools/lib/include/asyncsocket.h
open-vm-tools/lib/include/x86cpuid.h

index 4bdd4afd0462cfb60e1061056a46e685e29699ae..9151cf0ea750b67b42f8e6e9a9d82a3834e4c63a 100644 (file)
@@ -275,6 +275,7 @@ typedef struct AsyncSocketVTable {
                       Bool *bufferListWasEmpty);
    int (*send)(AsyncSocket *asock, Bool bufferListWasEmpty, void *buf, int len);
    int (*recv)(AsyncSocket *asock, void *buf, int len);
+   PollerFunction sendCallback;
    PollerFunction recvCallback;
    Bool (*hasDataPending)(AsyncSocket *asock);
    void (*cancelListenCb)(AsyncSocket *asock);
@@ -316,6 +317,7 @@ int AsyncSocketSendInternal(AsyncSocket *asock, void *buf, int len,
                             Bool *bufferListWasEmpty);
 int AsyncSocketSendSocket(AsyncSocket *asock, Bool bufferListWasEmpty,
                           void *buf, int len);
+void AsyncSocketSendCallback(void *clientData);
 AsyncSocket *AsyncSocketCreate(AsyncSocketPollParams *pollParams);
 void AsyncSocketDispatchConnect(AsyncSocket *asock, AsyncSocket *newsock);
 void AsyncSocketRecvCallback(void *clientData);
index 9c55b34d9e5c500cec423df8888f9eebc7d02410..2051f3dc5d3ab9797769695a61a89366c0bcad11 100644 (file)
@@ -60,6 +60,9 @@
 #include "msg.h"
 #include "posix.h"
 #include "vmci_sockets.h"
+#ifndef VMX86_TOOLS
+#include "vmdblib.h"
+#endif
 
 #define LOGLEVEL_MODULE asyncsocket
 #include "loglevel_user.h"
@@ -82,7 +85,6 @@ static int AsyncSocketMakeNonBlocking(int fd);
 static void AsyncSocketAcceptCallback(void *clientData);
 static void AsyncSocketConnectCallback(void *clientData);
 static void AsyncSocketRecvUDPCallback(void *clientData);
-static void AsyncSocketSendCallback(void *clientData);
 static int AsyncSocketBlockingWork(AsyncSocket *asock, Bool read, void *buf, int len,
                                    int *completed, int timeoutMS, Bool partial);
 static VMwareStatus AsyncSocketPollAdd(AsyncSocket *asock, Bool socket,
@@ -105,12 +107,21 @@ static int AsyncSocketRecv(AsyncSocket *asock, void *buf, int len,
 static Bool AsyncSocketHasDataPendingSocket(AsyncSocket *asock);
 static void AsyncSocketReleaseSocket(AsyncSocket *s);
 
+static VMwareStatus AsyncSocketIPollAdd(AsyncSocket *asock, Bool socket,
+                                        int flags, PollerFunction callback,
+                                        int info);
+static Bool AsyncSocketIPollRemove(AsyncSocket *asock, Bool socket, int flags,
+                                   PollerFunction callback);
+static void AsyncSocketIPollSendCallback(void *clientData);
+static void AsyncSocketIPollRecvCallback(void *clientData);
+
 
 static const AsyncSocketVTable asyncStreamSocketVTable = {
    AsyncSocketDispatchConnect,
    AsyncSocketSendInternal,
    AsyncSocketSendSocket,
    AsyncSocketRecvSocket,
+   AsyncSocketSendCallback,
    AsyncSocketRecvCallback,
    AsyncSocketHasDataPendingSocket,
    AsyncSocketCancelListenCbSocket,
@@ -127,6 +138,7 @@ static const AsyncSocketVTable asyncDgramSocketVTable = {
    AsyncSocketSendInternal,
    AsyncSocketSendSocket,
    AsyncSocketRecvSocket,
+   AsyncSocketSendCallback,
    AsyncSocketRecvUDPCallback,
    AsyncSocketHasDataPendingSocket,
    AsyncSocketCancelListenCbSocket,
@@ -138,6 +150,23 @@ static const AsyncSocketVTable asyncDgramSocketVTable = {
 };
 
 
+static const AsyncSocketVTable asyncStreamSocketIPollVTable = {
+   AsyncSocketDispatchConnect,
+   AsyncSocketSendInternal,
+   AsyncSocketSendSocket,
+   AsyncSocketRecvSocket,
+   AsyncSocketIPollSendCallback,
+   AsyncSocketIPollRecvCallback,
+   AsyncSocketHasDataPendingSocket,
+   AsyncSocketCancelListenCbSocket,
+   AsyncSocketCancelRecvCbSocket,
+   AsyncSocketCancelCbForCloseSocket,
+   AsyncSocketCancelCbForConnectingCloseSocket,
+   AsyncSocketCloseSocket,
+   AsyncSocketReleaseSocket,
+};
+
+
 /*
  *----------------------------------------------------------------------------
  *
@@ -1487,6 +1516,7 @@ AsyncSocketCreate(AsyncSocketPollParams *pollParams) // IN
       s->pollParams.pollClass = POLL_CS_MAIN;
       s->pollParams.flags = 0;
       s->pollParams.lock = NULL;
+      s->pollParams.iPoll = NULL;
    }
 
    return s;
@@ -1536,7 +1566,11 @@ AsyncSocket_AttachToSSLSock(SSLSock sslSock,
    s->fd = fd;
    s->type = SOCK_STREAM;
    s->asockType = ASYNCSOCKET_TYPE_SOCKET;
-   s->vt = &asyncStreamSocketVTable;
+   if (s->pollParams.iPoll == NULL) {
+      s->vt = &asyncStreamSocketVTable;
+   } else {
+      s->vt = &asyncStreamSocketIPollVTable;
+   }
 
    /* From now on socket is ours. */
    SSL_SetCloseOnShutdownFlag(sslSock);
@@ -2326,7 +2360,7 @@ AsyncSocketSendSocket(AsyncSocket *asock,      // IN:
        * already make 0-byte send() to force WSAEWOULDBLOCK.
        */
 
-      if (AsyncSocketPollAdd(asock, FALSE, 0, AsyncSocketSendCallback, 0)
+      if (AsyncSocketPollAdd(asock, FALSE, 0, asock->vt->sendCallback, 0)
           != VMWARE_STATUS_SUCCESS) {
          retVal = ASOCKERR_POLL;
          return retVal;
@@ -2337,7 +2371,7 @@ AsyncSocketSendSocket(AsyncSocket *asock,      // IN:
        */
 
       if (AsyncSocketPollAdd(asock, TRUE, POLL_FLAG_WRITE,
-                             AsyncSocketSendCallback)
+                             asock->vt->sendCallback)
           != VMWARE_STATUS_SUCCESS) {
          retVal = ASOCKERR_POLL;
          return retVal;
@@ -3218,7 +3252,7 @@ AsyncSocket_WaitForConnection(AsyncSocket *s,  // IN:
    */
    if (s->state == AsyncSocketConnecting) {
       removed = AsyncSocketPollRemove(s, TRUE, POLL_FLAG_WRITE,
-         AsyncSocketConnectCallback)
+                                      AsyncSocketConnectCallback)
          || AsyncSocketPollRemove(s, FALSE, 0, AsyncSocketConnectCallback);
       ASSERT(removed);
    }
@@ -3324,7 +3358,7 @@ AsyncSocket_DoOneMsg(AsyncSocket *s, Bool read, int timeoutMS)
       removed = AsyncSocketPollRemove(s, TRUE,
                                       POLL_FLAG_READ | POLL_FLAG_PERIODIC,
                                       s->vt->recvCallback);
-      ASSERT(removed);
+      ASSERT(removed || s->pollParams.iPoll);
 
       s->inBlockingRecv++;
       AsyncSocketUnlock(s); /* We may sleep in poll. */
@@ -3560,7 +3594,7 @@ AsyncSocketCancelRecvCbSocket(AsyncSocket *asock)  // IN:
       removed = AsyncSocketPollRemove(asock, TRUE,
                                       POLL_FLAG_READ | POLL_FLAG_PERIODIC,
                                       asock->vt->recvCallback);
-      ASSERT_NOT_IMPLEMENTED(removed);
+      ASSERT_NOT_IMPLEMENTED(removed || asock->pollParams.iPoll);
       asock->recvCb = FALSE;
    }
 }
@@ -3624,7 +3658,7 @@ AsyncSocketCancelCbForCloseSocket(AsyncSocket *asock)  // IN:
        * Callback might be temporarily removed in AsyncSocket_DoOneMsg.
        */
 
-      ASSERT_NOT_TESTED(removed);
+      ASSERT_NOT_TESTED(removed || asock->pollParams.iPoll);
 
       /*
        * We may still have the RTime callback, try to remove if it exists
@@ -3645,9 +3679,9 @@ AsyncSocketCancelCbForCloseSocket(AsyncSocket *asock)  // IN:
        */
 
       removed = AsyncSocketPollRemove(asock, TRUE, POLL_FLAG_WRITE,
-                                      AsyncSocketSendCallback)
-         || AsyncSocketPollRemove(asock, FALSE, 0, AsyncSocketSendCallback);
-      ASSERT(removed);
+                                      asock->vt->sendCallback)
+         || AsyncSocketPollRemove(asock, FALSE, 0, asock->vt->sendCallback);
+      ASSERT(removed || asock->pollParams.iPoll);
       asock->sendCb = FALSE;
    }
 }
@@ -4197,6 +4231,7 @@ AsyncSocketAcceptCallback(void *clientData)
 
    ASSERT(asock);
    ASSERT(asock->asockType != ASYNCSOCKET_TYPE_NAMEDPIPE);
+   ASSERT(asock->pollParams.iPoll == NULL);
    ASSERT(AsyncSocketIsLocked(asock));
 
    AsyncSocketAddRef(asock);
@@ -4238,6 +4273,7 @@ AsyncSocketConnectCallback(void *clientData)
 
    ASSERT(asock);
    ASSERT(asock->asockType != ASYNCSOCKET_TYPE_NAMEDPIPE);
+   ASSERT(asock->pollParams.iPoll == NULL);
    ASSERT(AsyncSocketIsLocked(asock));
 
    AsyncSocketAddRef(asock);
@@ -4288,6 +4324,63 @@ AsyncSocketRecvCallback(void *clientData)
 }
 
 
+/*
+ *----------------------------------------------------------------------------
+ *
+ * AsyncSocketIPollRecvCallback --
+ *
+ *      Poll callback for input waiting on the socket.  IVmdbPoll does not
+ *      handle callback locks, so this function first locks the asyncsocket
+ *      and verify that the recv callback has not been cancelled before
+ *      calling AsyncSocketFillRecvBuffer to do the real work.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Reads data, could fire recv completion or trigger socket destruction.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static void
+AsyncSocketIPollRecvCallback(void *clientData)  // IN:
+{
+#ifdef VMX86_TOOLS
+   NOT_IMPLEMENTED();
+#else
+   AsyncSocket *asock = (AsyncSocket *) clientData;
+   int error;
+
+   ASSERT(asock);
+   ASSERT(asock->asockType != ASYNCSOCKET_TYPE_NAMEDPIPE);
+   ASSERT(asock->pollParams.lock == NULL ||
+          !MXUser_IsCurThreadHoldingRecLock(asock->pollParams.lock));
+
+   AsyncSocketLock(asock);
+   if (!asock->recvCb) {
+      MXUserRecLock *lock = asock->pollParams.lock;
+
+      /* Release the reference added when registering this callback. */
+      AsyncSocketRelease(asock, TRUE);
+      if (lock != NULL) {
+         MXUser_DecRefRecLock(lock);
+      }
+      return;
+   }
+
+   AsyncSocketAddRef(asock);
+
+   error = AsyncSocketFillRecvBuffer(asock);
+   if (error == ASOCKERR_GENERIC || error == ASOCKERR_REMOTE_DISCONNECT) {
+      AsyncSocketHandleError(asock, error);
+   }
+
+   AsyncSocketRelease(asock, TRUE);
+#endif
+}
+
+
 /*
  *----------------------------------------------------------------------------
  *
@@ -4363,7 +4456,7 @@ exit:
  *----------------------------------------------------------------------------
  */
 
-static void
+void
 AsyncSocketSendCallback(void *clientData)
 {
    AsyncSocket *s = (AsyncSocket *) clientData;
@@ -4395,13 +4488,13 @@ AsyncSocketSendCallback(void *clientData)
 
       if (!s->sslConnected) {
          pollStatus = AsyncSocketPollAdd(s, FALSE, 0,
-                                         AsyncSocketSendCallback, 100000);
+                                         s->vt->sendCallback, 100000);
          ASSERT_NOT_IMPLEMENTED(pollStatus == VMWARE_STATUS_SUCCESS);
       } else
 #endif
       {
          pollStatus = AsyncSocketPollAdd(s, TRUE, POLL_FLAG_WRITE,
-                                         AsyncSocketSendCallback);
+                                         s->vt->sendCallback);
          ASSERT_NOT_IMPLEMENTED(pollStatus == VMWARE_STATUS_SUCCESS);
       }
       s->sendCb = TRUE;
@@ -4410,6 +4503,64 @@ AsyncSocketSendCallback(void *clientData)
 }
 
 
+/*
+ *----------------------------------------------------------------------------
+ *
+ * AsyncSocketIPollSendCallback --
+ *
+ *      IVmdbPoll callback for output socket buffer space available.  IVmdbPoll
+ *      does not handle callback locks, so this function first locks the
+ *      asyncsocket and verify that the send callback has not been cancelled.
+ *      IVmdbPoll only has periodic callbacks, so this function unregisters
+ *      itself before calling AsyncSocketSendCallback to do the real work.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      Writes data, could trigger write completion or socket destruction.
+ *
+ *----------------------------------------------------------------------------
+ */
+
+static void
+AsyncSocketIPollSendCallback(void *clientData)  // IN:
+{
+#ifdef VMX86_TOOLS
+   NOT_IMPLEMENTED();
+#else
+   AsyncSocket *s = (AsyncSocket *) clientData;
+   Bool removed;
+
+   ASSERT(s);
+   ASSERT(s->asockType != ASYNCSOCKET_TYPE_NAMEDPIPE);
+
+   AsyncSocketLock(s);
+   if (!s->sendCb) {
+      MXUserRecLock *lock = s->pollParams.lock;
+
+      /* Release the reference added when registering this callback. */
+      AsyncSocketRelease(s, TRUE);
+      if (lock != NULL) {
+         MXUser_DecRefRecLock(lock);
+      }
+      return;
+   }
+
+   AsyncSocketAddRef(s);
+
+   /* Unregister this callback as we want the non-periodic behavior. */
+   removed = AsyncSocketIPollRemove(s, TRUE, POLL_FLAG_WRITE,
+                                    AsyncSocketIPollSendCallback) ||
+             AsyncSocketIPollRemove(s, FALSE, 0, AsyncSocketIPollSendCallback);
+
+   AsyncSocketSendCallback(s);
+
+   AsyncSocketRelease(s, TRUE);
+#endif
+}
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -4545,6 +4696,10 @@ AsyncSocketPollAdd(AsyncSocket *asock,
       va_end(marker);
    }
 
+   if (asock->pollParams.iPoll != NULL) {
+      return AsyncSocketIPollAdd(asock, socket, flags, callback, info);
+   }
+
    return Poll_Callback(asock->pollParams.pollClass,
                         flags | asock->pollParams.flags,
                         callback, asock, type, info,
@@ -4579,6 +4734,10 @@ AsyncSocketPollRemove(AsyncSocket *asock,
 
    ASSERT(asock->asockType != ASYNCSOCKET_TYPE_NAMEDPIPE);
 
+   if (asock->pollParams.iPoll != NULL) {
+      return AsyncSocketIPollRemove(asock, socket, flags, callback);
+   }
+
    if (socket) {
       type = POLL_DEVICE;
       flags |= POLL_FLAG_SOCKET;
@@ -4592,6 +4751,134 @@ AsyncSocketPollRemove(AsyncSocket *asock,
 }
 
 
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * AsyncSocketIPollAdd --
+ *
+ *    Add a poll callback.  Wrapper for IVmdbPoll.Register[Timer].
+ *
+ *    If socket is FALSE, user has to pass in the timeout value
+ *
+ * Results:
+ *    VMwareStatus result code.
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static VMwareStatus
+AsyncSocketIPollAdd(AsyncSocket *asock,
+                    Bool socket,
+                    int flags,
+                    PollerFunction callback,
+                    int info)
+{
+#ifdef VMX86_TOOLS
+   return VMWARE_STATUS_ERROR;
+#else
+   VMwareStatus status = VMWARE_STATUS_SUCCESS;
+   VmdbRet ret;
+   IVmdbPoll *poll;
+
+   ASSERT(asock->pollParams.iPoll);
+   ASSERT(AsyncSocketIsLocked(asock));
+
+   /* Protect asyncsocket and lock from disappearing */
+   AsyncSocketAddRef(asock);
+   if (asock->pollParams.lock != NULL) {
+      MXUser_IncRefRecLock(asock->pollParams.lock);
+   }
+
+   poll = asock->pollParams.iPoll;
+
+   if (socket) {
+      int pollFlags = (flags & POLL_FLAG_READ) != 0 ? VMDB_PRF_READ
+                                                    : VMDB_PRF_WRITE;
+
+      ret = poll->Register(poll, pollFlags, callback, asock, info);
+   } else {
+      ret = poll->RegisterTimer(poll, callback, asock, info);
+   }
+
+   if (ret != VMDB_S_OK) {
+      Log(ASOCKPREFIX "failed to register callback (%s %d): error %d\n",
+          socket ? "socket" : "delay", info, ret);
+      if (asock->pollParams.lock != NULL) {
+         MXUser_DecRefRecLock(asock->pollParams.lock);
+      }
+      AsyncSocketRelease(asock, FALSE);
+      status = VMWARE_STATUS_ERROR;
+   }
+
+   return status;
+#endif
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * AsyncSocketIPollRemove --
+ *
+ *    Remove a poll callback.  Wrapper for IVmdbPoll.Unregister[Timer].
+ *
+ * Results:
+ *    TRUE  if the callback was registered and has been cancelled successfully.
+ *    FALSE if the callback was not registered, or the callback is already
+ *          scheduled to fire (and is guaranteed to fire).
+ *
+ * Side effects:
+ *    None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static Bool
+AsyncSocketIPollRemove(AsyncSocket *asock,
+                       Bool socket,
+                       int flags,
+                       PollerFunction callback)
+{
+#ifdef VMX86_TOOLS
+   return FALSE;
+#else
+   IVmdbPoll *poll;
+   Bool ret;
+
+   ASSERT(asock->pollParams.iPoll);
+   ASSERT(AsyncSocketIsLocked(asock));
+
+   poll = asock->pollParams.iPoll;
+
+   if (socket) {
+      int pollFlags = (flags & POLL_FLAG_READ) != 0 ? VMDB_PRF_READ
+                                                    : VMDB_PRF_WRITE;
+
+      ret = poll->Unregister(poll, pollFlags, callback, asock);
+   } else {
+      ret = poll->UnregisterTimer(poll, callback, asock);
+   }
+
+   if (ret) {
+      MXUserRecLock *lock = asock->pollParams.lock;
+
+      /* Release the reference taken when registering the callback. */
+      AsyncSocketRelease(asock, FALSE);
+      if (lock != NULL) {
+         MXUser_DecRefRecLock(lock);
+      }
+   }
+
+   return ret;
+#endif
+}
+
+
+
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -4832,6 +5119,7 @@ AsyncSocketSslAcceptCallback(void *clientData)
    VMwareStatus pollStatus;
 
    ASSERT(asock);
+   ASSERT(asock->pollParams.iPoll == NULL);
    ASSERT(AsyncSocketIsLocked(asock));
 
    AsyncSocketAddRef(asock);
index 58d08230d2328a9965895f86e477eebd58da1e03..4eea362c4fe2914c7758c0b8551b516853454170 100644 (file)
@@ -108,8 +108,7 @@ static char *FilePosixNearestExistingAncestor(char const *path);
 #if CAN_USE_FTS
 # include <fts.h>
 
-struct WalkDirContextImpl
-{
+struct WalkDirContextImpl {
    FTS *fts;
 };
 
@@ -119,6 +118,7 @@ struct WalkDirContextImpl
 #define FS_NFS_ON_ESX "NFS"
 /* A string for VMFS on ESX file system type */
 #define FS_VMFS_ON_ESX "VMFS"
+#define FS_VSAN_URI_PREFIX      "vsan:"
 
 #if defined __ANDROID__
 /*
@@ -254,13 +254,13 @@ bail:
  *
  * File_UnlinkDelayed --
  *
- *    Same as File_Unlink for POSIX systems since we can unlink anytime.
+ *      Same as File_Unlink for POSIX systems since we can unlink anytime.
  *
  * Results:
- *    Return 0 if the unlink is successful.   Otherwise, returns -1.
+ *      Return 0 if the unlink is successful.   Otherwise, returns -1.
  *
  * Side effects:
- *    None.
+ *      None.
  *
  *-----------------------------------------------------------------------------
  */
@@ -1339,7 +1339,7 @@ File_GetFreeSpace(ConstUnicode pathName,  // IN: File name
  *
  * File_GetVMFSAttributes --
  *
- *      Acquire the attributes for a given file on a VMFS volume.
+ *      Acquire the attributes for a given file or directory on a VMFS volume.
  *
  * Results:
  *      Integer return value and populated FS_PartitionListResult
@@ -1352,14 +1352,13 @@ File_GetFreeSpace(ConstUnicode pathName,  // IN: File name
  */
 
 int
-File_GetVMFSAttributes(ConstUnicode pathName,             // IN: File to test
+File_GetVMFSAttributes(ConstUnicode pathName,             // IN: File/dir to test
                        FS_PartitionListResult **fsAttrs)  // IN/OUT: VMFS Info
 {
    int fd;
    int ret;
    Unicode fullPath;
-
-   Unicode parentPath = NULL;
+   Unicode directory = NULL;
 
    fullPath = File_FullPath(pathName);
    if (fullPath == NULL) {
@@ -1367,7 +1366,11 @@ File_GetVMFSAttributes(ConstUnicode pathName,             // IN: File to test
       goto bail;
    }
 
-   File_SplitName(fullPath, NULL, &parentPath, NULL);
+   if (File_IsDirectory(fullPath)) {
+      directory = Unicode_Duplicate(fullPath);
+   } else {
+      File_SplitName(fullPath, NULL, &directory, NULL);
+   }
 
    if (!HostType_OSIsVMK()) {
       Log(LGPFX" %s: File %s not on VMFS volume\n", __func__, UTF8(pathName));
@@ -1382,7 +1385,7 @@ File_GetVMFSAttributes(ConstUnicode pathName,             // IN: File to test
    (*fsAttrs)->ioctlAttr.maxPartitions = FS_PLIST_DEF_MAX_PARTITIONS;
    (*fsAttrs)->ioctlAttr.getAttrSpec = FS_ATTR_SPEC_BASIC;
 
-   fd = Posix_Open(parentPath, O_RDONLY, 0);
+   fd = Posix_Open(directory, O_RDONLY, 0);
 
    if (fd == -1) {
       Log(LGPFX" %s: could not open %s: %s\n", __func__, UTF8(pathName),
@@ -1405,7 +1408,7 @@ File_GetVMFSAttributes(ConstUnicode pathName,             // IN: File to test
 
 bail:
    Unicode_Free(fullPath);
-   Unicode_Free(parentPath);
+   Unicode_Free(directory);
 
    return ret;
 }
@@ -1620,7 +1623,7 @@ File_GetVMFSMountInfo(ConstUnicode pathName,   // IN:
       if (memcmp(fsAttrs->fsType, FS_NFS_ON_ESX, sizeof(FS_NFS_ON_ESX)) == 0) {
          /*
           * logicalDevice from NFS3 client contains remote IP and remote
-          * mount point, separate by space.  Split them out.  If there is
+          * mount point, separated by space.  Split them out.  If there is
           * no space then this is probably NFS41 client, and we cannot
           * obtain its remote mount point details at this time.
           */
@@ -1813,40 +1816,61 @@ File_GetCapacity(ConstUnicode pathName)  // IN: Path name
 char *
 File_GetUniqueFileSystemID(char const *path)  // IN: File path
 {
-   if (HostType_OSIsVMK()) {
-      char *canPath;
-      char *existPath;
-
-      existPath = FilePosixNearestExistingAncestor(path);
-      canPath = Posix_RealPath(existPath);
-      free(existPath);
-
-      if (canPath == NULL) {
-         return NULL;
-      }
+#ifdef VMX86_SERVER
+   char vmfsVolumeName[FILE_MAXPATH];
+   char *existPath;
+   char *canPath;
 
-      /*
-       * VCFS doesn't have real mount points, so the mount point lookup below
-       * returns "/vmfs", instead of the VCFS mount point.
-       *
-       * See bug 61646 for why we care.
-       */
+   existPath = FilePosixNearestExistingAncestor(path);
+   canPath = Posix_RealPath(existPath);
+   free(existPath);
 
-      if (strncmp(canPath, VCFS_MOUNT_POINT, strlen(VCFS_MOUNT_POINT)) == 0) {
-         char vmfsVolumeName[FILE_MAXPATH];
+   if (canPath == NULL) {
+      return NULL;
+   }
 
-         if (sscanf(canPath, VCFS_MOUNT_PATH "%[^/]%*s",
-                    vmfsVolumeName) == 1) {
-            free(canPath);
+   /*
+    * VCFS doesn't have real mount points, so the mount point lookup below
+    * returns "/vmfs", instead of the VCFS mount point.
+    *
+    * See bug 61646 for why we care.
+    */
+   if (strncmp(canPath, VCFS_MOUNT_POINT, strlen(VCFS_MOUNT_POINT)) != 0 ||
+       sscanf(canPath, VCFS_MOUNT_PATH "%[^/]%*s", vmfsVolumeName) != 1) {
+      free(canPath);
+      goto exit;
+   }
 
-            return Str_SafeAsprintf(NULL, "%s/%s", VCFS_MOUNT_POINT,
-                                    vmfsVolumeName);
-         }
+   /*
+    * If the path points to a file or directory that is on a vsan datastore,
+    * we have to determine which namespace object is involved.
+    */
+   if (strncmp(vmfsVolumeName, FS_VSAN_URI_PREFIX,
+               strlen(FS_VSAN_URI_PREFIX)) == 0) {
+      FS_PartitionListResult *fsAttrs = NULL;
+      int res;
+
+      res = File_GetVMFSAttributes(canPath, &fsAttrs);
+
+      if (res >= 0 && fsAttrs != NULL &&
+          strncmp(fsAttrs->fsType, FS_VMFS_ON_ESX,
+                  strlen(FS_VMFS_ON_ESX)) == 0) {
+         char *unique;
+         unique = Str_SafeAsprintf(NULL, "%s/%s/%s",
+                                   VCFS_MOUNT_POINT, vmfsVolumeName,
+                                   fsAttrs->name);
+         free(fsAttrs);
+         free(canPath);
+         return unique;
       }
-
-      free(canPath);
+      free(fsAttrs);
    }
+   free(canPath);
 
+   return Str_SafeAsprintf(NULL, "%s/%s", VCFS_MOUNT_POINT,
+                           vmfsVolumeName);
+exit:
+#endif
    return FilePosixGetBlockDevice(path);
 }
 
@@ -2331,7 +2355,7 @@ Bool
 File_Replace(ConstUnicode oldName,  // IN: old file
              ConstUnicode newName)  // IN: new file
 {
-   int status;
+   int status = 0;
    Bool result = FALSE;
    char *newPath = NULL;
    char *oldPath = NULL;
@@ -2369,8 +2393,9 @@ File_Replace(ConstUnicode oldName,  // IN: old file
       goto bail;
    }
 
-   status = (rename(newPath, oldPath) == -1) ? errno : 0;
-   if (status != 0) {
+
+   if (rename(newPath, oldPath) < 0) {
+      status = errno;
       Msg_Append(MSGID(filePosix.replaceRenameFailed)
                  "Failed to rename \"%s\" to \"%s\": %s\n",
                  newName, oldName, Msg_ErrString());
@@ -3331,7 +3356,7 @@ FileIsWritableDir(ConstUnicode dirName)  // IN:
  *
  * File_MakeCfgFileExecutable --
  *
- *      Make a .vmx file executable. This is sometimes necessary
+ *     Make a .vmx file executable. This is sometimes necessary
  *      to enable MKS access to the VM.
  *
  *      Owner always gets rwx.  Group/other get x where r is set.
index c684d4dd88d18c625b83fd8f1ad5da2f67f54a17..e2219ee818f97a82c892914ce6bf848b81a9d15f 100644 (file)
@@ -116,12 +116,15 @@ typedef struct AsyncSocket AsyncSocket;
  * optional AsyncSocketPollParam* argument; if NULL the default behavior is
  * used (callback is registered in POLL_CS_MAIN and locked by the BULL).
  * Or the client can specify its favorite poll class and locking behavior.
+ * Use of IVmdbPoll is only supported for regular sockets and for Attach.
  */
 #include "poll.h"
+struct IVmdbPoll;
 typedef struct AsyncSocketPollParams {
    int flags;               /* Default 0, only POLL_FLAG_NO_BULL is valid */
    MXUserRecLock *lock;     /* Default: none but BULL */
    PollClassSet pollClass;  /* Default is POLL_CS_MAIN */
+   struct IVmdbPoll *iPoll; /* Default NULL: use Poll_Callback */
 } AsyncSocketPollParams;
 
 /*
index 24d0debc1f65634842b1f8bad39e84b99508378e..f2f668c580127f9080f1df55f33adcb5bb85ed60 100644 (file)
@@ -245,7 +245,11 @@ typedef enum {
  *
  *     ANY: A feature/field that IS ALWAYS SUPPORTED by the monitor.
  *     Even if the host does not support the feature, the monitor can
- *     expose the feature to the guest.
+ *     expose the feature to the guest. As with "YES", the guest cpuid
+ *     value defaults to the host/evc cpuid value.  But usually the
+ *     guest cpuid value is recomputed at power on, ignoring the default
+ *     value.
+ *     
  *
  *     NA: Only legal for levels not masked/tested by default (see
  *     above for this definition).  Such fields must always be marked
@@ -411,7 +415,7 @@ FLAG(   7,  0, EBX,  8,  1, BMI2,                                  YES, TRUE)  \
 FLAG(   7,  0, EBX,  9,  1, ENFSTRG,                               YES, FALSE) \
 FLAG(   7,  0, EBX, 10,  1, INVPCID,                               YES, FALSE) \
 FLAG(   7,  0, EBX, 11,  1, RTM,                                   YES, TRUE)  \
-FLAG(   7,  0, EBX, 13,  1, FP_SEGMENT_ZERO,                       YES, TRUE)
+FLAG(   7,  0, EBX, 13,  1, FP_SEGMENT_ZERO,                       ANY, TRUE)
 
 
 /*    LEVEL, SUB-LEVEL, REG, POS, SIZE, NAME,                  MON SUPP, CPL3 */