LCOV - code coverage report
Current view: top level - cmdline - mktest.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 222 238 93.3 %
Date: 2026-04-29 15:04:44 Functions: 18 18 100.0 %

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

Generated by: LCOV version 1.0