~n-muench/ubuntu/oneiric/open-vm-tools/open-vm-tools.fix-836277

« back to all changes in this revision

Viewing changes to lib/file/fileLockPrimitive.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-15 21:21:40 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080815212140-05fhxj8wroosysmj
Tags: 2008.08.08-109361-1ubuntu1
* Merge from Debian unstable (LP: #258393), remaining Ubuntu change:
  - add ubuntu_toolchain_FTBFS.dpatch patch, fix FTBFS
* Update ubuntu_toolchain_FTBFS.dpatch patch for the new version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
#include "vmware.h"
44
44
#include "hostinfo.h"
45
45
#include "util.h"
 
46
#include "err.h"
46
47
#include "log.h"
47
48
#include "str.h"
48
49
#include "file.h"
56
57
#define LOGLEVEL_MODULE main
57
58
#include "loglevel_user.h"
58
59
 
59
 
#define LOCK_SHARED     "S"
60
 
#define LOCK_EXCLUSIVE  "X"
 
60
#define LOCK_SHARED     "S"
 
61
#define LOCK_EXCLUSIVE  "X"
61
62
#define FILELOCK_PROGRESS_DEARTH 8000 // Dearth of progress time in msec
62
63
#define FILELOCK_PROGRESS_SAMPLE 200  // Progress sampling time in msec
63
64
 
64
65
static char implicitReadToken;
65
66
 
 
67
#define PARSE_TABLE_UINT   0
 
68
#define PARSE_TABLE_STRING 1
 
69
 
 
70
typedef struct parse_table
 
71
{
 
72
   int type;
 
73
   char *name;
 
74
   void *valuePtr;
 
75
} ParseTable;
 
76
 
66
77
 
67
78
/*
68
79
 *-----------------------------------------------------------------------------
69
80
 *
70
81
 * Sleeper --
71
82
 *
72
 
 *      Have the calling thread sleep "for a while". The duration of the
73
 
 *      sleep is determined by the count that is passed in. Checks are
74
 
 *      also done for exceeding the maximum wait time.
 
83
 *      Have the calling thread sleep "for a while". The duration of the
 
84
 *      sleep is determined by the count that is passed in. Checks are
 
85
 *      also done for exceeding the maximum wait time.
75
86
 *
76
87
 * Results:
77
 
 *      0       slept
78
 
 *      EAGAIN  maximum sleep time exceeded
 
88
 *      0       slept
 
89
 *      EAGAIN  maximum sleep time exceeded
79
90
 *
80
91
 * Side effects:
81
 
 *      None.
 
92
 *      None.
82
93
 *
83
94
 *-----------------------------------------------------------------------------
84
95
 */
127
138
 *
128
139
 * RemoveLockingFile --
129
140
 *
130
 
 *      Remove the specified file.
 
141
 *      Remove the specified file.
131
142
 *
132
143
 * Results:
133
 
 *      0       success
134
 
 *      > 0     failure (errno)
 
144
 *      0       success
 
145
 *      > 0     failure (errno)
135
146
 *
136
147
 * Side effects:
137
 
 *      None.
 
148
 *      None.
138
149
 *
139
150
 *-----------------------------------------------------------------------------
140
151
 */
149
160
   ASSERT(lockDir);
150
161
   ASSERT(fileName);
151
162
 
152
 
   path = Unicode_Join(lockDir, U(DIRSEPS), fileName, NULL);
 
163
   path = Unicode_Join(lockDir, DIRSEPS, fileName, NULL);
153
164
 
154
 
   err = FileDeletion(path, FALSE);
 
165
   err = FileDeletionRobust(path, FALSE);
155
166
 
156
167
   if (err != 0) {
157
168
      if (err == ENOENT) {
172
183
/*
173
184
 *-----------------------------------------------------------------------------
174
185
 *
 
186
 * FileLockParseArgs --
 
187
 *
 
188
 *      Parse the property list arguments of a lock file. The ParseTable
 
189
 *      contains names of properies that are interesting to the caller;
 
190
 *      only those values associated with the interesting names will be
 
191
 *      extracted, the others will be ignored.
 
192
 *
 
193
 * Results:
 
194
 *      TRUE    An error was detected
 
195
 *      FALSE   All is well
 
196
 *
 
197
 * Side effects:
 
198
 *      None
 
199
 *
 
200
 *-----------------------------------------------------------------------------
 
201
 */
 
202
 
 
203
static Bool
 
204
FileLockParseArgs(char *argv[],       // IN:
 
205
                  uint32 argCount,    // IN:
 
206
                  ParseTable *table,  // IN:
 
207
                  uint32 tableSize)   // IN:
 
208
{
 
209
   uint32 argPos = 5;  // The property list always starts with this argument
 
210
 
 
211
   while (argCount) {
 
212
      uint32 i;
 
213
      char *p = strchr(argv[argPos], '=');
 
214
 
 
215
      /* Validate the "name=value" form */
 
216
      if ((p == NULL) || (p == argv[argPos]) || (p[1] == '\0')) {
 
217
         return TRUE;
 
218
      }
 
219
 
 
220
      *p = '\0';
 
221
 
 
222
      /* Unknown names are ignored without error */
 
223
      for (i = 0; i < tableSize; i++) {
 
224
         if (strcmp(argv[argPos], table[i].name) == 0) {
 
225
            switch (table[i].type) {
 
226
            case PARSE_TABLE_UINT:
 
227
               if (sscanf(&p[1], "%u", (uint32 *) table[i].valuePtr) != 1) {
 
228
                  return TRUE;
 
229
               }
 
230
               break;
 
231
 
 
232
            case PARSE_TABLE_STRING:
 
233
               *((char **) table[i].valuePtr) = &p[1];
 
234
               break;
 
235
            }
 
236
         }
 
237
      }
 
238
 
 
239
      *p = '=';
 
240
 
 
241
      argPos++;
 
242
      argCount--;
 
243
   }
 
244
 
 
245
   return FALSE;
 
246
}
 
247
 
 
248
 
 
249
/*
 
250
 *-----------------------------------------------------------------------------
 
251
 *
175
252
 * FileLockMemberValues --
176
253
 *
177
 
 *      Returns the values associated with lock directory file.
 
254
 *      Returns the values associated with lock directory file.
178
255
 *
179
256
 * Results:
180
 
 *      0       Valid lock file; values have been returned
181
 
 *      > 0     Lock file problem (errno); values have not been returned
 
257
 *      0       Valid lock file; values have been returned
 
258
 *      > 0     Lock file problem (errno); values have not been returned
182
259
 *
183
260
 * Side effects:
184
261
 *      The lock file may be deleted if it is invalid
186
263
 *-----------------------------------------------------------------------------
187
264
 */
188
265
 
 
266
#define FL_MAX_ARGS 16
 
267
 
189
268
int
190
269
FileLockMemberValues(ConstUnicode lockDir,     // IN:
191
270
                     ConstUnicode fileName,    // IN:
193
272
                     uint32 requiredSize,      // IN:
194
273
                     LockValues *memberValues) // OUT:
195
274
{
196
 
   uint32 i;
 
275
   uint32 argc = 0;
197
276
   FILELOCK_FILE_HANDLE handle;
198
277
   uint32 len;
199
 
   char *argv[4];
 
278
   char *argv[FL_MAX_ARGS];
200
279
   int err;
201
280
   Unicode path;
202
281
   FileData fileData;
203
282
 
 
283
   ParseTable table = { PARSE_TABLE_STRING,
 
284
                        "lc",
 
285
                        (void *) &memberValues->locationChecksum
 
286
                      };
 
287
 
204
288
   ASSERT(lockDir);
205
289
   ASSERT(fileName);
206
290
 
207
 
   path = Unicode_Join(lockDir, U(DIRSEPS), fileName, NULL);
 
291
   path = Unicode_Join(lockDir, DIRSEPS, fileName, NULL);
208
292
 
209
293
   err = FileLockOpenFile(path, O_RDONLY, &handle);
210
294
 
224
308
   }
225
309
 
226
310
   /* Attempt to obtain the lock file attributes now that it is opened */
227
 
   err = FileAttributes(path, &fileData);
 
311
   err = FileAttributesRobust(path, &fileData);
228
312
 
229
313
   if (err != 0) {
230
314
      Warning(LGPFX" %s file size failure on '%s': %s\n", __FUNCTION__,
266
350
   }
267
351
 
268
352
   /* Extract and validate the lock file data. */
269
 
   for (i = 0; i < 4; i++) {
270
 
      argv[i] = strtok((i == 0) ? buffer : NULL, " ");
271
 
 
272
 
      if (argv[i] == NULL) {
273
 
         Warning(LGPFX" %s mandatory argument %u is missing!\n",
274
 
                 __FUNCTION__, i);
275
 
 
 
353
   for (argc = 0; argc < FL_MAX_ARGS; argc++) {
 
354
      argv[argc] = strtok((argc == 0) ? buffer : NULL, " ");
 
355
 
 
356
      if (argv[argc] == NULL) {
 
357
         break;
 
358
      }
 
359
   }
 
360
 
 
361
   if ((argc < 4) || ((argc == FL_MAX_ARGS) && (strtok(NULL, " ") != NULL))) {
 
362
      goto corrupt;
 
363
   }
 
364
 
 
365
   /*
 
366
    * Lock file arguments are space separated. There is a minimum of 4
 
367
    * arguments - machineID, executionID, Lamport number and lock type.
 
368
    * The maximum number of arguments is FL_MAX_ARGS.
 
369
    *
 
370
    * The fifth argument, if present, is the payload or "[" if there is no
 
371
    * payload and additional arguments are present. The additional arguments
 
372
    * form  a properly list - one or more "name=value" pairs.
 
373
    *
 
374
    * Here is picture of valid forms:
 
375
    *
 
376
    * 0 1 2 3 4 5 6    Comment
 
377
    *-------------------------
 
378
    * A B C D         contents, no payload, no list entries
 
379
    * A B C D [       contents, no payload, no list entries
 
380
    * A B C D P       contents, a payload,  no list entries
 
381
    * A B C D [ x     contents, no payload, one list entry
 
382
    * A B C D P x     contents, a payload,  one list entry
 
383
    * A B C D [ x y   contents, no payload, two list entries,
 
384
    * A B C D P x y   contents, a payload,  two list entries
 
385
    */
 
386
 
 
387
   memberValues->locationChecksum = NULL;
 
388
 
 
389
   if (argc == 4) {
 
390
      memberValues->payload = NULL;
 
391
   } else {
 
392
      if (strcmp(argv[4], "[") == 0) {
 
393
         memberValues->payload = NULL;
 
394
      } else {
 
395
         memberValues->payload = argv[4];
 
396
      }
 
397
 
 
398
      if (FileLockParseArgs(argv, argc - 5, &table, 1)) {
276
399
         goto corrupt;
277
400
      }
278
401
   }
279
402
 
280
 
   memberValues->payload = strtok(NULL, " ");
281
 
 
282
403
   if (sscanf(argv[2], "%u", &memberValues->lamportNumber) != 1) {
283
 
      Warning(LGPFX" %s Lamport number conversion error\n",
284
 
              __FUNCTION__);
285
 
 
286
404
      goto corrupt;
287
405
   }
288
406
 
289
407
   if ((strcmp(argv[3], LOCK_SHARED) != 0) &&
290
408
       (strcmp(argv[3], LOCK_EXCLUSIVE) != 0)) {
291
 
      Warning(LGPFX" %s unknown lock type '%s'\n", __FUNCTION__, argv[3]);
292
 
 
293
409
      goto corrupt;
294
410
   }
295
411
 
306
422
   Warning(LGPFX" %s removing problematic lock file '%s'\n", __FUNCTION__,
307
423
           UTF8(path));
308
424
 
 
425
   if (argc) {
 
426
      Log(LGPFX" %s '%s' contents are:\n", __FUNCTION__, UTF8(fileName));
 
427
 
 
428
      for (len = 0; len < argc; len++) {
 
429
         Log(LGPFX" %s %s argv[%d]: '%s'\n", __FUNCTION__, UTF8(fileName),
 
430
             len, argv[len]);
 
431
      }
 
432
   }
 
433
 
309
434
   /* Remove the lock file and behave like it has disappeared */
310
 
   err = FileDeletion(path, FALSE);
 
435
   err = FileDeletionRobust(path, FALSE);
311
436
 
312
437
   if (err == 0) {
313
438
      err = ENOENT;
325
450
 *
326
451
 * FileLockValidName --
327
452
 *
328
 
 *      Validate the format of the file name.
 
453
 *      Validate the format of the file name.
329
454
 *
330
455
 * Results:
331
 
 *      TRUE    yes
332
 
 *      FALSE   No
 
456
 *      TRUE    Yes
 
457
 *      FALSE   No
333
458
 *
334
459
 * Side effects:
335
 
 *      None
 
460
 *      None
336
461
 *
337
462
 *-----------------------------------------------------------------------------
338
463
 */
345
470
   ASSERT(fileName);
346
471
 
347
472
   /* The fileName must start with the ASCII character, 'M', 'D' or 'E' */
348
 
   if (Unicode_FindSubstrInRange(U("MDE"), 0, -1, fileName, 0,
 
473
   if (Unicode_FindSubstrInRange("MDE", 0, -1, fileName, 0,
349
474
                                 1) == UNICODE_INDEX_NOT_FOUND) {
350
475
      return FALSE;
351
476
   }
352
477
 
353
478
   /* The fileName must contain 5 ASCII digits after the initial character */
354
479
   for (i = 0; i < 5; i++) {
355
 
      if (Unicode_FindSubstrInRange(U("0123456789"), 0, -1, fileName, i + 1,
 
480
      if (Unicode_FindSubstrInRange("0123456789", 0, -1, fileName, i + 1,
356
481
                                    1) == UNICODE_INDEX_NOT_FOUND) {
357
482
         return FALSE;
358
483
      }
359
484
   }
360
485
 
361
486
   /* The fileName must terminate with the appropriate suffix string */
362
 
   return Unicode_EndsWith(fileName, U(FILELOCK_SUFFIX));
 
487
   return Unicode_EndsWith(fileName, FILELOCK_SUFFIX);
363
488
}
364
489
 
365
490
 
368
493
 *
369
494
 * ActivateLockList
370
495
 *
371
 
 *      Insure a lock list entry exists for the lock directory.
 
496
 *      Insure a lock list entry exists for the lock directory.
372
497
 *
373
498
 * Results:
374
 
 *      0       success
375
 
 *      > 0     error (errno)
 
499
 *     0        success
 
500
 *     > 0      error (errno)
376
501
 *
377
502
 * Side effects:
378
 
 *      None.
 
503
 *     None.
379
504
 *
380
505
 *-----------------------------------------------------------------------------
381
506
 */
388
513
 
389
514
   ASSERT(dirName);
390
515
 
391
 
   ASSERT(Unicode_StartsWith(dirName, U("D")));
 
516
   ASSERT(Unicode_StartsWith(dirName, "D"));
392
517
 
393
518
   /* Search the list for a matching entry */
394
519
   for (ptr = myValues->lockList; ptr != NULL; ptr = ptr->next) {
418
543
/*
419
544
 *-----------------------------------------------------------------------------
420
545
 *
 
546
 * FileLockLocationChecksum --
 
547
 *
 
548
 *      Compute the location checksum of the argument path.
 
549
 *
 
550
 * Results:
 
551
 *      The location checksum as dynamically allocated string.
 
552
 *
 
553
 * Side effects:
 
554
 *      None
 
555
 *
 
556
 *-----------------------------------------------------------------------------
 
557
 */
 
558
 
 
559
static char *
 
560
FileLockLocationChecksum(ConstUnicode path)  // IN:
 
561
{
 
562
   int c;
 
563
   uint32 hash = 5381;
 
564
 
 
565
#if defined(_WIN32)
 
566
   char *p;
 
567
   Unicode value = Unicode_Duplicate(path);
 
568
 
 
569
   /* Don't get fooled by mixed case; "normalize" */
 
570
   Str_ToLower(value);
 
571
   p = value;
 
572
#else
 
573
   char *p = (char *) path;
 
574
#endif
 
575
 
 
576
   /* DBJ2 hash... good enough? */
 
577
   while ((c = *p++)) {
 
578
      hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
 
579
   }
 
580
 
 
581
#if defined(_WIN32)
 
582
   Unicode_Free(value);
 
583
#endif
 
584
 
 
585
   return Str_SafeAsprintf(NULL, "%u", hash);
 
586
}
 
587
 
 
588
 
 
589
/*
 
590
 *-----------------------------------------------------------------------------
 
591
 *
421
592
 * ScanDirectory --
422
593
 *
423
 
 *      Call the specified function for each member file found in the
424
 
 *      specified directory.
 
594
 *      Call the specified function for each member file found in the
 
595
 *      specified directory.
425
596
 *
426
597
 * Results:
427
 
 *      0       success
428
 
 *      > 0     failure
 
598
 *      0       success
 
599
 *      > 0     failure
429
600
 *
430
601
 * Side effects:
431
 
 *      Anything that this not a valid locking file is deleted.
 
602
 *     Anything that this not a valid locking file is deleted.
432
603
 *
433
604
 *-----------------------------------------------------------------------------
434
605
 */
449
620
   int numEntries;
450
621
 
451
622
   Unicode *fileList = NULL;
 
623
   char *myExecutionID = NULL;
 
624
   char *locationChecksum = NULL;
452
625
 
453
626
   ASSERT(lockDir);
454
627
 
455
 
   numEntries = File_ListDirectory(lockDir, &fileList);
 
628
   numEntries = FileListDirectoryRobust(lockDir, &fileList);
456
629
 
457
630
   if (numEntries == -1) {
458
 
      Log(LGPFX" %s: Could not read the directory '%s'.\n",
459
 
          __FUNCTION__, UTF8(lockDir));
 
631
      Log(LGPFX" %s: Could not read the directory '%s': %d\n",
 
632
          __FUNCTION__, UTF8(lockDir), Err_Errno());
460
633
 
461
 
      return EDOM;      // out of my domain
 
634
      return EDOM;  // out of my domain
462
635
   }
463
636
 
464
637
   /* Pass 1: Validate entries and handle any 'D' entries */
486
659
       * this will cleaned-up.
487
660
       */
488
661
 
489
 
      if (Unicode_StartsWith(fileList[i], U("D"))) {
 
662
      if (Unicode_StartsWith(fileList[i], "D")) {
490
663
         if (cleanUp) {
491
664
            err = ActivateLockList(fileList[i], myValues);
492
665
            if (err != 0) {
503
676
      goto bail;
504
677
   }
505
678
 
 
679
   myExecutionID = FileLockGetExecutionID();
 
680
   locationChecksum = FileLockLocationChecksum(lockDir);
 
681
 
506
682
   /* Pass 2: Handle the 'M' entries */
507
683
   for (i = 0, err = 0; i < numEntries; i++) {
508
684
      LockValues *ptr;
511
687
      char       buffer[FILELOCK_DATA_SIZE];
512
688
 
513
689
      if ((fileList[i] == NULL) ||
514
 
          (Unicode_StartsWith(fileList[i], U("E")))) {
 
690
          (Unicode_StartsWith(fileList[i], "E"))) {
515
691
         continue;
516
692
      }
517
693
 
538
714
 
539
715
         /* Remove any stale locking files */
540
716
         if (FileLockMachineIDMatch(myValues->machineID,
541
 
                                    memberValues.machineID) &&
542
 
             !FileLockValidOwner(memberValues.executionID,
543
 
                                 memberValues.payload)) {
544
 
            Log(LGPFX" %s discarding %s from %s'; invalid executionID.\n",
545
 
                __FUNCTION__, UTF8(fileList[i]), UTF8(lockDir));
546
 
 
547
 
            Unicode_Free(memberValues.memberName);
548
 
 
549
 
            err = RemoveLockingFile(lockDir, fileList[i]);
550
 
            if (err != 0) {
551
 
               break;
552
 
            }
553
 
 
554
 
            continue;
 
717
                                    memberValues.machineID)) {
 
718
            char *dispose = NULL;
 
719
 
 
720
            if (FileLockValidOwner(memberValues.executionID,
 
721
                                   memberValues.payload)) {
 
722
               /* If it's mine it better still be where I put it! */
 
723
               if ((strcmp(myExecutionID, memberValues.executionID) == 0) &&
 
724
                   ((memberValues.locationChecksum != NULL) &&
 
725
                    (strcmp(memberValues.locationChecksum,
 
726
                            locationChecksum) != 0))) {
 
727
                  dispose = "lock file has been moved.";
 
728
               }
 
729
            } else {
 
730
               dispose = "invalid executionID.";
 
731
            }
 
732
 
 
733
            if (dispose) {
 
734
               Log(LGPFX" %s discarding %s from %s': %s\n",
 
735
                   __FUNCTION__, UTF8(fileList[i]), UTF8(lockDir), dispose);
 
736
 
 
737
               Unicode_Free(memberValues.memberName);
 
738
 
 
739
               err = RemoveLockingFile(lockDir, fileList[i]);
 
740
               if (err != 0) {
 
741
                  break;
 
742
               }
 
743
 
 
744
               continue;
 
745
            }
555
746
         }
556
747
 
557
748
         ptr = &memberValues;
576
767
   }
577
768
 
578
769
   free(fileList);
 
770
   free(locationChecksum);
 
771
   free(myExecutionID);
579
772
 
580
773
   return err;
581
774
}
586
779
 *
587
780
 * Scanner --
588
781
 *
589
 
 *      Call the specified function for each member file found in the
590
 
 *      specified directory. If a rescan is necessary check the list
591
 
 *      of outstanding locks and handle removing stale locks.
 
782
 *      Call the specified function for each member file found in the
 
783
 *      specified directory. If a rescan is necessary check the list
 
784
 *      of outstanding locks and handle removing stale locks.
592
785
 *
593
786
 * Results:
594
 
 *      0       success
595
 
 *      > 0     failure
 
787
 *     0        success
 
788
 *     > 0      failure
596
789
 *
597
790
 * Side effects:
598
 
 *      None
 
791
 *     None
599
792
 *
600
793
 *-----------------------------------------------------------------------------
601
794
 */
643
836
               Unicode path;
644
837
               UnicodeIndex index;
645
838
 
646
 
               ASSERT(Unicode_StartsWith(ptr->dirName, U("D")));
 
839
               ASSERT(Unicode_StartsWith(ptr->dirName, "D"));
647
840
 
648
841
               Log(LGPFX" %s discarding %s data from '%s'.\n",
649
842
                   __FUNCTION__, UTF8(ptr->dirName), UTF8(lockDir));
650
843
 
651
 
               path = Unicode_Join(lockDir, U(DIRSEPS), ptr->dirName, NULL);
 
844
               path = Unicode_Join(lockDir, DIRSEPS, ptr->dirName, NULL);
652
845
 
653
 
               index = Unicode_FindLast(path, U("D"));
 
846
               index = Unicode_FindLast(path, "D");
654
847
               ASSERT(index != UNICODE_INDEX_NOT_FOUND);
655
848
 
656
 
               temp = Unicode_Replace(path, index, 1, U("M"));
657
 
               FileDeletion(temp, FALSE);
658
 
               Unicode_Free(temp);
659
 
 
660
 
               temp = Unicode_Replace(path, index, 1, U("E"));
661
 
               FileDeletion(temp, FALSE);
662
 
               Unicode_Free(temp);
663
 
 
664
 
               FileRemoveDirectory(path);
 
849
               temp = Unicode_Replace(path, index, 1, "M");
 
850
               FileDeletionRobust(temp, FALSE);
 
851
               Unicode_Free(temp);
 
852
 
 
853
               temp = Unicode_Replace(path, index, 1, "E");
 
854
               FileDeletionRobust(temp, FALSE);
 
855
               Unicode_Free(temp);
 
856
 
 
857
               FileRemoveDirectoryRobust(path);
665
858
 
666
859
               Unicode_Free(path);
667
860
 
710
903
 *
711
904
 * FileUnlockIntrinsic --
712
905
 *
713
 
 *      Release a lock on a file.
714
 
 *
715
 
 *      The locker is required to identify themselves in a "universally
716
 
 *      unique" manner. This is done via two parameters:
717
 
 *
718
 
 *      machineID --
719
 
 *              This a machine/hardware identifier string.
720
 
 *
721
 
 *              The MAC address of a hardware Ethernet, a WWN of a
722
 
 *              hardware FibreChannel HBA, the UUID of an Infiniband HBA
723
 
 *              and a machine serial number (e.g. Macs) are all good
724
 
 *              candidates for a machine identifier.
725
 
 *
726
 
 *      executionID --
727
 
 *              This is an string which differentiates one thread of
728
 
 *              execution from another within the host OS. In a
729
 
 *              non-threaded environment this can simply be some form
730
 
 *              of process identifier (e.g. getpid() on UNIXen or
731
 
 *              _getpid() on Windows). When a process makes use of
732
 
 *              threads AND more than one thread may perform locking
733
 
 *              this identifier must discriminate between all threads
734
 
 *              within the process.
735
 
 *
736
 
 *      All of the ID strings must encode their respective information
737
 
 *      such that any OS may utilize the strings as part of a file name.
738
 
 *      Keep them short and, at a minimum, do not use ':', '/', '\', '.'
739
 
 *      and white space characters.
 
906
 *      Release a lock on a file.
740
907
 *
741
908
 * Results:
742
 
 *      0       unlocked
743
 
 *      > 0     errno
 
909
 *      0       unlocked
 
910
 *      > 0     errno
744
911
 *
745
912
 * Side effects:
746
 
 *      None.
 
913
 *      None.
747
914
 *
748
915
 *-----------------------------------------------------------------------------
749
916
 */
750
917
 
751
918
int
752
 
FileUnlockIntrinsic(const char *machineID,    // IN:
753
 
                    const char *executionID,  // IN:
754
 
                    ConstUnicode pathName,    // IN:
755
 
                    const void *lockToken)    // IN:
 
919
FileUnlockIntrinsic(ConstUnicode pathName,  // IN:
 
920
                    const void *lockToken)  // IN:
756
921
{
757
922
   int err;
758
923
 
759
 
   ASSERT(machineID);
760
 
   ASSERT(executionID);
761
924
   ASSERT(pathName);
762
925
   ASSERT(lockToken);
763
926
 
764
 
   LOG(1, ("Releasing lock on %s (%s, %s).\n", UTF8(pathName),
765
 
       machineID, executionID));
 
927
   LOG(1, ("Requesting unlock on %s\n", UTF8(pathName)));
766
928
 
767
929
   if (lockToken == &implicitReadToken) {
768
930
      /*
772
934
 
773
935
      err = 0;
774
936
   } else {
775
 
      Unicode dirPath;
 
937
      Unicode lockDir;
776
938
 
777
939
      /* The lock directory path */
778
 
      dirPath = Unicode_Append(pathName, U(FILELOCK_SUFFIX));
 
940
      lockDir = Unicode_Append(pathName, FILELOCK_SUFFIX);
779
941
 
780
942
      /*
781
943
       * The lock token is the (unicode) path of the lock file.
784
946
       *       matching the machineID and executionID.
785
947
       */
786
948
 
787
 
      err = FileDeletion((Unicode) lockToken, FALSE);
 
949
      err = FileDeletionRobust((Unicode) lockToken, FALSE);
788
950
 
789
951
      if (err && vmx86_debug) {
790
952
         Log(LGPFX" %s failed for '%s': %s\n",
798
960
 
799
961
      Unicode_Free((Unicode) lockToken);
800
962
 
801
 
      FileRemoveDirectory(dirPath); // just in case we can clean up
 
963
      FileRemoveDirectoryRobust(lockDir); // just in case we can clean up
802
964
 
803
 
      Unicode_Free(dirPath);
 
965
      Unicode_Free(lockDir);
804
966
   }
805
967
 
806
968
   return err;
812
974
 *
813
975
 * WaitForPossession --
814
976
 *
815
 
 *      Wait until the caller has a higher priority towards taking
816
 
 *      possession of a lock than the specified file.
 
977
 *      Wait until the caller has a higher priority towards taking
 
978
 *      possession of a lock than the specified file.
817
979
 *
818
980
 * Results:
819
 
 *      0       success
820
 
 *      > 0     error (errno)
 
981
 *     0        success
 
982
 *     > 0      error (errno)
821
983
 *
822
984
 * Side effects:
823
 
 *      None.
 
985
 *     None.
824
986
 *
825
987
 *-----------------------------------------------------------------------------
826
988
 */
852
1014
 
853
1015
      loopCount = 0;
854
1016
 
855
 
      path = Unicode_Join(lockDir, U(DIRSEPS), fileName, NULL);
 
1017
      path = Unicode_Join(lockDir, DIRSEPS, fileName, NULL);
856
1018
 
857
1019
      while ((err = Sleeper(myValues, &loopCount)) == 0) {
858
1020
         /* still there? */
859
 
         err = FileAttributes(path, NULL);
 
1021
         err = FileAttributesRobust(path, NULL);
860
1022
         if (err != 0) {
861
1023
            if (err == ENOENT) {
862
1024
               /* Not there anymore; locker unlocked or timed out */
906
1068
 *
907
1069
 * NumberScan --
908
1070
 *
909
 
 *      Determine the maxmimum number value within the current locking set.
 
1071
 *      Determine the maxmimum number value within the current locking set.
910
1072
 *
911
1073
 * Results:
912
 
 *      0       success
913
 
 *      > 0     failure (errno)
 
1074
 *     0        success
 
1075
 *     > 0      failure (errno)
914
1076
 *
915
1077
 * Side effects:
916
 
 *      None.
 
1078
 *     None.
917
1079
 *
918
1080
 *-----------------------------------------------------------------------------
919
1081
 */
940
1102
 *
941
1103
 * SimpleRandomNumber --
942
1104
 *
943
 
 *      Return a random number in the range of 0 and 2^16-1.
 
1105
 *      Return a random number in the range of 0 and 2^16-1.
944
1106
 *
945
1107
 * Results:
946
 
 *      Random number is returned.
 
1108
 *      Random number is returned.
947
1109
 *
948
1110
 * Side Effects:
949
 
 *      None.
 
1111
 *      None.
950
1112
 *
951
1113
 *-----------------------------------------------------------------------------
952
1114
 */
996
1158
 *
997
1159
 * MakeDirectory --
998
1160
 *
999
 
 *      Create a directory.
 
1161
 *      Create a directory.
1000
1162
 *
1001
1163
 * Results:
1002
 
 *      0       success
1003
 
 *      > 0     failure (errno)
 
1164
 *      0       success
 
1165
 *      > 0     failure (errno)
1004
1166
 *
1005
1167
 * Side Effects:
1006
1168
 *      File system may be modified.
1009
1171
 */
1010
1172
 
1011
1173
static int
1012
 
MakeDirectory(ConstUnicode pathName)
 
1174
MakeDirectory(ConstUnicode pathName)  // IN:
1013
1175
{
1014
1176
   int err;
1015
1177
 
1021
1183
 
1022
1184
   ASSERT(pathName);
1023
1185
 
1024
 
   err = FileCreateDirectory(pathName);
 
1186
   err = FileCreateDirectoryRobust(pathName);
1025
1187
 
1026
1188
#if !defined(_WIN32)
1027
1189
   umask(save);
1036
1198
 *
1037
1199
 * CreateEntryDirectory --
1038
1200
 *
1039
 
 *      Create an entry directory in the specified locking directory.
 
1201
 *      Create an entry directory in the specified locking directory.
1040
1202
 *
1041
 
 *      Due to FileLock_UnlockFile() attempting to remove the locking
1042
 
 *      directory on an unlock operation (to "clean up" and remove the
1043
 
 *      locking directory when it is no longer needed), this routine
1044
 
 *      must carefully handle a number of race conditions to insure the
1045
 
 *      the locking directory exists and the entry directory is created
1046
 
 *      within.
 
1203
 *      Due to FileLock_UnlockFile() attempting to remove the locking
 
1204
 *      directory on an unlock operation (to "clean up" and remove the
 
1205
 *      locking directory when it is no longer needed), this routine
 
1206
 *      must carefully handle a number of race conditions to insure the
 
1207
 *      the locking directory exists and the entry directory is created
 
1208
 *      within.
1047
1209
 *
1048
1210
 * Results:
1049
 
 *      0       success
1050
 
 *      > 0     failure (errno)
 
1211
 *      0       success
 
1212
 *      > 0     failure (errno)
1051
1213
 *
1052
1214
 * Side Effects:
1053
 
 *      On success returns the number identifying the entry directory and
1054
 
 *      the entry directory path name.
 
1215
 *      On success returns the number identifying the entry directory and
 
1216
 *      the entry directory path name.
1055
1217
 *
1056
1218
 *-----------------------------------------------------------------------------
1057
1219
 */
1081
1243
      Unicode temp;
1082
1244
      FileData fileData;
1083
1245
 
1084
 
      err = FileAttributes(lockDir, &fileData);
 
1246
      err = FileAttributesRobust(lockDir, &fileData);
1085
1247
      if (err == 0) {
1086
1248
        /* The name exists. Deal with it... */
1087
1249
 
1101
1263
 
1102
1264
        if (fileData.fileType != FILE_TYPE_DIRECTORY) {
1103
1265
           /* Not a directory; attempt to remove the debris */
1104
 
           if (FileDeletion(lockDir, FALSE) != 0) {
 
1266
           if (FileDeletionRobust(lockDir, FALSE) != 0) {
1105
1267
              Warning(LGPFX" %s: '%s' exists and is not a directory.\n",
1106
1268
                      __FUNCTION__, UTF8(lockDir));
1107
1269
 
1136
1298
      *memberName = Unicode_Format("M%05u%s", randomNumber, FILELOCK_SUFFIX);
1137
1299
 
1138
1300
      temp = Unicode_Format("D%05u%s", randomNumber, FILELOCK_SUFFIX);
1139
 
      *entryDirectory = Unicode_Join(lockDir, U(DIRSEPS), temp, NULL);
 
1301
      *entryDirectory = Unicode_Join(lockDir, DIRSEPS, temp, NULL);
1140
1302
      Unicode_Free(temp);
1141
1303
 
1142
1304
      temp = Unicode_Format("E%05u%s", randomNumber, FILELOCK_SUFFIX);
1143
 
      *entryFilePath = Unicode_Join(lockDir, U(DIRSEPS), temp, NULL);
 
1305
      *entryFilePath = Unicode_Join(lockDir, DIRSEPS, temp, NULL);
1144
1306
      Unicode_Free(temp);
1145
1307
 
1146
 
      *memberFilePath = Unicode_Join(lockDir, U(DIRSEPS), *memberName, NULL);
 
1308
      *memberFilePath = Unicode_Join(lockDir, DIRSEPS, *memberName, NULL);
1147
1309
 
1148
1310
      err = MakeDirectory(*entryDirectory);
1149
1311
 
1158
1320
          * good member files.
1159
1321
          */
1160
1322
 
1161
 
         err = FileAttributes(*memberFilePath, NULL);
 
1323
         err = FileAttributesRobust(*memberFilePath, NULL);
1162
1324
 
1163
1325
         if (err != 0) {
1164
1326
            if (err == ENOENT) {
1172
1334
             }
1173
1335
         }
1174
1336
 
1175
 
         FileRemoveDirectory(*entryDirectory);
 
1337
         FileRemoveDirectoryRobust(*entryDirectory);
1176
1338
      } else {
1177
1339
          if (err != EEXIST) {
1178
1340
             Warning(LGPFX" %s creation failure on '%s': %s\n",
1213
1375
 *
1214
1376
 * CreateMemberFile --
1215
1377
 *
1216
 
 *      Create the member file.
 
1378
 *      Create the member file.
1217
1379
 *
1218
1380
 * Results:
1219
 
 *      0       success
1220
 
 *      > 0     failure (errno)
 
1381
 *     0        success
 
1382
 *     > 0      failure (errno)
1221
1383
 *
1222
1384
 * Side Effects:
1223
 
 *      None
 
1385
 *     None
1224
1386
 *
1225
1387
 *-----------------------------------------------------------------------------
1226
1388
 */
1238
1400
   ASSERT(entryFilePath);
1239
1401
   ASSERT(memberFilePath);
1240
1402
 
1241
 
   /* Populate the buffer with appropriate data */
1242
 
   Str_Sprintf(buffer, sizeof buffer, "%s %s %u %s %s", myValues->machineID,
1243
 
               myValues->executionID, myValues->lamportNumber,
 
1403
   /*
 
1404
    * Populate the buffer with appropriate data
 
1405
    *
 
1406
    * Lock file arguments are space separated. There is a minimum of 4
 
1407
    * arguments - machineID, executionID, Lamport number and lock type.
 
1408
    * The maximum number of argument is FL_MAX_ARGS.
 
1409
    *
 
1410
    * The fifth argument, if present, is the payload or "[" if there is no
 
1411
    * payload and additional arguments are present. The additional arguments
 
1412
    * form  a properly list - one or more "name=value" pairs.
 
1413
    */
 
1414
 
 
1415
   Str_Sprintf(buffer, sizeof buffer, "%s %s %u %s %s lc=%s",
 
1416
               myValues->machineID,
 
1417
               myValues->executionID,
 
1418
               myValues->lamportNumber,
1244
1419
               myValues->lockType,
1245
 
               myValues->payload == NULL ? "" : myValues->payload);
 
1420
               myValues->payload == NULL ? "[" : myValues->payload,
 
1421
               myValues->locationChecksum);
1246
1422
 
1247
1423
   /* Attempt to write the data */
1248
1424
   err = FileLockWriteFile(entryHandle, buffer, sizeof buffer, &len);
1282
1458
      if (vmx86_debug) {
1283
1459
         Log(LGPFX" %s FileLockFileType() of '%s': %s\n",
1284
1460
             __FUNCTION__, UTF8(entryFilePath),
1285
 
            strerror(FileAttributes(entryFilePath, NULL)));
 
1461
            strerror(FileAttributesRobust(entryFilePath, NULL)));
1286
1462
 
1287
1463
         Log(LGPFX" %s FileLockFileType() of '%s': %s\n",
1288
1464
             __FUNCTION__, UTF8(memberFilePath),
1289
 
            strerror(FileAttributes(memberFilePath, NULL)));
 
1465
            strerror(FileAttributesRobust(memberFilePath, NULL)));
1290
1466
      }
1291
1467
 
1292
1468
      return err;
1300
1476
 *
1301
1477
 * FileLockIntrinsic --
1302
1478
 *
1303
 
 *      Obtain a lock on a file; shared or exclusive access.
1304
 
 *
1305
 
 *      Each locker is required to identify themselves in a "universally
1306
 
 *      unique" manner. This is done via two parameters:
1307
 
 *
1308
 
 *      machineID --
1309
 
 *              This a machine/hardware identifier string.
1310
 
 *
1311
 
 *              The MAC address of a hardware Ethernet, a WWN of a
1312
 
 *              hardware FibreChannel HBA, the UUID of an Infiniband HBA
1313
 
 *              and a machine serial number (e.g. Macs) are all good
1314
 
 *              candidates for a machine identifier.
1315
 
 *
1316
 
 *              The machineID is "univerally unique", discriminating
1317
 
 *              between all computational platforms.
1318
 
 *
1319
 
 *      executionID --
1320
 
 *              This is an string which differentiates one thread of
1321
 
 *              execution from another within the host OS. In a
1322
 
 *              non-threaded environment this can simply be some form
1323
 
 *              of process identifier (e.g. getpid() on UNIXen or
1324
 
 *              _getpid() on Windows). When a process makes use of
1325
 
 *              threads AND more than one thread may perform locking
1326
 
 *              this identifier must discriminate between all threads
1327
 
 *              within the process.
1328
 
 *
1329
 
 *      All of the ID strings must encode their respective information
1330
 
 *      such that any OS may utilize the strings as part of a file name.
1331
 
 *      Keep them short and, at a minimum, do not use ':', '/', '\', '.'
1332
 
 *      and white space characters.
1333
 
 *
1334
 
 *      msecMaxWaitTime specifies the maximum amount of time, in
1335
 
 *      milliseconds, to wait for the lock before returning the "not
1336
 
 *      acquired" status. A value of FILELOCK_TRYLOCK_WAIT is the
1337
 
 *      equivalent of a "try lock" - the lock will be acquired only if
1338
 
 *      there is no contention. A value of FILELOCK_INFINITE_WAIT
1339
 
 *      specifies "waiting forever" to acquire the lock.
 
1479
 *      Obtain a lock on a file; shared or exclusive access.
 
1480
 *
 
1481
 *      msecMaxWaitTime specifies the maximum amount of time, in
 
1482
 *      milliseconds, to wait for the lock before returning the "not
 
1483
 *      acquired" status. A value of FILELOCK_TRYLOCK_WAIT is the
 
1484
 *      equivalent of a "try lock" - the lock will be acquired only if
 
1485
 *      there is no contention. A value of FILELOCK_INFINITE_WAIT
 
1486
 *      specifies "waiting forever" to acquire the lock.
1340
1487
 *
1341
1488
 * Results:
1342
 
 *      NULL    Lock not acquired. Check err.
1343
 
 *              err     0       Lock Timed Out
1344
 
 *              err     > 0     errno
1345
 
 *      !NULL   Lock Acquired. This is the "lockToken" for an unlock.
 
1489
 *      NULL    Lock not acquired. Check err.
 
1490
 *              err     0       Lock Timed Out
 
1491
 *              err     > 0     errno
 
1492
 *      !NULL   Lock Acquired. This is the "lockToken" for an unlock.
1346
1493
 *
1347
1494
 * Side effects:
1348
 
 *      None.
 
1495
 *      None.
1349
1496
 *
1350
1497
 *-----------------------------------------------------------------------------
1351
1498
 */
1352
1499
 
1353
1500
void *
1354
 
FileLockIntrinsic(const char *machineID,    // IN:
1355
 
                  const char *executionID,  // IN:
1356
 
                  const char *payload,      // IN:
1357
 
                  ConstUnicode pathName,    // IN:
1358
 
                  Bool exclusivity,         // IN:
1359
 
                  uint32 msecMaxWaitTime,   // IN:
1360
 
                  int *err)                 // OUT:
 
1501
FileLockIntrinsic(ConstUnicode pathName,   // IN:
 
1502
                  Bool exclusivity,        // IN:
 
1503
                  uint32 msecMaxWaitTime,  // IN:
 
1504
                  const char *payload,     // IN:
 
1505
                  int *err)                // OUT:
1361
1506
{
1362
1507
   FILELOCK_FILE_HANDLE handle;
1363
1508
   LockValues myValues;
1364
1509
 
1365
 
   Unicode dirPath = NULL;
 
1510
   Unicode lockDir = NULL;
1366
1511
   Unicode entryFilePath = NULL;
1367
1512
   Unicode memberFilePath = NULL;
1368
1513
   Unicode entryDirectory = NULL;
1369
1514
 
1370
 
   ASSERT(machineID);
1371
 
   ASSERT(executionID);
1372
1515
   ASSERT(pathName);
1373
1516
   ASSERT(err);
1374
1517
 
 
1518
   /* Construct the locking directory path */
 
1519
   lockDir = Unicode_Append(pathName, FILELOCK_SUFFIX);
 
1520
 
1375
1521
   /* establish our values */
1376
 
   myValues.machineID = (char *) machineID;
1377
 
   myValues.executionID = (char *) executionID;
 
1522
 
 
1523
   myValues.machineID = (char *) FileLockGetMachineID(); // don't free this!
 
1524
   myValues.executionID = FileLockGetExecutionID();      // free this!
1378
1525
   myValues.payload = (char *) payload;
1379
1526
   myValues.lockType = exclusivity ? LOCK_EXCLUSIVE : LOCK_SHARED;
1380
1527
   myValues.lamportNumber = 0;
 
1528
   myValues.locationChecksum = FileLockLocationChecksum(lockDir); // free this!
1381
1529
   myValues.waitTime = 0;
1382
1530
   myValues.msecMaxWaitTime = msecMaxWaitTime;
1383
1531
   myValues.memberName = NULL;
1386
1534
       myValues.lockType, UTF8(pathName), myValues.machineID,
1387
1535
       myValues.executionID, myValues.msecMaxWaitTime));
1388
1536
 
1389
 
   /* Construct the locking directory path */
1390
 
   dirPath = Unicode_Append(pathName, U(FILELOCK_SUFFIX));
1391
 
 
1392
1537
   /*
1393
1538
    * Attempt to create the locking and entry directories; obtain the
1394
1539
    * entry and member path names.
1395
1540
    */
1396
1541
 
1397
 
   *err = CreateEntryDirectory(machineID, executionID, dirPath,
 
1542
   *err = CreateEntryDirectory(myValues.machineID, myValues.executionID,
 
1543
                               lockDir,
1398
1544
                               &entryDirectory, &entryFilePath,
1399
1545
                               &memberFilePath, &myValues.memberName);
1400
1546
 
1432
1578
 
1433
1579
   if (*err != 0) {
1434
1580
      /* clean up */
1435
 
      FileRemoveDirectory(entryDirectory);
1436
 
      FileRemoveDirectory(dirPath);
 
1581
      FileRemoveDirectoryRobust(entryDirectory);
 
1582
      FileRemoveDirectoryRobust(lockDir);
1437
1583
 
1438
1584
      goto bail;
1439
1585
   }
1440
1586
 
1441
1587
   /* what is max(Number[1]... Number[all lockers])? */
1442
 
   *err = Scanner(dirPath, NumberScan, &myValues, FALSE);
 
1588
   *err = Scanner(lockDir, NumberScan, &myValues, FALSE);
1443
1589
 
1444
1590
   if (*err != 0) {
1445
1591
      /* clean up */
1446
1592
      FileLockCloseFile(handle);
1447
 
      FileDeletion(entryFilePath, FALSE);
1448
 
      FileRemoveDirectory(entryDirectory);
1449
 
      FileRemoveDirectory(dirPath);
 
1593
      FileDeletionRobust(entryFilePath, FALSE);
 
1594
      FileRemoveDirectoryRobust(entryDirectory);
 
1595
      FileRemoveDirectoryRobust(lockDir);
1450
1596
 
1451
1597
      goto bail;
1452
1598
   }
1458
1604
   *err = CreateMemberFile(handle, &myValues, entryFilePath, memberFilePath);
1459
1605
 
1460
1606
   /* Remove entry directory; it has done its job */
1461
 
   FileRemoveDirectory(entryDirectory);
 
1607
   FileRemoveDirectoryRobust(entryDirectory);
1462
1608
 
1463
1609
   if (*err != 0) {
1464
1610
      /* clean up */
1465
 
      FileDeletion(entryFilePath, FALSE);
1466
 
      FileDeletion(memberFilePath, FALSE);
1467
 
      FileRemoveDirectory(dirPath);
 
1611
      FileDeletionRobust(entryFilePath, FALSE);
 
1612
      FileDeletionRobust(memberFilePath, FALSE);
 
1613
      FileRemoveDirectoryRobust(lockDir);
1468
1614
 
1469
1615
      goto bail;
1470
1616
   }
1471
1617
 
1472
1618
   /* Attempt to acquire the lock */
1473
 
   *err = Scanner(dirPath, WaitForPossession, &myValues, TRUE);
 
1619
   *err = Scanner(lockDir, WaitForPossession, &myValues, TRUE);
1474
1620
 
1475
1621
   switch (*err) {
1476
1622
   case 0:
1478
1624
 
1479
1625
   case EAGAIN:
1480
1626
      /* clean up */
1481
 
      FileDeletion(memberFilePath, FALSE);
1482
 
      FileRemoveDirectory(dirPath);
 
1627
      FileDeletionRobust(memberFilePath, FALSE);
 
1628
      FileRemoveDirectoryRobust(lockDir);
1483
1629
 
1484
1630
      /* FALL THROUGH */
1485
1631
   default:
1488
1634
 
1489
1635
bail:
1490
1636
 
1491
 
   Unicode_Free(dirPath);
 
1637
   Unicode_Free(lockDir);
1492
1638
   Unicode_Free(entryDirectory);
1493
1639
   Unicode_Free(entryFilePath);
1494
1640
   Unicode_Free(myValues.memberName);
 
1641
   free(myValues.locationChecksum);
 
1642
   free(myValues.executionID);
1495
1643
 
1496
1644
   if (*err != 0) {
1497
1645
      Unicode_Free(memberFilePath);
1511
1659
 *
1512
1660
 * ScannerVMX --
1513
1661
 *
1514
 
 *      VMX hack scanner
 
1662
 *      VMX hack scanner
1515
1663
 *
1516
1664
 * Results:
1517
 
 *      0       success
1518
 
 *      > 0     error (errno)
 
1665
 *      0       success
 
1666
 *      > 0     error (errno)
1519
1667
 *
1520
1668
 * Side effects:
1521
 
 *      None.
 
1669
 *      None.
1522
1670
 *
1523
1671
 *-----------------------------------------------------------------------------
1524
1672
 */
1543
1691
 *
1544
1692
 * FileLockHackVMX --
1545
1693
 *
1546
 
 *      The VMX file delete primitive.
 
1694
 *      The VMX file delete primitive.
1547
1695
 *
1548
1696
 * Results:
1549
 
 *      0       unlocked
1550
 
 *      > 0     errno
 
1697
 *      0       unlocked
 
1698
 *      > 0     errno
1551
1699
 *
1552
1700
 * Side effects:
1553
1701
 *      Changes the host file system.
1554
1702
 *
1555
1703
 * Note:
1556
 
 *      THIS IS A HORRIBLE HACK AND NEEDS TO BE REMOVED ASAP!!!
 
1704
 *      THIS IS A HORRIBLE HACK AND NEEDS TO BE REMOVED ASAP!!!
1557
1705
 *
1558
1706
 *----------------------------------------------------------------------
1559
1707
 */
1560
1708
 
1561
1709
int
1562
 
FileLockHackVMX(const char *machineID,    // IN:
1563
 
                const char *executionID,  // IN:
1564
 
                ConstUnicode pathName)    // IN:
 
1710
FileLockHackVMX(ConstUnicode pathName)  // IN:
1565
1711
{
1566
 
   int        err;
 
1712
   int err;
1567
1713
   LockValues myValues;
1568
1714
 
1569
 
   Unicode dirPath = NULL;
 
1715
   Unicode lockDir = NULL;
1570
1716
   Unicode entryFilePath = NULL;
1571
1717
   Unicode memberFilePath = NULL;
1572
1718
   Unicode entryDirectory = NULL;
1573
1719
 
1574
1720
   ASSERT(pathName);
1575
1721
 
 
1722
   /* first the locking directory path name */
 
1723
   lockDir = Unicode_Append(pathName, FILELOCK_SUFFIX);
 
1724
 
 
1725
   /* establish our values */
 
1726
   myValues.machineID = (char *) FileLockGetMachineID(); // don't free this!
 
1727
   myValues.executionID = FileLockGetExecutionID();      // free this!
 
1728
   myValues.locationChecksum = FileLockLocationChecksum(lockDir); // free this!
 
1729
   myValues.lamportNumber = 0;
 
1730
   myValues.memberName = NULL;
 
1731
 
1576
1732
   LOG(1, ("%s on %s (%s, %s).\n", __FUNCTION__, UTF8(pathName),
1577
 
       machineID, executionID));
1578
 
 
1579
 
   /* establish our values */
1580
 
   myValues.machineID = (char *) machineID;
1581
 
   myValues.executionID = (char *) executionID;
1582
 
   myValues.lamportNumber = 0;
1583
 
   myValues.memberName = NULL;
1584
 
 
1585
 
   /* first the locking directory path name */
1586
 
   dirPath = Unicode_Append(pathName, U(FILELOCK_SUFFIX));
1587
 
 
1588
 
   err = CreateEntryDirectory(machineID, executionID, dirPath,
 
1733
       myValues.machineID, myValues.executionID));
 
1734
 
 
1735
   err = CreateEntryDirectory(myValues.machineID, myValues.executionID,
 
1736
                              lockDir,
1589
1737
                              &entryDirectory, &entryFilePath,
1590
1738
                              &memberFilePath, &myValues.memberName);
1591
1739
 
1594
1742
   }
1595
1743
 
1596
1744
   /* Scan the lock directory */
1597
 
   err = Scanner(dirPath, ScannerVMX, &myValues, FALSE);
 
1745
   err = Scanner(lockDir, ScannerVMX, &myValues, FALSE);
1598
1746
 
1599
1747
   if (err == 0) {
1600
1748
      /* if no members are valid, clean up */
1601
1749
      if (myValues.lamportNumber == 1) {
1602
 
         FileDeletion(pathName, FALSE);
 
1750
         FileDeletionRobust(pathName, FALSE);
1603
1751
      }
1604
1752
   } else {
1605
1753
      if (vmx86_debug) {
1609
1757
   }
1610
1758
 
1611
1759
   /* clean up */
1612
 
   FileRemoveDirectory(entryDirectory);
1613
 
   FileRemoveDirectory(dirPath);
 
1760
   FileRemoveDirectoryRobust(entryDirectory);
 
1761
   FileRemoveDirectoryRobust(lockDir);
1614
1762
 
1615
1763
bail:
1616
1764
 
1617
 
   Unicode_Free(dirPath);
 
1765
   Unicode_Free(lockDir);
1618
1766
   Unicode_Free(entryDirectory);
1619
1767
   Unicode_Free(entryFilePath);
1620
1768
   Unicode_Free(memberFilePath);
1621
1769
   Unicode_Free(myValues.memberName);
 
1770
   free(myValues.locationChecksum);
 
1771
   free(myValues.executionID);
1622
1772
 
1623
1773
   return err;
1624
1774
}