summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordzwdz2022-08-14 20:23:03 +0200
committerdzwdz2022-08-14 20:23:03 +0200
commitb58a95e1a529db1f640eb9ac3ca6e0244790e0ca (patch)
treede39c579fe54320ebcae408294c343ec607fdbd7 /src
parent42483d68b641c3f271e6c6888d095112dc90929e (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.c96
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;
+}