From: VMware, Inc <> Date: Wed, 18 Sep 2013 03:25:16 +0000 (-0700) Subject: Changes in shared code that don't affect open-vm-tools functionality. X-Git-Tag: 2013.09.16-1328054~73 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=48a12d8ff6d89e2e06f094cdf0c34e29fe338cbc;p=thirdparty%2Fopen-vm-tools.git Changes in shared code that don't affect open-vm-tools functionality. Signed-off-by: Dmitry Torokhov --- diff --git a/open-vm-tools/lib/asyncsocket/asyncSocketInt.h b/open-vm-tools/lib/asyncsocket/asyncSocketInt.h index 4bdd4afd0..9151cf0ea 100644 --- a/open-vm-tools/lib/asyncsocket/asyncSocketInt.h +++ b/open-vm-tools/lib/asyncsocket/asyncSocketInt.h @@ -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); diff --git a/open-vm-tools/lib/asyncsocket/asyncsocket.c b/open-vm-tools/lib/asyncsocket/asyncsocket.c index 9c55b34d9..2051f3dc5 100644 --- a/open-vm-tools/lib/asyncsocket/asyncsocket.c +++ b/open-vm-tools/lib/asyncsocket/asyncsocket.c @@ -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); diff --git a/open-vm-tools/lib/file/filePosix.c b/open-vm-tools/lib/file/filePosix.c index 58d08230d..4eea362c4 100644 --- a/open-vm-tools/lib/file/filePosix.c +++ b/open-vm-tools/lib/file/filePosix.c @@ -108,8 +108,7 @@ static char *FilePosixNearestExistingAncestor(char const *path); #if CAN_USE_FTS # include -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. diff --git a/open-vm-tools/lib/include/asyncsocket.h b/open-vm-tools/lib/include/asyncsocket.h index c684d4dd8..e2219ee81 100644 --- a/open-vm-tools/lib/include/asyncsocket.h +++ b/open-vm-tools/lib/include/asyncsocket.h @@ -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; /* diff --git a/open-vm-tools/lib/include/x86cpuid.h b/open-vm-tools/lib/include/x86cpuid.h index 24d0debc1..f2f668c58 100644 --- a/open-vm-tools/lib/include/x86cpuid.h +++ b/open-vm-tools/lib/include/x86cpuid.h @@ -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 */