#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <assert.h>
#include <libgen.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "fio.h"
#include "verify.h"
#include "parse.h"
#include "lib/fls.h"
#include "options.h"
#include "crc/crc32c.h"
/*
* Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
*/
static char *get_opt_postfix(const char *str)
{
char *p = strstr(str, ":");
if (!p)
return NULL;
p++;
strip_blank_front(&p);
strip_blank_end(p);
return strdup(p);
}
static int converthexchartoint(char a)
{
int base;
switch (a) {
case '0'...'9':
base = '0';
break;
case 'A'...'F':
base = 'A' - 10;
break;
case 'a'...'f':
base = 'a' - 10;
break;
default:
base = 0;
}
return a - base;
}
static int bs_cmp(const void *p1, const void *p2)
{
const struct bssplit *bsp1 = p1;
const struct bssplit *bsp2 = p2;
return bsp1->perc < bsp2->perc;
}
static int bssplit_ddir(struct thread_options *o, int ddir, char *str)
{
struct bssplit *bssplit;
unsigned int i, perc, perc_missing;
unsigned int max_bs, min_bs;
long long val;
char *fname;
o->bssplit_nr[ddir] = 4;
bssplit = malloc(4 * sizeof(struct bssplit));
i = 0;
max_bs = 0;
min_bs = -1;
while ((fname = strsep(&str, ":")) != NULL) {
char *perc_str;
if (!strlen(fname))
break;
/*
* grow struct buffer, if needed
*/
if (i == o->bssplit_nr[ddir]) {
o->bssplit_nr[ddir] <<= 1;
bssplit = realloc(bssplit, o->bssplit_nr[ddir]
* sizeof(struct bssplit));
}
perc_str = strstr(fname, "/");
if (perc_str) {
*perc_str = '\0';
perc_str++;
perc = atoi(perc_str);
if (perc > 100)
perc = 100;
else if (!perc)
perc = -1U;
} else
perc = -1U;
if (str_to_decimal(fname, &val, 1, o, 0, 0)) {
log_err("fio: bssplit conversion failed\n");
free(bssplit);
return 1;
}
if (val > max_bs)
max_bs = val;
if (val < min_bs)
min_bs = val;
bssplit[i].bs = val;
bssplit[i].perc = perc;
i++;
}
o->bssplit_nr[ddir] = i;
/*
* Now check if the percentages add up, and how much is missing
*/
perc = perc_missing = 0;
for (i = 0; i < o->bssplit_nr[ddir]; i++) {
struct bssplit *bsp = &bssplit[i];
if (bsp->perc == -1U)
perc_missing++;
else
perc += bsp->perc;
}
if (perc > 100 && perc_missing > 1) {
log_err("fio: bssplit percentages add to more than 100%%\n");
free(bssplit);
return 1;
}
/*
* If values didn't have a percentage set, divide the remains between
* them.
*/
if (perc_missing) {
if (perc_missing == 1 && o->bssplit_nr[ddir] == 1)
perc = 100;
for (i = 0; i < o->bssplit_nr[ddir]; i++) {
struct bssplit *bsp = &bssplit[i];
if (bsp->perc == -1U)
bsp->perc = (100 - perc) / perc_missing;
}
}
o->min_bs[ddir] = min_bs;
o->max_bs[ddir] = max_bs;
/*
* now sort based on percentages, for ease of lookup
*/
qsort(bssplit, o->bssplit_nr[ddir], sizeof(struct bssplit), bs_cmp);
o->bssplit[ddir] = bssplit;
return 0;
}
static int str_bssplit_cb(void *data, const char *input)
{
struct thread_data *td = data;
char *str, *p, *odir, *ddir;
int ret = 0;
if (parse_dryrun())
return 0;
p = str = strdup(input);
strip_blank_front(&str);
strip_blank_end(str);
odir = strchr(str, ',');
if (odir) {
ddir = strchr(odir + 1, ',');
if (ddir) {
ret = bssplit_ddir(&td->o, DDIR_TRIM, ddir + 1);
if (!ret)
*ddir = '\0';
} else {
char *op;
op = strdup(odir + 1);
ret = bssplit_ddir(&td->o, DDIR_TRIM, op);
free(op);
}
if (!ret)
ret = bssplit_ddir(&td->o, DDIR_WRITE, odir + 1);
if (!ret) {
*odir = '\0';
ret = bssplit_ddir(&td->o, DDIR_READ, str);
}
} else {
char *op;
op = strdup(str);
ret = bssplit_ddir(&td->o, DDIR_WRITE, op);
free(op);
if (!ret) {
op = strdup(str);
ret = bssplit_ddir(&td->o, DDIR_TRIM, op);
free(op);
}
ret = bssplit_ddir(&td->o, DDIR_READ, str);
}
free(p);
return ret;
}
static int str2error(char *str)
{
const char *err[] = { "EPERM", "ENOENT", "ESRCH", "EINTR", "EIO",
"ENXIO", "E2BIG", "ENOEXEC", "EBADF",
"ECHILD", "EAGAIN", "ENOMEM", "EACCES",
"EFAULT", "ENOTBLK", "EBUSY", "EEXIST",
"EXDEV", "ENODEV", "ENOTDIR", "EISDIR",
"EINVAL", "ENFILE", "EMFILE", "ENOTTY",
"ETXTBSY","EFBIG", "ENOSPC", "ESPIPE",
"EROFS","EMLINK", "EPIPE", "EDOM", "ERANGE" };
int i = 0, num = sizeof(err) / sizeof(void *);
while (i < num) {
if (!strcmp(err[i], str))
return i + 1;
i++;
}
return 0;
}
static int ignore_error_type(struct thread_data *td, int etype, char *str)
{
unsigned int i;
int *error;
char *fname;
if (etype >= ERROR_TYPE_CNT) {
log_err("Illegal error type\n");
return 1;
}
td->o.ignore_error_nr[etype] = 4;
error = malloc(4 * sizeof(struct bssplit));
i = 0;
while ((fname = strsep(&str, ":")) != NULL) {
if (!strlen(fname))
break;
/*
* grow struct buffer, if needed
*/
if (i == td->o.ignore_error_nr[etype]) {
td->o.ignore_error_nr[etype] <<= 1;
error = realloc(error, td->o.ignore_error_nr[etype]
* sizeof(int));
}
if (fname[0] == 'E') {
error[i] = str2error(fname);
} else {
error[i] = atoi(fname);
if (error[i] < 0)
error[i] = -error[i];
}
if (!error[i]) {
log_err("Unknown error %s, please use number value \n",
fname);
free(error);
return 1;
}
i++;
}
if (i) {
td->o.continue_on_error |= 1 << etype;
td->o.ignore_error_nr[etype] = i;
td->o.ignore_error[etype] = error;
} else
free(error);
return 0;
}
static int str_ignore_error_cb(void *data, const char *input)
{
struct thread_data *td = data;
char *str, *p, *n;
int type = 0, ret = 1;
if (parse_dryrun())
return 0;
p = str = strdup(input);
strip_blank_front(&str);
strip_blank_end(str);
while (p) {
n = strchr(p, ',');
if (n)
*n++ = '\0';
ret = ignore_error_type(td, type, p);
if (ret)
break;
p = n;
type++;
}
free(str);
return ret;
}
static int str_rw_cb(void *data, const char *str)
{
struct thread_data *td = data;
struct thread_options *o = &td->o;
char *nr;
if (parse_dryrun())
return 0;
o->ddir_seq_nr = 1;
o->ddir_seq_add = 0;
nr = get_opt_postfix(str);
if (!nr)
return 0;
if (td_random(td))
o->ddir_seq_nr = atoi(nr);
else {
long long val;
if (str_to_decimal(nr, &val, 1, o, 0, 0)) {
log_err("fio: rw postfix parsing failed\n");
free(nr);
return 1;
}
o->ddir_seq_add = val;
}
free(nr);
return 0;
}
static int str_mem_cb(void *data, const char *mem)
{
struct thread_data *td = data;
if (td->o.mem_type == MEM_MMAPHUGE || td->o.mem_type == MEM_MMAP)
td->o.mmapfile = get_opt_postfix(mem);
return 0;
}
static int fio_clock_source_cb(void *data, const char *str)
{
struct thread_data *td = data;
fio_clock_source = td->o.clocksource;
fio_clock_source_set = 1;
fio_clock_init();
return 0;
}
static int str_rwmix_read_cb(void *data, unsigned long long *val)
{
struct thread_data *td = data;
td->o.rwmix[DDIR_READ] = *val;
td->o.rwmix[DDIR_WRITE] = 100 - *val;
return 0;
}
static int str_rwmix_write_cb(void *data, unsigned long long *val)
{
struct thread_data *td = data;
td->o.rwmix[DDIR_WRITE] = *val;
td->o.rwmix[DDIR_READ] = 100 - *val;
return 0;
}
static int str_exitall_cb(void)
{
exitall_on_terminate = 1;
return 0;
}
#ifdef FIO_HAVE_CPU_AFFINITY
int fio_cpus_split(os_cpu_mask_t *mask, unsigned int cpu_index)
{
unsigned int i, index, cpus_in_mask;
const long max_cpu = cpus_online();
cpus_in_mask = fio_cpu_count(mask);
cpu_index = cpu_index % cpus_in_mask;
index = 0;
for (i = 0; i < max_cpu; i++) {
if (!fio_cpu_isset(mask, i))
continue;
if (cpu_index != index)
fio_cpu_clear(mask, i);
index++;
}
return fio_cpu_count(mask);
}
static int str_cpumask_cb(void *data, unsigned long long *val)
{
struct thread_data *td = data;
unsigned int i;
long max_cpu;
int ret;
if (parse_dry
没有合适的资源?快使用搜索试试~ 我知道了~
fio-2.2.5.tar.gz
需积分: 17 19 下载量 81 浏览量
2018-09-26
16:16:28
上传
评论
收藏 535KB GZ 举报
温馨提示
共321个文件
h:135个
c:117个
fio:36个
linux测试磁盘iops工具FIO,依赖yum install libaio-devel
资源推荐
资源详情
资源评论
收起资源包目录
fio-2.2.5.tar.gz (321个子文件)
fio.1 68KB
fio2gnuplot.1 4KB
fio_generate_plots.1 2KB
options.c 92KB
init.c 52KB
gfio.c 51KB
stat.c 48KB
backend.c 46KB
io_u.c 41KB
server.c 40KB
gclient.c 40KB
client.c 40KB
goptions.c 38KB
verify.c 35KB
filesetup.c 32KB
net.c 30KB
rdma.c 29KB
iolog.c 24KB
parse.c 24KB
btrace2fio.c 23KB
graph.c 23KB
posix.c 22KB
cconv.c 20KB
diskutil.c 18KB
eta.c 14KB
xxhash.c 14KB
gettime.c 13KB
ioengines.c 13KB
prio_tree.c 12KB
dedupe.c 12KB
rbd.c 11KB
idletime.c 11KB
blktrace.c 11KB
axmap.c 10KB
act.c 10KB
windowsaio.c 10KB
sha256.c 10KB
smalloc.c 9KB
sg.c 9KB
binject.c 9KB
libaio.c 9KB
sync.c 9KB
json.c 8KB
lfsr.c 8KB
rbtree.c 7KB
libfio.c 7KB
genzipf.c 7KB
sha512.c 7KB
splice.c 6KB
memory.c 6KB
crc64.c 6KB
guasi.c 6KB
mmap.c 6KB
glusterfs.c 6KB
test.c 6KB
sha1.c 6KB
libhdfs.c 6KB
posixaio.c 5KB
mutex.c 5KB
crc32c.c 5KB
ghelpers.c 5KB
solarisaio.c 5KB
md5.c 5KB
fusion-aw.c 5KB
e4defrag.c 5KB
rand.c 4KB
printing.c 4KB
crc32.c 4KB
filelock.c 4KB
glusterfs_async.c 4KB
skeleton_external.c 4KB
cgroup.c 4KB
null.c 3KB
getopt_long.c 3KB
flist_sort.c 3KB
lfsr-test.c 3KB
tickmarks.c 3KB
tiobench.c 3KB
crc16.c 3KB
cpu.c 3KB
falloc.c 2KB
tp.c 2KB
axmap.c 2KB
fifo.c 2KB
filehash.c 2KB
glusterfs_sync.c 2KB
zipf.c 2KB
flow.c 2KB
profile.c 2KB
cairo_text_helpers.c 2KB
time.c 2KB
gerror.c 2KB
bloom.c 2KB
gettime-thread.c 2KB
crc7.c 2KB
crc32c-intel.c 2KB
log.c 2KB
ieee754.c 2KB
trim.c 2KB
num2str.c 2KB
共 321 条
- 1
- 2
- 3
- 4
资源评论
sinat_26876183
- 粉丝: 0
- 资源: 5
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功