1 /* $OpenBSD: vioscribble.c,v 1.4 2023/07/26 05:50:45 anton Exp $ */ 2 3 /* 4 * Copyright (c) 2018 Ori Bernstein <ori@eigenstate.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * Quick hack of a program to try to test vioqcow2.c against 21 * vioraw.c. 22 * 23 * Compile with: 24 * 25 * cc -pthread -o scribble vioscribble.c vioqcow2.c vioraw.c 26 */ 27 #include <sys/param.h> /* PAGE_SIZE */ 28 #include <sys/socket.h> 29 #include <sys/stat.h> 30 31 #include <machine/vmmvar.h> 32 #include <dev/pci/pcireg.h> 33 #include <dev/pci/pcidevs.h> 34 #include <dev/pv/virtioreg.h> 35 #include <dev/pv/vioblkreg.h> 36 #include <dev/pv/vioscsireg.h> 37 38 #include <net/if.h> 39 #include <netinet/in.h> 40 #include <netinet/if_ether.h> 41 42 #include <errno.h> 43 #include <event.h> 44 #include <poll.h> 45 #include <stddef.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <pthread.h> 49 #include <fcntl.h> 50 #include <unistd.h> 51 #include <assert.h> 52 #include <err.h> 53 #include <stdarg.h> 54 #include <syslog.h> 55 56 #include "vmd.h" 57 #include "vmm.h" 58 #include "virtio.h" 59 60 #define CLUSTERSZ 65536 61 62 struct virtio_backing qcowfile; 63 struct virtio_backing rawfile; 64 65 /* We expect the scribble disks to be 4g in size */ 66 #define DISKSZ (4ull*1024ull*1024ull*1024ull) 67 68 static void 69 fill(size_t off, char *buf, size_t len) 70 { 71 size_t i; 72 73 /* use the top bits of off, since we can guess at where we went wrong. */ 74 for (i = 0; i < len; i++) 75 buf[i] = (off >> 8); 76 } 77 78 int 79 main(int argc, char **argv) 80 { 81 int qcfd, rawfd, i; 82 char buf[64*1024], cmp[64*1024]; 83 off_t len, off, qcsz, rawsz; 84 85 log_init(1, LOG_DAEMON); 86 87 qcfd = open("scribble.qcow2", O_RDWR); 88 rawfd = open("scribble.raw", O_RDWR); 89 if (qcfd == -1) 90 err(1, "unable to open qcow"); 91 if (virtio_qcow2_init(&qcowfile, &qcsz, &qcfd, 1) == -1) 92 err(1, "unable to init qcow"); 93 if (rawfd == -1 || virtio_raw_init(&rawfile, &rawsz, &rawfd, 1) == -1) 94 err(1, "unable to open raw"); 95 96 srandom_deterministic(123); 97 98 /* scribble to both disks */ 99 printf("scribbling...\n"); 100 for (i = 0; i < 1024*16; i++) { 101 off = (random() % DISKSZ); 102 len = random() % sizeof buf + 1; 103 fill(off, buf, sizeof buf); 104 if (qcowfile.pwrite(qcowfile.p, buf, len, off) == -1) 105 printf("iter %d: unable to write at %llx\n", i, off); 106 rawfile.pwrite(rawfile.p, buf, len, off); 107 108 if (qcowfile.pread(qcowfile.p, buf, len, off) == -1) 109 printf("unable to read at %llx\n", off); 110 rawfile.pread(rawfile.p, cmp, len, off); 111 if (memcmp(buf, cmp, len) != 0) { 112 printf("iter %d: mismatch at 0x%llx (espected val: %d)\n", 113 i, off, (char)(off >> 8)); 114 break; 115 } 116 } 117 118 /* validate that both disks match */ 119 printf("validating...\n"); 120 for (off = 0; off < DISKSZ; off += sizeof buf) { 121 if (qcowfile.pread(qcowfile.p, buf, sizeof buf, off) == -1) 122 printf("unable to read at %llx\n", off); 123 rawfile.pread(rawfile.p, cmp, sizeof buf, off); 124 if (memcmp(buf, cmp, sizeof buf) != 0) { 125 printf("mismatch at 0x%llx (espected val: %d)\n", 126 off, (char)(off >> 8)); 127 break; 128 } 129 } 130 return 0; 131 } 132