--- client/tests/disktest/Makefile | 2 - client/tests/disktest/disktest.c | 379 ---------------------------------- client/tests/disktest/disktest.py | 8 +- client/tests/disktest/src/Makefile | 13 ++ client/tests/disktest/src/disktest.c | 379 ++++++++++++++++++++++++++++++++++ 5 files changed, 395 insertions(+), 386 deletions(-) delete mode 100644 client/tests/disktest/Makefile delete mode 100644 client/tests/disktest/disktest.c create mode 100644 client/tests/disktest/src/Makefile create mode 100644 client/tests/disktest/src/disktest.c
diff --git a/client/tests/disktest/Makefile b/client/tests/disktest/Makefile deleted file mode 100644 index b93f66c..0000000 --- a/client/tests/disktest/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -disktest: disktest.c - cc disktest.c -Wall -D_FILE_OFFSET_BITS=64 -D _GNU_SOURCE -static -o disktest diff --git a/client/tests/disktest/disktest.c b/client/tests/disktest/disktest.c deleted file mode 100644 index b07feb2..0000000 --- a/client/tests/disktest/disktest.c +++ /dev/null @@ -1,379 +0,0 @@ -// Copyright Martin J. Bligh & Google. <[email protected]>. -// New Year's Eve, 2006 -// Released under the GPL v2. -// -// Compile with -D_FILE_OFFSET_BITS=64 -D _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <time.h> -#include <getopt.h> -#include <errno.h> -#include <malloc.h> -#include <string.h> - -struct pattern { - unsigned int sector; - unsigned int signature; -}; - -#define SECTOR_SIZE 512 -#define PATTERN_PER_SECTOR (SECTOR_SIZE / sizeof(struct pattern)) - -char *filename = "testfile"; -volatile int stop = 0; -int init_only = 0; -int verify_only = 0; -unsigned int megabytes = 1; -unsigned int skip_mb = 0; -unsigned int start_block = 0; -unsigned int blocksize = 4096; -unsigned int seconds = 15; -unsigned int linear_tasks = 1; -unsigned int random_tasks = 4; -unsigned int blocks; -unsigned int sectors_per_block; -unsigned int signature = 0; -unsigned int stop_on_error = 0; - -void die(char *error) -{ - fprintf(stderr, error); - fprintf(stderr, "\n"); - exit(1); -} - -/* - * Fill a block with it's own sector number - * buf must be at least blocksize - */ -void write_block(int fd, unsigned int block, struct pattern *buffer) -{ - unsigned int i, sec_offset, sector; - off_t offset; - struct pattern *sector_buffer; - - for (sec_offset = 0; sec_offset < sectors_per_block; sec_offset++) { - sector = (block * sectors_per_block) + sec_offset; - sector_buffer = &buffer[sec_offset * PATTERN_PER_SECTOR]; - - for (i = 0; i < PATTERN_PER_SECTOR; i++) { - sector_buffer[i].sector = sector; - sector_buffer[i].signature = signature; - } - } - - offset = block; offset *= blocksize; // careful of overflow - lseek(fd, offset, SEEK_SET); - if (write(fd, buffer, blocksize) != blocksize) { - fprintf(stderr, "Write failed : file %s : block %d\n", filename, block); - exit(1); - } -} - -/* - * Verify a block contains the correct signature and sector numbers for - * each sector within that block. We check every copy within the sector - * and count how many were wrong. - * - * buf must be at least blocksize - */ -int verify_block(int fd, unsigned int block, struct pattern *buffer, char *err) -{ - unsigned int sec_offset, sector; - off_t offset; - int i, errors = 0; - struct pattern *sector_buffer; - - offset = block; offset *= blocksize; // careful of overflow - lseek(fd, offset, SEEK_SET); - if (read(fd, buffer, blocksize) != blocksize) { - fprintf(stderr, "read failed: block %d (errno: %d) filename %s %s\n", block, errno, filename, err); - exit(1); - } - - for (sec_offset = 0; sec_offset < sectors_per_block; sec_offset++) { - unsigned int read_sector = 0, read_signature = 0; - unsigned int sector_errors = 0, signature_errors = 0; - - sector = (block * sectors_per_block) + sec_offset; - sector_buffer = &buffer[sec_offset * PATTERN_PER_SECTOR]; - - for (i = 0; i < PATTERN_PER_SECTOR; i++) { - if (sector_buffer[i].sector != sector) { - read_sector = sector_buffer[i].sector; - sector_errors++; - errors++; - } - if (sector_buffer[i].signature != signature) { - read_signature = sector_buffer[i].signature; - signature_errors++; - errors++; - } - } - if (sector_errors) - printf("Block %d (from %d to %d) sector %08x has wrong sector number %08x (%d/%d) filename %s %s\n", - block, start_block, start_block+blocks, - sector, read_sector, - sector_errors, PATTERN_PER_SECTOR, - filename, err); - if (signature_errors) - printf("Block %d (from %d to %d) sector %08x signature is %08x should be %08x (%d/%d) filename %s %s\n", - block, start_block, start_block+blocks, - sector, read_signature, signature, - signature_errors, PATTERN_PER_SECTOR, - filename, err); - - } - return errors; -} - -void write_file(unsigned int end_time, int random_access) -{ - int fd, pid; - unsigned int block; - void *buffer; - - fflush(stdout); fflush(stderr); - pid = fork(); - - if (pid < 0) - die ("error forking child"); - if (pid != 0) // parent - return; - - fd = open(filename, O_RDWR, 0666); - buffer = malloc(blocksize); - - if (random_access) { - srandom(time(NULL) - getpid()); - while(time(NULL) < end_time) { - block = start_block + (unsigned int)(random() % blocks); - write_block(fd, block, buffer); - } - } else { - while(time(NULL) < end_time) - for (block = start_block; block < start_block + blocks; block++) - write_block(fd, block, buffer); - } - free(buffer); - exit(0); -} - -void verify_file(unsigned int end_time, int random_access, int direct) -{ - int pid, error = 0; - char err_msg[40]; - char *err = err_msg; - fflush(stdout); fflush(stderr); - pid = fork(); - - if (pid < 0) - die ("error forking child"); - if (pid != 0) // parent - return; - - int fd; - unsigned int block; - unsigned int align = (blocksize > 4096) ? blocksize : 4096; - void *buffer = memalign(align, blocksize); - - if (direct) { - fd = open(filename, O_RDONLY | O_DIRECT); - strcpy(err, "direct"); - err += 6; - } else { - fd = open(filename, O_RDONLY); - strcpy(err, "cached"); - err += 6; - } - - if (random_access) { - strcpy(err, ",random"); - srandom(time(NULL) - getpid()); - while(time(NULL) < end_time) { - block = start_block + (unsigned int)(random() % blocks); - if (verify_block(fd, block, buffer, err_msg)) - error = 1; - } - } else { - strcpy(err, ",linear"); - while(time(NULL) < end_time) - for (block = start_block; block < start_block + blocks; block++) - if (verify_block(fd, block, buffer, err_msg)) - error = 1; - } - free(buffer); - exit(error); -} - -void usage(void) -{ - printf("Usage: disktest\n"); - printf(" [-f filename] filename to use (testfile)\n"); - printf(" [-s seconds] seconds to run for (15)\n"); - printf(" [-m megabytes] megabytes to use (1)\n"); - printf(" [-M megabytes] megabytes to skip (0)\n"); - printf(" [-b blocksize] blocksize (4096)\n"); - printf(" [-l linear tasks] linear access tasks (4)\n"); - printf(" [-r random tasks] random access tasks (4)\n"); - printf(" [-v] verify pre-existing file\n"); - printf(" [-i] only do init phase\n"); - printf(" [-S] stop immediately on error\n"); - printf("\n"); -} - -unsigned int double_verify(int fd, void *buffer, char *err) -{ - unsigned int block, errors = 0; - - for (block = start_block; block < start_block + blocks; block++) { - if (verify_block(fd, block, buffer, err)) { - if (stop_on_error) - return 1; - errors++; - } - } - return errors; -} - -int main(int argc, char *argv[]) -{ - unsigned int block; - time_t start_time, end_time; - int tasks, opt, retcode, pid; - void *init_buffer; - - /* Parse all input options */ - while ((opt = getopt(argc, argv, "vf:s:m:M:b:l:r:iS")) != -1) { - switch (opt) { - case 'v': - verify_only = 1; - break; - case 'f': - filename = optarg; - break; - case 's': - seconds = atoi(optarg); - break; - case 'm': - megabytes = atoi(optarg); - break; - case 'M': - skip_mb = atoi(optarg); - break; - case 'b': - blocksize = atoi(optarg); - break; - case 'l': - linear_tasks = atoi(optarg); - break; - case 'r': - random_tasks = atoi(optarg); - break; - case 'i': - init_only = 1; - break; - case 'S': - stop_on_error = 1; - break; - default: - usage(); - exit(1); - } - } - argc -= optind; - argv += optind; - - /* blocksize must be < 1MB, and a divisor. Tough */ - blocks = megabytes * (1024 * 1024 / blocksize); - start_block = skip_mb * (1024 * 1024 / blocksize); - sectors_per_block = blocksize / SECTOR_SIZE; - init_buffer = malloc(blocksize); - - if (verify_only) { - struct stat stat_buf; - - printf("Verifying %s\n", filename); - int fd = open(filename, O_RDONLY); - if (fd < 0) - die("open failed"); - - if (fstat(fd, &stat_buf) != 0) - die("fstat failed"); - megabytes = stat_buf.st_size / (1024 * 1024); - blocks = megabytes * (1024 * 1024 / blocksize); - if (read(fd, init_buffer, SECTOR_SIZE) != SECTOR_SIZE) { - fprintf(stderr, "read failed of initial sector (errno: %d) filename %s\n", errno, filename); - exit(1); - } - lseek(fd, 0, SEEK_SET); - signature = ((struct pattern *)init_buffer)->signature; - - printf("Checking %d megabytes using signature %08x\n", - megabytes, signature); - if (double_verify(fd, init_buffer, "init1")) - exit(1); - else - exit(0); - } - - signature = (getpid() << 16) + ((unsigned int) time(NULL) & 0xffff); - - /* Initialise file */ - int fd = open(filename, O_RDWR | O_TRUNC | O_CREAT, 0666); - if (fd < 0) - die("open failed"); - - start_time = time(NULL); - - printf("Ininitializing block %d to %d in file %s (signature %08x)\n", start_block, start_block+blocks, filename, signature); - /* Initialise all file data to correct blocks */ - for (block = start_block; block < start_block+blocks; block++) - write_block(fd, block, init_buffer); - if(fsync(fd) != 0) - die("fsync failed"); - if (double_verify(fd, init_buffer, "init1")) { - if (!stop_on_error) { - printf("First verify failed. Repeating for posterity\n"); - double_verify(fd, init_buffer, "init2"); - } - exit(1); - } - - printf("Wrote %d MB to %s (%d seconds)\n", megabytes, filename, (int) (time(NULL) - start_time)); - - free(init_buffer); - if (init_only) - exit(0); - - end_time = time(NULL) + seconds; - - /* Fork off all linear access pattern tasks */ - for (tasks = 0; tasks < linear_tasks; tasks++) - write_file(end_time, 0); - - /* Fork off all random access pattern tasks */ - for (tasks = 0; tasks < random_tasks; tasks++) - write_file(end_time, 1); - - /* Verify in all four possible ways */ - verify_file(end_time, 0, 0); - verify_file(end_time, 0, 1); - verify_file(end_time, 1, 0); - verify_file(end_time, 1, 1); - - for (tasks = 0; tasks < linear_tasks + random_tasks + 4; tasks++) { - pid = wait(&retcode); - if (retcode != 0) { - printf("pid %d exited with status %d\n", pid, retcode); - exit(1); - } - } - return 0; -} diff --git a/client/tests/disktest/disktest.py b/client/tests/disktest/disktest.py index 574c5ca..f432dc3 100644 --- a/client/tests/disktest/disktest.py +++ b/client/tests/disktest/disktest.py @@ -5,14 +5,12 @@ from autotest_lib.client.common_lib import error class disktest(test.test): version = 1 + preserve_srcdir = True def setup(self): - os.mkdir(self.srcdir) - os.chdir(self.bindir) - utils.system('cp disktest.c src/') os.chdir(self.srcdir) - cflags = '-D_FILE_OFFSET_BITS=64 -D _GNU_SOURCE -static -Wall' - utils.system('cc disktest.c ' + cflags + ' -o disktest') + utils.system('make clean') + utils.system('make') def initialize(self): diff --git a/client/tests/disktest/src/Makefile b/client/tests/disktest/src/Makefile new file mode 100644 index 0000000..40c4d7e --- /dev/null +++ b/client/tests/disktest/src/Makefile @@ -0,0 +1,13 @@ +CFLAGS = -O2 -Wall -D_FILE_OFFSET_BITS=64 -D _GNU_SOURCE -static +TARGET = disktest + + +all: $(TARGET) + + +$(TARGET): disktest.c + $(CC) $(CFLAGS) $^ -o $@ + + +clean: + $(RM) $(TARGET) diff --git a/client/tests/disktest/src/disktest.c b/client/tests/disktest/src/disktest.c new file mode 100644 index 0000000..b07feb2 --- /dev/null +++ b/client/tests/disktest/src/disktest.c @@ -0,0 +1,379 @@ +// Copyright Martin J. Bligh & Google. <[email protected]>. +// New Year's Eve, 2006 +// Released under the GPL v2. +// +// Compile with -D_FILE_OFFSET_BITS=64 -D _GNU_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <getopt.h> +#include <errno.h> +#include <malloc.h> +#include <string.h> + +struct pattern { + unsigned int sector; + unsigned int signature; +}; + +#define SECTOR_SIZE 512 +#define PATTERN_PER_SECTOR (SECTOR_SIZE / sizeof(struct pattern)) + +char *filename = "testfile"; +volatile int stop = 0; +int init_only = 0; +int verify_only = 0; +unsigned int megabytes = 1; +unsigned int skip_mb = 0; +unsigned int start_block = 0; +unsigned int blocksize = 4096; +unsigned int seconds = 15; +unsigned int linear_tasks = 1; +unsigned int random_tasks = 4; +unsigned int blocks; +unsigned int sectors_per_block; +unsigned int signature = 0; +unsigned int stop_on_error = 0; + +void die(char *error) +{ + fprintf(stderr, error); + fprintf(stderr, "\n"); + exit(1); +} + +/* + * Fill a block with it's own sector number + * buf must be at least blocksize + */ +void write_block(int fd, unsigned int block, struct pattern *buffer) +{ + unsigned int i, sec_offset, sector; + off_t offset; + struct pattern *sector_buffer; + + for (sec_offset = 0; sec_offset < sectors_per_block; sec_offset++) { + sector = (block * sectors_per_block) + sec_offset; + sector_buffer = &buffer[sec_offset * PATTERN_PER_SECTOR]; + + for (i = 0; i < PATTERN_PER_SECTOR; i++) { + sector_buffer[i].sector = sector; + sector_buffer[i].signature = signature; + } + } + + offset = block; offset *= blocksize; // careful of overflow + lseek(fd, offset, SEEK_SET); + if (write(fd, buffer, blocksize) != blocksize) { + fprintf(stderr, "Write failed : file %s : block %d\n", filename, block); + exit(1); + } +} + +/* + * Verify a block contains the correct signature and sector numbers for + * each sector within that block. We check every copy within the sector + * and count how many were wrong. + * + * buf must be at least blocksize + */ +int verify_block(int fd, unsigned int block, struct pattern *buffer, char *err) +{ + unsigned int sec_offset, sector; + off_t offset; + int i, errors = 0; + struct pattern *sector_buffer; + + offset = block; offset *= blocksize; // careful of overflow + lseek(fd, offset, SEEK_SET); + if (read(fd, buffer, blocksize) != blocksize) { + fprintf(stderr, "read failed: block %d (errno: %d) filename %s %s\n", block, errno, filename, err); + exit(1); + } + + for (sec_offset = 0; sec_offset < sectors_per_block; sec_offset++) { + unsigned int read_sector = 0, read_signature = 0; + unsigned int sector_errors = 0, signature_errors = 0; + + sector = (block * sectors_per_block) + sec_offset; + sector_buffer = &buffer[sec_offset * PATTERN_PER_SECTOR]; + + for (i = 0; i < PATTERN_PER_SECTOR; i++) { + if (sector_buffer[i].sector != sector) { + read_sector = sector_buffer[i].sector; + sector_errors++; + errors++; + } + if (sector_buffer[i].signature != signature) { + read_signature = sector_buffer[i].signature; + signature_errors++; + errors++; + } + } + if (sector_errors) + printf("Block %d (from %d to %d) sector %08x has wrong sector number %08x (%d/%d) filename %s %s\n", + block, start_block, start_block+blocks, + sector, read_sector, + sector_errors, PATTERN_PER_SECTOR, + filename, err); + if (signature_errors) + printf("Block %d (from %d to %d) sector %08x signature is %08x should be %08x (%d/%d) filename %s %s\n", + block, start_block, start_block+blocks, + sector, read_signature, signature, + signature_errors, PATTERN_PER_SECTOR, + filename, err); + + } + return errors; +} + +void write_file(unsigned int end_time, int random_access) +{ + int fd, pid; + unsigned int block; + void *buffer; + + fflush(stdout); fflush(stderr); + pid = fork(); + + if (pid < 0) + die ("error forking child"); + if (pid != 0) // parent + return; + + fd = open(filename, O_RDWR, 0666); + buffer = malloc(blocksize); + + if (random_access) { + srandom(time(NULL) - getpid()); + while(time(NULL) < end_time) { + block = start_block + (unsigned int)(random() % blocks); + write_block(fd, block, buffer); + } + } else { + while(time(NULL) < end_time) + for (block = start_block; block < start_block + blocks; block++) + write_block(fd, block, buffer); + } + free(buffer); + exit(0); +} + +void verify_file(unsigned int end_time, int random_access, int direct) +{ + int pid, error = 0; + char err_msg[40]; + char *err = err_msg; + fflush(stdout); fflush(stderr); + pid = fork(); + + if (pid < 0) + die ("error forking child"); + if (pid != 0) // parent + return; + + int fd; + unsigned int block; + unsigned int align = (blocksize > 4096) ? blocksize : 4096; + void *buffer = memalign(align, blocksize); + + if (direct) { + fd = open(filename, O_RDONLY | O_DIRECT); + strcpy(err, "direct"); + err += 6; + } else { + fd = open(filename, O_RDONLY); + strcpy(err, "cached"); + err += 6; + } + + if (random_access) { + strcpy(err, ",random"); + srandom(time(NULL) - getpid()); + while(time(NULL) < end_time) { + block = start_block + (unsigned int)(random() % blocks); + if (verify_block(fd, block, buffer, err_msg)) + error = 1; + } + } else { + strcpy(err, ",linear"); + while(time(NULL) < end_time) + for (block = start_block; block < start_block + blocks; block++) + if (verify_block(fd, block, buffer, err_msg)) + error = 1; + } + free(buffer); + exit(error); +} + +void usage(void) +{ + printf("Usage: disktest\n"); + printf(" [-f filename] filename to use (testfile)\n"); + printf(" [-s seconds] seconds to run for (15)\n"); + printf(" [-m megabytes] megabytes to use (1)\n"); + printf(" [-M megabytes] megabytes to skip (0)\n"); + printf(" [-b blocksize] blocksize (4096)\n"); + printf(" [-l linear tasks] linear access tasks (4)\n"); + printf(" [-r random tasks] random access tasks (4)\n"); + printf(" [-v] verify pre-existing file\n"); + printf(" [-i] only do init phase\n"); + printf(" [-S] stop immediately on error\n"); + printf("\n"); +} + +unsigned int double_verify(int fd, void *buffer, char *err) +{ + unsigned int block, errors = 0; + + for (block = start_block; block < start_block + blocks; block++) { + if (verify_block(fd, block, buffer, err)) { + if (stop_on_error) + return 1; + errors++; + } + } + return errors; +} + +int main(int argc, char *argv[]) +{ + unsigned int block; + time_t start_time, end_time; + int tasks, opt, retcode, pid; + void *init_buffer; + + /* Parse all input options */ + while ((opt = getopt(argc, argv, "vf:s:m:M:b:l:r:iS")) != -1) { + switch (opt) { + case 'v': + verify_only = 1; + break; + case 'f': + filename = optarg; + break; + case 's': + seconds = atoi(optarg); + break; + case 'm': + megabytes = atoi(optarg); + break; + case 'M': + skip_mb = atoi(optarg); + break; + case 'b': + blocksize = atoi(optarg); + break; + case 'l': + linear_tasks = atoi(optarg); + break; + case 'r': + random_tasks = atoi(optarg); + break; + case 'i': + init_only = 1; + break; + case 'S': + stop_on_error = 1; + break; + default: + usage(); + exit(1); + } + } + argc -= optind; + argv += optind; + + /* blocksize must be < 1MB, and a divisor. Tough */ + blocks = megabytes * (1024 * 1024 / blocksize); + start_block = skip_mb * (1024 * 1024 / blocksize); + sectors_per_block = blocksize / SECTOR_SIZE; + init_buffer = malloc(blocksize); + + if (verify_only) { + struct stat stat_buf; + + printf("Verifying %s\n", filename); + int fd = open(filename, O_RDONLY); + if (fd < 0) + die("open failed"); + + if (fstat(fd, &stat_buf) != 0) + die("fstat failed"); + megabytes = stat_buf.st_size / (1024 * 1024); + blocks = megabytes * (1024 * 1024 / blocksize); + if (read(fd, init_buffer, SECTOR_SIZE) != SECTOR_SIZE) { + fprintf(stderr, "read failed of initial sector (errno: %d) filename %s\n", errno, filename); + exit(1); + } + lseek(fd, 0, SEEK_SET); + signature = ((struct pattern *)init_buffer)->signature; + + printf("Checking %d megabytes using signature %08x\n", + megabytes, signature); + if (double_verify(fd, init_buffer, "init1")) + exit(1); + else + exit(0); + } + + signature = (getpid() << 16) + ((unsigned int) time(NULL) & 0xffff); + + /* Initialise file */ + int fd = open(filename, O_RDWR | O_TRUNC | O_CREAT, 0666); + if (fd < 0) + die("open failed"); + + start_time = time(NULL); + + printf("Ininitializing block %d to %d in file %s (signature %08x)\n", start_block, start_block+blocks, filename, signature); + /* Initialise all file data to correct blocks */ + for (block = start_block; block < start_block+blocks; block++) + write_block(fd, block, init_buffer); + if(fsync(fd) != 0) + die("fsync failed"); + if (double_verify(fd, init_buffer, "init1")) { + if (!stop_on_error) { + printf("First verify failed. Repeating for posterity\n"); + double_verify(fd, init_buffer, "init2"); + } + exit(1); + } + + printf("Wrote %d MB to %s (%d seconds)\n", megabytes, filename, (int) (time(NULL) - start_time)); + + free(init_buffer); + if (init_only) + exit(0); + + end_time = time(NULL) + seconds; + + /* Fork off all linear access pattern tasks */ + for (tasks = 0; tasks < linear_tasks; tasks++) + write_file(end_time, 0); + + /* Fork off all random access pattern tasks */ + for (tasks = 0; tasks < random_tasks; tasks++) + write_file(end_time, 1); + + /* Verify in all four possible ways */ + verify_file(end_time, 0, 0); + verify_file(end_time, 0, 1); + verify_file(end_time, 1, 0); + verify_file(end_time, 1, 1); + + for (tasks = 0; tasks < linear_tasks + random_tasks + 4; tasks++) { + pid = wait(&retcode); + if (retcode != 0) { + printf("pid %d exited with status %d\n", pid, retcode); + exit(1); + } + } + return 0; +} -- 1.6.6 _______________________________________________ Autotest mailing list [email protected] http://test.kernel.org/cgi-bin/mailman/listinfo/autotest
