summaryrefslogtreecommitdiff
path: root/open-vm-tools/lib/file/fileInt.h
blob: 5faf6ac0ef166923b4ef8416d6243911c1e84f22 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
/*********************************************************
 * Copyright (C) 2007-2015 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
 * by the Free Software Foundation version 2.1 and no later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the Lesser GNU General Public
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
 *
 *********************************************************/

/*
 * fileInt.h --
 *
 *     Things internal to the file library.
 */

#if !defined(__FILE_INTERNAL_H__)
#define __FILE_INTERNAL_H__

#define INCLUDE_ALLOW_USERLEVEL
#include "includeCheck.h"
#include "err.h"
#include "posix.h"
#include "file.h"
#include "fileIO.h"
#include "fileLock.h"
#include "unicodeTypes.h"
#include "memaligned.h"

/*
 * Max supported file size is 64 TB.
 */
#define MAX_SUPPORTED_FILE_SIZE CONST64U(0x400000000000)

#if defined __linux__
/*
 * These magic constants are used only for parsing Linux statfs data.
 * So they make sense only for Linux build. If you need them on other OSes,
 * think once more.
 */

#define ADFS_SUPER_MAGIC      0xadf5
#define AFFS_SUPER_MAGIC      0xADFF
#define EXT_SUPER_MAGIC       0x137D
#define EXT2_OLD_SUPER_MAGIC  0xEF51
#define EXT2_SUPER_MAGIC      0xEF53
#define EXT3_SUPER_MAGIC      0xEF53
#define EXT4_SUPER_MAGIC      0xEF53
#define HFSPLUS_SUPER_MAGIC   0x482B
#define NFS_SUPER_MAGIC       0x6969
#define SMB_SUPER_MAGIC       0x517B
#define ISOFS_SUPER_MAGIC     0x9660
#define JFFS2_SUPER_MAGIC     0x72b6
#define PROC_SUPER_MAGIC      0x9fa0
#define OPENPROM_SUPER_MAGIC  0x9fa1
#define USBDEVICE_SUPER_MAGIC 0x9fa2
#define AUTOFS_SUPER_MAGIC    0x0187

#if !defined(MSDOS_SUPER_MAGIC)
#define MSDOS_SUPER_MAGIC     0x4D44
#endif

#define XENIX_SUPER_MAGIC     0x012FF7B4
#define SYSV4_SUPER_MAGIC     0x012FF7B5
#define SYSV2_SUPER_MAGIC     0x012FF7B6
#define COH_SUPER_MAGIC       0x012FF7B7
#define UFS_SUPER_MAGIC       0x00011954
#define XFS_SUPER_MAGIC       0x58465342
#define VMFS_SUPER_MAGIC      0x2fABF15E
#define TMPFS_SUPER_MAGIC     0x01021994
#define JFS_SUPER_MAGIC       0x3153464a
#define AFS_SUPER_MAGIC       0x5346414F
#define CIFS_SUPER_MAGIC      0xFF534D42

#if !defined(REISERFS_SUPER_MAGIC)
#define REISERFS_SUPER_MAGIC  0x52654973
#endif
#endif // linux

#define LGPFX "FILE:"

#define FILE_TYPE_REGULAR      0
#define FILE_TYPE_DIRECTORY    1
#define FILE_TYPE_BLOCKDEVICE  2
#define FILE_TYPE_CHARDEVICE   3
#define FILE_TYPE_SYMLINK      4
#define FILE_TYPE_FIFO         5
#define FILE_TYPE_SOCKET       6
#define FILE_TYPE_UNCERTAIN    7

typedef struct FileData {
   uint64 fileAccessTime;
   uint64 fileCreationTime;
   uint64 fileModificationTime;
   uint64 fileSize;
   int    fileType;
   int    fileMode;
   int    fileOwner;
   int    fileGroup;
} FileData;

#define FILE_MAX_WAIT_TIME_MS 2000  // maximum wait time in milliseconds

void FileIOResolveLockBits(int *access);

#if defined(_WIN32)
int FileMapErrorToErrno(const char *functionName,
                        Err_Number status);

Bool FileRetryThisError(DWORD error,
                        uint32 numCodes,
                        DWORD *codes);

int FileAttributesRetry(ConstUnicode pathName,
                        uint32 msecMaxWaitTime,
                        FileData *fileData);

int FileDeletionRetry(ConstUnicode pathName,
                      Bool handleLink,
                      uint32 msecMaxWaitTime);

int FileCreateDirectoryRetry(ConstUnicode pathName,
                             int mask,
                             uint32 msecMaxWaitTime);

int FileRemoveDirectoryRetry(ConstUnicode pathName,
                             uint32 msecMaxWaitTime);

int FileListDirectoryRetry(ConstUnicode pathName,
                           uint32 msecMaxWaitTime,
                           Unicode **ids);

#define FileAttributes(a, b)       FileAttributesRetry((a), 0, (b))
#define FileDeletion(a, b)         FileDeletionRetry((a), (b), 0)
#define FileCreateDirectory(a, b)  FileCreateDirectoryRetry((a), (b), 0)
#define FileRemoveDirectory(a)     FileRemoveDirectoryRetry((a), 0)

#define FileListDirectoryRobust(a, b) \
                    FileListDirectoryRetry((a), FILE_MAX_WAIT_TIME_MS, (b))
#define FileAttributesRobust(a, b) \
                    FileAttributesRetry((a), FILE_MAX_WAIT_TIME_MS, (b))
#define FileRenameRobust(a, b) \
                    File_RenameRetry((a), (b), FILE_MAX_WAIT_TIME_MS)
#define FileDeletionRobust(a, b) \
                    FileDeletionRetry((a), (b), FILE_MAX_WAIT_TIME_MS)
#define FileCreateDirectoryRobust(a, b) \
                    FileCreateDirectoryRetry((a), (b), FILE_MAX_WAIT_TIME_MS)
#define FileRemoveDirectoryRobust(a) \
                    FileRemoveDirectoryRetry((a), FILE_MAX_WAIT_TIME_MS)
#else
static INLINE int
FileMapErrorToErrno(const char *functionName,
                    Err_Number status)
{
   return status;
}

char *FilePosixGetBlockDevice(char const *path);

int FileAttributes(ConstUnicode pathName,
                   FileData *fileData);

int FileDeletion(ConstUnicode pathName,
                 Bool handleLink);

int FileCreateDirectory(ConstUnicode pathName,
                       int mask);

int FileRemoveDirectory(ConstUnicode pathName);

#define FileListDirectoryRobust(a, b)    File_ListDirectory((a), (b))
#define FileAttributesRobust(a, b)       FileAttributes((a), (b))
#define FileRenameRobust(a, b)           File_Rename((a), (b))
#define FileDeletionRobust(a, b)         FileDeletion((a), (b))
#define FileCreateDirectoryRobust(a, b)  FileCreateDirectory((a), (b))
#define FileRemoveDirectoryRobust(a)     FileRemoveDirectory((a))
#endif

typedef struct active_lock
{
  struct active_lock *next;
  uint32              age;
  Bool                marked;
  Unicode             dirName;
} ActiveLock;

typedef struct lock_values
{
   char         *machineID;
   char         *executionID;
   char         *lockType;
   char         *locationChecksum;
   Unicode       memberName;
   unsigned int  lamportNumber;
   Bool          exclusivity;
   uint32        waitTime;
   uint32        msecMaxWaitTime;
   ActiveLock   *lockList;
} LockValues;

#include "file_extensions.h"

#define FILELOCK_SUFFIX "." LOCK_FILE_EXTENSION

#define FILELOCK_DATA_SIZE 512

uint32 FileSleeper(uint32 msecMinSleepTime,
                   uint32 msecMaxSleepTime);

uint32 FileSimpleRandom(void);

const char *FileLockGetMachineID(void);

char *FileLockGetExecutionID(void);

Bool FileLockMachineIDMatch(char *host,
                            char *second);

int FileLockMemberValues(ConstUnicode lockDir, 
                         ConstUnicode fileName,
                         char *buffer,
                         size_t size,
                         LockValues *memberValues);

FileLockToken *FileLockIntrinsic(ConstUnicode filePathName,
                                 Bool exclusivity,
                                 uint32 msecMaxWaitTime,
                                 int *err);

int FileUnlockIntrinsic(FileLockToken *tokenPtr);

Bool FileLockIsLocked(ConstUnicode filePath,
                      int *err);

Bool FileLockValidExecutionID(const char *executionID);

Bool FileLockValidName(ConstUnicode fileName);

void FileLockAppendMessage(MsgList **msgs,
                           int err);

Bool FileIsWritableDir(ConstUnicode dirName);

UnicodeIndex FileFirstSlashIndex(ConstUnicode pathName,
                                 UnicodeIndex startIndex);

FileIOResult
FileIOCreateRetry(FileIODescriptor *fd,
                  ConstUnicode pathName,
                  int access,
                  FileIOOpenAction action,
                  int mode,
                  uint32 msecMaxWaitTime);


/*
 * FileIOAligned_* are useful on hosted platforms where malloc/memalign/valloc
 * for "large buffers" (in the range 64 KiB - 1 MiB) will generally fall
 * through to mmap/munmap, which is expensive due to page table modifications
 * and the attendant TLB flushing (which requires IPIs and possibly world
 * switches) on other threads running in the same address space.  In particular,
 * on Mac OS 10.6.6 on a Westmere-class Mac Pro, mmap + memcpy + munmap adds
 * around a millisecond of CPU time and a hundred IPIs to a 512 KiB write.  See
 * PR#685845.
 *
 * This isn't applicable to ESX because
 * 1. we don't use this path for disk IO
 * 2. we don't want to do extra large allocations
 * 3. we don't have the same alignment constraints
 * so simply define it away to nothing.
 *
 * Tools is another case, we can use this path for IO but we don't want to add
 * MXUserExclLock dependencies.
 */

#if defined(VMX86_TOOLS) || defined(VMX86_SERVER)
#define FileIOAligned_PoolInit()     /* nothing */
#define FileIOAligned_PoolExit()     /* nothing */
#define FileIOAligned_PoolMalloc(sz) NULL
#define FileIOAligned_PoolFree(ptr)  FALSE
#else
void FileIOAligned_PoolInit(void);
void FileIOAligned_PoolExit(void);
void *FileIOAligned_PoolMalloc(size_t);
Bool FileIOAligned_PoolFree(void *);
#endif

static INLINE void *
FileIOAligned_Malloc(size_t sz)  // IN:
{
   void *buf = FileIOAligned_PoolMalloc(sz);

   if (!buf) {
      buf = Aligned_Malloc(sz);
   }

   return buf;
}

static INLINE void
FileIOAligned_Free(void *ptr)  // IN:
{
   if (!FileIOAligned_PoolFree(ptr)) {
      Aligned_Free(ptr);
   }
}

#if defined(__APPLE__)
int PosixFileOpener(ConstUnicode pathName,
                    int flags,
                    mode_t mode);
#else
#define PosixFileOpener(a, b, c) Posix_Open(a, b, c);
#endif

#endif