#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 <netinet/in.h>
#include "fio.h"
#include "verify.h"
#include "parse.h"
#include "lib/fls.h"
#include "lib/pattern.h"
#include "options.h"
#include "optgroup.h"
char client_sockaddr_str[INET6_ADDRSTRLEN] = { 0 };
#define cb_data_to_td(data) container_of(data, struct thread_data, o)
static struct pattern_fmt_desc fmt_desc[] = {
{
.fmt = "%o",
.len = FIELD_SIZE(struct io_u *, offset),
.paste = paste_blockoff
}
};
/*
* 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 bs_cmp(const void *p1, const void *p2)
{
const struct bssplit *bsp1 = p1;
const struct bssplit *bsp2 = p2;
return (int) bsp1->perc - (int) bsp2->perc;
}
struct split {
unsigned int nr;
unsigned int val1[100];
unsigned int val2[100];
};
static int split_parse_ddir(struct thread_options *o, struct split *split,
enum fio_ddir ddir, char *str)
{
unsigned int i, perc;
long long val;
char *fname;
split->nr = 0;
i = 0;
while ((fname = strsep(&str, ":")) != NULL) {
char *perc_str;
if (!strlen(fname))
break;
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");
return 1;
}
split->val1[i] = val;
split->val2[i] = perc;
i++;
if (i == 100)
break;
}
split->nr = i;
return 0;
}
static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str)
{
unsigned int i, perc, perc_missing;
unsigned int max_bs, min_bs;
struct split split;
memset(&split, 0, sizeof(split));
if (split_parse_ddir(o, &split, ddir, str))
return 1;
if (!split.nr)
return 0;
max_bs = 0;
min_bs = -1;
o->bssplit[ddir] = malloc(split.nr * sizeof(struct bssplit));
o->bssplit_nr[ddir] = split.nr;
for (i = 0; i < split.nr; i++) {
if (split.val1[i] > max_bs)
max_bs = split.val1[i];
if (split.val1[i] < min_bs)
min_bs = split.val1[i];
o->bssplit[ddir][i].bs = split.val1[i];
o->bssplit[ddir][i].perc =split.val2[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 = &o->bssplit[ddir][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(o->bssplit[ddir]);
o->bssplit[ddir] = NULL;
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 = &o->bssplit[ddir][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(o->bssplit[ddir], o->bssplit_nr[ddir], sizeof(struct bssplit), bs_cmp);
return 0;
}
typedef int (split_parse_fn)(struct thread_options *, enum fio_ddir, char *);
static int str_split_parse(struct thread_data *td, char *str, split_parse_fn *fn)
{
char *odir, *ddir;
int ret = 0;
odir = strchr(str, ',');
if (odir) {
ddir = strchr(odir + 1, ',');
if (ddir) {
ret = fn(&td->o, DDIR_TRIM, ddir + 1);
if (!ret)
*ddir = '\0';
} else {
char *op;
op = strdup(odir + 1);
ret = fn(&td->o, DDIR_TRIM, op);
free(op);
}
if (!ret)
ret = fn(&td->o, DDIR_WRITE, odir + 1);
if (!ret) {
*odir = '\0';
ret = fn(&td->o, DDIR_READ, str);
}
} else {
char *op;
op = strdup(str);
ret = fn(&td->o, DDIR_WRITE, op);
free(op);
if (!ret) {
op = strdup(str);
ret = fn(&td->o, DDIR_TRIM, op);
free(op);
}
if (!ret)
ret = fn(&td->o, DDIR_READ, str);
}
return ret;
}
static int str_bssplit_cb(void *data, const char *input)
{
struct thread_data *td = cb_data_to_td(data);
char *str, *p;
int ret = 0;
p = str = strdup(input);
strip_blank_front(&str);
strip_blank_end(str);
ret = str_split_parse(td, str, bssplit_ddir);
if (parse_dryrun()) {
int i;
for (i = 0; i < DDIR_RWDIR_CNT; i++) {
free(td->o.bssplit[i]);
td->o.bssplit[i] = NULL;
td->o.bssplit_nr[i] = 0;
}
}
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(char *);
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 = cb_data_to_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 = cb_data_to_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 = cb_data_to_td(data);
if (td->o.mem_type == MEM_MMAPHUGE || td->o.mem_type == MEM_MMAP ||
td->o.mem_type == MEM_MMAPSHARED)
td->o.mmapfile = get_opt_postfix(mem);
return 0;
}
static int fio_clock_source_cb(void *data, const char *str)
{
struct thread_data *td = cb_data_to_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 = cb_data_to_td(data);
td
没有合适的资源?快使用搜索试试~ 我知道了~
Linux fio性能压测工具
需积分: 41 0 下载量 134 浏览量
2022-09-04
19:30:32
上传
评论
收藏 649KB GZ 举报
温馨提示
共382个文件
h:154个
c:138个
fio:47个
fio性能压测工具
资源详情
资源评论
资源推荐
收起资源包目录
Linux fio性能压测工具 (382个子文件)
fio.1 92KB
fiologparser_hist.py.1 7KB
fio2gnuplot.1 4KB
fio_generate_plots.1 2KB
options.c 116KB
stat.c 68KB
init.c 62KB
server.c 56KB
backend.c 52KB
gfio.c 51KB
client.c 47KB
io_u.c 45KB
gclient.c 40KB
verify.c 39KB
goptions.c 38KB
filesetup.c 35KB
libmtd.c 33KB
rdma.c 32KB
iolog.c 32KB
net.c 30KB
parse.c 26KB
cconv.c 24KB
btrace2fio.c 23KB
posix.c 23KB
graph.c 23KB
sg.c 21KB
diskutil.c 18KB
eta.c 15KB
rbd.c 14KB
read-to-pipe-async.c 14KB
xxhash.c 14KB
ioengines.c 14KB
gettime.c 13KB
blktrace.c 13KB
dedupe.c 12KB
prio_tree.c 12KB
idletime.c 12KB
pattern.c 11KB
axmap.c 10KB
act.c 10KB
libhdfs.c 10KB
sync.c 10KB
windowsaio.c 10KB
sha256.c 10KB
pmemblk.c 10KB
smalloc.c 9KB
libmtd_legacy.c 9KB
steadystate.c 9KB
libaio.c 9KB
binject.c 9KB
libfio.c 8KB
json.c 8KB
genzipf.c 8KB
dev-dax.c 8KB
lfsr.c 8KB
workqueue.c 7KB
rbtree.c 7KB
memory.c 7KB
sha512.c 7KB
splice.c 6KB
crc64.c 6KB
mutex.c 6KB
guasi.c 6KB
glusterfs.c 6KB
test.c 6KB
mmap.c 6KB
sha1.c 6KB
rate-submit.c 5KB
posixaio.c 5KB
crc32c.c 5KB
ghelpers.c 5KB
solarisaio.c 5KB
md5.c 5KB
fusion-aw.c 5KB
mtd.c 5KB
rand.c 5KB
e4defrag.c 5KB
printing.c 4KB
filelock.c 4KB
crc32.c 4KB
helper_thread.c 4KB
getopt_long.c 4KB
glusterfs_async.c 4KB
skeleton_external.c 4KB
cgroup.c 4KB
flist_sort.c 3KB
null.c 3KB
lfsr-test.c 3KB
verify-state.c 3KB
tickmarks.c 3KB
tiobench.c 3KB
time.c 3KB
crc32c-arm64.c 3KB
filehash.c 3KB
cpu.c 3KB
crc16.c 3KB
optgroup.c 3KB
falloc.c 2KB
num2str.c 2KB
zipf.c 2KB
共 382 条
- 1
- 2
- 3
- 4
牛牛的笔记
- 粉丝: 596
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于matlab开发的根据rvm回归模型自己编的matlab程序.rar
- 高效C++学生成绩管理系统:教育技术+C++17编程+数据管理+教务自动化
- 基于matlab开发的Tipping的相关向量机RVM的回归MATLAB程序,有英文注释,可以运行.rar
- 一个点击正反转程序实例,可实现案件电机正反转
- 搜索链接淘特搜索引擎共享版-tot-search-engine.rar
- 第十八届全国大学生智能汽车竞赛 摄像头组/镜头组
- 基于matlab开发的AUV惯性导航系统matlab仿真程序,包括轨迹生成、gps和sins组合、gps和dvl组合.rar
- 基于SSM的“个性化电子相册”的设计与实现.zip
- 如何在撰写科研文献时,使用ai工具辅助去完成科研工作
- 吉林大学计组笔记 自用 基于b站翼云图灵的课.pdf
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0