]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Change to common source files not applicable to open-vm-tools.
authorKaty Feng <fkaty@vmware.com>
Fri, 24 Mar 2023 20:29:28 +0000 (13:29 -0700)
committerKaty Feng <fkaty@vmware.com>
Fri, 24 Mar 2023 20:29:28 +0000 (13:29 -0700)
open-vm-tools/lib/file/filePosix.c
open-vm-tools/lib/include/file.h

index 85cb5268c3e664f1a00f23181d07a31473d3dece..85aab22d6d815d0c59452135fbba80f0a905345c 100644 (file)
 #include "hostType.h"
 #include "vmfs.h"
 #include "hashTable.h"
+#include "hostinfo.h"
+#include "log.h"
 
 #ifdef VMX86_SERVER
 #include "fs_public.h"
+#include "fs3Layout.h"
 #endif
 
 #define LOGLEVEL_MODULE main
@@ -1526,7 +1529,130 @@ File_GetVMFSMountInfo(const char *pathName,    // IN:
 
    return ret;
 }
-#endif
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * File_GetVMFSLockInfo --
+ *
+ *      Get lock information about a file that has probably caused a
+ *      locking conflict.
+ *
+ *      If the file is locked by a process local to the current host,
+ *      FS open flags, world ID, and world name will be returned (or
+ *      0/NULL if not).
+ *
+ *      If the file is on VMFS, the owner MAC address and lock mode of
+ *      the on-disk lock will be provided (or 0/NULL if not).
+ *
+ *      (It's possible for a file to be on a non-VMFS shared datastore
+ *      like NFS/VVol/VSAN and be locked by another host. In that
+ *      case, this function might not return any information.)
+ *
+ * Results:
+ *      0 on success (and see above), -1 otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+File_GetVMFSLockInfo(const char *path,         // IN
+                     uint32 *outOpenFlags,     // OUT:
+                     uint32 *outWorldID,       // OUT:
+                     char **outWorldName,      // OUT:
+                     char **outVMFSMacAddr,    // OUT:
+                     uint32 *outVMFSLockMode)  // OUT:
+{
+   int ret = -1;
+   int ioctlRet;
+   int fd = -1;
+   FS_GetFileLockInfoArgs lockArgs = {0};
+   FS_DumpFDData dumpArgs = {0};
+   char *dir = NULL;
+   char *fileName = NULL;
+
+   *outOpenFlags = 0;
+   *outWorldID = INVALID_WORLD_ID;
+   *outWorldName = NULL;
+   *outVMFSMacAddr = NULL;
+   *outVMFSLockMode = 0;
+
+   File_SplitName(path, NULL, &dir, &fileName);
+
+   fd = Posix_Open(dir, O_RDONLY, 0);
+   if (fd == -1) {
+      Log(LGPFX" %s: could not open directory \"%s\": %s\n", __FUNCTION__, dir,
+          Err_Errno2String(errno));
+      goto exit;
+   }
+
+   Str_Strncpy(lockArgs.fileName, sizeof lockArgs.fileName, fileName,
+               strlen(fileName));
+   ioctlRet = ioctl(fd, IOCTLCMD_GETFILELOCKINFO, (char *)&lockArgs);
+   /* If this fails, it might be open only on another machine. */
+   if (ioctlRet != -1) {
+      *outOpenFlags = lockArgs.openFlags;
+      *outWorldID = lockArgs.worldID;
+      *outWorldName = Util_SafeStrdup(lockArgs.worldName);
+   }
+
+   Str_Strncpy(dumpArgs.args.fileName, sizeof dumpArgs.args.fileName,
+               fileName, strlen(fileName));
+   ioctlRet = ioctl(fd, IOCTLCMD_VMFS_DUMP_METADATA, (char *)&dumpArgs);
+   /* If this fails, it probably isn't on VMFS. */
+   if (ioctlRet != -1) {
+      FS3_FileDescriptor *fileDesc =
+         (FS3_FileDescriptor *)&dumpArgs.result.descriptor;
+      FS3_DiskLock *diskLock = FS3_DISKLOCK(&fileDesc->lockBlock);
+      if (dumpArgs.result.descriptorLength < sizeof(FS3_FileDescriptor)) {
+         /* This should not happen. */
+         Log(LGPFX" %s: VMFS file descriptor size %u too small (need "
+             "%"FMTSZ"u) for file \"%s\"\n", __FUNCTION__,
+             dumpArgs.result.descriptorLength, sizeof(FS3_FileDescriptor),
+             path);
+         goto exit;
+      }
+
+      *outVMFSLockMode = diskLock->mode;
+
+      if (diskLock->mode != FS3_LC_FREE &&
+          diskLock->mode != FS3_LC_EXCLUSIVE) {
+         /*
+          * This is a non-exclusive lock. Thus it can have multiple holders.
+          * For now, return only the first.
+          */
+         if (diskLock->numHolders == 0 ||
+             diskLock->numHolders > FS3_MAX_LOCK_HOLDERS) {
+            Log(LGPFX" %s: Corrupt VMFS disk lock found for file \"%s\", "
+                "invalid number of holders %u.\n", __FUNCTION__, path,
+                diskLock->numHolders);
+            goto exit;
+         }
+         *outVMFSMacAddr = Str_SafeAsprintf(NULL, FS_UUID_FMTSTR,
+            FS_UUID_VAARGS(&diskLock->holders[0].uid));
+      } else {
+         /* Exclusive lock, so there is only one owner. */
+         *outVMFSMacAddr = Str_SafeAsprintf(NULL, FS_UUID_FMTSTR,
+            FS_UUID_VAARGS(&diskLock->owner));
+      }
+   }
+
+   ret = 0;
+
+  exit:
+   if (fd != -1) {
+      close(fd);
+   }
+   free(dir);
+   free(fileName);
+   return ret;
+}
+
+#endif // VMX86_SERVER
 
 
 /*
index f4fc3c0a06d83f513532978b12ec79e20b6bca05..3651b3cd920d0b10a7832c7f6a7f8ae6fdb2afa3 100644 (file)
@@ -116,6 +116,13 @@ int File_GetVMFSMountInfo(const char *pathName,
                           char **remoteIP,
                           char **remoteMountPoint,
                           char **localMountPoint);
+
+int File_GetVMFSLockInfo(const char *path,
+                         uint32 *outOpenFlags,
+                         uint32 *outWorldID,
+                         char **outWorldName,
+                         char **outVMFSMacAddr,
+                         uint32 *outVMFSLockMode);
 #endif
 
 Bool File_SupportsZeroedThick(const char *pathName);