]> git.sesse.net Git - bcachefs-tools-debian/blobdiff - bcache-test.c
UUIDs
[bcachefs-tools-debian] / bcache-test.c
index 8db853b6313028265fe83ffcae87e2ae500c9b22..0f8ad3761bdf8868266765e301c8faed5f670f66 100644 (file)
@@ -1,3 +1,4 @@
+#define _FILE_OFFSET_BITS      64
 #define _XOPEN_SOURCE 500
 #define _GNU_SOURCE
 
@@ -10,6 +11,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
+#include <sys/klog.h>
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -26,6 +28,8 @@ static const unsigned char bcache_magic[] = {
 
 unsigned char zero[4096];
 
+bool klog = false;
+
 #define Pread(fd, buf, size, offset) do {                              \
        int _read = 0, _r;                                              \
        while (_read < size) {                                          \
@@ -58,7 +62,7 @@ double normal()
                n = 0 / (double) 0;
                return x;
        }
-       
+
        do {
                x = random() / (double) (RAND_MAX / 2) - 1;
                y = random() / (double) (RAND_MAX / 2) - 1;
@@ -95,49 +99,120 @@ struct pagestuff {
        int writecount;
 };
 
+void flushlog(void)
+{
+       char logbuf[1 << 21];
+       int w = 0, len;
+       static int fd;
+
+       if (!klog)
+               return;
+
+       if (!fd) {
+               klogctl(8, 0, 6);
+
+               sprintf(logbuf, "log.%i", abs(random()) % 1000);
+               fd = open(logbuf, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+
+               if (fd == -1) {
+                       perror("Error opening log file");
+                       exit(EXIT_FAILURE);
+               }
+       }
+
+       len = klogctl(4, logbuf, 1 << 21);
+
+       if (len == -1) {
+               perror("Error reading kernel log");
+               exit(EXIT_FAILURE);
+       }
+
+       while (w < len) {
+               int r = write(fd, logbuf + w, len - w);
+               if (r == -1) {
+                       perror("Error writing log");
+                       exit(EXIT_FAILURE);
+               }
+               w += r;
+       }
+}
+
+void aio_loop(int nr)
+{
+
+}
+
+void usage()
+{
+       exit(EXIT_FAILURE);
+}
+
 int main(int argc, char **argv)
 {
-       bool walk = false, randsize = false, verbose = false, csum = false, destructive = false;
-       int fd1, fd2 = 0, direct = 0, nbytes = 4096, j;
-       unsigned long size, i, offset = 0, done = 0;
+       bool walk = false, randsize = false, verbose = false, csum = false, rtest = false, wtest = false;
+       int fd1, fd2 = 0, direct = 0, nbytes = 4096, j, o;
+       unsigned long size, i, offset = 0, done = 0, unique = 0, benchmark = 0;
        void *buf1 = NULL, *buf2 = NULL;
        struct pagestuff *pages, *p;
        unsigned char c[16];
        time_t last_printed = 0;
+       extern char *optarg;
 
        RC4_KEY writedata;
        RC4_set_key(&writedata, 16, bcache_magic);
 
-       for (i = 1; i < argc; i++) {
-               if (strcmp(argv[i], "direct") == 0)
+       while ((o = getopt(argc, argv, "dnwvscwlb:")) != EOF)
+               switch (o) {
+               case 'd':
                        direct = O_DIRECT;
-               else if (strcmp(argv[i], "walk") == 0)
+                       break;
+               case 'n':
                        walk = true;
-               else if (strcmp(argv[i], "verbose") == 0)
+                       break;
+               case 'v':
                        verbose = true;
-               else if (strcmp(argv[i], "size") == 0)
+                       break;
+               case 's':
                        randsize = true;
-               else if (strcmp(argv[i], "csum") == 0)
+                       break;
+               case 'c':
                        csum = true;
-               else if (strcmp(argv[i], "write") == 0)
-                       destructive = true;
-               else
                        break;
-       }
+               case 'w':
+                       wtest = true;
+                       break;
+               case 'r':
+                       rtest = true;
+                       break;
+               case 'l':
+                       klog = true;
+                       break;
+               case 'b':
+                       benchmark = atol(optarg);
+                       break;
+               default:
+                       usage();
+               }
+
+       argv += optind;
+       argc -= optind;
+
+       if (!rtest && !wtest)
+               rtest = true;
 
-       if (i + 1 > argc) {
+       if (argc < 1) {
                printf("Please enter a device to test\n");
                exit(EXIT_FAILURE);
        }
 
-       if (i + 2 > argc && !csum) {
+       if (!csum && !benchmark && argc < 2) {
                printf("Please enter a device to compare against\n");
                exit(EXIT_FAILURE);
        }
 
-       fd1 = open(argv[i], (destructive ? O_RDWR : O_RDONLY)|direct);
-       if (!csum)
-               fd2 = open(argv[i + 1], (destructive ? O_RDWR : O_RDONLY)|direct);
+       fd1 = open(argv[0], (wtest ? O_RDWR : O_RDONLY)|direct);
+       if (!csum && !benchmark)
+               fd2 = open(argv[1], (wtest ? O_RDWR : O_RDONLY)|direct);
 
        if (fd1 == -1 || fd2 == -1) {
                perror("Error opening device");
@@ -145,7 +220,7 @@ int main(int argc, char **argv)
        }
 
        size = getblocks(fd1);
-       if (!csum)
+       if (!csum && !benchmark)
                size = MIN(size, getblocks(fd2));
 
        size = size / 8 - 16;
@@ -159,8 +234,8 @@ int main(int argc, char **argv)
        }
        //setvbuf(stdout, NULL, _IONBF, 0);
 
-       for (i = 0;; i++) {
-               bool writing = destructive && (i & 1);
+       for (i = 0; !benchmark || i < benchmark; i++) {
+               bool writing = (wtest && (i & 1)) || !rtest;
                nbytes = randsize ? drand48() * 16 + 1 : 1;
                nbytes <<= 12;
 
@@ -169,6 +244,9 @@ int main(int argc, char **argv)
                offset %= size;
                offset <<= 12;
 
+               if (!(i % 200))
+                       flushlog();
+
                if (!verbose) {
                        time_t now = time(NULL);
                        if (now - last_printed >= 2) {
@@ -176,14 +254,14 @@ int main(int argc, char **argv)
                                goto print;
                        }
                } else
-print:                 printf("Loop %6li offset %9li sectors %3i, %6lu mb done\n",
-                              i, offset >> 9, nbytes >> 9, done >> 11);
+print:                 printf("Loop %6li offset %9li sectors %3i, %6lu mb done, %6lu mb unique\n",
+                              i, offset >> 9, nbytes >> 9, done >> 11, unique >> 11);
 
                done += nbytes >> 9;
 
                if (!writing)
                        Pread(fd1, buf1, nbytes, offset);
-               if (!writing && !csum)
+               if (!writing && !csum && !benchmark)
                        Pread(fd2, buf2, nbytes, offset);
 
                for (j = 0; j < nbytes; j += 4096) {
@@ -201,28 +279,36 @@ print:                    printf("Loop %6li offset %9li sectors %3i, %6lu mb done\n",
                                        memcpy(&p->csum[0], c, 16);
                                } else if (memcmp(&p->csum[0], c, 16))
                                        goto bad;
-                       } else if (!writing &&
+                       } else if (!writing && !benchmark &&
                                   memcmp(buf1 + j,
                                          buf2 + j,
                                          4096))
                                goto bad;
 
+                       if (!p->writecount && !p->readcount)
+                               unique += 8;
+
                        writing ? p->writecount++ : p->readcount++;
                }
                if (writing)
                        Pwrite(fd1, buf1, nbytes, offset);
-               if (writing && !csum)
+               if (writing && !csum && !benchmark)
                        Pwrite(fd2, buf2, nbytes, offset);
        }
+       printf("Loop %6li offset %9li sectors %3i, %6lu mb done, %6lu mb unique\n",
+              i, offset >> 9, nbytes >> 9, done >> 11, unique >> 11);
+       exit(EXIT_SUCCESS);
 err:
        perror("IO error");
+       flushlog();
        exit(EXIT_FAILURE);
 bad:
-       printf("Bad read! loop %li offset %li sectors %i, sector %i, readcount %i writecount %i\n",
-              i, offset >> 9, nbytes >> 9, j >> 9, p->readcount, p->writecount);
+       printf("Bad read! loop %li offset %li readcount %i writecount %i\n",
+              i, (offset + j) >> 9, p->readcount, p->writecount);
 
        if (!memcmp(&p->oldcsum[0], c, 16))
                printf("Matches previous csum\n");
 
+       flushlog();
        exit(EXIT_FAILURE);
 }