Some fixes and add NOR integrity code
[yaffs2.git] / direct / nor_stress.c
1 #include "nor_stress.h"
2
3
4 #include "yaffsfs.h"
5
6 #include <stdio.h>
7
8
9
10 static unsigned powerUps;
11 static unsigned cycleStarts;
12 static unsigned cycleEnds;
13
14
15 char fullPathName[100];
16 char fullPowerUpName[100];
17 char fullStartName[100];
18 char fullEndName[100];
19 char fullMainName[100];
20 char fullTempMainName[100];
21 char fullTempCounterName[100];
22
23
24 void MakeName(char *fullName,const char *prefix, const char *name)
25 {
26   strcpy(fullName,prefix);
27   strcat(fullName,"/");
28   strcat(fullName,name);
29 }
30
31
32 void MakeFullNames(const char *prefix)
33 {
34   MakeName(fullPathName,prefix,"");
35   MakeName(fullPowerUpName,prefix,"powerUps");
36   MakeName(fullStartName,prefix,"starts");
37   MakeName(fullEndName,prefix,"ends");
38   MakeName(fullMainName,prefix,"main");
39   MakeName(fullTempCounterName,prefix,"tmp-counter");
40   MakeName(fullTempMainName,prefix,"tmp-main");
41 }
42
43 static void FatalError(void)
44 {
45   printf("Integrity error\n");
46   while(1){}
47 }
48
49 static void UpdateCounter(const char *name, unsigned *val,  int initialise)
50 {
51   int inh;
52   int outh;
53   unsigned x[2];
54   int nread = 0;
55   int nwritten = 0;
56   
57   x[0] = x[1] = 0;
58   
59   if(initialise){
60     x[0] = 0; 
61     x[1] = 1;
62   } else {
63     inh = yaffs_open(name,O_RDONLY, S_IREAD | S_IWRITE);
64     if(inh >= 0){
65       nread = yaffs_read(inh,x,sizeof(x));
66       yaffs_close(inh);
67     }
68
69     if(nread != sizeof(x) ||
70        x[0] + 1 != x[1]){
71       printf("Error reading counter %s handle %d, x[0] %u x[1] %u last error %d\n",
72               name, inh, x[0], x[1],yaffsfs_GetLastError());
73       FatalError();
74               
75     }
76     x[0]++;
77     x[1]++;
78   }
79   
80   outh = yaffs_open(fullTempCounterName, O_RDWR | O_TRUNC | O_CREAT, S_IREAD | S_IWRITE);
81   if(outh >= 0){
82     nwritten = yaffs_write(outh,x,sizeof(x));
83     yaffs_close(outh);
84     yaffs_rename(fullTempCounterName,name);
85   }
86   
87   if(nwritten != sizeof(x)){
88       printf("Error writing counter %s handle %d, x[0] %u x[1] %u\n",
89               name, inh, x[0], x[1]);
90       FatalError();
91   }
92   
93   *val = x[0];
94   
95   printf("##\n"
96          "## Set counter %s to %u\n"
97          "##\n", name,x[0]);
98 }
99
100
101 static void dump_directory_tree_worker(const char *dname,int recursive)
102 {
103         yaffs_DIR *d;
104         yaffs_dirent *de;
105         struct yaffs_stat s;
106         char str[1000];
107                         
108         d = yaffs_opendir(dname);
109         
110         if(!d)
111         {
112                 printf("opendir failed\n");
113         }
114         else
115         {
116                 while((de = yaffs_readdir(d)) != NULL)
117                 {
118                         strcpy(str,dname);
119                         strcat(str,"/");
120                         strcat(str,de->d_name);
121                         
122                         yaffs_lstat(str,&s);
123                         
124                         printf("%s inode %d obj %x length %d mode %X ",str,s.st_ino,de->d_dont_use,(int)s.st_size,s.st_mode);
125                         switch(s.st_mode & S_IFMT)
126                         {
127                                 case S_IFREG: printf("data file"); break;
128                                 case S_IFDIR: printf("directory"); break;
129                                 case S_IFLNK: printf("symlink -->");
130                                                           if(yaffs_readlink(str,str,100) < 0)
131                                                                 printf("no alias");
132                                                           else
133                                                                 printf("\"%s\"",str);    
134                                                           break;
135                                 default: printf("unknown"); break;
136                         }
137                         
138                         printf("\n");
139
140                         if((s.st_mode & S_IFMT) == S_IFDIR && recursive)
141                                 dump_directory_tree_worker(str,1);
142                                                         
143                 }
144                 
145                 yaffs_closedir(d);
146         }
147
148 }
149
150 static void dump_directory_tree(const char *dname)
151 {
152         dump_directory_tree_worker(dname,1);
153         printf("\n");
154         printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname));
155 }
156
157
158
159
160 #define XX_SIZE 500
161
162 static unsigned xx[XX_SIZE];
163
164 static int yWriteFile(const char *fname, unsigned sz32)
165 {
166         int h;
167         int r;
168         int i;
169         unsigned checksum = 0;
170         
171         printf("Writing file %s\n",fname);
172
173         h = yaffs_open(fname,O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE);
174
175         if(h < 0){
176                 printf("could not open file %s\n",fname);
177                 return h;
178         }
179
180         xx[0] = sz32;
181         checksum ^= xx[0];
182
183         if((r = yaffs_write(h,xx,sizeof(unsigned))) != sizeof(unsigned)){
184                 goto WRITE_ERROR;
185         }
186                 
187         while(sz32> 0){
188                 for(i = 0; i < XX_SIZE; i++){
189                   xx[i] = sz32 + i;
190                   checksum ^= xx[i];
191                 }
192
193                 if((r = yaffs_write(h,xx,sizeof(xx))) != sizeof(xx)){
194                         goto WRITE_ERROR;
195                 }
196                 sz32--;
197         }
198
199         xx[0] = checksum;
200
201         if((r = yaffs_write(h,xx,sizeof(unsigned))) != sizeof(unsigned)){
202                 goto WRITE_ERROR;
203         }
204         
205         
206         yaffs_close(h);
207         return 0;
208
209 WRITE_ERROR:
210         printf("ywrite error at position %d\n",(int)yaffs_lseek(h,0,SEEK_END));
211         yaffs_close(h);
212         return -1;
213         
214 }
215
216 static int yVerifyFile(const char *fName)
217 {
218         unsigned checksum = 0;
219         unsigned totalSize;
220         unsigned sz32;
221         unsigned recordedSize = 0;
222         int r;
223         int h;
224         int i;
225         int retval = 0;
226
227
228         printf("Verifying file %s\n",fName);
229                 
230         h = yaffs_open(fName, O_RDONLY,S_IREAD | S_IWRITE);
231
232         if(h < 0){
233                 printf("could not open file %s\n",fName);
234                 return -1;
235         }
236
237         totalSize = yaffs_lseek(h,0,SEEK_END);
238         yaffs_lseek(h,0,SEEK_SET);
239
240         r = yaffs_read(h,&sz32,sizeof(sz32));
241
242         if(r != sizeof(sz32)){
243                 printf("reading size failed ... returned %d\n",r);
244                 yaffs_close(h);
245                 return -1;
246         }
247         
248         recordedSize = sz32 * sizeof(xx) + 8;
249
250         printf("verify %s: file size is %d, recorded size is %d\n", fName, totalSize, recordedSize);
251         if(totalSize != recordedSize){
252                 printf("!!!!!!!!!!!!!!!!!!!!!!!!file size is wrong, should be %d, is %d\n", recordedSize,totalSize);
253                 yaffs_close(h);
254                 return -1;
255         }
256
257         checksum ^= sz32;
258
259
260         while(sz32 > 0){
261                 r = yaffs_read(h,xx,sizeof(xx));
262                 if(r != sizeof(xx)){
263                         printf("!!!!!!!!!!!!!!!!!!!!!!!!!!reading data failed ... returned %d\n",r);
264                         yaffs_close(h);
265                         return -1;
266                 }
267                 for(i = 0; i < XX_SIZE; i++)
268                   checksum ^= xx[i];
269                 sz32--;
270         }
271         r = yaffs_read(h,xx,sizeof(xx[0]));
272         if(r != sizeof(xx[0])){
273                 printf("!!!!!!!!!!!!!!!!!!!!!!!!!!reading data failed ... returned %d\n",r);
274                 yaffs_close(h);
275                 return -1;
276         }
277         
278         checksum ^= xx[0];
279
280         if(checksum != 0){
281                 printf("!!!!!!!!!!!!!!!!!!!!! checksum failed\n");
282                 retval = -1;
283         } else
284                 printf("verified ok\n");
285         yaffs_close(h);
286
287         return retval;
288 }
289
290 static unsigned long next = 1;
291 int myrand(void) {
292   next = next * 1103515245 + 12345;
293   return((unsigned)(next/65536) % 32768);
294 }
295
296 static void DoUpdateMainFile(void)
297 {
298         int result;
299         int sz32;
300         sz32 = (myrand() % 1000)   + 20;
301         
302         result = yWriteFile(fullTempMainName,sz32);
303         if(result)
304             FatalError();
305         yaffs_rename(fullTempMainName,fullMainName);
306 }
307
308 static void DoVerifyMainFile(void)
309 {
310         int result;
311         result = yVerifyFile(fullMainName);
312         if(result)
313             FatalError();
314
315 }
316
317
318 void NorStressTestInitialise(const char *prefix)
319 {
320   MakeFullNames(prefix);
321   
322   yaffs_StartUp();
323   yaffs_mount(fullPathName);
324   UpdateCounter(fullPowerUpName,&powerUps,1);
325   UpdateCounter(fullStartName,&cycleStarts,1);
326   UpdateCounter(fullEndName,&cycleEnds,1);
327   UpdateCounter(fullPowerUpName,&powerUps,1);
328   DoUpdateMainFile();
329   DoVerifyMainFile();
330   yaffs_unmount(fullPathName);
331 }
332
333
334 void NorStressTestRun(const char *prefix)
335 {
336   MakeFullNames(prefix);
337
338   yaffs_StartUp();
339   yaffs_mount(fullPathName);
340   
341   dump_directory_tree(fullPathName);
342   
343   UpdateCounter(fullPowerUpName,&powerUps,0);
344   
345   while(1){
346     UpdateCounter(fullStartName, &cycleStarts,0);
347     DoVerifyMainFile();
348     DoUpdateMainFile();
349     dump_directory_tree(fullPathName);
350   
351     UpdateCounter(fullEndName,&cycleEnds,0);
352   }
353 }