diff options
author | dzwdz | 2022-08-14 20:23:03 +0200 |
---|---|---|
committer | dzwdz | 2022-08-14 20:23:03 +0200 |
commit | b58a95e1a529db1f640eb9ac3ca6e0244790e0ca (patch) | |
tree | de39c579fe54320ebcae408294c343ec607fdbd7 /src | |
parent | 42483d68b641c3f271e6c6888d095112dc90929e (diff) |
user/iochk: tool for checking correctness of fs implementations
example usage: `iochk -v / /init/ /init/long.txt /kdev/ata/0`
Diffstat (limited to 'src')
-rw-r--r-- | src/user/app/iochk/iochk.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/user/app/iochk/iochk.c b/src/user/app/iochk/iochk.c new file mode 100644 index 0000000..38e0473 --- /dev/null +++ b/src/user/app/iochk/iochk.c @@ -0,0 +1,96 @@ +#include <assert.h> +#include <camellia/syscalls.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +static bool verbose = false; + +#define verbosef(...) do { if (verbose) printf(__VA_ARGS__); } while (0) +#define eprintf(fmt, ...) fprintf(stderr, "iochk: "fmt"\n" __VA_OPT__(,) __VA_ARGS__) + + +void check(handle_t h) { + const size_t buflen = 4096; + const size_t offsets[] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 16, 32, 64, 128, 256, + 512, 1024, 2048, + }; + char *buflast = malloc(buflen); + char *bufcur = malloc(buflen); + if (!buflast || !bufcur) { + eprintf("out of memory"); + goto end; + } + + long offlast = 0; + long retlast = _syscall_read(h, buflast, buflen, offlast); + if (retlast < 0) { + eprintf("error %d when reading at offset %d", retlast, offlast); + goto end; + } + + for (size_t i = 0; i < sizeof(offsets) / sizeof(offsets[0]); i++) { + char *tmp; + long offcur = offsets[i]; + long diff = offcur - offlast; + assert(diff >= 0); + if (retlast < diff) break; + + long retcur = _syscall_read(h, bufcur, buflen, offcur); + if (retcur < 0) { + eprintf("error %d when reading at offset %d", retlast, offcur); + break; + } + if (retcur < retlast + offlast - offcur) { + verbosef("warn: unexpected ret %d < %d + %d - %d\n", retcur, retlast, offlast, offcur); + } + if (memcmp(buflast + diff, bufcur, retlast - diff)) { + eprintf("unconsistent read from offsets %d and %d", offlast, offcur); + } + + offlast = offcur; + retlast = retcur; + tmp = bufcur; + bufcur = buflast; + buflast = tmp; + } + + // TODO check negative offsets + +end: + free(buflast); + free(bufcur); +} + +int main(int argc, char **argv) { + int c; + while ((c = getopt(argc, argv, "v")) != -1) { + switch (c) { + case 'v': + verbose = true; + break; + default: + return 1; + } + } + if (optind >= argc) { + eprintf("no files given"); + return 1; + } + for (; optind < argc; optind++) { + const char *path = argv[optind]; + verbosef("checking %s...\n", path); + handle_t h = _syscall_open(path, strlen(path), 0); + if (h < 0) { + eprintf("couldn't open %s", path); + continue; + } + check(h); + close(h); + } + return 0; +} |