windows-tests-torture-source-20090131
[openafs.git] / src / WINNT / tests / torture / Source / WinThreads.c
1 #include <windows.h>
2 #include "includes.h"
3 #include "common.h"
4 #ifdef HAVE_HESOID
5     #include "ResolveLocker.h"
6     int ResolveLocker(USER_OPTIONS *attachOption);
7 #endif
8 #ifndef NO_AFS_SOURCE
9     #include <afs\stds.h>
10     #include <afs\smb_iocons.h>
11     #include <afs\afsint.h>
12     #include <afs\pioctl_nt.h>
13 #else
14     #define VIOCGETVOLSTAT  0x7
15     #define afs_int32   int
16
17     struct VolumeStatus {
18             afs_int32 Vid;
19             afs_int32 ParentId;
20             char Online;
21             char InService;
22             char Blessed;
23             char NeedsSalvage;
24             afs_int32 Type;
25             afs_int32 MinQuota;
26             afs_int32 MaxQuota;
27             afs_int32 BlocksInUse;
28             afs_int32 PartBlocksAvail;
29             afs_int32 PartMaxBlocks;
30     };
31
32     typedef struct VolumeStatus VolumeStatus;
33
34     typedef struct ViceIoctl {
35             long in_size;
36             long out_size;
37             void *in;
38             void *out;
39     } viceIoctl_t;
40 extern long pioctl(char *pathp, long opcode, struct ViceIoctl *blob, int follow);
41 #endif
42
43 #define MAX_PARAMS 20
44 #define ival(s) strtol(s, NULL, 0)
45 #define AFSDLL "afsauthent.dll"
46
47 #define WINTORTURE_ASFDLL_ONLINE        1
48 #define WINTORTURE_ASFDLL_OFFLINE       2
49 #define WINTORTURE_ASFDLL_NOTFOUND      3
50 #define WINTORTURE_ASFPIOCTL_NOTFOUND   4
51
52 extern int verbose;
53
54 extern void EndSecondTime(int cmd);
55 extern void StartSecondTime(int cmd);
56 extern void LogMessage(int ProcessNumber, char *HostName, char *FileName, char *message, int LogID);
57 extern void LogStats(char *FileName, int ToLog, int Iteration,  int NumberOfProcesses, int NumberOfThreads,
58                      char *HostName, int ProcessNumber, struct cmd_struct ThreadCommandInfo[],
59                      char *CommandLine, char *TargetDirectory);
60 extern void SubstituteString(char *s,const char *pattern,const char *insert, size_t len);
61
62 int  IsOnline(char *strPath);
63 BOOL run_netbench(int client, char *ClientTxt, char *PathToSecondDir);
64
65 HANDLE  MutexHandle;
66 HANDLE  FileMutexHandle;
67 HANDLE  ShutDownEventHandle;
68 HANDLE  PauseEventHandle;
69 HANDLE  ContinueEventHandle;
70 HANDLE  OSMutexHandle;
71
72 __declspec( thread ) int    AfsTrace;
73 __declspec( thread ) int    CurrentLoop;
74 __declspec( thread ) int    ProcessNumber = 0;
75 __declspec( thread ) int    LogID = 0;
76 __declspec( thread ) int    LineCount = 0;
77 __declspec( thread ) int    *pThreadStatus;
78 __declspec( thread ) DWORD  TickCount1,TickCount2, MilliTickStart;
79 __declspec( thread ) int    BufferSize = 4096;
80 __declspec( thread ) char   *IoBuffer = NULL;
81 __declspec( thread ) char   AfsLocker[256];
82 __declspec( thread ) char   OriginalAfsLocker[256];
83 __declspec( thread ) char   HostName[256];
84 __declspec( thread ) struct cmd_struct ThreadCommandInfo[CMD_MAX_CMD + 1];
85 __declspec( thread ) FTABLE ftable[MAX_FILES];
86 __declspec( thread ) HANDLE hWinEventHandle;
87 __declspec( thread ) EXIT_STATUS *pExitStatus;
88 __declspec( thread ) DWORD  LastKnownError;
89
90
91 DWORD WINAPI StressTestThread(LPVOID lpThreadParameter)
92 {
93     int         j;
94     int         rc;
95     size_t      count;
96     int         ProcessID;
97     char        EventName[64];
98     char        FileName[256];
99     char        CommandLine[512];
100     char        TargetDirectory[512];
101     char        WorkingDirectory[512];
102     char        ClientText[128];
103     char        PathToSecondDir[256];
104     char        temp[512];
105     BOOL        PrintStats;
106     PARAMETERLIST *pParameterList;
107     struct cmd_struct *WinCommandInfo;
108
109     pParameterList = (PARAMETERLIST *)lpThreadParameter;
110     pThreadStatus = pParameterList->pThreadStatus;
111     BufferSize = pParameterList->BufferSize;
112     ProcessNumber = pParameterList->ProcessNumber;
113     PrintStats = pParameterList->PrintStats;
114     CurrentLoop = pParameterList->CurrentLoop;
115     ProcessID = pParameterList->ProcessID;
116     LogID = pParameterList->LogID;
117     AfsTrace = pParameterList->AfsTrace;
118     pExitStatus = pParameterList->pExitStatus;
119     strcpy(TargetDirectory, pParameterList->TargetDirectory);
120     strcpy(CommandLine, pParameterList->CommandLine);
121     strcpy(ClientText, pParameterList->ClientText);
122     strcpy(PathToSecondDir, pParameterList->PathToSecondDir);
123     strcpy(AfsLocker, pParameterList->AfsLocker);
124     strcpy(HostName, pParameterList->HostName);
125     WinCommandInfo = ( struct cmd_struct *)pParameterList->CommandInfo;
126
127     sprintf(EventName, "%d%sEvent%05d", ProcessID, HostName, ProcessNumber);
128     hWinEventHandle = OpenEvent(EVENT_ALL_ACCESS, TRUE, EventName);
129
130     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
131     GetCurrentDirectory(sizeof(WorkingDirectory), WorkingDirectory);
132     sprintf(temp, "%s\\log%05d\\%s", WorkingDirectory, LogID, HostName);
133     CreateDirectory(temp, NULL);
134
135
136     memset(ftable, '\0', sizeof(ftable[0]) * MAX_FILES);
137     IoBuffer = malloc(BufferSize);
138     if (!IoBuffer)
139     {
140         strcpy(pExitStatus->Reason, "Unable to allocate buffer");
141         pExitStatus->ExitStatus = 1;
142         SetEvent(hWinEventHandle);
143         ExitThread(1);
144     }
145
146     ShutDownEventHandle = CreateEvent(NULL, TRUE, FALSE, "AfsShutdownEvent");
147     PauseEventHandle = CreateEvent(NULL, TRUE, FALSE, "AfsPauseEvent");
148     ContinueEventHandle = CreateEvent(NULL, TRUE, FALSE, "AfsContinueEvent");
149     OSMutexHandle = CreateMutex(NULL, FALSE, "WinTortureOSMutex");
150     MutexHandle = CreateMutex(NULL, FALSE, "WinTortureMutex");
151
152     strcpy(OriginalAfsLocker, AfsLocker);
153
154     while (1)
155     {
156         LastKnownError = 0;
157         for (j = 0; j <= CMD_MAX_CMD; j++)
158         {
159             WinCommandInfo[j].count = 0;
160             WinCommandInfo[j].min_sec = 0;
161             WinCommandInfo[j].max_sec = 0;
162             WinCommandInfo[j].MilliSeconds = 0;
163             WinCommandInfo[j].total_sec = 0;
164             WinCommandInfo[j].total_sum_of_squares = 0;
165             WinCommandInfo[j].ErrorCount = 0;
166             WinCommandInfo[j].ErrorTime = 0;
167             ThreadCommandInfo[j].count = 0;
168             ThreadCommandInfo[j].min_sec = 1000;
169             ThreadCommandInfo[j].max_sec = 0;
170             ThreadCommandInfo[j].MilliSeconds = 0;
171             ThreadCommandInfo[j].total_sec = 0;
172             ThreadCommandInfo[j].total_sum_of_squares = 0;
173             ThreadCommandInfo[j].ErrorCount = 0;
174             ThreadCommandInfo[j].ErrorTime = 0;
175         }
176
177         run_netbench(ProcessNumber, ClientText, PathToSecondDir);
178         if (LastKnownError != ERROR_NETNAME_DELETED)
179             break; 
180         sprintf(temp, "entered error %d processing\n", LastKnownError);
181         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
182
183         count = strlen(pExitStatus->Reason);
184         if (count != 0)
185             memset(pExitStatus->Reason, '\0', count);
186         pExitStatus->ExitStatus = 0;
187         (*pThreadStatus) = 1;
188         count = 0;
189         
190         while ((rc = IsOnline(OriginalAfsLocker)) != WINTORTURE_ASFDLL_ONLINE)
191         {
192             if ((count > 3) || (rc == WINTORTURE_ASFDLL_NOTFOUND) || (rc == WINTORTURE_ASFPIOCTL_NOTFOUND))
193             {
194                 LastKnownError = 0;
195                 sprintf(temp, "AFS path \"%s\" appears to be off-line\n", OriginalAfsLocker);
196                 strcpy(pExitStatus->Reason, temp);
197                 pExitStatus->ExitStatus = 1;
198                 (*pThreadStatus) = 0;
199                 printf("%s", temp);
200                 LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
201                 strcpy(temp, "Stress test is terminating\n");
202                 printf(temp);
203                 LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
204                 break;
205             }
206             sprintf(temp, "AFS path \"%s\" is online, sleeping 10 seconds before continuing\n", OriginalAfsLocker);
207             LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
208             ++count;
209             Sleep(10 * 1000);
210         }
211         sprintf(temp, "leaving error 0x%x processing\n", LastKnownError);
212         LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
213         if (count > 3)
214             break;
215     }
216     free(IoBuffer);
217
218     for (j = 0; j <= CMD_MAX_CMD; j++)
219     {
220         WinCommandInfo[j].count += ThreadCommandInfo[j].count;
221         WinCommandInfo[j].min_sec += ThreadCommandInfo[j].min_sec;
222         WinCommandInfo[j].max_sec += ThreadCommandInfo[j].max_sec;
223         WinCommandInfo[j].total_sec += ThreadCommandInfo[j].total_sec;
224         WinCommandInfo[j].total_sum_of_squares += ThreadCommandInfo[j].total_sum_of_squares;
225         WinCommandInfo[j].ErrorCount += ThreadCommandInfo[j].ErrorCount;
226         WinCommandInfo[j].ErrorTime += ThreadCommandInfo[j].ErrorTime;
227     }
228
229     memset(WorkingDirectory, '\0', sizeof(WorkingDirectory));
230     GetCurrentDirectory(sizeof(WorkingDirectory), WorkingDirectory);
231     sprintf(FileName, "%s\\log%05d\\%s\\Thread_%05d_Stats.log", WorkingDirectory, LogID, HostName, ProcessNumber);
232
233     if (PrintStats)
234     {
235         WaitForSingleObject(MutexHandle, 4 * 1000);
236         LogStats(FileName, 0, CurrentLoop, 0, 0, HostName, ProcessNumber, ThreadCommandInfo, CommandLine, TargetDirectory);
237         ReleaseMutex(MutexHandle);
238     }
239
240     LogStats(FileName, 1, CurrentLoop, 0, 0, HostName, ProcessNumber, ThreadCommandInfo,CommandLine, TargetDirectory);
241
242     SetEvent(hWinEventHandle);
243     CloseHandle(hWinEventHandle);
244 //    CloseHandle(OSMutexHandle);
245 //    CloseHandle(MutexHandle);
246
247     ExitThread(0);
248     return(0);
249 }
250
251 BOOL run_netbench(int client, char *ClientText, char *PathToSecondDir)
252 {
253     pstring line;
254     pstring line1;
255     char    cname[20];
256     char    *params[MAX_PARAMS];
257     char    temp[256];
258     char    FileName[256];
259     char    *pPtr;
260     int     rc;
261     int     i;
262     int     IncreaseBy;
263     BOOL    correct = TRUE;
264     DWORD   dwFlags = 0;
265     DWORD   NumberOfBytes;
266     DWORD   TotalBytesRead;
267     HANDLE  hFile;
268     enum    states bm_state;
269     CRITICAL_SECTION CriticalSection;
270
271
272     InitializeCriticalSection(&CriticalSection);
273
274     sprintf(cname, "client%d", client);
275
276     sprintf(temp, "Started Iteration %d\n", CurrentLoop);
277     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
278     LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
279     sprintf(temp, "Thread %d started\n", ProcessNumber);
280     sprintf(FileName, "Thread_%05d.log", ProcessNumber);
281     LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
282
283     hFile = CreateFile(ClientText, GENERIC_READ | STANDARD_RIGHTS_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 
284
285     if (hFile == INVALID_HANDLE_VALUE) 
286     {
287         perror(ClientText);
288         return(-1);
289     }
290
291     StartSecondTime(CMD_NONAFS);
292     TotalBytesRead = 0;
293     while (1)
294     {
295         memset(line, '\0', sizeof(line));
296         NumberOfBytes = 0;
297         rc = ReadFile(hFile, line, 128, &NumberOfBytes, NULL);
298         if (rc && NumberOfBytes == 0)
299             break;
300         pPtr = strchr(line, '\n');
301         IncreaseBy = 0;
302         if (pPtr != NULL)
303         {
304             IncreaseBy += 1;
305             (*pPtr) = '\0';
306             if ((*(pPtr - 1)) == '\r')
307             {
308                 IncreaseBy += 1;
309                 (*(pPtr - 1)) = '\0';
310             }
311         }
312         TotalBytesRead += (DWORD)(strlen(line) + IncreaseBy);
313         SetFilePointer(hFile, TotalBytesRead, 0, FILE_BEGIN);
314         strcpy(line1, line);
315         if (rc = WaitForSingleObject(PauseEventHandle, 0) == WAIT_OBJECT_0)
316         {
317             strcpy(temp, "AFS suspend request received\n");
318             sprintf(FileName, "Thread_%05d.log", ProcessNumber);
319             LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
320             while (WaitForSingleObject(ContinueEventHandle, 5000) == WAIT_TIMEOUT);
321             strcpy(temp, "AFS continue request received\n");
322             sprintf(FileName, "Thread_%05d.log", ProcessNumber);
323             LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
324         }
325         if (rc = WaitForSingleObject(ShutDownEventHandle, 0) == WAIT_OBJECT_0)
326         {
327             strcpy(temp, "AFS shutdown request received\n");
328             sprintf(FileName, "Thread_%05d.log", ProcessNumber);
329             LogMessage(ProcessNumber, HostName, FileName, temp, LogID);
330             break;
331         }
332         LineCount++;
333         if (strlen(line) == 0)
334             continue;
335         if (line[0] == '#')
336             continue;
337         /*printf("[%d] %s\n", LineCount, line);*/
338
339         for (i = 0; i < MAX_PARAMS; i++)
340             params[i] = NULL;
341
342         SubstituteString(line,"client1", cname, sizeof(line));
343         sprintf(temp, "%s%05d", HostName, LogID);
344         SubstituteString(line,"clients", temp, sizeof(line));
345         SubstituteString(line,"\\\\afs\\locker", AfsLocker, sizeof(line));
346         if (strlen(PathToSecondDir) != 0)
347                 SubstituteString(line,"\\\\afs\\lcolby", PathToSecondDir, sizeof(line));
348
349         if (verbose)
350         {
351             EnterCriticalSection(&CriticalSection);
352             printf("Thread%05d - %-6d - %s\n", ProcessNumber, LineCount, line);
353             LeaveCriticalSection(&CriticalSection);
354         }
355
356         pPtr = line;
357         i = 0;
358         while (pPtr != NULL)
359         {
360             if ((*pPtr) == ' ')
361             {
362                 (*pPtr) = '\0';
363                 ++pPtr;
364                 continue;
365             }
366             params[i] = pPtr;
367             ++i;
368             pPtr = strstr(pPtr, " ");
369             if (pPtr != NULL)
370             {
371                 (*pPtr) = '\0';
372                 ++pPtr;
373             }
374             
375         }
376
377         params[i] = "";
378
379         if (i < 1) 
380             continue;
381
382         if (!strncmp(params[0],"SMB", 3)) 
383         {
384             printf("ERROR: You are using a dbench 1 load file\n");
385             if (GetHandleInformation((HANDLE)hWinEventHandle, &dwFlags))
386                 break;
387                 }
388         if (!strcmp(params[0], "BM_SETUP"))
389         {
390             bm_state = BM_SETUP;
391         } 
392         else if (!strcmp(params[0], "BM_WARMUP"))
393         {
394             bm_state = BM_WARMUP;
395         } 
396         else if (!strcmp(params[0], "BM_MEASURE"))
397         {
398             bm_state = BM_MEASURE;
399             if (verbose)
400                 fprintf(stderr, "setting state to BM_MEASURE\n");
401         } 
402         else if (!strcmp(params[0],"RECONNECT")) 
403         {
404             if (verbose)
405                 fprintf(stderr, "Reconnecting ...\n");
406         } 
407         else if (!strcmp(params[0], "SYNC"))
408         {
409             int length = atoi(params[1]), st = 0;
410             if (verbose)
411                 fprintf(stderr, "Syncing for %d seconds\n", length);
412         } 
413         else if (!strcmp(params[0],"NTCreateX")) 
414         {
415             if (nb_createx(params[1], ival(params[2]), ival(params[3]), ival(params[4])) == -1)
416                 break;
417         } 
418         else if (!stricmp(params[0],"SetLocker"))
419         {
420             if (nb_SetLocker(params[1]) == -1)
421                 break;
422         } 
423         else if (!stricmp(params[0],"Xrmdir")) 
424         {
425             if (nb_Xrmdir(params[1], params[2]) == -1)
426                 break;
427         } 
428         else if (!stricmp(params[0],"Mkdir")) 
429         {
430             if (nb_Mkdir(params[1]) == -1)
431                 break;
432         } 
433         else if (!stricmp(params[0],"Attach")) 
434         {
435             if (nb_Attach(params[1], params[2]) == -1)
436                 break;
437         } 
438         else if (!stricmp(params[0],"Detach")) 
439         {
440             if (nb_Detach(params[1], params[2]) == -1)
441                 break;
442         } 
443         else if (!stricmp(params[0],"CreateFile")) 
444         {
445             if (nb_CreateFile(params[1], atol(params[2])) == -1)
446                 break;
447         } 
448         else if (!stricmp(params[0],"CopyFiles")) 
449         {
450             if (nb_CopyFile(params[1], params[2]) == -1)
451                 break;
452         } 
453         else if (!stricmp(params[0],"DeleteFiles")) 
454         {
455             if (nb_DeleteFile(params[1]) == -1)
456                 break;
457         } 
458         else if (!stricmp(params[0],"Move")) 
459         {
460             if (nb_Move(params[1], params[2]) == -1)
461                 break;
462         } 
463         else if (!stricmp(params[0],"Xcopy")) 
464         {
465             if (nb_xcopy(params[1], params[2]) == -1)
466                 break;
467         } 
468         else if (!strcmp(params[0],"Close")) 
469         {
470             if (nb_close(ival(params[1])) == -1)
471                 break;
472         } 
473         else if (!strcmp(params[0],"Rename")) 
474         {
475             if (nb_rename(params[1], params[2]) == -1)
476                 break;
477         } 
478         else if (!strcmp(params[0],"Unlink")) 
479         {
480             if (nb_unlink(params[1]) == -1)
481                 break;
482         } 
483         else if (!strcmp(params[0],"Deltree"))
484         {
485             if (nb_deltree(params[1]) == -1)
486                 break;
487         } 
488         else if (!strcmp(params[0],"Rmdir")) 
489         {
490             if (nb_rmdir(params[1]) == -1)
491                 break;
492         } 
493         else if (!strcmp(params[0],"QUERY_PATH_INFORMATION"))
494         {
495             if (nb_qpathinfo(params[1], ival(params[2])) == -1)
496                 break;
497         } 
498         else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) 
499         {
500             if (nb_qfileinfo(ival(params[1])) == -1)
501                 break;
502         } 
503         else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) 
504         {
505             if (nb_qfsinfo(ival(params[1])) == -1)
506                 break;
507         } 
508         else if (!strcmp(params[0],"FIND_FIRST")) 
509         {
510             if (nb_findfirst(params[1]) == -1)
511                 break;
512         } 
513         else if (!strcmp(params[0],"WriteX")) 
514         {
515             if (nb_writex(ival(params[1]), ival(params[2]), ival(params[3]), ival(params[4])) == -1)
516                 break;
517         } 
518         else if (!strcmp(params[0],"ReadX")) 
519         {
520             if (nb_readx(ival(params[1]), ival(params[2]), ival(params[3]), ival(params[4])) == -1)
521                 break;
522         } 
523         else if (!strcmp(params[0],"Flush")) 
524         {
525             if (nb_flush(ival(params[1])) == -1)
526                 break;
527         } 
528         else if (!strcmp(params[0],"LockingX")) 
529         {
530             if (nb_lock(ival(params[1]), ival(params[2]), ival(params[3]), ival(params[4]),
531                         (unsigned char)ival(params[5]), ival(params[6])) == -1)
532                 break;
533         } 
534         else 
535         {
536             printf("Unknown operation %s\n", params[0]);
537             printf("Line read = %s\n", line1);
538             break;
539         }
540     }
541     CloseHandle(hFile);
542
543 //    nb_cleanup(cname);
544
545     EndSecondTime(CMD_NONAFS);
546
547     for (i = 0; i < MAX_FILES; i++) 
548     {
549         if (ftable[i].handle > 0)
550             nb_close(ftable[i].handle);
551     }
552
553         DeleteCriticalSection(&CriticalSection);
554
555     return(correct);
556 }
557
558 typedef long ( __cdecl  *PPIOCTL)(char *pathp, long opcode, struct ViceIoctl *blobp, int follow);
559
560 int IsOnline(char *strPath)
561 {
562     int     bret;
563     char    space[2048];
564     int     code;
565     int     rc;
566     struct  ViceIoctl blob;
567     struct  VolumeStatus *status;
568     static PPIOCTL ppioctl = NULL;
569     static HINSTANCE hAfsDll = NULL;
570
571     rc = WaitForSingleObject(OSMutexHandle, 5 * 1000);
572     bret = FALSE;
573     if (hAfsDll == NULL)
574         hAfsDll = LoadLibrary(AFSDLL);
575     if (hAfsDll)
576     {
577         if (ppioctl == NULL)
578             ppioctl = (PPIOCTL)GetProcAddress(hAfsDll, "pioctl");
579         if (ppioctl != NULL)
580         {
581             blob.in_size = 0;
582             blob.out_size = sizeof(space);
583             blob.out = space;
584             if (!(code = ppioctl(strPath, VIOCGETVOLSTAT, &blob, 1)))
585             {
586                 bret = WINTORTURE_ASFDLL_ONLINE;
587                 status = (VolumeStatus *)space;
588                 if (!status->Online || !status->InService || !status->Blessed || status->NeedsSalvage)
589                     bret = WINTORTURE_ASFDLL_OFFLINE;
590             }
591         }
592         else
593             bret = WINTORTURE_ASFPIOCTL_NOTFOUND;
594     }
595     else
596         bret = WINTORTURE_ASFDLL_NOTFOUND;
597
598     if (rc == WAIT_OBJECT_0)
599         ReleaseMutex(OSMutexHandle);
600
601     return(bret);
602 }
603