zfs/cmd/zpios/zpios_util.c

477 lines
12 KiB
C
Raw Normal View History

/*
* ZPIOS is a heavily modified version of the original PIOS test code.
* It is designed to have the test code running in the Linux kernel
* against ZFS while still being flexibly controled from user space.
*
* Copyright (C) 2008-2010 Lawrence Livermore National Security, LLC.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Brian Behlendorf <behlendorf1@llnl.gov>.
* LLNL-CODE-403049
*
* Original PIOS Test Code
* Copyright (C) 2004 Cluster File Systems, Inc.
* Written by Peter Braam <braam@clusterfs.com>
* Atul Vidwansa <atul@clusterfs.com>
* Milind Dumbare <milind@clusterfs.com>
*
* This file is part of ZFS on Linux.
* For details, see <http://zfsonlinux.org/>.
*
* ZPIOS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* ZPIOS is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with ZPIOS. If not, see <http://www.gnu.org/licenses/>.
Add large block support to zpios(1) benchmark As part of the large block support effort, it makes sense to add support for large blocks to **zpios(1)**. The specifying of a zfs block size for zpios is optional and will default to 128K if the block size is not specified. `zpios ... -S size | --blocksize size ...` This will use *size* ZFS blocks for each test, specified as a comma delimited list with an optional unit suffix. The supported range is powers of two from 128K through 16M. A range of block sizes can be tested as follows: `-S 128K,256K,512K,1M` Example run below (non realistic results from a VM and output abbreviated for space) ``` --regioncount=750 --regionsize=8M --chunksize=1M --offset=4K --threaddelay=0 --cleanup --human-readable --verbose --cleanup --blocksize=128K,256K,512K,1M th-cnt rg-cnt rg-sz ch-sz blksz wr-data wr-bw rd-data rd-bw --------------------------------------------------------------------- 4 750 8m 1m 128k 5g 90.06m 5g 93.37m 4 750 8m 1m 256k 5g 79.71m 5g 99.81m 4 750 8m 1m 512k 5g 42.20m 5g 93.14m 4 750 8m 1m 1m 5g 35.51m 5g 89.36m 8 750 8m 1m 128k 5g 85.49m 5g 90.81m 8 750 8m 1m 256k 5g 61.42m 5g 99.24m 8 750 8m 1m 512k 5g 49.09m 5g 108.78m 16 750 8m 1m 128k 5g 86.28m 5g 88.73m 16 750 8m 1m 256k 5g 64.34m 5g 93.47m 16 750 8m 1m 512k 5g 68.84m 5g 124.47m 16 750 8m 1m 1m 5g 53.97m 5g 97.20m --------------------------------------------------------------------- ``` Signed-off-by: Don Brady <don.brady@intel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3795 Closes #2071
2015-09-17 23:55:22 +00:00
*
* Copyright (c) 2015, Intel Corporation.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <regex.h>
#include "zpios.h"
/* extracts an unsigned int (64) and K,M,G,T from the string */
/* and returns a 64 bit value converted to the proper units */
static int
kmgt_to_uint64(const char *str, uint64_t *val)
{
char *endptr;
int rc = 0;
*val = strtoll(str, &endptr, 0);
if ((str == endptr) && (*val == 0))
return (EINVAL);
switch (endptr[0]) {
case 'k': case 'K':
*val = (*val) << 10;
break;
case 'm': case 'M':
*val = (*val) << 20;
break;
case 'g': case 'G':
*val = (*val) << 30;
break;
case 't': case 'T':
*val = (*val) << 40;
break;
case '\0':
break;
default:
rc = EINVAL;
}
return (rc);
}
static char *
uint64_to_kmgt(char *str, uint64_t val)
{
char postfix[] = "kmgt";
int i = -1;
while ((val >= KB) && (i < 4)) {
val = (val >> 10);
i++;
}
if (i >= 4)
(void) snprintf(str, KMGT_SIZE-1, "inf");
else
(void) snprintf(str, KMGT_SIZE-1, "%lu%c", (unsigned long)val,
(i == -1) ? '\0' : postfix[i]);
return (str);
}
static char *
kmgt_per_sec(char *str, uint64_t v, double t)
{
char postfix[] = "kmgt";
double val = ((double)v) / t;
int i = -1;
while ((val >= (double)KB) && (i < 4)) {
val /= (double)KB;
i++;
}
if (i >= 4)
(void) snprintf(str, KMGT_SIZE-1, "inf");
else
(void) snprintf(str, KMGT_SIZE-1, "%.2f%c", val,
(i == -1) ? '\0' : postfix[i]);
return (str);
}
static char *
print_flags(char *str, uint32_t flags)
{
str[0] = (flags & DMU_WRITE) ? 'w' : '-';
str[1] = (flags & DMU_READ) ? 'r' : '-';
str[2] = (flags & DMU_VERIFY) ? 'v' : '-';
str[3] = (flags & DMU_REMOVE) ? 'c' : '-';
str[4] = (flags & DMU_FPP) ? 'p' : 's';
str[5] = (flags & (DMU_WRITE_ZC | DMU_READ_ZC)) ? 'z' : '-';
str[6] = (flags & DMU_WRITE_NOWAIT) ? 'O' : '-';
str[7] = '\0';
return (str);
}
static int
regex_match(const char *string, char *pattern)
{
regex_t re = { 0 };
int rc;
rc = regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB | REG_ICASE);
if (rc) {
fprintf(stderr, "Error: Couldn't do regcomp, %d\n", rc);
return (rc);
}
rc = regexec(&re, string, (size_t) 0, NULL, 0);
regfree(&re);
return (rc);
}
/* fills the pios_range_repeat structure of comma separated values */
static int
split_string(const char *optarg, char *pattern, range_repeat_t *range)
{
const char comma[] = ",";
char *cp, *token[32];
int rc, i = 0;
if ((rc = regex_match(optarg, pattern)))
return (rc);
cp = strdup(optarg);
if (cp == NULL)
return (ENOMEM);
do {
/*
* STRTOK(3) Each subsequent call, with a null pointer as the
* value of the * first argument, starts searching from the
* saved pointer and behaves as described above.
*/
if (i == 0) {
token[i] = strtok(cp, comma);
} else {
token[i] = strtok(NULL, comma);
}
} while ((token[i++] != NULL) && (i < 32));
range->val_count = i - 1;
for (i = 0; i < range->val_count; i++)
kmgt_to_uint64(token[i], &range->val[i]);
free(cp);
return (0);
}
int
set_count(char *pattern1, char *pattern2, range_repeat_t *range,
char *optarg, uint32_t *flags, char *arg)
{
Add large block support to zpios(1) benchmark As part of the large block support effort, it makes sense to add support for large blocks to **zpios(1)**. The specifying of a zfs block size for zpios is optional and will default to 128K if the block size is not specified. `zpios ... -S size | --blocksize size ...` This will use *size* ZFS blocks for each test, specified as a comma delimited list with an optional unit suffix. The supported range is powers of two from 128K through 16M. A range of block sizes can be tested as follows: `-S 128K,256K,512K,1M` Example run below (non realistic results from a VM and output abbreviated for space) ``` --regioncount=750 --regionsize=8M --chunksize=1M --offset=4K --threaddelay=0 --cleanup --human-readable --verbose --cleanup --blocksize=128K,256K,512K,1M th-cnt rg-cnt rg-sz ch-sz blksz wr-data wr-bw rd-data rd-bw --------------------------------------------------------------------- 4 750 8m 1m 128k 5g 90.06m 5g 93.37m 4 750 8m 1m 256k 5g 79.71m 5g 99.81m 4 750 8m 1m 512k 5g 42.20m 5g 93.14m 4 750 8m 1m 1m 5g 35.51m 5g 89.36m 8 750 8m 1m 128k 5g 85.49m 5g 90.81m 8 750 8m 1m 256k 5g 61.42m 5g 99.24m 8 750 8m 1m 512k 5g 49.09m 5g 108.78m 16 750 8m 1m 128k 5g 86.28m 5g 88.73m 16 750 8m 1m 256k 5g 64.34m 5g 93.47m 16 750 8m 1m 512k 5g 68.84m 5g 124.47m 16 750 8m 1m 1m 5g 53.97m 5g 97.20m --------------------------------------------------------------------- ``` Signed-off-by: Don Brady <don.brady@intel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3795 Closes #2071
2015-09-17 23:55:22 +00:00
uint64_t count = range->val_count;
if (flags)
*flags |= FLAG_SET;
range->next_val = 0;
if (regex_match(optarg, pattern1) == 0) {
kmgt_to_uint64(optarg, &range->val[0]);
range->val_count = 1;
} else if (split_string(optarg, pattern2, range) < 0) {
fprintf(stderr, "Error: Incorrect pattern for %s, '%s'\n",
arg, optarg);
return (EINVAL);
Add large block support to zpios(1) benchmark As part of the large block support effort, it makes sense to add support for large blocks to **zpios(1)**. The specifying of a zfs block size for zpios is optional and will default to 128K if the block size is not specified. `zpios ... -S size | --blocksize size ...` This will use *size* ZFS blocks for each test, specified as a comma delimited list with an optional unit suffix. The supported range is powers of two from 128K through 16M. A range of block sizes can be tested as follows: `-S 128K,256K,512K,1M` Example run below (non realistic results from a VM and output abbreviated for space) ``` --regioncount=750 --regionsize=8M --chunksize=1M --offset=4K --threaddelay=0 --cleanup --human-readable --verbose --cleanup --blocksize=128K,256K,512K,1M th-cnt rg-cnt rg-sz ch-sz blksz wr-data wr-bw rd-data rd-bw --------------------------------------------------------------------- 4 750 8m 1m 128k 5g 90.06m 5g 93.37m 4 750 8m 1m 256k 5g 79.71m 5g 99.81m 4 750 8m 1m 512k 5g 42.20m 5g 93.14m 4 750 8m 1m 1m 5g 35.51m 5g 89.36m 8 750 8m 1m 128k 5g 85.49m 5g 90.81m 8 750 8m 1m 256k 5g 61.42m 5g 99.24m 8 750 8m 1m 512k 5g 49.09m 5g 108.78m 16 750 8m 1m 128k 5g 86.28m 5g 88.73m 16 750 8m 1m 256k 5g 64.34m 5g 93.47m 16 750 8m 1m 512k 5g 68.84m 5g 124.47m 16 750 8m 1m 1m 5g 53.97m 5g 97.20m --------------------------------------------------------------------- ``` Signed-off-by: Don Brady <don.brady@intel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3795 Closes #2071
2015-09-17 23:55:22 +00:00
} else if (count == range->val_count) {
fprintf(stderr, "Error: input ignored for %s, '%s'\n",
arg, optarg);
}
return (0);
}
/*
* Validates the value with regular expression and sets low, high, incr
* according to value at which flag will be set. Sets the flag after.
*/
int
set_lhi(char *pattern, range_repeat_t *range, char *optarg,
int flag, uint32_t *flag_thread, char *arg)
{
int rc;
if ((rc = regex_match(optarg, pattern))) {
fprintf(stderr, "Error: Wrong pattern in %s, '%s'\n",
arg, optarg);
return (rc);
}
switch (flag) {
case FLAG_LOW:
kmgt_to_uint64(optarg, &range->val_low);
break;
case FLAG_HIGH:
kmgt_to_uint64(optarg, &range->val_high);
break;
case FLAG_INCR:
kmgt_to_uint64(optarg, &range->val_inc_perc);
break;
default:
assert(0);
}
*flag_thread |= flag;
return (0);
}
int
set_noise(uint64_t *noise, char *optarg, char *arg)
{
if (regex_match(optarg, REGEX_NUMBERS) == 0) {
kmgt_to_uint64(optarg, noise);
} else {
fprintf(stderr, "Error: Incorrect pattern for %s\n", arg);
return (EINVAL);
}
return (0);
}
int
set_load_params(cmd_args_t *args, char *optarg)
{
char *param, *search, *searchdup, comma[] = ",";
int rc = 0;
search = strdup(optarg);
if (search == NULL)
return (ENOMEM);
searchdup = search;
while ((param = strtok(search, comma)) != NULL) {
search = NULL;
if (strcmp("fpp", param) == 0) {
args->flags |= DMU_FPP; /* File Per Process/Thread */
} else if (strcmp("ssf", param) == 0) {
args->flags &= ~DMU_FPP; /* Single Shared File */
} else if (strcmp("dmuio", param) == 0) {
args->io_type |= DMU_IO;
args->flags |= (DMU_WRITE | DMU_READ);
} else {
fprintf(stderr, "Invalid load: %s\n", param);
rc = EINVAL;
}
}
free(searchdup);
return (rc);
}
/*
* Checks the low, high, increment values against the single value for
* mutual exclusion, for e.g threadcount is mutually exclusive to
* threadcount_low, ..._high, ..._incr
*/
int
check_mutual_exclusive_command_lines(uint32_t flag, char *arg)
{
if ((flag & FLAG_SET) && (flag & (FLAG_LOW | FLAG_HIGH | FLAG_INCR))) {
fprintf(stderr, "Error: --%s can not be given with --%s_low, "
"--%s_high or --%s_incr.\n", arg, arg, arg, arg);
return (0);
}
if ((flag & (FLAG_LOW | FLAG_HIGH | FLAG_INCR)) && !(flag & FLAG_SET)) {
if (flag != (FLAG_LOW | FLAG_HIGH | FLAG_INCR)) {
fprintf(stderr, "Error: One or more values missing "
"from --%s_low, --%s_high, --%s_incr.\n",
arg, arg, arg);
return (0);
}
}
return (1);
}
void
print_stats_header(cmd_args_t *args)
{
if (args->verbose) {
printf(
"status name id\tth-cnt\trg-cnt\trg-sz\t"
Add large block support to zpios(1) benchmark As part of the large block support effort, it makes sense to add support for large blocks to **zpios(1)**. The specifying of a zfs block size for zpios is optional and will default to 128K if the block size is not specified. `zpios ... -S size | --blocksize size ...` This will use *size* ZFS blocks for each test, specified as a comma delimited list with an optional unit suffix. The supported range is powers of two from 128K through 16M. A range of block sizes can be tested as follows: `-S 128K,256K,512K,1M` Example run below (non realistic results from a VM and output abbreviated for space) ``` --regioncount=750 --regionsize=8M --chunksize=1M --offset=4K --threaddelay=0 --cleanup --human-readable --verbose --cleanup --blocksize=128K,256K,512K,1M th-cnt rg-cnt rg-sz ch-sz blksz wr-data wr-bw rd-data rd-bw --------------------------------------------------------------------- 4 750 8m 1m 128k 5g 90.06m 5g 93.37m 4 750 8m 1m 256k 5g 79.71m 5g 99.81m 4 750 8m 1m 512k 5g 42.20m 5g 93.14m 4 750 8m 1m 1m 5g 35.51m 5g 89.36m 8 750 8m 1m 128k 5g 85.49m 5g 90.81m 8 750 8m 1m 256k 5g 61.42m 5g 99.24m 8 750 8m 1m 512k 5g 49.09m 5g 108.78m 16 750 8m 1m 128k 5g 86.28m 5g 88.73m 16 750 8m 1m 256k 5g 64.34m 5g 93.47m 16 750 8m 1m 512k 5g 68.84m 5g 124.47m 16 750 8m 1m 1m 5g 53.97m 5g 97.20m --------------------------------------------------------------------- ``` Signed-off-by: Don Brady <don.brady@intel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3795 Closes #2071
2015-09-17 23:55:22 +00:00
"ch-sz\toffset\trg-no\tch-no\tth-dly\tflags\tblksz\ttime\t"
"cr-time\trm-time\twr-time\trd-time\twr-data\twr-ch\t"
"wr-bw\trd-data\trd-ch\trd-bw\n");
printf(
Add large block support to zpios(1) benchmark As part of the large block support effort, it makes sense to add support for large blocks to **zpios(1)**. The specifying of a zfs block size for zpios is optional and will default to 128K if the block size is not specified. `zpios ... -S size | --blocksize size ...` This will use *size* ZFS blocks for each test, specified as a comma delimited list with an optional unit suffix. The supported range is powers of two from 128K through 16M. A range of block sizes can be tested as follows: `-S 128K,256K,512K,1M` Example run below (non realistic results from a VM and output abbreviated for space) ``` --regioncount=750 --regionsize=8M --chunksize=1M --offset=4K --threaddelay=0 --cleanup --human-readable --verbose --cleanup --blocksize=128K,256K,512K,1M th-cnt rg-cnt rg-sz ch-sz blksz wr-data wr-bw rd-data rd-bw --------------------------------------------------------------------- 4 750 8m 1m 128k 5g 90.06m 5g 93.37m 4 750 8m 1m 256k 5g 79.71m 5g 99.81m 4 750 8m 1m 512k 5g 42.20m 5g 93.14m 4 750 8m 1m 1m 5g 35.51m 5g 89.36m 8 750 8m 1m 128k 5g 85.49m 5g 90.81m 8 750 8m 1m 256k 5g 61.42m 5g 99.24m 8 750 8m 1m 512k 5g 49.09m 5g 108.78m 16 750 8m 1m 128k 5g 86.28m 5g 88.73m 16 750 8m 1m 256k 5g 64.34m 5g 93.47m 16 750 8m 1m 512k 5g 68.84m 5g 124.47m 16 750 8m 1m 1m 5g 53.97m 5g 97.20m --------------------------------------------------------------------- ``` Signed-off-by: Don Brady <don.brady@intel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3795 Closes #2071
2015-09-17 23:55:22 +00:00
"-------------------------------------------------"
"-------------------------------------------------"
"-------------------------------------------------"
"--------------------------------------------------\n");
} else {
printf(
"status name id\t"
"wr-data\twr-ch\twr-bw\t"
"rd-data\trd-ch\trd-bw\n");
printf(
"-----------------------------------------"
"--------------------------------------\n");
}
}
static void
print_stats_human_readable(cmd_args_t *args, zpios_cmd_t *cmd)
{
zpios_stats_t *summary_stats;
double t_time, wr_time, rd_time, cr_time, rm_time;
char str[KMGT_SIZE];
if (args->rc)
printf("FAIL: %3d ", args->rc);
else
printf("PASS: ");
printf("%-12s", args->name ? args->name : ZPIOS_NAME);
printf("%2u\t", cmd->cmd_id);
if (args->verbose) {
printf("%u\t", cmd->cmd_thread_count);
printf("%u\t", cmd->cmd_region_count);
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_region_size));
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_chunk_size));
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_offset));
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_region_noise));
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_chunk_noise));
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_thread_delay));
printf("%s\t", print_flags(str, cmd->cmd_flags));
Add large block support to zpios(1) benchmark As part of the large block support effort, it makes sense to add support for large blocks to **zpios(1)**. The specifying of a zfs block size for zpios is optional and will default to 128K if the block size is not specified. `zpios ... -S size | --blocksize size ...` This will use *size* ZFS blocks for each test, specified as a comma delimited list with an optional unit suffix. The supported range is powers of two from 128K through 16M. A range of block sizes can be tested as follows: `-S 128K,256K,512K,1M` Example run below (non realistic results from a VM and output abbreviated for space) ``` --regioncount=750 --regionsize=8M --chunksize=1M --offset=4K --threaddelay=0 --cleanup --human-readable --verbose --cleanup --blocksize=128K,256K,512K,1M th-cnt rg-cnt rg-sz ch-sz blksz wr-data wr-bw rd-data rd-bw --------------------------------------------------------------------- 4 750 8m 1m 128k 5g 90.06m 5g 93.37m 4 750 8m 1m 256k 5g 79.71m 5g 99.81m 4 750 8m 1m 512k 5g 42.20m 5g 93.14m 4 750 8m 1m 1m 5g 35.51m 5g 89.36m 8 750 8m 1m 128k 5g 85.49m 5g 90.81m 8 750 8m 1m 256k 5g 61.42m 5g 99.24m 8 750 8m 1m 512k 5g 49.09m 5g 108.78m 16 750 8m 1m 128k 5g 86.28m 5g 88.73m 16 750 8m 1m 256k 5g 64.34m 5g 93.47m 16 750 8m 1m 512k 5g 68.84m 5g 124.47m 16 750 8m 1m 1m 5g 53.97m 5g 97.20m --------------------------------------------------------------------- ``` Signed-off-by: Don Brady <don.brady@intel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3795 Closes #2071
2015-09-17 23:55:22 +00:00
printf("%s\t", uint64_to_kmgt(str, cmd->cmd_block_size));
}
if (args->rc) {
printf("\n");
return;
}
summary_stats = (zpios_stats_t *)cmd->cmd_data_str;
t_time = zpios_timespec_to_double(summary_stats->total_time.delta);
wr_time = zpios_timespec_to_double(summary_stats->wr_time.delta);
rd_time = zpios_timespec_to_double(summary_stats->rd_time.delta);
cr_time = zpios_timespec_to_double(summary_stats->cr_time.delta);
rm_time = zpios_timespec_to_double(summary_stats->rm_time.delta);
if (args->verbose) {
printf("%.2f\t", t_time);
printf("%.3f\t", cr_time);
printf("%.3f\t", rm_time);
printf("%.2f\t", wr_time);
printf("%.2f\t", rd_time);
}
printf("%s\t", uint64_to_kmgt(str, summary_stats->wr_data));
printf("%s\t", uint64_to_kmgt(str, summary_stats->wr_chunks));
printf("%s\t", kmgt_per_sec(str, summary_stats->wr_data, wr_time));
printf("%s\t", uint64_to_kmgt(str, summary_stats->rd_data));
printf("%s\t", uint64_to_kmgt(str, summary_stats->rd_chunks));
printf("%s\n", kmgt_per_sec(str, summary_stats->rd_data, rd_time));
fflush(stdout);
}
static void
print_stats_table(cmd_args_t *args, zpios_cmd_t *cmd)
{
zpios_stats_t *summary_stats;
double wr_time, rd_time;
if (args->rc)
printf("FAIL: %3d ", args->rc);
else
printf("PASS: ");
printf("%-12s", args->name ? args->name : ZPIOS_NAME);
printf("%2u\t", cmd->cmd_id);
if (args->verbose) {
printf("%u\t", cmd->cmd_thread_count);
printf("%u\t", cmd->cmd_region_count);
printf("%llu\t", (long long unsigned)cmd->cmd_region_size);
printf("%llu\t", (long long unsigned)cmd->cmd_chunk_size);
printf("%llu\t", (long long unsigned)cmd->cmd_offset);
printf("%u\t", cmd->cmd_region_noise);
printf("%u\t", cmd->cmd_chunk_noise);
printf("%u\t", cmd->cmd_thread_delay);
printf("0x%x\t", cmd->cmd_flags);
Add large block support to zpios(1) benchmark As part of the large block support effort, it makes sense to add support for large blocks to **zpios(1)**. The specifying of a zfs block size for zpios is optional and will default to 128K if the block size is not specified. `zpios ... -S size | --blocksize size ...` This will use *size* ZFS blocks for each test, specified as a comma delimited list with an optional unit suffix. The supported range is powers of two from 128K through 16M. A range of block sizes can be tested as follows: `-S 128K,256K,512K,1M` Example run below (non realistic results from a VM and output abbreviated for space) ``` --regioncount=750 --regionsize=8M --chunksize=1M --offset=4K --threaddelay=0 --cleanup --human-readable --verbose --cleanup --blocksize=128K,256K,512K,1M th-cnt rg-cnt rg-sz ch-sz blksz wr-data wr-bw rd-data rd-bw --------------------------------------------------------------------- 4 750 8m 1m 128k 5g 90.06m 5g 93.37m 4 750 8m 1m 256k 5g 79.71m 5g 99.81m 4 750 8m 1m 512k 5g 42.20m 5g 93.14m 4 750 8m 1m 1m 5g 35.51m 5g 89.36m 8 750 8m 1m 128k 5g 85.49m 5g 90.81m 8 750 8m 1m 256k 5g 61.42m 5g 99.24m 8 750 8m 1m 512k 5g 49.09m 5g 108.78m 16 750 8m 1m 128k 5g 86.28m 5g 88.73m 16 750 8m 1m 256k 5g 64.34m 5g 93.47m 16 750 8m 1m 512k 5g 68.84m 5g 124.47m 16 750 8m 1m 1m 5g 53.97m 5g 97.20m --------------------------------------------------------------------- ``` Signed-off-by: Don Brady <don.brady@intel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3795 Closes #2071
2015-09-17 23:55:22 +00:00
printf("%u\t", cmd->cmd_block_size);
}
if (args->rc) {
printf("\n");
return;
}
summary_stats = (zpios_stats_t *)cmd->cmd_data_str;
wr_time = zpios_timespec_to_double(summary_stats->wr_time.delta);
rd_time = zpios_timespec_to_double(summary_stats->rd_time.delta);
if (args->verbose) {
printf("%ld.%02ld\t",
(long)summary_stats->total_time.delta.ts_sec,
(long)summary_stats->total_time.delta.ts_nsec);
printf("%ld.%02ld\t",
(long)summary_stats->cr_time.delta.ts_sec,
(long)summary_stats->cr_time.delta.ts_nsec);
printf("%ld.%02ld\t",
(long)summary_stats->rm_time.delta.ts_sec,
(long)summary_stats->rm_time.delta.ts_nsec);
printf("%ld.%02ld\t",
(long)summary_stats->wr_time.delta.ts_sec,
(long)summary_stats->wr_time.delta.ts_nsec);
printf("%ld.%02ld\t",
(long)summary_stats->rd_time.delta.ts_sec,
(long)summary_stats->rd_time.delta.ts_nsec);
}
printf("%lld\t", (long long unsigned)summary_stats->wr_data);
printf("%lld\t", (long long unsigned)summary_stats->wr_chunks);
printf("%.4f\t", (double)summary_stats->wr_data / wr_time);
printf("%lld\t", (long long unsigned)summary_stats->rd_data);
printf("%lld\t", (long long unsigned)summary_stats->rd_chunks);
printf("%.4f\n", (double)summary_stats->rd_data / rd_time);
fflush(stdout);
}
void
print_stats(cmd_args_t *args, zpios_cmd_t *cmd)
{
if (args->human_readable)
print_stats_human_readable(args, cmd);
else
print_stats_table(args, cmd);
}