diff options
author | Raghavendra Bhat <raghavendrabhat@gluster.com> | 2011-10-17 11:04:35 +0530 |
---|---|---|
committer | Vijay Bellur <vijay@gluster.com> | 2011-11-15 23:26:33 -0800 |
commit | 78f3ee4fb1687db948ad5d07d1ed9e6177cc54bc (patch) | |
tree | a719a6756c7b9b05b7840e6a596b8185a521d98e /extras | |
parent | 34795adcc93497d97f1cd258102f4fa4b540464b (diff) |
rdd: create the file and do rdd if the file does not exist.
rdd takes input file and copies the its data to the specified output
file ( by creating it) by selecting random offset. If the input file
does not exist it will not work. This patch will create the input file
if it does not exist and then does the copy. File size is given as an
argument. If the file exists it truncates the file and then does the copy.
Change-Id: Ia09451e9e80e13f27320f1edc12c73c0dcf663a9
BUG: 3724
Reviewed-on: http://review.gluster.com/596
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vijay@gluster.com>
Diffstat (limited to 'extras')
-rw-r--r-- | extras/benchmarking/rdd.c | 176 |
1 files changed, 174 insertions, 2 deletions
diff --git a/extras/benchmarking/rdd.c b/extras/benchmarking/rdd.c index e616022e2d9..b06333370ae 100644 --- a/extras/benchmarking/rdd.c +++ b/extras/benchmarking/rdd.c @@ -36,6 +36,18 @@ #define UNIX_PATH_MAX 108 #endif +#define UNIT_KB 1024ULL +#define UNIT_MB UNIT_KB*1024ULL +#define UNIT_GB UNIT_MB*1024ULL +#define UNIT_TB UNIT_GB*1024ULL +#define UNIT_PB UNIT_TB*1024ULL + +#define UNIT_KB_STRING "KB" +#define UNIT_MB_STRING "MB" +#define UNIT_GB_STRING "GB" +#define UNIT_TB_STRING "TB" +#define UNIT_PB_STRING "PB" + struct rdd_file { char path[UNIX_PATH_MAX]; struct stat st; @@ -53,6 +65,7 @@ struct rdd_config { pthread_mutex_t lock; struct rdd_file in_file; struct rdd_file out_file; + ssize_t file_size; }; static struct rdd_config rdd_config; @@ -91,6 +104,21 @@ rdd_parse_opts (int key, char *arg, } strncpy (rdd_config.in_file.path, arg, len); + rdd_config.in_file.path[len] = '\0'; + } + break; + + case 'f': + { + char *tmp = NULL; + unsigned long long fs = 0; + if (string2bytesize (arg, &fs) == -1) { + fprintf (stderr, "invalid argument for file size " + "(%s)\n", arg); + return -1; + } + + rdd_config.file_size = fs; } break; @@ -189,6 +217,81 @@ rdd_parse_opts (int key, char *arg, return 0; } +int +string2bytesize (const char *str, unsigned long long *n) +{ + unsigned long long value = 0ULL; + char *tail = NULL; + int old_errno = 0; + const char *s = NULL; + + if (str == NULL || n == NULL) + { + errno = EINVAL; + return -1; + } + + for (s = str; *s != '\0'; s++) + { + if (isspace (*s)) + { + continue; + } + if (*s == '-') + { + return -1; + } + break; + } + + old_errno = errno; + errno = 0; + value = strtoull (str, &tail, 10); + + if (errno == ERANGE || errno == EINVAL) + { + return -1; + } + + if (errno == 0) + { + errno = old_errno; + } + + if (tail[0] != '\0') + { + if (strcasecmp (tail, UNIT_KB_STRING) == 0) + { + value *= UNIT_KB; + } + else if (strcasecmp (tail, UNIT_MB_STRING) == 0) + { + value *= UNIT_MB; + } + else if (strcasecmp (tail, UNIT_GB_STRING) == 0) + { + value *= UNIT_GB; + } + else if (strcasecmp (tail, UNIT_TB_STRING) == 0) + { + value *= UNIT_TB; + } + else if (strcasecmp (tail, UNIT_PB_STRING) == 0) + { + value *= UNIT_PB; + } + + else + { + return -1; + } + } + + *n = value; + + return 0; +} + static struct argp_option rdd_options[] = { {"if", 'i', "INPUT_FILE", 0, "input-file"}, {"of", 'o', "OUTPUT_FILE", 0, "output-file"}, @@ -201,6 +304,9 @@ static struct argp_option rdd_options[] = { "Number of read-write sequences (defaults to 1000000)"}, {"max-ops", 'm', "MAXOPS", 0, "maximum number of read-writes to be performed in a sequence (defaults to 1)"}, + {"file-size", 'f', "FILESIZE", 0, + "the size of the file which will be created and upon it I/O will be done" + " (defaults to 100MB"}, {0, 0, 0, 0, 0} }; @@ -216,12 +322,16 @@ static struct argp argp = { static void rdd_default_config (void) { + char *tmp_path = "rdd.in"; + rdd_config.thread_count = 2; rdd_config.iters = 1000000; rdd_config.max_bs = 4096; rdd_config.min_bs = 1024; rdd_config.in_file.fd = rdd_config.out_file.fd = -1; rdd_config.max_ops_per_seq = 1; + strncpy (rdd_config.in_file.path, tmp_path, strlen (tmp_path)); + rdd_config.file_size = 104857600; return; } @@ -234,13 +344,17 @@ rdd_valid_config (void) int fd = -1; fd = open (rdd_config.in_file.path, O_RDONLY); - if (fd == -1) { + if (fd == -1 && (errno != ENOENT)) { + fprintf (stderr, "open: (%s)", strerror (errno)); ret = 0; goto out; } close (fd); if (rdd_config.min_bs > rdd_config.max_bs) { + fprintf (stderr, "minimum blocksize %ld is greater than the " + "maximum blocksize %ld", rdd_config.min_bs, + rdd_config.max_bs); ret = 0; goto out; } @@ -356,11 +470,69 @@ cleanup (void) } static int +check_and_create (void) +{ + int ret = -1; + char buf[4096] = {0,}; + struct stat stbuf = {0,}; + int fd[2] = {-1,}; + size_t total_size = -1; + + total_size = rdd_config.file_size; + + ret = stat (rdd_config.in_file.path, &stbuf); + if (ret == -1 && (errno != ENOENT)) + goto out; + + fd[1] = open (rdd_config.in_file.path, O_CREAT | O_WRONLY | O_TRUNC); + if (fd[1] == -1) + goto out; + + fd[0] = open ("/dev/urandom", O_RDONLY); + if (fd[0] == -1) + goto out; + + while (total_size > 0) { + if (total_size >= 4096) { + ret = read (fd[0], buf, 4096); + if (ret == -1) + goto out; + ret = write (fd[1], buf, 4096); + if (ret == -1) + goto out; + total_size = total_size - 4096; + } else { + ret = read (fd[0], buf, total_size); + if (ret == -1) + goto out; + ret = write (fd[1], buf, total_size); + if (ret == -1) + goto out; + total_size = total_size - total_size; + } + + } + + ret = 0; + +out: + if (fd[0] > 0) + close (fd[0]); + if (fd[1] > 0) + close (fd[1]); + return ret; +} + +static int rdd_spawn_threads (void) { int i = 0, ret = -1, fd = -1; char buf[4096]; + ret = check_and_create (); + if (ret == -1) + goto out; + fd = open (rdd_config.in_file.path, O_RDONLY); if (fd < 0) { fprintf (stderr, "cannot open %s (%s)\n", @@ -378,7 +550,7 @@ rdd_spawn_threads (void) } rdd_config.in_file.fd = fd; - fd = open (rdd_config.out_file.path, O_WRONLY | O_CREAT, + fd = open (rdd_config.out_file.path, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IROTH); if (fd < 0) { close (rdd_config.in_file.fd); |