Mercurial > yaffs-ecoscentric
comparison direct/nor_stress.c @ 233:d48d8f8a93a2
Some fixes and add NOR integrity code
| author | charles |
|---|---|
| date | Fri, 07 Nov 2008 00:36:36 +0000 |
| parents | |
| children | d74a9a8c1f49 |
comparison
equal
deleted
inserted
replaced
| 232:26a5a095ef02 | 233:d48d8f8a93a2 |
|---|---|
| 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 } |
