Skip to content

Commit

Permalink
Add integrity test for huge writes. Fix speed calc problem.
Browse files Browse the repository at this point in the history
This commit

* Fixes a speed calculation on the integrity tests (we were
  assuming total transferred bytes was the size of the disk,
  which it is for throughputtest but is not for the integrity
  test)

* Adds a binary blob integrityhuge-test.tr, which contains
  instructions to do huge oversize reads and writes with
  flushes over a 50MB disk. This is added as a binary blob
  so everyone has the same data.

* Adds make-integrityhuge.c - a simple program which will make
  the above binary blob (though as it uses random data it will
  not be the same each time)

* Adds an /integrity_huge test to "make check"

* Modifies integritytest() to use properly buffered I/O so it
  does not deadlock.

* Modifies integritytest() to keep handles in a hash table
  to avoid spurious memory accesses if the server returns
  a duff handle.
  • Loading branch information
abligh committed May 28, 2011
1 parent 4b78826 commit cfbb9a0
Show file tree
Hide file tree
Showing 5 changed files with 310 additions and 28 deletions.
5 changes: 3 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ bin_PROGRAMS = nbd-server
sbin_PROGRAMS = @NBD_CLIENT_NAME@
EXTRA_PROGRAMS = nbd-client knbd-client nbd-trdump
TESTS_ENVIRONMENT=$(srcdir)/simple_test
TESTS = cmd cfg1 cfgmulti cfgnew cfgsize write flush integrity
TESTS = cmd cfg1 cfgmulti cfgnew cfgsize write flush integrity integrityhuge
check_PROGRAMS = nbd-tester-client
knbd_client_SOURCES = nbd-client.c cliserv.h
nbd_client_SOURCES = nbd-client.c cliserv.h
Expand All @@ -15,7 +15,7 @@ nbd_tester_client_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@
nbd_trdump_CFLAGS = @CFLAGS@ @GLIB_CFLAGS@
nbd_server_LDADD = @GLIB_LIBS@
nbd_tester_client_LDADD = @GLIB_LIBS@
EXTRA_DIST = gznbd simple_test integrity-test.tr maketr
EXTRA_DIST = gznbd simple_test integrity-test.tr integrityhuge-test.tr maketr
dist-hook:
rm -Rf `find $(distdir) -name '.svn' -type d -print`
cmd:
Expand All @@ -26,4 +26,5 @@ cfgsize:
write:
flush:
integrity:
integrityhuge:

Binary file added integrityhuge-test.tr
Binary file not shown.
94 changes: 94 additions & 0 deletions make-integrityhuge.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* make-integrityhuge
*
* Make a file to test oversize writes
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <stdint.h>
#include <unistd.h>
#include "config.h"
#include "cliserv.h"
#include "nbd.h"

const uint64_t filesize=50*1000*1000;
const uint64_t transactions = 250;

static inline void dowrite(int f, void *buf, size_t len) {
ssize_t res;

while(len>0) {
if((res=write(f, buf, len)) <=0) {
perror ("Error writing transactions");
exit(1);
}
len-=res;
buf+=res;
}
}

static inline uint64_t getrandomuint64() {
uint64_t r=0;
int i;
/* RAND_MAX may be as low as 2^15 */
for (i= 1 ; i<=5; i++)
r ^= random() ^ (r << 15);
return r;
}

int main(int argc, char**argv) {
struct nbd_request req;
struct nbd_reply rep;
uint64_t handle;
int writefd = 1; /*stdout*/

req.magic = htonl(NBD_REQUEST_MAGIC);
rep.magic = htonl(NBD_REPLY_MAGIC);
rep.error = 0;

for (handle = 0; handle < transactions; handle++)
{
uint64_t offset;
uint64_t length;
uint64_t flags;
uint32_t command;

/* make the length between 0x400 and the length of the disk -08x800, with all
* the bottom bits clear */
length = ((getrandomuint64() % (filesize-0x800)) & ~((uint64_t)0x3ff)) + 0x400;
/* generate an offset that will fit the length */
offset = (getrandomuint64() % (filesize-length)) & ~((uint64_t)0x3ff);
flags = getrandomuint64();

command = (flags & 0x01)?NBD_CMD_READ:NBD_CMD_WRITE;

if (!(flags & 0x0f))
command = NBD_CMD_FLAG_FUA | NBD_CMD_WRITE;

if (!(flags & 0xf0)) {
offset = 0;
length = 0;
command = NBD_CMD_FLUSH;
}

*(uint64_t *)(req.handle) = htonll(handle);
*(uint64_t *)(rep.handle) = htonll(handle);
req.type = htonl(command);
req.from = htonll(offset);
req.len = htonl(length);

dowrite(writefd, &req, sizeof(req));
dowrite(writefd, &rep, sizeof(rep));
}

req.type = htonl(NBD_CMD_DISC);
req.from = 0;
req.len = 0;
dowrite(writefd, &req, sizeof(req));

return 0;
}
Loading

0 comments on commit cfbb9a0

Please sign in to comment.