|
Network Block Device @PACKAGE_VERSION@
|
00001 /* 00002 * make-integrityhuge 00003 * 00004 * Make a file to test oversize writes 00005 */ 00006 00007 #include <stdlib.h> 00008 #include <stdio.h> 00009 #include <string.h> 00010 #include <sys/time.h> 00011 #include <sys/types.h> 00012 #include <stdint.h> 00013 #include <unistd.h> 00014 #include "config.h" 00015 #include "cliserv.h" 00016 #include "nbd.h" 00017 00018 const uint64_t filesize=50*1000*1000; 00019 const uint64_t transactions = 250; 00020 00021 static inline void dowrite(int f, void *buf, size_t len) { 00022 ssize_t res; 00023 00024 while(len>0) { 00025 if((res=write(f, buf, len)) <=0) { 00026 perror ("Error writing transactions"); 00027 exit(1); 00028 } 00029 len-=res; 00030 buf+=res; 00031 } 00032 } 00033 00034 static inline uint64_t getrandomuint64() { 00035 uint64_t r=0; 00036 int i; 00037 /* RAND_MAX may be as low as 2^15 */ 00038 for (i= 1 ; i<=5; i++) 00039 r ^= random() ^ (r << 15); 00040 return r; 00041 } 00042 00043 int main(int argc, char**argv) { 00044 struct nbd_request req; 00045 struct nbd_reply rep; 00046 uint64_t handle; 00047 int writefd = 1; /*stdout*/ 00048 00049 req.magic = htonl(NBD_REQUEST_MAGIC); 00050 rep.magic = htonl(NBD_REPLY_MAGIC); 00051 rep.error = 0; 00052 00053 for (handle = 0; handle < transactions; handle++) 00054 { 00055 uint64_t offset; 00056 uint64_t length; 00057 uint64_t flags; 00058 uint32_t command; 00059 00060 /* make the length between 0x400 and the length of the disk -08x800, with all 00061 * the bottom bits clear */ 00062 length = ((getrandomuint64() % (filesize-0x800)) & ~((uint64_t)0x3ff)) + 0x400; 00063 /* generate an offset that will fit the length */ 00064 offset = (getrandomuint64() % (filesize-length)) & ~((uint64_t)0x3ff); 00065 flags = getrandomuint64(); 00066 00067 command = (flags & 0x01)?NBD_CMD_READ:NBD_CMD_WRITE; 00068 00069 if (!(flags & 0x0f)) 00070 command = NBD_CMD_FLAG_FUA | NBD_CMD_WRITE; 00071 00072 if (!(flags & 0xf0)) { 00073 offset = 0; 00074 length = 0; 00075 command = NBD_CMD_FLUSH; 00076 } 00077 00078 *(uint64_t *)(req.handle) = htonll(handle); 00079 *(uint64_t *)(rep.handle) = htonll(handle); 00080 req.type = htonl(command); 00081 req.from = htonll(offset); 00082 req.len = htonl(length); 00083 00084 dowrite(writefd, &req, sizeof(req)); 00085 dowrite(writefd, &rep, sizeof(rep)); 00086 } 00087 00088 req.type = htonl(NBD_CMD_DISC); 00089 req.from = 0; 00090 req.len = 0; 00091 dowrite(writefd, &req, sizeof(req)); 00092 00093 return 0; 00094 }
1.7.3