Line data Source code
1 : /*
2 : * Copyright (C) 2011 Andrea Mazzoleni
3 : *
4 : * This program is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * This program is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "portable.h"
19 :
20 : #include "support.h"
21 :
22 : /****************************************************************************/
23 : /* random */
24 :
25 : /**
26 : * Pseudo random number generator.
27 : */
28 : unsigned long long seed = 0;
29 :
30 55864576 : unsigned rnd(unsigned max)
31 : {
32 55864576 : seed = seed * 6364136223846793005LL + 1442695040888963407LL;
33 :
34 55864576 : return (seed >> 32) % max;
35 : }
36 :
37 55453401 : unsigned rndnz(unsigned max)
38 : {
39 55453401 : if (max <= 1)
40 2831 : return 1;
41 : else
42 55450570 : return rnd(max - 1) + 1;
43 : }
44 :
45 32695 : void rndnz_range(unsigned char* data, int size)
46 : {
47 : int i;
48 :
49 55479340 : for (i = 0; i < size; ++i)
50 55446645 : data[i] = rndnz(256);
51 32695 : }
52 :
53 1821 : void rndnz_damage(unsigned char* data, int size)
54 : {
55 : int i;
56 :
57 : /* corrupt ensuring always different data */
58 3642 : for (i = 0; i < size; ++i) {
59 : unsigned char c;
60 :
61 : do {
62 1825 : c = rndnz(256);
63 1825 : } while (c == data[i]);
64 :
65 1821 : data[i] = c;
66 : }
67 1821 : }
68 :
69 : char CHARSET[] = "qwertyuiopasdfghjklzxcvbnm1234567890 .-+";
70 : #define CHARSET_LEN (sizeof(CHARSET) - 1)
71 :
72 26833 : void rnd_name(char* file)
73 : {
74 26833 : int l = 1 + rnd(20);
75 :
76 335293 : while (l) {
77 281627 : *file++ = CHARSET[rnd(CHARSET_LEN)];
78 281627 : --l;
79 : }
80 26833 : *file = 0;
81 26833 : }
82 :
83 : /****************************************************************************/
84 : /* file */
85 :
86 146777 : int file_cmp(const void* a, const void* b)
87 : {
88 146777 : return strcmp(a, b);
89 : }
90 :
91 1821 : int fallback(int f, struct stat* st)
92 : {
93 : #if HAVE_FUTIMENS
94 : struct timespec tv[2];
95 : #else
96 : struct timeval tv[2];
97 : #endif
98 : int ret;
99 :
100 : #if HAVE_FUTIMENS /* futimens() is preferred because it gives nanosecond precision */
101 1821 : tv[0].tv_sec = st->st_mtime;
102 1821 : if (STAT_NSEC(st) != STAT_NSEC_INVALID)
103 1821 : tv[0].tv_nsec = STAT_NSEC(st);
104 : else
105 0 : tv[0].tv_nsec = 0;
106 1821 : tv[1].tv_sec = tv[0].tv_sec;
107 1821 : tv[1].tv_nsec = tv[0].tv_nsec;
108 :
109 1821 : ret = futimens(f, tv);
110 : #elif HAVE_FUTIMES /* fallback to futimes() if nanosecond precision is not available */
111 : tv[0].tv_sec = st->st_mtime;
112 : if (STAT_NSEC(st) != STAT_NSEC_INVALID)
113 : tv[0].tv_usec = STAT_NSEC(st) / 1000;
114 : else
115 : tv[0].tv_usec = 0;
116 : tv[1].tv_sec = tv[0].tv_sec;
117 : tv[1].tv_usec = tv[0].tv_usec;
118 :
119 : ret = futimes(f, tv);
120 : #elif HAVE_FUTIMESAT /* fallback to futimesat() for Solaris, it only has futimesat() */
121 : tv[0].tv_sec = st->st_mtime;
122 : if (STAT_NSEC(st) != STAT_NSEC_INVALID)
123 : tv[0].tv_usec = STAT_NSEC(st) / 1000;
124 : else
125 : tv[0].tv_usec = 0;
126 : tv[1].tv_sec = tv[0].tv_sec;
127 : tv[1].tv_usec = tv[0].tv_usec;
128 :
129 : ret = futimesat(f, 0, tv);
130 : #else
131 : #error No function available to set file timestamps
132 : #endif
133 1821 : return ret;
134 : }
135 :
136 : /****************************************************************************/
137 : /* cmd */
138 :
139 : /**
140 : * Create a file with random content.
141 : * - If the file exists it's rewritten, but avoiding to truncating it to 0.
142 : */
143 23267 : void cmd_generate_file(const char* path, int size)
144 : {
145 : unsigned char* data;
146 : int f;
147 :
148 : /* remove the existing file/symlink if any */
149 23267 : if (remove(path) != 0) {
150 22446 : if (errno != ENOENT) {
151 : /* LCOV_EXCL_START */
152 : log_fatal("Error removing file %s\n", path);
153 : exit(EXIT_FAILURE);
154 : /* LCOV_EXCL_STOP */
155 : }
156 : } else {
157 : /* don't truncate files to 0 size to avoid ZERO file size protection */
158 821 : ++size;
159 : }
160 :
161 23267 : data = malloc(size);
162 :
163 : /* We don't write zero bytes because we want to test */
164 : /* the recovering of new files, after an aborted sync */
165 : /* If the files contains full blocks at zero */
166 : /* this is an impossible condition to recover */
167 : /* because we cannot differentiate between an unused block */
168 : /* and a file filled with 0 */
169 23267 : rndnz_range(data, size);
170 :
171 23267 : f = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_NOFOLLOW, 0600);
172 23267 : if (f < 0) {
173 : /* LCOV_EXCL_START */
174 : log_fatal("Error creating file %s\n", path);
175 : exit(EXIT_FAILURE);
176 : /* LCOV_EXCL_STOP */
177 : }
178 :
179 23267 : if (write(f, data, size) != size) {
180 : /* LCOV_EXCL_START */
181 : log_fatal("Error writing file %s\n", path);
182 : exit(EXIT_FAILURE);
183 : /* LCOV_EXCL_STOP */
184 : }
185 :
186 23267 : if (close(f) != 0) {
187 : /* LCOV_EXCL_START */
188 : log_fatal("Error closing file %s\n", path);
189 : exit(EXIT_FAILURE);
190 : /* LCOV_EXCL_STOP */
191 : }
192 :
193 23267 : free(data);
194 23267 : }
195 :
196 : /**
197 : * Create a symlink.
198 : * - If the file already exists, it's removed.
199 : */
200 924 : void cmd_generate_symlink(const char* path, const char* linkto)
201 : {
202 : /* remove the existing file/symlink if any */
203 924 : if (remove(path) != 0) {
204 903 : if (errno != ENOENT) {
205 : /* LCOV_EXCL_START */
206 : log_fatal("Error removing file %s\n", path);
207 : exit(EXIT_FAILURE);
208 : /* LCOV_EXCL_STOP */
209 : }
210 : }
211 :
212 924 : if (symlink(linkto, path) != 0) {
213 : /* LCOV_EXCL_START */
214 : log_fatal("Error writing symlink %s\n", path);
215 : exit(EXIT_FAILURE);
216 : /* LCOV_EXCL_STOP */
217 : }
218 924 : }
219 :
220 : /**
221 : * Create a file or a symlink with a random name.
222 : */
223 24000 : void cmd_generate(int disk, int size)
224 : {
225 : char path[PATH_MAX];
226 : char* file;
227 :
228 24000 : snprintf(path, sizeof(path), "bench/disk%d/", disk);
229 24000 : file = path + strlen(path);
230 :
231 : /* add a directory */
232 24000 : *file++ = 'a' + rnd(2);
233 24000 : *file = 0;
234 :
235 : /* create it */
236 24000 : if (mkdir(path, 0777) != 0) {
237 23988 : if (errno != EEXIST) {
238 : /* LCOV_EXCL_START */
239 : log_fatal("Error creating directory %s\n", path);
240 : exit(EXIT_FAILURE);
241 : /* LCOV_EXCL_STOP */
242 : }
243 : }
244 :
245 24000 : *file++ = '/';
246 :
247 : while (1) {
248 : /* add a random file */
249 25909 : rnd_name(file);
250 :
251 : /* skip some invalid file name, see http://en.wikipedia.org/wiki/Filename */
252 25909 : if (strcmp(file, ".") == 0
253 25874 : || strcmp(file, "..") == 0
254 25874 : || strcmp(file, "prn") == 0
255 25874 : || strcmp(file, "con") == 0
256 25873 : || strcmp(file, "nul") == 0
257 25873 : || strcmp(file, "aux") == 0
258 25873 : || file[0] == ' '
259 25199 : || file[strlen(file) - 1] == ' '
260 24608 : || file[strlen(file) - 1] == '.'
261 : ) {
262 1909 : continue;
263 : }
264 :
265 24000 : break;
266 1909 : }
267 :
268 : #ifndef WIN32 /* Windows XP doesn't support symlinks */
269 24000 : if (rnd(32) == 0) {
270 : /* symlink */
271 : char linkto[PATH_MAX];
272 :
273 733 : rnd_name(linkto);
274 :
275 733 : cmd_generate_symlink(path, linkto);
276 : } else
277 : #endif
278 : {
279 : /* file */
280 23267 : cmd_generate_file(path, size);
281 : }
282 24000 : }
283 :
284 : /**
285 : * Write a partially a file.
286 : * - The file must exist.
287 : * - The file size is not changed.
288 : * - The written data may be equal or not at the already existing one.
289 : * - If it's a symlink nothing is done.
290 : */
291 6265 : void cmd_write(const char* path, int size)
292 : {
293 : struct stat st;
294 :
295 6265 : if (lstat(path, &st) != 0) {
296 : /* LCOV_EXCL_START */
297 : log_fatal("Error accessing %s\n", path);
298 : exit(EXIT_FAILURE);
299 : /* LCOV_EXCL_STOP */
300 : }
301 :
302 6265 : if (S_ISREG(st.st_mode)) {
303 : unsigned char* data;
304 : off_t off;
305 : int f;
306 :
307 : /* not over the end */
308 6238 : if (size > st.st_size)
309 687 : size = st.st_size;
310 :
311 : /* start at random position inside the file */
312 6238 : if (size < st.st_size)
313 5551 : off = rnd(st.st_size - size);
314 : else
315 687 : off = 0;
316 :
317 6238 : data = malloc(size);
318 :
319 6238 : rndnz_range(data, size);
320 :
321 6238 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
322 6238 : if (f < 0) {
323 : /* LCOV_EXCL_START */
324 : log_fatal("Error creating file %s\n", path);
325 : exit(EXIT_FAILURE);
326 : /* LCOV_EXCL_STOP */
327 : }
328 :
329 6238 : if (lseek(f, off, SEEK_SET) != off) {
330 : /* LCOV_EXCL_START */
331 : log_fatal("Error seeking file %s\n", path);
332 : exit(EXIT_FAILURE);
333 : /* LCOV_EXCL_STOP */
334 : }
335 :
336 6238 : if (write(f, data, size) != size) {
337 : /* LCOV_EXCL_START */
338 : log_fatal("Error writing file %s\n", path);
339 : exit(EXIT_FAILURE);
340 : /* LCOV_EXCL_STOP */
341 : }
342 :
343 6238 : if (close(f) != 0) {
344 : /* LCOV_EXCL_START */
345 : log_fatal("Error closing file %s\n", path);
346 : exit(EXIT_FAILURE);
347 : /* LCOV_EXCL_STOP */
348 : }
349 :
350 6238 : free(data);
351 : }
352 6265 : }
353 :
354 : /**
355 : * Damage a file.
356 : * - The file must exist.
357 : * - The file size is not changed.
358 : * - The written data is SURELY different than the already existing one.
359 : * - The file timestamp is NOT modified.
360 : * - If it's a symlink nothing is done.
361 : */
362 1882 : void cmd_damage(const char* path, int size)
363 : {
364 : struct stat st;
365 :
366 : /* here a 0 size means to change nothing */
367 : /* as also the timestamp should not be changed */
368 1882 : if (!size)
369 3 : return;
370 :
371 1882 : if (lstat(path, &st) != 0) {
372 : /* LCOV_EXCL_START */
373 : log_fatal("Error accessing %s\n", path);
374 : exit(EXIT_FAILURE);
375 : /* LCOV_EXCL_STOP */
376 : }
377 :
378 1882 : if (st.st_size == 0)
379 3 : return;
380 :
381 1879 : if (S_ISREG(st.st_mode)) {
382 : off_t off;
383 : unsigned char* data;
384 : int f;
385 :
386 : /* not over the end */
387 1821 : if (size > st.st_size)
388 0 : size = st.st_size;
389 :
390 : /* start at random position inside the file */
391 1821 : if (size < st.st_size)
392 1820 : off = rnd(st.st_size - size);
393 : else
394 1 : off = 0;
395 :
396 1821 : data = malloc(size);
397 :
398 1821 : f = open(path, O_RDWR | O_BINARY | O_NOFOLLOW);
399 1821 : if (f < 0) {
400 : /* LCOV_EXCL_START */
401 : log_fatal("Error creating file %s\n", path);
402 : exit(EXIT_FAILURE);
403 : /* LCOV_EXCL_STOP */
404 : }
405 :
406 1821 : if (lseek(f, off, SEEK_SET) != off) {
407 : /* LCOV_EXCL_START */
408 : log_fatal("Error seeking file %s\n", path);
409 : exit(EXIT_FAILURE);
410 : /* LCOV_EXCL_STOP */
411 : }
412 :
413 1821 : if (read(f, data, size) != size) {
414 : /* LCOV_EXCL_START */
415 : log_fatal("Error writing file %s\n", path);
416 : exit(EXIT_FAILURE);
417 : /* LCOV_EXCL_STOP */
418 : }
419 :
420 1821 : rndnz_damage(data, size);
421 :
422 1821 : if (lseek(f, off, SEEK_SET) != off) {
423 : /* LCOV_EXCL_START */
424 : log_fatal("Error seeking file %s\n", path);
425 : exit(EXIT_FAILURE);
426 : /* LCOV_EXCL_STOP */
427 : }
428 :
429 1821 : if (write(f, data, size) != size) {
430 : /* LCOV_EXCL_START */
431 : log_fatal("Error writing file %s\n", path);
432 : exit(EXIT_FAILURE);
433 : /* LCOV_EXCL_STOP */
434 : }
435 :
436 1821 : if (fallback(f, &st) != 0) {
437 : /* LCOV_EXCL_START */
438 : log_fatal("Error setting time for file %s\n", path);
439 : exit(EXIT_FAILURE);
440 : /* LCOV_EXCL_STOP */
441 : }
442 :
443 1821 : if (close(f) != 0) {
444 : /* LCOV_EXCL_START */
445 : log_fatal("Error closing file %s\n", path);
446 : exit(EXIT_FAILURE);
447 : /* LCOV_EXCL_STOP */
448 : }
449 :
450 1821 : free(data);
451 : }
452 : }
453 :
454 : /**
455 : * Append to a file.
456 : * - The file must exist.
457 : * - If it's a symlink nothing is done.
458 : */
459 3190 : void cmd_append(const char* path, int size)
460 : {
461 : struct stat st;
462 :
463 3190 : if (lstat(path, &st) != 0) {
464 : /* LCOV_EXCL_START */
465 : log_fatal("Error accessing %s\n", path);
466 : exit(EXIT_FAILURE);
467 : /* LCOV_EXCL_STOP */
468 : }
469 :
470 3190 : if (S_ISREG(st.st_mode)) {
471 : unsigned char* data;
472 : int f;
473 :
474 3190 : data = malloc(size);
475 :
476 3190 : rndnz_range(data, size);
477 :
478 3190 : f = open(path, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW);
479 3190 : if (f < 0) {
480 : /* LCOV_EXCL_START */
481 : log_fatal("Error opening file %s\n", path);
482 : exit(EXIT_FAILURE);
483 : /* LCOV_EXCL_STOP */
484 : }
485 :
486 3190 : if (write(f, data, size) != size) {
487 : /* LCOV_EXCL_START */
488 : log_fatal("Error writing file %s\n", path);
489 : exit(EXIT_FAILURE);
490 : /* LCOV_EXCL_STOP */
491 : }
492 :
493 3190 : if (close(f) != 0) {
494 : /* LCOV_EXCL_START */
495 : log_fatal("Error closing file %s\n", path);
496 : exit(EXIT_FAILURE);
497 : /* LCOV_EXCL_STOP */
498 : }
499 :
500 3190 : free(data);
501 : }
502 3190 : }
503 :
504 : /**
505 : * Truncate a file.
506 : * - The file must exist.
507 : * - The file is NEVER truncated to 0.
508 : * - If it's a symlink nothing is done.
509 : */
510 3042 : void cmd_truncate(const char* path, int size)
511 : {
512 : struct stat st;
513 :
514 3042 : if (lstat(path, &st) != 0) {
515 : /* LCOV_EXCL_START */
516 : log_fatal("Error accessing %s\n", path);
517 : exit(EXIT_FAILURE);
518 : /* LCOV_EXCL_STOP */
519 : }
520 :
521 3042 : if (S_ISREG(st.st_mode)) {
522 : off_t off;
523 : int f;
524 :
525 : /* if file is empty, just rewrite it */
526 3042 : if (st.st_size == 0) {
527 3 : size = 0;
528 : } else {
529 : /* don't truncate files to 0 size to avoid ZERO file size protection */
530 3039 : if (size >= st.st_size)
531 162 : size = st.st_size - 1;
532 : }
533 :
534 3042 : off = st.st_size - size;
535 :
536 3042 : f = open(path, O_WRONLY | O_BINARY | O_NOFOLLOW);
537 3042 : if (f < 0) {
538 : /* LCOV_EXCL_START */
539 : log_fatal("Error opening file %s\n", path);
540 : exit(EXIT_FAILURE);
541 : /* LCOV_EXCL_STOP */
542 : }
543 :
544 3042 : if (ftruncate(f, off) != 0) {
545 : /* LCOV_EXCL_START */
546 : log_fatal("Error truncating file %s\n", path);
547 : exit(EXIT_FAILURE);
548 : /* LCOV_EXCL_STOP */
549 : }
550 :
551 3042 : if (close(f) != 0) {
552 : /* LCOV_EXCL_START */
553 : log_fatal("Error closing file %s\n", path);
554 : exit(EXIT_FAILURE);
555 : /* LCOV_EXCL_STOP */
556 : }
557 : }
558 3042 : }
559 :
560 : /**
561 : * Delete a file.
562 : * - The file must exist.
563 : */
564 3254 : void cmd_delete(const char* path)
565 : {
566 3254 : if (remove(path) != 0) {
567 : /* LCOV_EXCL_START */
568 : log_fatal("Error removing %s\n", path);
569 : exit(EXIT_FAILURE);
570 : /* LCOV_EXCL_STOP */
571 : }
572 3254 : }
573 :
574 : /**
575 : * Change a file. Or deleted/truncated/append/created.
576 : * - The file must exist.
577 : */
578 13128 : void cmd_change(const char* path, int size)
579 : {
580 : struct stat st;
581 :
582 13128 : if (!size)
583 33 : return;
584 :
585 13095 : if (lstat(path, &st) != 0) {
586 : /* LCOV_EXCL_START */
587 : log_fatal("Error accessing %s\n", path);
588 : exit(EXIT_FAILURE);
589 : /* LCOV_EXCL_STOP */
590 : }
591 :
592 13095 : if (S_ISLNK(st.st_mode)) {
593 : /* symlink */
594 393 : if (rnd(2) == 0) {
595 : /* delete */
596 202 : if (remove(path) != 0) {
597 : /* LCOV_EXCL_START */
598 : log_fatal("Error removing %s\n", path);
599 : exit(EXIT_FAILURE);
600 : /* LCOV_EXCL_STOP */
601 : }
602 : } else {
603 : /* recreate */
604 : char linkto[PATH_MAX];
605 :
606 191 : if (remove(path) != 0) {
607 : /* LCOV_EXCL_START */
608 : log_fatal("Error removing %s\n", path);
609 : exit(EXIT_FAILURE);
610 : /* LCOV_EXCL_STOP */
611 : }
612 :
613 191 : rnd_name(linkto);
614 :
615 191 : cmd_generate_symlink(path, linkto);
616 : }
617 12702 : } else if (S_ISREG(st.st_mode)) {
618 : int r;
619 :
620 12702 : r = rnd(4);
621 :
622 12702 : if (r == 0) {
623 3216 : cmd_write(path, size);
624 9486 : } else if (r == 1) {
625 3190 : cmd_append(path, size);
626 6296 : } else if (r == 2) {
627 3042 : cmd_truncate(path, size);
628 : } else {
629 3254 : cmd_delete(path);
630 : }
631 : }
632 : }
633 :
634 1 : void help(void)
635 : {
636 1 : printf("Test for " PACKAGE " v" VERSION " by Andrea Mazzoleni, " PACKAGE_URL "\n");
637 1 : printf("Usage:\n");
638 1 : printf("\tmktest generate SEED DISK_NUM FILE_NUM FILE_SIZE\n");
639 1 : printf("\tmktest damage SEED NUM SIZE FILE\n");
640 1 : printf("\tmktest write SEED NUM SIZE FILE\n");
641 1 : printf("\tmktest change SEED SIZE FILE\n");
642 1 : printf("\tmktest append SEED SIZE FILE\n");
643 1 : printf("\tmktest truncate SEED SIZE FILE\n");
644 1 : }
645 :
646 22 : int main(int argc, char* argv[])
647 : {
648 : int i, j, b;
649 :
650 22 : lock_init();
651 :
652 22 : if (argc < 2) {
653 1 : help();
654 1 : exit(EXIT_SUCCESS);
655 : }
656 :
657 21 : if (strcmp(argv[1], "generate") == 0) {
658 : int disk, file, size;
659 :
660 4 : if (argc != 6) {
661 : /* LCOV_EXCL_START */
662 : help();
663 : exit(EXIT_FAILURE);
664 : /* LCOV_EXCL_STOP */
665 : }
666 :
667 4 : seed = atoi(argv[2]);
668 4 : disk = atoi(argv[3]);
669 4 : file = atoi(argv[4]);
670 4 : size = atoi(argv[5]);
671 :
672 28 : for (i = 0; i < disk; ++i) {
673 24024 : for (j = 0; j < file; ++j) {
674 24000 : if (j == 0)
675 : /* create at least a big one */
676 24 : cmd_generate(i + 1, size);
677 23976 : else if (j == 1)
678 : /* create at least an empty one */
679 24 : cmd_generate(i + 1, 0);
680 : else
681 23952 : cmd_generate(i + 1, rnd(size));
682 : }
683 : }
684 17 : } else if (strcmp(argv[1], "write") == 0) {
685 : int fail, size;
686 :
687 7 : if (argc < 6) {
688 : /* LCOV_EXCL_START */
689 : help();
690 : exit(EXIT_FAILURE);
691 : /* LCOV_EXCL_STOP */
692 : }
693 :
694 7 : seed = atoi(argv[2]);
695 7 : fail = atoi(argv[3]);
696 7 : size = atoi(argv[4]);
697 7 : b = 5;
698 :
699 : /* sort the file names */
700 7 : qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
701 :
702 977 : for (i = b; i < argc; ++i)
703 4019 : for (j = 0; j < fail; ++j)
704 3049 : cmd_write(argv[i], rndnz(size));
705 10 : } else if (strcmp(argv[1], "damage") == 0) {
706 : int fail, size;
707 :
708 3 : if (argc < 6) {
709 : /* LCOV_EXCL_START */
710 : help();
711 : exit(EXIT_FAILURE);
712 : /* LCOV_EXCL_STOP */
713 : }
714 :
715 3 : seed = atoi(argv[2]);
716 3 : fail = atoi(argv[3]);
717 3 : size = atoi(argv[4]);
718 3 : b = 5;
719 :
720 : /* sort the file names */
721 3 : qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
722 :
723 1885 : for (i = b; i < argc; ++i)
724 3764 : for (j = 0; j < fail; ++j)
725 1882 : cmd_damage(argv[i], rndnz(size)); /* at least one byte */
726 7 : } else if (strcmp(argv[1], "append") == 0) {
727 : int size;
728 :
729 0 : if (argc < 5) {
730 : /* LCOV_EXCL_START */
731 : help();
732 : exit(EXIT_FAILURE);
733 : /* LCOV_EXCL_STOP */
734 : }
735 :
736 0 : seed = atoi(argv[2]);
737 0 : size = atoi(argv[3]);
738 0 : b = 4;
739 :
740 : /* sort the file names */
741 0 : qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
742 :
743 0 : for (i = b; i < argc; ++i)
744 0 : cmd_append(argv[i], rndnz(size)); /* at least one byte */
745 7 : } else if (strcmp(argv[1], "truncate") == 0) {
746 : int size;
747 :
748 0 : if (argc < 5) {
749 : /* LCOV_EXCL_START */
750 : help();
751 : exit(EXIT_FAILURE);
752 : /* LCOV_EXCL_STOP */
753 : }
754 :
755 0 : seed = atoi(argv[2]);
756 0 : size = atoi(argv[3]);
757 0 : b = 4;
758 :
759 : /* sort the file names */
760 0 : qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
761 :
762 0 : for (i = b; i < argc; ++i)
763 0 : cmd_truncate(argv[i], rnd(size));
764 7 : } else if (strcmp(argv[1], "change") == 0) {
765 : int size;
766 :
767 7 : if (argc < 5) {
768 : /* LCOV_EXCL_START */
769 : help();
770 : exit(EXIT_FAILURE);
771 : /* LCOV_EXCL_STOP */
772 : }
773 :
774 7 : seed = atoi(argv[2]);
775 7 : size = atoi(argv[3]);
776 7 : b = 4;
777 :
778 : /* sort the file names */
779 7 : qsort(&argv[b], argc - b, sizeof(argv[b]), file_cmp);
780 :
781 13135 : for (i = b; i < argc; ++i)
782 13128 : cmd_change(argv[i], rnd(size));
783 : } else {
784 : /* LCOV_EXCL_START */
785 : help();
786 : exit(EXIT_FAILURE);
787 : /* LCOV_EXCL_STOP */
788 : }
789 :
790 21 : lock_done();
791 :
792 21 : return 0;
793 : }
794 :
|