11 extern void afsi_log(char *pattern, ...);
12 extern DWORD cm_ValidateCache;
14 static HANDLE hMemoryMappedFile = NULL;
15 static HANDLE hCacheHeap = NULL;
18 GranularityAdjustment(afs_uint64 size)
21 static afs_uint64 qwGranularity = 0;
23 if ( !qwGranularity ) {
24 GetSystemInfo(&sysInfo);
25 afsi_log("Granularity - %lX", sysInfo.dwAllocationGranularity);
26 qwGranularity = sysInfo.dwAllocationGranularity;
29 size = (size + (qwGranularity - 1)) & ~(qwGranularity - 1);
34 ComputeSizeOfConfigData(void)
37 size = sizeof(cm_config_data_t);
42 ComputeSizeOfVolumes(DWORD maxvols)
45 size = maxvols * sizeof(cm_volume_t);
50 ComputeSizeOfCellHT(DWORD maxcells)
53 size = cm_NextHighestPowerOf2((afs_uint32)(maxcells/7)) * sizeof(cm_cell_t *);
58 ComputeSizeOfVolumeHT(DWORD maxvols)
61 size = cm_NextHighestPowerOf2((afs_uint32)(maxvols/7)) * sizeof(cm_volume_t *);
66 ComputeSizeOfCells(DWORD maxcells)
69 size = maxcells * sizeof(cm_cell_t);
74 ComputeSizeOfACLCache(DWORD stats)
77 size = 2 * (stats + 10) * sizeof(cm_aclent_t);
82 ComputeSizeOfSCache(DWORD stats)
85 size = (stats + 10) * sizeof(cm_scache_t);
90 ComputeSizeOfSCacheHT(DWORD stats)
93 size = cm_NextHighestPowerOf2(stats / 2 ) * sizeof(cm_scache_t *);;
98 ComputeSizeOfDNLCache(void)
101 size = NHSIZE * sizeof(cm_nc_t *) + NCSIZE * sizeof(cm_nc_t);
106 ComputeSizeOfDataBuffers(afs_uint64 cacheBlocks, DWORD blockSize)
109 size = cacheBlocks * blockSize;
114 ComputeSizeOfDataHT(afs_uint64 cacheBlocks)
117 size = cm_NextHighestPowerOf2((afs_uint32)(cacheBlocks/7)) * sizeof(cm_buf_t *);
122 ComputeSizeOfDataHeaders(afs_uint64 cacheBlocks)
125 size = cacheBlocks * sizeof(cm_buf_t);
130 ComputeSizeOfMappingFile(DWORD stats, DWORD maxVols, DWORD maxCells, DWORD chunkSize, afs_uint64 cacheBlocks, DWORD blockSize)
134 size = ComputeSizeOfConfigData()
135 + ComputeSizeOfVolumes(maxVols)
136 + 4 * ComputeSizeOfVolumeHT(maxVols)
137 + ComputeSizeOfCells(maxCells)
138 + 2 * ComputeSizeOfCellHT(maxCells)
139 + ComputeSizeOfACLCache(stats)
140 + ComputeSizeOfSCache(stats)
141 + ComputeSizeOfSCacheHT(stats)
142 + ComputeSizeOfDNLCache()
143 + ComputeSizeOfDataBuffers(cacheBlocks, blockSize)
144 + 2 * ComputeSizeOfDataHT(cacheBlocks)
145 + ComputeSizeOfDataHeaders(cacheBlocks);
149 /* Create a security attribute structure suitable for use when the cache file
150 * is created. What we mainly want is that only the administrator should be
151 * able to do anything with the file. We create an ACL with only one entry,
152 * an entry that grants all rights to the administrator.
154 PSECURITY_ATTRIBUTES CreateCacheFileSA()
156 PSECURITY_ATTRIBUTES psa;
157 PSECURITY_DESCRIPTOR psd;
158 SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
160 DWORD AdminSIDlength;
164 /* Get Administrator SID */
165 AllocateAndInitializeSid(&authority, 2,
166 SECURITY_BUILTIN_DOMAIN_RID,
167 DOMAIN_ALIAS_RID_ADMINS,
171 /* Create Administrator-only ACL */
172 AdminSIDlength = GetLengthSid(AdminSID);
173 ACLlength = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE)
174 + AdminSIDlength - sizeof(DWORD);
175 AdminOnlyACL = GlobalAlloc(GMEM_FIXED, ACLlength);
176 InitializeAcl(AdminOnlyACL, ACLlength, ACL_REVISION);
177 AddAccessAllowedAce(AdminOnlyACL, ACL_REVISION,
178 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
181 /* Create security descriptor */
182 psd = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_DESCRIPTOR));
183 InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION);
184 SetSecurityDescriptorDacl(psd, TRUE, AdminOnlyACL, FALSE);
186 /* Create security attributes structure */
187 psa = GlobalAlloc(GMEM_FIXED, sizeof(SECURITY_ATTRIBUTES));
188 psa->nLength = sizeof(SECURITY_ATTRIBUTES);
189 psa->lpSecurityDescriptor = psd;
190 psa->bInheritHandle = FALSE;
196 /* Free a security attribute structure created by CreateCacheFileSA() */
197 VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa)
202 GetSecurityDescriptorDacl(psa->lpSecurityDescriptor, &b1, &pAcl, &b2);
204 GlobalFree(psa->lpSecurityDescriptor);
209 cm_IsCacheValid(void)
213 afsi_log("Validating Cache Contents");
215 if (cm_ValidateACLCache()) {
216 afsi_log("ACL Cache validation failure");
218 } else if (cm_ValidateDCache()) {
219 afsi_log("Data Cache validation failure");
221 } else if (cm_ValidateVolume()) {
222 afsi_log("Volume validation failure");
224 } else if (cm_ValidateCell()) {
225 afsi_log("Cell validation failure");
227 } else if (cm_ValidateSCache()) {
228 afsi_log("Stat Cache validation failure");
236 cm_ShutdownMappedMemory(void)
238 cm_config_data_t * config_data_p = (cm_config_data_t *)cm_data.baseAddress;
241 afsi_log("Closing AFS Cache:");
242 afsi_log(" Base Address = %p", config_data_p);
243 afsi_log(" stats = %u", cm_data.stats);
244 afsi_log(" chunkSize = %u", cm_data.chunkSize);
245 afsi_log(" blockSize = %u", cm_data.blockSize);
246 afsi_log(" bufferSize = %I64u", cm_data.bufferSize);
247 afsi_log(" cacheType = %u", cm_data.cacheType);
248 afsi_log(" volumeHashTableSize = %u", cm_data.volumeHashTableSize);
249 afsi_log(" currentVolumes = %u", cm_data.currentVolumes);
250 afsi_log(" maxVolumes = %u", cm_data.maxVolumes);
251 afsi_log(" cellHashTableSize = %u", cm_data.cellHashTableSize);
252 afsi_log(" currentCells = %u", cm_data.currentCells);
253 afsi_log(" maxCells = %u", cm_data.maxCells);
254 afsi_log(" scacheHashTableSize = %u", cm_data.scacheHashTableSize);
255 afsi_log(" currentSCaches = %u", cm_data.currentSCaches);
256 afsi_log(" maxSCaches = %u", cm_data.maxSCaches);
260 cm_ShutdownACLCache();
265 HeapFree(hCacheHeap, 0, cm_data.baseAddress);
266 HeapDestroy(hCacheHeap);
267 afsi_log("Memory Heap has been destroyed");
269 if (cm_ValidateCache == 2)
270 dirty = !cm_IsCacheValid();
272 *config_data_p = cm_data;
273 config_data_p->dirty = dirty;
274 UnmapViewOfFile(config_data_p);
275 CloseHandle(hMemoryMappedFile);
276 hMemoryMappedFile = NULL;
277 afsi_log("Memory Mapped File has been closed");
283 cm_ValidateMappedMemory(char * cachePath)
285 HANDLE hf = INVALID_HANDLE_VALUE, hm;
286 PSECURITY_ATTRIBUTES psa;
287 BY_HANDLE_FILE_INFORMATION fileInfo;
289 afs_uint64 mappingSize;
290 char * baseAddress = NULL;
291 cm_config_data_t * config_data_p;
293 psa = CreateCacheFileSA();
294 hf = CreateFile( cachePath,
295 GENERIC_READ | GENERIC_WRITE,
296 FILE_SHARE_READ | FILE_SHARE_WRITE,
299 FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM |
300 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_FLAG_RANDOM_ACCESS,
302 FreeCacheFileSA(psa);
304 if (hf == INVALID_HANDLE_VALUE) {
305 fprintf(stderr, "Error creating cache file \"%s\" error %d\n",
306 cachePath, GetLastError());
307 return CM_ERROR_INVAL;
310 /* The file is being re-used; check to see if the existing data can be reused */
311 if ( !GetFileInformationByHandle(hf, &fileInfo) ) {
313 fprintf(stderr, "Unable to obtain File Information\n");
314 return CM_ERROR_INVAL;
317 afsi_log("Existing File Size: %08X:%08X",
318 fileInfo.nFileSizeHigh,
319 fileInfo.nFileSizeLow);
321 hm = CreateFileMapping( hf,
325 sizeof(cm_config_data_t),
328 if (GetLastError() == ERROR_DISK_FULL) {
329 fprintf(stderr, "Error creating file mapping for \"%s\": disk full (%lX)\n",
330 cachePath, sizeof(cm_config_data_t));
332 hm = CreateFileMapping( hf,
336 fileInfo.nFileSizeLow,
339 if (GetLastError() == ERROR_DISK_FULL) {
341 return CM_ERROR_TOOMANYBUFS;
343 fprintf(stderr,"Error creating file mapping for \"%s\": %d\n",
344 cachePath, GetLastError());
346 return CM_ERROR_INVAL;
349 fprintf(stderr, "Retry with file size (%lX) succeeds",
350 fileInfo.nFileSizeLow);
353 afsi_log("Error creating file mapping for \"%s\": %d",
354 cachePath, GetLastError());
356 return CM_ERROR_INVAL;
360 config_data_p = MapViewOfFile( hm,
363 sizeof(cm_config_data_t));
364 if ( config_data_p == NULL ) {
365 fprintf(stderr, "Unable to MapViewOfFile\n");
366 if (hf != INVALID_HANDLE_VALUE)
369 return CM_ERROR_INVAL;
372 if ( config_data_p->dirty ) {
373 fprintf(stderr, "Previous session terminated prematurely\n");
374 UnmapViewOfFile(config_data_p);
377 return CM_ERROR_INVAL;
380 mappingSize = config_data_p->bufferSize;
381 baseAddress = config_data_p->baseAddress;
382 UnmapViewOfFile(config_data_p);
385 hm = CreateFileMapping( hf,
388 (DWORD)(mappingSize >> 32),
389 (DWORD)(mappingSize & 0xFFFFFFFF),
392 if (GetLastError() == ERROR_DISK_FULL) {
393 fprintf(stderr, "Error creating file mapping for \"%s\": disk full [2]\n",
396 return CM_ERROR_TOOMANYBUFS;
398 fprintf(stderr, "Error creating file mapping for \"%s\": %d\n",
399 cachePath, GetLastError());
401 return CM_ERROR_INVAL;
404 baseAddress = MapViewOfFileEx( hm,
409 if (baseAddress == NULL) {
410 fprintf(stderr, "Error mapping view of file: %d\n", GetLastError());
411 baseAddress = MapViewOfFile( hm,
414 (SIZE_T)mappingSize);
415 if (baseAddress == NULL) {
417 if (hf != INVALID_HANDLE_VALUE)
419 return CM_ERROR_INVAL;
421 fprintf(stderr, "Unable to re-load cache file at base address\n");
423 if (hf != INVALID_HANDLE_VALUE)
425 return CM_ERROR_INVAL;
429 config_data_p = (cm_config_data_t *) baseAddress;
431 fprintf(stderr,"AFS Cache data:\n");
432 fprintf(stderr," Base Address = %p\n",baseAddress);
433 fprintf(stderr," stats = %u\n", config_data_p->stats);
434 fprintf(stderr," chunkSize = %u\n", config_data_p->chunkSize);
435 fprintf(stderr," blockSize = %u\n", config_data_p->blockSize);
436 fprintf(stderr," bufferSize = %I64u\n", config_data_p->bufferSize);
437 fprintf(stderr," cacheType = %u\n", config_data_p->cacheType);
438 fprintf(stderr," volumeHashTableSize = %u\n", config_data_p->volumeHashTableSize);
439 fprintf(stderr," currentVolumes = %u\n", config_data_p->currentVolumes);
440 fprintf(stderr," maxVolumes = %u\n", config_data_p->maxVolumes);
441 fprintf(stderr," cellHashTableSize = %u\n", config_data_p->cellHashTableSize);
442 fprintf(stderr," currentCells = %u\n", config_data_p->currentCells);
443 fprintf(stderr," maxCells = %u\n", config_data_p->maxCells);
444 fprintf(stderr," scacheHashTableSize = %u\n", config_data_p->scacheHashTableSize);
445 fprintf(stderr," currentSCaches = %u\n", config_data_p->currentSCaches);
446 fprintf(stderr," maxSCaches = %u\n", config_data_p->maxSCaches);
447 cm_data = *config_data_p;
449 // perform validation of persisted data structures
450 // if there is a failure, start from scratch
451 if (!cm_IsCacheValid()) {
452 fprintf(stderr,"Cache file fails validation test\n");
453 UnmapViewOfFile(config_data_p);
454 return CM_ERROR_INVAL;
457 fprintf(stderr,"Cache passes validation test\n");
458 UnmapViewOfFile(config_data_p);
463 GetVolSerialNumber(char * cachePath)
469 if ( cachePath[0] == '\\' && cachePath[1] == '\\' ||
470 cachePath[0] == '/' && cachePath[1] == '/' )
472 rootpath[0]=rootpath[1]='\\';
473 for ( i=2; cachePath[i]; i++ ) {
474 rootpath[i] = cachePath[i];
475 if ( cachePath[i] == '\\' || cachePath[i] == '/' ) {
480 } else if ( cachePath[1] == ':' ) {
481 rootpath[0] = cachePath[0];
486 for ( ; cachePath[i]; i++ ) {
487 rootpath[i] = cachePath[i];
488 if ( cachePath[i] == '\\' || cachePath[i] == '/' ) {
495 GetVolumeInformation(rootpath, NULL, 0, &serial, NULL, NULL, NULL, 0);
499 BOOL GetTextualSid( PSID pSid, PBYTE TextualSid, LPDWORD lpdwBufferLen )
501 PSID_IDENTIFIER_AUTHORITY psia;
502 DWORD dwSubAuthorities;
503 DWORD dwSidRev=SID_REVISION;
507 // Validate the binary SID.
508 if(!IsValidSid(pSid))
511 // Get the identifier authority value from the SID.
513 psia = GetSidIdentifierAuthority(pSid);
515 // Get the number of subauthorities in the SID.
517 dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
519 // Compute the buffer length.
520 // S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
522 dwSidSize=(15 + 12 + (12 * dwSubAuthorities) + 1);
524 // Check input buffer length.
525 // If too small, indicate the proper size and set the last error.
527 if (TextualSid == NULL || *lpdwBufferLen < dwSidSize)
529 *lpdwBufferLen = dwSidSize;
530 SetLastError(ERROR_INSUFFICIENT_BUFFER);
534 // Add 'S' prefix and revision number to the string.
535 dwSidSize=sprintf(TextualSid, "S-%lu-", dwSidRev );
537 // Add a SID identifier authority to the string.
538 if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
540 dwSidSize+=sprintf(TextualSid + strlen(TextualSid),
541 "0x%02hx%02hx%02hx%02hx%02hx%02hx",
542 (USHORT)psia->Value[0],
543 (USHORT)psia->Value[1],
544 (USHORT)psia->Value[2],
545 (USHORT)psia->Value[3],
546 (USHORT)psia->Value[4],
547 (USHORT)psia->Value[5]);
551 dwSidSize+=sprintf(TextualSid + strlen(TextualSid),
553 (ULONG)(psia->Value[5] ) +
554 (ULONG)(psia->Value[4] << 8) +
555 (ULONG)(psia->Value[3] << 16) +
556 (ULONG)(psia->Value[2] << 24) );
559 // Add SID subauthorities to the string.
561 for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
563 dwSidSize+=sprintf(TextualSid + dwSidSize, "-%lu",
564 *GetSidSubAuthority(pSid, dwCounter) );
571 IsSubAuthValid( PBYTE SidData, DWORD SidLength )
576 if ( SidLength % sizeof(DWORD) == 0 ) {
577 for ( sidPtr = SidData + SidLength - 5*sizeof(DWORD);
579 sidPtr -= sizeof(DWORD) )
580 if ( ((PDWORD)sidPtr)[1] == 0x05000000 &&
581 ((PDWORD)sidPtr)[2] == 0x00000015 )
583 if ( sidPtr < SidData )
590 GetMachineSid(PBYTE SidBuffer, DWORD SidSize)
603 // Read the last subauthority of the current computer SID
605 if( RegOpenKey( HKEY_LOCAL_MACHINE, "SECURITY\\SAM\\Domains\\Account",
606 &hKey) != ERROR_SUCCESS ) {
611 RegQueryValueEx( hKey, "V", NULL, &dwType, vData, &dwLen );
612 vData = (PBYTE) malloc( dwLen );
613 dwStatus = RegQueryValueEx( hKey, "V", NULL, &dwType, vData, &dwLen );
615 if( dwStatus != ERROR_SUCCESS ) {
620 // Make sure that we're dealing with a SID we understand
622 pSid = IsSubAuthValid( vData, dwLen );
624 if( !pSid || SidSize < dwLen - (pSid - vData)) {
629 memset(SidBuffer, 0, SidSize);
630 memcpy(SidBuffer, pSid, dwLen - (pSid - vData) );
636 cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD maxVols, DWORD maxCells,
637 DWORD chunkSize, afs_uint64 cacheBlocks, afs_uint32 blockSize)
639 afs_uint64 mappingSize;
641 DWORD volumeSerialNumber = 0;
642 DWORD sidStringSize = 0;
644 CHAR machineSid[6 * sizeof(DWORD)]="";
645 char * baseAddress = NULL;
646 cm_config_data_t * config_data_p;
649 volumeSerialNumber = GetVolSerialNumber(cachePath);
650 GetMachineSid(machineSid, sizeof(machineSid));
652 mappingSize = ComputeSizeOfMappingFile(stats, maxVols, maxCells, chunkSize, cacheBlocks, blockSize);
654 if ( virtualCache ) {
655 hCacheHeap = HeapCreate( HEAP_GENERATE_EXCEPTIONS, 0, 0);
657 baseAddress = HeapAlloc(hCacheHeap, 0, mappingSize);
659 if (baseAddress == NULL) {
660 afsi_log("Error allocating Virtual Memory gle=%d",
662 return CM_ERROR_INVAL;
666 HANDLE hf = INVALID_HANDLE_VALUE, hm;
667 PSECURITY_ATTRIBUTES psa;
669 psa = CreateCacheFileSA();
670 hf = CreateFile( cachePath,
671 GENERIC_READ | GENERIC_WRITE,
672 FILE_SHARE_READ | FILE_SHARE_WRITE,
675 FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM |
676 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_FLAG_RANDOM_ACCESS,
678 FreeCacheFileSA(psa);
680 if (hf == INVALID_HANDLE_VALUE) {
681 afsi_log("Error creating cache file \"%s\" error %d",
682 cachePath, GetLastError());
683 return CM_ERROR_INVAL;
686 if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
687 BY_HANDLE_FILE_INFORMATION fileInfo;
689 /* The file is being re-used; check to see if the existing data can be reused */
690 afsi_log("Cache File \"%s\" already exists", cachePath);
692 if ( GetFileInformationByHandle(hf, &fileInfo) ) {
694 afsi_log("Existing File Size: %08X:%08X",
695 fileInfo.nFileSizeHigh,
696 fileInfo.nFileSizeLow);
697 filesize = fileInfo.nFileSizeHigh;
699 filesize += fileInfo.nFileSizeLow;
700 if (filesize > GranularityAdjustment(mappingSize)) {
701 psa = CreateCacheFileSA();
702 hf = CreateFile( cachePath,
703 GENERIC_READ | GENERIC_WRITE,
704 FILE_SHARE_READ | FILE_SHARE_WRITE,
707 FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM |
708 FILE_ATTRIBUTE_NOT_CONTENT_INDEXED | FILE_FLAG_RANDOM_ACCESS,
710 FreeCacheFileSA(psa);
712 if (hf == INVALID_HANDLE_VALUE) {
713 afsi_log("Error creating cache file \"%s\" error %d",
714 cachePath, GetLastError());
715 return CM_ERROR_INVAL;
718 GetFileInformationByHandle(hf, &fileInfo);
719 afsi_log(" New File Size: %08X:%08X",
720 fileInfo.nFileSizeHigh,
721 fileInfo.nFileSizeLow);
725 hm = CreateFileMapping( hf,
729 sizeof(cm_config_data_t),
732 if (GetLastError() == ERROR_DISK_FULL) {
733 afsi_log("Error creating file mapping for \"%s\": disk full (%lX)",
734 cachePath, sizeof(cm_config_data_t));
736 hm = CreateFileMapping( hf,
739 (DWORD)(mappingSize >> 32),
740 (DWORD)(mappingSize & 0xFFFFFFFF),
743 if (GetLastError() == ERROR_DISK_FULL) {
745 return CM_ERROR_TOOMANYBUFS;
747 afsi_log("Error creating file mapping for \"%s\": %d",
748 cachePath, GetLastError());
750 return CM_ERROR_INVAL;
753 afsi_log("Retry with mapping size (%lX) succeeds", mappingSize);
756 afsi_log("Error creating file mapping for \"%s\": %d",
757 cachePath, GetLastError());
759 return CM_ERROR_INVAL;
763 config_data_p = MapViewOfFile( hm,
766 sizeof(cm_config_data_t));
767 if ( config_data_p == NULL ) {
768 if (hf != INVALID_HANDLE_VALUE)
771 return CM_ERROR_INVAL;
774 if ( config_data_p->size == sizeof(cm_config_data_t) &&
775 config_data_p->magic == CM_CONFIG_DATA_MAGIC &&
776 config_data_p->stats == stats &&
777 config_data_p->maxVolumes == maxVols &&
778 config_data_p->maxCells == maxCells &&
779 config_data_p->chunkSize == chunkSize &&
780 config_data_p->buf_nbuffers == cacheBlocks &&
781 config_data_p->blockSize == blockSize &&
782 config_data_p->bufferSize == mappingSize)
784 if ( config_data_p->dirty ) {
785 afsi_log("Previous session terminated prematurely");
787 baseAddress = config_data_p->baseAddress;
791 afsi_log("Configuration changed or Not a persistent cache file");
793 UnmapViewOfFile(config_data_p);
797 hm = CreateFileMapping( hf,
800 (DWORD)(mappingSize >> 32),
801 (DWORD)(mappingSize & 0xFFFFFFFF),
804 if (GetLastError() == ERROR_DISK_FULL) {
805 afsi_log("Error creating file mapping for \"%s\": disk full [2]",
807 return CM_ERROR_TOOMANYBUFS;
809 afsi_log("Error creating file mapping for \"%s\": %d",
810 cachePath, GetLastError());
811 return CM_ERROR_INVAL;
813 baseAddress = MapViewOfFileEx( hm,
819 if (baseAddress == NULL) {
820 afsi_log("Error mapping view of file: %d", GetLastError());
821 baseAddress = MapViewOfFile( hm,
825 (SIZE_T)mappingSize);
826 if (baseAddress == NULL) {
827 if (hf != INVALID_HANDLE_VALUE)
830 return CM_ERROR_INVAL;
835 hMemoryMappedFile = hf;
838 config_data_p = (cm_config_data_t *) baseAddress;
841 afsi_log("Reusing existing AFS Cache data:");
842 cm_data = *config_data_p;
844 afsi_log(" Map Address = %p", baseAddress);
845 afsi_log(" baseAddress = %p", config_data_p->baseAddress);
846 afsi_log(" stats = %u", config_data_p->stats);
847 afsi_log(" chunkSize = %u", config_data_p->chunkSize);
848 afsi_log(" blockSize = %u", config_data_p->blockSize);
849 afsi_log(" bufferSize = %I64u", config_data_p->bufferSize);
850 afsi_log(" cacheType = %u", config_data_p->cacheType);
851 afsi_log(" volumeHashTableSize = %u", config_data_p->volumeHashTableSize);
852 afsi_log(" currentVolumes = %u", config_data_p->currentVolumes);
853 afsi_log(" maxVolumes = %u", config_data_p->maxVolumes);
854 afsi_log(" cellHashTableSize = %u", config_data_p->cellHashTableSize);
855 afsi_log(" currentCells = %u", config_data_p->currentCells);
856 afsi_log(" maxCells = %u", config_data_p->maxCells);
857 afsi_log(" scacheHashTableSize = %u", config_data_p->scacheHashTableSize);
858 afsi_log(" currentSCaches = %u", config_data_p->currentSCaches);
859 afsi_log(" maxSCaches = %u", config_data_p->maxSCaches);
862 * perform validation of persisted data structures
863 * if there is a failure, start from scratch
865 * if the baseAddress changed then the embedded pointers
866 * within the data structures are no longer valid.
867 * in theory we could walk the tree and adjust the pointer
868 * values based on the offet but that has not been
871 if (baseAddress != cm_data.baseAddress ||
872 cm_ValidateCache && !cm_IsCacheValid()) {
878 afsi_log("Building AFS Cache from scratch");
879 memset(&cm_data, 0, sizeof(cm_config_data_t));
880 cm_data.size = sizeof(cm_config_data_t);
881 cm_data.magic = CM_CONFIG_DATA_MAGIC;
882 cm_data.baseAddress = baseAddress;
883 cm_data.stats = stats;
884 cm_data.chunkSize = chunkSize;
885 cm_data.blockSize = blockSize;
886 cm_data.bufferSize = mappingSize;
888 cm_data.scacheHashTableSize = cm_NextHighestPowerOf2(stats / 2);
889 cm_data.volumeHashTableSize = cm_NextHighestPowerOf2((afs_uint32)(maxVols/7));
890 cm_data.cellHashTableSize = cm_NextHighestPowerOf2((afs_uint32)(maxCells/7));
892 cm_data.cacheType = CM_BUF_CACHETYPE_VIRTUAL;
894 cm_data.cacheType = CM_BUF_CACHETYPE_FILE;
897 cm_data.buf_nbuffers = cacheBlocks;
898 cm_data.buf_nOrigBuffers = 0;
899 cm_data.buf_blockSize = blockSize;
900 cm_data.buf_hashSize = cm_NextHighestPowerOf2((afs_uint32)(cacheBlocks/7));
902 cm_data.mountRootGen = 0;
904 baseAddress += ComputeSizeOfConfigData();
905 cm_data.volumeBaseAddress = (cm_volume_t *) baseAddress;
906 baseAddress += ComputeSizeOfVolumes(maxVols);
907 cm_data.volumeNameHashTablep = (cm_volume_t **)baseAddress;
908 baseAddress += ComputeSizeOfVolumeHT(maxVols);
909 cm_data.volumeRWIDHashTablep = (cm_volume_t **)baseAddress;
910 baseAddress += ComputeSizeOfVolumeHT(maxVols);
911 cm_data.volumeROIDHashTablep = (cm_volume_t **)baseAddress;
912 baseAddress += ComputeSizeOfVolumeHT(maxVols);
913 cm_data.volumeBKIDHashTablep = (cm_volume_t **)baseAddress;
914 baseAddress += ComputeSizeOfVolumeHT(maxVols);
915 cm_data.cellNameHashTablep = (cm_cell_t **)baseAddress;
916 baseAddress += ComputeSizeOfCellHT(maxCells);
917 cm_data.cellIDHashTablep = (cm_cell_t **)baseAddress;
918 baseAddress += ComputeSizeOfCellHT(maxCells);
919 cm_data.cellBaseAddress = (cm_cell_t *) baseAddress;
920 baseAddress += ComputeSizeOfCells(maxCells);
921 cm_data.aclBaseAddress = (cm_aclent_t *) baseAddress;
922 baseAddress += ComputeSizeOfACLCache(stats);
923 cm_data.scacheBaseAddress = (cm_scache_t *) baseAddress;
924 baseAddress += ComputeSizeOfSCache(stats);
925 cm_data.scacheHashTablep = (cm_scache_t **) baseAddress;
926 baseAddress += ComputeSizeOfSCacheHT(stats);
927 cm_data.dnlcBaseAddress = (cm_nc_t *) baseAddress;
928 baseAddress += ComputeSizeOfDNLCache();
929 cm_data.buf_scacheHashTablepp = (cm_buf_t **) baseAddress;
930 baseAddress += ComputeSizeOfDataHT(cacheBlocks);
931 cm_data.buf_fileHashTablepp = (cm_buf_t **) baseAddress;
932 baseAddress += ComputeSizeOfDataHT(cacheBlocks);
933 cm_data.bufHeaderBaseAddress = (cm_buf_t *) baseAddress;
934 baseAddress += ComputeSizeOfDataHeaders(cacheBlocks);
935 cm_data.bufDataBaseAddress = (char *) baseAddress;
936 baseAddress += ComputeSizeOfDataBuffers(cacheBlocks, blockSize);
937 cm_data.bufEndOfData = (char *) baseAddress;
938 cm_data.buf_dirtyListp = NULL;
939 cm_data.buf_dirtyListEndp = NULL;
940 /* Make sure the fakeDirVersion is always increasing */
941 cm_data.fakeDirVersion = time(NULL);
942 cm_data.fakeUnique = 0;
943 UuidCreate((UUID *)&cm_data.Uuid);
944 cm_data.volSerialNumber = volumeSerialNumber;
945 memcpy(cm_data.Sid, machineSid, sizeof(machineSid));
948 * make sure that the file is fully allocated
949 * by writing a non-zero byte to the end
951 cm_data.baseAddress[mappingSize-1] = 0xFF;
955 if ( volumeSerialNumber == 0 || volumeSerialNumber != cm_data.volSerialNumber ) {
957 afsi_log("Volume serial number change, generating new UUID");
958 afsi_log("Old volume Serial Number: 0x%x", cm_data.volSerialNumber);
959 } else if ( machineSid[0] && memcmp(machineSid, cm_data.Sid, sizeof(machineSid))) {
961 afsi_log("Machine Sid changed, generating new UUID");
962 GetTextualSid( (PSID)cm_data.Sid, NULL, &sidStringSize );
964 p = malloc(sidStringSize * sizeof(TCHAR));
966 rc = GetTextualSid( (PSID)cm_data.Sid, p, &sidStringSize );
967 afsi_log("Old Machine SID: %s", rc ? p : "unknown");
971 afsi_log("Old Machine SID: unknown");
976 UuidCreate((UUID *)&cm_data.Uuid);
977 cm_data.volSerialNumber = volumeSerialNumber;
978 memcpy(cm_data.Sid, machineSid, sizeof(machineSid));
982 afsi_log("Volume Serial Number: 0x%x", cm_data.volSerialNumber);
984 GetTextualSid( (PSID)cm_data.Sid, NULL, &sidStringSize );
986 p = malloc(sidStringSize * sizeof(TCHAR));
988 rc = GetTextualSid( (PSID)cm_data.Sid, p, &sidStringSize );
989 afsi_log("Machine SID: %s", rc ? p : "unknown");
993 afsi_log("Machine SID: unknown");
996 UuidToString((UUID *)&cm_data.Uuid, &p);
997 afsi_log("Initializing Uuid to %s",p);
1000 afsi_log("Initializing Volume Data");
1001 cm_InitVolume(newCache, maxVols);
1003 afsi_log("Initializing Cell Data");
1004 cm_InitCell(newCache, maxCells);
1006 afsi_log("Initializing ACL Data");
1007 cm_InitACLCache(newCache, 2*stats);
1009 afsi_log("Initializing Stat Data");
1010 cm_InitSCache(newCache, stats);
1012 afsi_log("Initializing Data Buffers");
1013 cm_InitDCache(newCache, 0, cacheBlocks);
1015 *config_data_p = cm_data;
1016 config_data_p->dirty = 1;
1018 afsi_log("Cache Initialization Complete");