Added diskspeed utility.
This commit is contained in:
@@ -37,7 +37,7 @@ STD = basename cal cat cb chgrp chmod cmp col comm cp dd du \
|
||||
echo ed fgrep file grep head hostid join kill last ln \
|
||||
mesg mkdir mv nice od pagesize pr printenv pwd rev rm rmail rmdir \
|
||||
size sleep sort split sum sync tail tar tee time touch tr \
|
||||
tsort tty uniq w wc whereis who
|
||||
tsort tty uniq w wc whereis who diskspeed
|
||||
|
||||
# C programs that live in the current directory and need explicit make lines.
|
||||
#
|
||||
|
||||
191
src/cmd/diskspeed.c
Normal file
191
src/cmd/diskspeed.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Measure a speed of file read/write operations.
|
||||
*
|
||||
* Copyright (c) 2015, Serge Vakulenko
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this
|
||||
* software for any purpose with or without fee is hereby granted,
|
||||
* provided that the above copyright notice and this permission
|
||||
* notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
* THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
|
||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define MAX_BLOCK_SZ 64 /* kbytes */
|
||||
#define MAX_DATA_SZ 1024 /* Mbytes */
|
||||
|
||||
const char version[] = "1.0";
|
||||
const char copyright[] = "Copyright (C) 2015 Serge Vakulenko";
|
||||
|
||||
char *progname;
|
||||
int verbose;
|
||||
char block[MAX_BLOCK_SZ*1024];
|
||||
|
||||
/*
|
||||
* Get current time in microseconds.
|
||||
*/
|
||||
unsigned current_msec()
|
||||
{
|
||||
struct timeval t;
|
||||
|
||||
gettimeofday(&t, 0);
|
||||
return t.tv_sec * 1000 + t.tv_usec / 1000;
|
||||
}
|
||||
|
||||
unsigned elapsed_msec(unsigned t0)
|
||||
{
|
||||
struct timeval t1;
|
||||
unsigned msec;
|
||||
|
||||
gettimeofday (&t1, 0);
|
||||
msec = t1.tv_sec * 1000 + t1.tv_usec / 1000;
|
||||
msec -= t0;
|
||||
if (msec < 1)
|
||||
msec = 1;
|
||||
return msec;
|
||||
}
|
||||
|
||||
void usage()
|
||||
{
|
||||
fprintf(stderr, "Disk speed test, Version %s, %s\n", version, copyright);
|
||||
fprintf(stderr, "Usage:\n");
|
||||
fprintf(stderr, " %s [-v] [-b blocksz] [-m datasz] [filename]\n", progname);
|
||||
fprintf(stderr, "Options:\n");
|
||||
fprintf(stderr, " -v verbose mode\n");
|
||||
fprintf(stderr, " -b # block size in kbytes, default 4\n");
|
||||
fprintf(stderr, " -m # data size in Mbytes, default 8\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int blocksize_kbytes = 4;
|
||||
int datasize_mbytes = 8;
|
||||
int nbytes, fd, n;
|
||||
char *filename = 0;
|
||||
unsigned t0, msec;
|
||||
|
||||
progname = *argv;
|
||||
for (;;) {
|
||||
switch (getopt(argc, argv, "vb:m:")) {
|
||||
case EOF:
|
||||
break;
|
||||
case 'v':
|
||||
++verbose;
|
||||
continue;
|
||||
case 'b':
|
||||
blocksize_kbytes = strtol(optarg, 0, 0);
|
||||
continue;
|
||||
case 'm':
|
||||
datasize_mbytes = strtol(optarg, 0, 0);
|
||||
continue;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
break;
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc > 1)
|
||||
usage();
|
||||
|
||||
if (argc == 1)
|
||||
filename = argv[0];
|
||||
|
||||
/*
|
||||
* Verify parameters.
|
||||
*/
|
||||
if (blocksize_kbytes < 1 || blocksize_kbytes > MAX_BLOCK_SZ) {
|
||||
fprintf(stderr, "Bad block size = %d kbytes.\n", blocksize_kbytes);
|
||||
fprintf(stderr, "Valid range is 1...%d kbytes.\n", MAX_BLOCK_SZ);
|
||||
exit(-1);
|
||||
}
|
||||
if (datasize_mbytes < 1 || datasize_mbytes > MAX_DATA_SZ) {
|
||||
fprintf(stderr, "Bad data size = %d Mbytes.\n", datasize_mbytes);
|
||||
fprintf(stderr, "Valid range is 1...%d Mbytes.\n", MAX_DATA_SZ);
|
||||
exit(-1);
|
||||
}
|
||||
if (filename)
|
||||
printf("File name: %s\n", filename);
|
||||
else
|
||||
filename = "diskspeed.data";
|
||||
if (access(filename, 0) >= 0) {
|
||||
fprintf(stderr, "File '%s' already exists: cannot overwrite.\n",
|
||||
filename);
|
||||
fprintf(stderr, "Please, delete the file manually.\n");
|
||||
exit(-1);
|
||||
}
|
||||
printf("Testing %d-kbyte block size.\n", blocksize_kbytes);
|
||||
|
||||
/*
|
||||
* Fill buffer with some data.
|
||||
*/
|
||||
for (n=0; n<sizeof(block); n++) {
|
||||
block[n] = ~n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the file.
|
||||
*/
|
||||
fd = open(filename, O_RDWR | O_CREAT, 0664);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Cannot create file '%s'.\n", filename);
|
||||
exit(-1);
|
||||
}
|
||||
if (verbose)
|
||||
printf("Created file '%s'.\n", filename);
|
||||
|
||||
/*
|
||||
* Write data to file.
|
||||
*/
|
||||
sync();
|
||||
t0 = current_msec();
|
||||
nbytes = blocksize_kbytes * 1024;
|
||||
for (n=0; n<datasize_mbytes*1024/blocksize_kbytes; n++) {
|
||||
if (write(fd, block, nbytes) != nbytes) {
|
||||
fprintf(stderr, "Write error at block %d.\n", n);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
msec = elapsed_msec(t0);
|
||||
printf ("Write speed: %u Mbytes in %u.%03u seconds = %u kbytes/sec\n",
|
||||
datasize_mbytes, msec/1000, msec%1000,
|
||||
datasize_mbytes*1024000U / msec);
|
||||
|
||||
/*
|
||||
* Read data from file.
|
||||
*/
|
||||
sync();
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
t0 = current_msec();
|
||||
for (n=0; n<datasize_mbytes*1024/blocksize_kbytes; n++) {
|
||||
if (read(fd, block, nbytes) != nbytes) {
|
||||
fprintf(stderr, "Read error at block %d.\n", n);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
msec = elapsed_msec(t0);
|
||||
printf (" Read speed: %u Mbytes in %u.%03u seconds = %u kbytes/sec\n",
|
||||
datasize_mbytes, msec/1000, msec%1000,
|
||||
datasize_mbytes*1024000U / msec);
|
||||
|
||||
close(fd);
|
||||
unlink(filename);
|
||||
if (verbose)
|
||||
printf("File '%s' deleted.\n", filename);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user