1 /* This FileX test concentrates on the Fault-Tolerant log recover directory operation.  */
2 /*
3 For FAT 12, 16, 32, one cluster size is 1024 bytes;
4 
5         1024         1024          1024       1024          1024         1024
6     |------------|------------|-----------|------------|------------|------------|
7     |  TEST.TXT  |  TEST1.TXT | TEST2.TXT |            |            |            |
8     |------------|------------|-----------|------------|------------|------------|
9          28           1000         19
10 
11 Check recover directory operation:
12 Step1: Format and open the media;
13 Step2: Enable fault tolerant feature;
14 Step3: Write 28 bytes into TEST.TXT;
15 Step4: Write 1000 bytes into TEST1.TXT;
16 Step5: Write 19 bytes into TEST2.TXT;
17 Step6: Create new thread to continue to write 2048 data into TEST1.TXT(greater than one cluster):
18 Step7: Terminate the new thread to simulate poweroff when update the directory into media and the redo log has been generated.
19 Step8: Create new thread and enable fault tolerant feature to recover the data(redo operation);
20 Step9: Terminate the new thread to simulate poweroff when recover the directory;
21 Step10: Open the media and enable fault tolerant feature to recover the data(redo operation);
22 Step11: Check the test files.
23 */
24 
25 #ifndef FX_STANDALONE_ENABLE
26 #include   "tx_api.h"
27 #else
28 #define    _GNU_SOURCE
29 #define    _DEFAULT_SOURCE
30 #include   <pthread.h>
31 #include   <unistd.h>
32 #endif
33 #include   "fx_api.h"
34 #include   "fx_system.h"
35 #include   "fx_fault_tolerant.h"
36 #include   <stdio.h>
37 #include   "fx_ram_driver_test.h"
38 extern void    test_control_return(UINT status);
39 void    filex_fault_tolerant_log_recover_directory_test_application_define(void *first_unused_memory);
40 
41 #if defined (FX_ENABLE_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT) && defined (FX_FAULT_TOLERANT_DATA)
42 
43 #define     DEMO_STACK_SIZE         4096
44 #define CACHE_SIZE                  2048
45 #define FAULT_TOLERANT_SIZE         FX_FAULT_TOLERANT_MINIMAL_BUFFER_SIZE
46 
47 
48 /* Define the ThreadX and FileX object control blocks...  */
49 
50 #ifndef FX_STANDALONE_ENABLE
51 static TX_THREAD                ftest_0;
52 static TX_THREAD                ftest_1;
53 static TX_THREAD                ftest_2;
54 #else
55 static pthread_t                ptid1;
56 static pthread_t                ptid2;
57 #endif
58 static FX_MEDIA                 ram_disk;
59 static FX_FILE                  my_file;
60 static UCHAR                    *pointer;
61 
62 /* Define the counters used in the test application...  */
63 
64 #ifndef FX_STANDALONE_ENABLE
65 static UCHAR                    *cache_buffer;
66 static UCHAR                    *fault_tolerant_buffer;
67 static UCHAR                    *thread_1_buffer;
68 static UCHAR                    *thread_2_buffer;
69 #else
70 static UCHAR                    cache_buffer[CACHE_SIZE];
71 static UCHAR                    fault_tolerant_buffer[FAULT_TOLERANT_SIZE];
72 #endif
73 static UINT                     error_couter = 0;
74 static UINT                     directory_write_interrupt_1 = FX_FALSE;
75 static UINT                     directory_write_interrupt_2 = FX_FALSE;
76 static CHAR                     write_buffer[4096];
77 static UINT                     write_buffer_size = 4096;
78 static UINT                     write_index;
79 static CHAR                     read_buffer[4096];
80 static UINT                     read_buffer_size = 4096;
81 static UINT                     i;
82 
83 #define TEST_COUNT              3            /* FAT12, 16, 32.  */
84 
85 /* Define thread prototypes.  */
86 
87 static void    ftest_0_entry(ULONG thread_input);
88 #ifndef FX_STANDALONE_ENABLE
89 static void    ftest_1_entry(ULONG thread_input);
90 static void    ftest_2_entry(ULONG thread_input);
91 #else
92 static void   * ftest_1_entry(void * thread_input);
93 static void   * ftest_2_entry(void * thread_input);
94 #endif
95 extern void    _fx_ram_driver(FX_MEDIA *media_ptr);
96 extern void    test_control_return(UINT status);
97 extern UINT    _filex_fault_tolerant_log_check(FX_MEDIA *media_ptr);
98 extern UINT    (*driver_write_callback)(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
99 static UINT    my_driver_write_1(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
100 static UINT    my_driver_write_2(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr);
101 
102 
103 
104 /* Define what the initial system looks like.  */
105 
106 #ifdef CTEST
test_application_define(void * first_unused_memory)107 void test_application_define(void *first_unused_memory)
108 #else
109 void    filex_fault_tolerant_log_recover_directory_test_application_define(void *first_unused_memory)
110 #endif
111 {
112 
113 
114 #ifndef FX_STANDALONE_ENABLE
115     /* Setup the working pointer.  */
116     pointer =  (UCHAR *) first_unused_memory;
117 
118     /* Create the main thread.  */
119 
120     tx_thread_create(&ftest_0, "thread 0", ftest_0_entry, 0,
121             pointer, DEMO_STACK_SIZE,
122             4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
123 
124     pointer =  pointer + DEMO_STACK_SIZE;
125 
126     /* Setup memory for the RAM disk and the sector cache.  */
127     cache_buffer =  pointer;
128     pointer += CACHE_SIZE;
129     fault_tolerant_buffer = pointer;
130     pointer += FAULT_TOLERANT_SIZE;
131     thread_1_buffer = pointer;
132     pointer += DEMO_STACK_SIZE;
133     thread_2_buffer = pointer;
134     pointer += DEMO_STACK_SIZE;
135 #endif
136 
137     /* Initialize the FileX system.  */
138     fx_system_initialize();
139 #ifdef FX_STANDALONE_ENABLE
140     ftest_0_entry(0);
141 #endif
142 }
143 
144 
145 
146 /* Define the test threads.  */
147 
ftest_0_entry(ULONG thread_input)148 static void    ftest_0_entry(ULONG thread_input)
149 {
150 
151 UINT        status;
152 ULONG       actual;
153 
154     FX_PARAMETER_NOT_USED(thread_input);
155 
156     /* Print out some test information banners.  */
157     printf("FileX Test:   Fault Tolerant Log Recover DIR Test....................");
158 
159     /* Random genearte the write data.  */
160     for (write_index = 0; write_index < write_buffer_size; write_index ++)
161         write_buffer[write_index] = (CHAR)rand();
162 
163     /* Loop to test FAT 12, 16, 32.   */
164     for (i = 0; i < TEST_COUNT; i ++)
165     {
166         if (i == 0)
167         {
168             /* Format the media with FAT12.  This needs to be done before opening it!  */
169             status =  fx_media_format(&ram_disk,
170                                      _fx_ram_driver,         // Driver entry
171                                      ram_disk_memory_large,  // RAM disk memory pointer
172                                      cache_buffer,           // Media buffer pointer
173                                      CACHE_SIZE,             // Media buffer size
174                                      "MY_RAM_DISK",          // Volume Name
175                                      1,                      // Number of FATs
176                                      32,                     // Directory Entries
177                                      0,                      // Hidden sectors
178                                      256,                    // Total sectors
179                                      256,                    // Sector size
180                                      8,                      // Sectors per cluster
181                                      1,                      // Heads
182                                      1);                     // Sectors per track
183         }
184         else if (i == 1)
185         {
186             /* Format the media with FAT16.  This needs to be done before opening it!  */
187             status =  fx_media_format(&ram_disk,
188                                      _fx_ram_driver,         // Driver entry
189                                      ram_disk_memory_large,  // RAM disk memory pointer
190                                      cache_buffer,           // Media buffer pointer
191                                      CACHE_SIZE,             // Media buffer size
192                                      "MY_RAM_DISK",          // Volume Name
193                                      1,                      // Number of FATs
194                                      32,                     // Directory Entries
195                                      0,                      // Hidden sectors
196                                      4200 * 8,               // Total sectors
197                                      256,                    // Sector size
198                                      8,                      // Sectors per cluster
199                                      1,                      // Heads
200                                      1);                     // Sectors per track
201         }
202         else if (i == 2)
203         {
204             /* Format the media with FAT32.  This needs to be done before opening it!  */
205             status =  fx_media_format(&ram_disk,
206                                      _fx_ram_driver,         // Driver entry
207                                      ram_disk_memory_large,  // RAM disk memory pointer
208                                      cache_buffer,           // Media buffer pointer
209                                      CACHE_SIZE,             // Media buffer size
210                                      "MY_RAM_DISK",          // Volume Name
211                                      1,                      // Number of FATs
212                                      32,                     // Directory Entries
213                                      0,                      // Hidden sectors
214                                      70000 * 8,              // Total sectors
215                                      256,                    // Sector size
216                                      8,                      // Sectors per cluster
217                                      1,                      // Heads
218                                      1);                     // Sectors per track
219         }
220 
221         /* Determine if the format had an error.  */
222         if (status)
223         {
224 
225             printf("ERROR!\n");
226             test_control_return(1);
227         }
228 
229         /* Open the ram_disk.  */
230         status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
231 
232         /* Check the status.  */
233         if (status != FX_SUCCESS)
234         {
235 
236             /* Error, return error code.  */
237             printf("ERROR!\n");
238             test_control_return(2);
239         }
240 
241         /* Enable the Fault-tolerant feature.  */
242         status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
243 
244         /* Check status.   */
245         if (status)
246         {
247 
248             printf("ERROR!\n");
249             test_control_return(3);
250         }
251 
252         /* Create a file called TEST.TXT in the root directory.  */
253         status =  fx_file_create(&ram_disk, "TEST.TXT");
254 
255         /* Check the create status.  */
256         if (status != FX_SUCCESS)
257         {
258 
259             printf("ERROR!\n");
260             test_control_return(4);
261         }
262 
263         /* Open the test file.  */
264         status =  fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
265 
266         /* Check the file open status.  */
267         if (status != FX_SUCCESS)
268         {
269 
270             printf("ERROR!\n");
271             test_control_return(5);
272         }
273 
274         /* Write a string to the test file.  */
275         status =  fx_file_write(&my_file, " ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", 28);
276 
277         /* Check the file write status.  */
278         if (status != FX_SUCCESS)
279         {
280 
281             printf("ERROR!\n");
282             test_control_return(6);
283         }
284 
285         /* Seek to the beginning of the test file.  */
286         status =  fx_file_seek(&my_file, 0);
287 
288         /* Check the file seek status.  */
289         if (status != FX_SUCCESS)
290         {
291 
292             printf("ERROR!\n");
293             test_control_return(7);
294         }
295 
296         /* Clean the buffer.  */
297         memset(read_buffer, 0, read_buffer_size);
298 
299         /* Read the bytes of the test file.  */
300         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
301 
302         /* Check the file read status.  */
303         if ((status != FX_SUCCESS) || (actual != 28))
304         {
305 
306             printf("ERROR!\n");
307             test_control_return(8);
308         }
309 
310         /* Close the test file.  */
311         status =  fx_file_close(&my_file);
312 
313         /* Check the file close status.  */
314         if (status != FX_SUCCESS)
315         {
316 
317             printf("ERROR!\n");
318             test_control_return(9);
319         }
320 
321         /* Create a file called TEST1.TXT in the root directory.  */
322         status =  fx_file_create(&ram_disk, "TEST1.TXT");
323 
324         /* Check the create status.  */
325         if (status != FX_SUCCESS)
326         {
327 
328             printf("ERROR!\n");
329             test_control_return(10);
330         }
331 
332         /* Open the test file.  */
333         status =  fx_file_open(&ram_disk, &my_file, "TEST1.TXT", FX_OPEN_FOR_WRITE);
334 
335         /* Check the file open status.  */
336         if (status != FX_SUCCESS)
337         {
338 
339             printf("ERROR!\n");
340             test_control_return(11);
341         }
342 
343         /* Write a string to the test file.  */
344         status =  fx_file_write(&my_file, (void *) write_buffer, 1000);
345 
346         /* Check the file write status.  */
347         if (status != FX_SUCCESS)
348         {
349 
350             printf("ERROR!\n");
351             test_control_return(12);
352         }
353 
354         /* Seek to the beginning of the test file.  */
355         status =  fx_file_seek(&my_file, 0);
356 
357         /* Check the file seek status.  */
358         if (status != FX_SUCCESS)
359         {
360 
361             printf("ERROR!\n");
362             test_control_return(13);
363         }
364 
365         /* Clean the buffer.  */
366         memset(read_buffer, 0, read_buffer_size);
367 
368         /* Read the bytes of the test file.  */
369         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
370 
371         /* Check the file read status.  */
372         if ((status != FX_SUCCESS) || (actual != 1000))
373         {
374 
375             printf("ERROR!\n");
376             test_control_return(14);
377         }
378 
379         /* Close the test file.  */
380         status =  fx_file_close(&my_file);
381 
382         /* Check the file close status.  */
383         if (status != FX_SUCCESS)
384         {
385 
386             printf("ERROR!\n");
387             test_control_return(15);
388         }
389 
390         /* Create a file called TEST2.TXT in the root directory.  */
391         status =  fx_file_create(&ram_disk, "TEST2.TXT");
392 
393         /* Check the create status.  */
394         if (status != FX_SUCCESS)
395         {
396 
397             printf("ERROR!\n");
398             test_control_return(16);
399         }
400 
401         /* Open the test file.  */
402         status =  fx_file_open(&ram_disk, &my_file, "TEST2.TXT", FX_OPEN_FOR_WRITE);
403 
404         /* Check the file open status.  */
405         if (status != FX_SUCCESS)
406         {
407 
408             printf("ERROR!\n");
409             test_control_return(17);
410         }
411 
412         /* Write a string to the test file.  */
413         status =  fx_file_write(&my_file, " EXPRESSLOGIC_TEST\n", 19);
414 
415         /* Check the file write status.  */
416         if (status != FX_SUCCESS)
417         {
418 
419             printf("ERROR!\n");
420             test_control_return(18);
421         }
422 
423         /* Seek to the beginning of the test file.  */
424         status =  fx_file_seek(&my_file, 0);
425 
426         /* Check the file seek status.  */
427         if (status != FX_SUCCESS)
428         {
429 
430             printf("ERROR!\n");
431             test_control_return(19);
432         }
433 
434         /* Clean the buffer.  */
435         memset(read_buffer, 0, read_buffer_size);
436 
437         /* Read the bytes of the test file.  */
438         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
439 
440         /* Check the file read status.  */
441         if ((status != FX_SUCCESS) || (actual != 19))
442         {
443 
444             printf("ERROR!\n");
445             test_control_return(20);
446         }
447 
448         /* Close the test file.  */
449         status =  fx_file_close(&my_file);
450 
451         /* Check the file close status.  */
452         if (status != FX_SUCCESS)
453         {
454 
455             printf("ERROR!\n");
456             test_control_return(21);
457         }
458 
459         /* Create the new thread.  */
460 #ifndef FX_STANDALONE_ENABLE
461         tx_thread_create(&ftest_1, "thread 1", ftest_1_entry, 0,
462                         thread_1_buffer, DEMO_STACK_SIZE,
463                         4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
464 #endif
465         /* directory_write_interrupt */
466         directory_write_interrupt_1 = FX_FALSE;
467 
468         /* Let the other thread run.  */
469 #ifndef FX_STANDALONE_ENABLE
470         tx_thread_relinquish();
471 #else
472         pthread_create(&ptid1, NULL, &ftest_1_entry, NULL);
473         usleep(10);
474         pthread_join(ptid1,NULL);
475 
476 #endif
477 
478         /* Delete the thread.  */
479 #ifndef FX_STANDALONE_ENABLE
480         tx_thread_delete(&ftest_1);
481 
482         /* Create the new thread.  */
483         tx_thread_create(&ftest_2, "thread 2", ftest_2_entry, 0,
484                         thread_2_buffer, DEMO_STACK_SIZE,
485                         4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
486 #else
487         pthread_cancel(ptid1);
488 #endif
489         /* directory_write_interrupt */
490         directory_write_interrupt_2 = FX_FALSE;
491 
492         /* Let the other thread run.  */
493 #ifndef FX_STANDALONE_ENABLE
494         tx_thread_relinquish();
495 #else
496         pthread_create(&ptid2, NULL, &ftest_2_entry, NULL);
497         usleep(10);
498         pthread_join(ptid2,NULL);
499 
500 #endif
501 
502         /* Recover the log again.  */
503 
504         /* Open the ram_disk.  */
505         status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
506 
507         /* Check the status.  */
508         if (status != FX_SUCCESS)
509         {
510 
511             /* Error, return error code.  */
512             printf("ERROR!\n");
513             test_control_return(22);
514         }
515 
516         /* Enable the Fault-tolerant feature to recover the media.  */
517         status = fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
518 
519         /* Check status.   */
520         if (status)
521         {
522 
523             printf("ERROR!\n");
524             test_control_return(23);
525         }
526 
527         /* Open the test file.  */
528         status =  fx_file_open(&ram_disk, &my_file, "TEST.TXT", FX_OPEN_FOR_WRITE);
529 
530         /* Check the file open status.  */
531         if (status != FX_SUCCESS)
532         {
533 
534             printf("ERROR!\n");
535             test_control_return(24);
536         }
537 
538         /* Seek to the beginning of the test file.  */
539         status =  fx_file_seek(&my_file, 0);
540 
541         /* Check the file seek status.  */
542         if (status != FX_SUCCESS)
543         {
544 
545             printf("ERROR!\n");
546             test_control_return(25);
547         }
548 
549         /* Clean the buffer.  */
550         memset(read_buffer, 0, read_buffer_size);
551 
552         /* Read the bytes of the test file.  */
553         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
554 
555         /* Check the file read status.  */
556         if ((status != FX_SUCCESS) || (actual != 28) || memcmp(read_buffer, " ABCDEFGHIJKLMNOPQRSTUVWXYZ\n", actual))
557         {
558 
559             printf("ERROR!\n");
560             test_control_return(26);
561         }
562 
563         /* Close the test file.  */
564         status =  fx_file_close(&my_file);
565 
566         /* Check the file close status.  */
567         if (status != FX_SUCCESS)
568         {
569 
570             printf("ERROR!\n");
571             test_control_return(27);
572         }
573 
574         /* Open the test file.  */
575         status =  fx_file_open(&ram_disk, &my_file, "TEST1.TXT", FX_OPEN_FOR_WRITE);
576 
577         /* Check the file open status.  */
578         if (status != FX_SUCCESS)
579         {
580 
581             printf("ERROR!\n");
582             test_control_return(28);
583         }
584 
585         /* Seek to the beginning of the test file.  */
586         status =  fx_file_seek(&my_file, 0);
587 
588         /* Check the file seek status.  */
589         if (status != FX_SUCCESS)
590         {
591 
592             printf("ERROR!\n");
593             test_control_return(29);
594         }
595 
596         /* Clean the buffer.  */
597         memset(read_buffer, 0, read_buffer_size);
598 
599         /* Read the bytes of the test file.  */
600         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
601 
602         /* Check the file read status.  */
603         if ((status != FX_SUCCESS) || (actual != 2048 + 1000) || memcmp(read_buffer, write_buffer, actual))
604         {
605 
606             printf("ERROR!\n");
607             test_control_return(30);
608         }
609 
610         /* Close the test file.  */
611         status =  fx_file_close(&my_file);
612 
613         /* Check the file close status.  */
614         if (status != FX_SUCCESS)
615         {
616 
617             printf("ERROR!\n");
618             test_control_return(31);
619         }
620 
621         /* Open the test file.  */
622         status =  fx_file_open(&ram_disk, &my_file, "TEST2.TXT", FX_OPEN_FOR_WRITE);
623 
624         /* Check the file open status.  */
625         if (status != FX_SUCCESS)
626         {
627 
628             printf("ERROR!\n");
629             test_control_return(32);
630         }
631 
632         /* Seek to the beginning of the test file.  */
633         status =  fx_file_seek(&my_file, 0);
634 
635         /* Check the file seek status.  */
636         if (status != FX_SUCCESS)
637         {
638 
639             printf("ERROR!\n");
640             test_control_return(33);
641         }
642 
643         /* Clean the buffer.  */
644         memset(read_buffer, 0, read_buffer_size);
645 
646         /* Read the bytes of the test file.  */
647         status =  fx_file_read(&my_file, read_buffer, read_buffer_size, &actual);
648 
649         /* Check the file read status.  */
650         if ((status != FX_SUCCESS) || (actual != 19) || memcmp(read_buffer, " EXPRESSLOGIC_TEST\n", actual))
651         {
652 
653             printf("ERROR!\n");
654             test_control_return(34);
655         }
656 
657         /* Close the test file.  */
658         status =  fx_file_close(&my_file);
659 
660         /* Check the file close status.  */
661         if (status != FX_SUCCESS)
662         {
663 
664             printf("ERROR!\n");
665             test_control_return(35);
666         }
667 
668         /* Close the media.  */
669         status =  fx_media_close(&ram_disk);
670 
671         /* Determine if the test was successful.  */
672         if ((status != FX_SUCCESS) || (directory_write_interrupt_1 != FX_TRUE) || (directory_write_interrupt_2 != FX_TRUE) || (error_couter))
673         {
674 
675             printf("ERROR!\n");
676             test_control_return(36);
677         }
678 
679         /* Delete the thread.  */
680 #ifndef FX_STANDALONE_ENABLE
681         tx_thread_delete(&ftest_2);
682 #else
683         pthread_cancel(ptid2);
684 #endif
685     }
686 
687     /* Output successful.  */
688     printf("SUCCESS!\n");
689     test_control_return(0);
690 }
691 
692 /* Define the test threads.  */
693 
694 #ifndef FX_STANDALONE_ENABLE
ftest_1_entry(ULONG thread_input)695 static void    ftest_1_entry(ULONG thread_input)
696 #else
697  void  *  ftest_1_entry(void * thread_input)
698 #endif
699 {
700 #ifdef FX_STANDALONE_ENABLE
701     UINT oldtype;
702     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
703     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
704 #endif
705     UINT        status;
706 
707     FX_PARAMETER_NOT_USED(thread_input);
708 
709     /* Set the callback function to simulate poweoff operation when write directory.  */
710     driver_write_callback = my_driver_write_1;
711 
712     /* Open the test file.  */
713     status =  fx_file_open(&ram_disk, &my_file, "TEST1.TXT", FX_OPEN_FOR_WRITE);
714 
715     /* Check the file open status.  */
716     if (status != FX_SUCCESS)
717     {
718         error_couter ++;
719 #ifndef FX_STANDALONE_ENABLE
720         return;
721 #else
722         return NULL;
723 #endif
724     }
725 
726     /* Write 2048 bytes to the file, then update the directory.  (bytes should be greate than one cluster).  */
727     fx_file_write(&my_file, (void *) (write_buffer + 1000), 2048);
728 }
729 
730 #ifndef FX_STANDALONE_ENABLE
ftest_2_entry(ULONG thread_input)731 static void    ftest_2_entry(ULONG thread_input)
732 #else
733 static void  *  ftest_2_entry(void * thread_input)
734 #endif
735 {
736 #ifdef FX_STANDALONE_ENABLE
737     UINT oldtype;
738     pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
739     pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
740 #endif
741 
742     UINT        status;
743 
744     FX_PARAMETER_NOT_USED(thread_input);
745 
746     /* Open the ram_disk.  */
747     status =  fx_media_open(&ram_disk, "RAM DISK", _fx_ram_driver, ram_disk_memory_large, cache_buffer, CACHE_SIZE);
748 
749     /* Check the status.  */
750     if (status != FX_SUCCESS)
751     {
752 
753         error_couter ++;
754 #ifndef FX_STANDALONE_ENABLE
755         return;
756 #else
757         return NULL;
758 #endif
759     }
760 
761     /* Set the callback function to simulate poweoff operation when recover the directory.  */
762     driver_write_callback = my_driver_write_2;
763 
764     /* Enable the Fault-tolerant feature to recover the media.  */
765     fx_fault_tolerant_enable(&ram_disk, fault_tolerant_buffer, FAULT_TOLERANT_SIZE);
766 }
767 
my_driver_write_1(FX_MEDIA * media_ptr,UINT sector_type,UCHAR * block_ptr,UINT * operation_ptr)768 static UINT my_driver_write_1(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr)
769 {
770 
771     FX_PARAMETER_NOT_USED(block_ptr);
772 
773     /* Interrupt the directory write operation.  */
774     if ((sector_type == FX_DIRECTORY_SECTOR) && (_filex_fault_tolerant_log_check(media_ptr) & FX_FAULT_TOLERANT_LOG_REDO_DONE))
775     {
776 
777         /* Set the write interrupt operation.  */
778         *operation_ptr = FX_OP_WRITE_INTERRUPT;
779 
780         /* Update the flag.  */
781         directory_write_interrupt_1 = FX_TRUE;
782 
783         /* Clean the callback function.  */
784         driver_write_callback = FX_NULL;
785 
786         /* Delete the media protection structure if FX_SINGLE_THREAD is not
787         defined.  */
788 #ifndef FX_SINGLE_THREAD
789 #ifndef FX_DONT_CREATE_MUTEX
790 
791         /* Note that the protection is never released. The mutex delete
792         service will handle all threads waiting access to this media
793         control block.  */
794         tx_mutex_delete(&(media_ptr -> fx_media_protect));
795 #endif
796 #endif
797 
798         /* Clean the media data.  */
799         _fx_system_media_opened_ptr = FX_NULL;
800         _fx_system_media_opened_count = 0;
801 
802         /* Clean the media.  */
803         memset(media_ptr, 0, sizeof(FX_MEDIA));
804 
805         /* Simulate poweroff.  */
806         /* First terminate the thread to ensure it is ready for deletion.  */
807 #ifndef FX_STANDALONE_ENABLE
808         tx_thread_terminate(&ftest_1);
809 #else
810         pthread_cancel(ptid1);
811 #endif
812     }
813 
814     /* Return.  */
815     return FX_SUCCESS;
816 }
817 
my_driver_write_2(FX_MEDIA * media_ptr,UINT sector_type,UCHAR * block_ptr,UINT * operation_ptr)818 static UINT my_driver_write_2(FX_MEDIA *media_ptr, UINT sector_type, UCHAR *block_ptr, UINT *operation_ptr)
819 {
820 
821     FX_PARAMETER_NOT_USED(block_ptr);
822 
823     /* Interrupt the directory write operation.  */
824     if (sector_type == FX_DIRECTORY_SECTOR)
825     {
826 
827         /* Set the write interrupt operation.  */
828         *operation_ptr = FX_OP_WRITE_INTERRUPT;
829 
830         /* Update the flag.  */
831         directory_write_interrupt_2 = FX_TRUE;
832 
833         /* Clean the callback function.  */
834         driver_write_callback = FX_NULL;
835 
836         /* Delete the media protection structure if FX_SINGLE_THREAD is not
837         defined.  */
838 #ifndef FX_SINGLE_THREAD
839 #ifndef FX_DONT_CREATE_MUTEX
840 
841         /* Note that the protection is never released. The mutex delete
842         service will handle all threads waiting access to this media
843         control block.  */
844         tx_mutex_delete(&(media_ptr -> fx_media_protect));
845 #endif
846 #endif
847 
848         /* Clean the media data.  */
849         _fx_system_media_opened_ptr = FX_NULL;
850         _fx_system_media_opened_count = 0;
851 
852         /* Clean the media.  */
853         memset(media_ptr, 0, sizeof(FX_MEDIA));
854 
855         /* Simulate poweroff.  */
856         /* First terminate the thread to ensure it is ready for deletion.  */
857 #ifndef FX_STANDALONE_ENABLE
858         tx_thread_terminate(&ftest_2);
859 #else
860         pthread_cancel(ptid2);
861 #endif
862     }
863 
864     /* Return.  */
865     return FX_SUCCESS;
866 }
867 
868 #else
869 
870 #ifdef CTEST
test_application_define(void * first_unused_memory)871 void test_application_define(void *first_unused_memory)
872 #else
873 void    filex_fault_tolerant_log_recover_directory_test_application_define(void *first_unused_memory)
874 #endif
875 {
876 
877     FX_PARAMETER_NOT_USED(first_unused_memory);
878 
879     /* Print out some test information banners.  */
880     printf("FileX Test:   Fault Tolerant Log Recover DIR Test....................N/A\n");
881 
882     test_control_return(255);
883 }
884 #endif
885 
886