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