#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[ZONESPLIT_MAX];
unsigned long long val2[ZONESPLIT_MAX];
};
static int split_parse_ddir(struct thread_options *o, struct split *split,
enum fio_ddir ddir, char *str, bool absolute,
unsigned int max_splits)
{
unsigned long long perc;
unsigned int i;
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++;
if (absolute) {
if (str_to_decimal(perc_str, &val, 1, o, 0, 0)) {
log_err("fio: split conversion failed\n");
return 1;
}
perc = val;
} else {
perc = atoi(perc_str);
if (perc > 100)
perc = 100;
else if (!perc)
perc = -1U;
}
} else {
if (absolute)
perc = 0;
else
perc = -1U;
}
if (str_to_decimal(fname, &val, 1, o, 0, 0)) {
log_err("fio: split conversion failed\n");
return 1;
}
split->val1[i] = val;
split->val2[i] = perc;
i++;
if (i == max_splits) {
log_err("fio: hit max of %d split entries\n", i);
break;
}
}
split->nr = i;
return 0;
}
static int bssplit_ddir(struct thread_options *o, enum fio_ddir ddir, char *str,
bool data)
{
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, data, BSSPLIT_MAX))
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 *, bool);
static int str_split_parse(struct thread_data *td, char *str,
split_parse_fn *fn, bool data)
{
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, data);
if (!ret)
*ddir = '\0';
} else {
char *op;
op = strdup(odir + 1);
ret = fn(&td->o, DDIR_TRIM, op, data);
free(op);
}
if (!ret)
ret = fn(&td->o, DDIR_WRITE, odir + 1, data);
if (!ret) {
*odir = '\0';
ret = fn(&td->o, DDIR_READ, str, data);
}
} else {
char *op;
op = strdup(str);
ret = fn(&td->o, DDIR_WRITE, op, data);
free(op);
if (!ret) {
op = strdup(str);
ret = fn(&td->o, DDIR_TRIM, op, data);
free(op);
}
if (!ret)
ret = fn(&td->o, DDIR_READ, str, data);
}
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, false);
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, enum error_type_bit 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 = calloc(4, sizeof(int));
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);
td->o.ignore_error_nr[etype] = 0;
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 {
td->o.ignore_error_nr[etype] = 0;
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 ret = 1;
enum error_type_bit type = 0;
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;
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
FIO-master3.5 (418个子文件)
fio.1 131KB
fiologparser_hist.py.1 7KB
fio2gnuplot.1 4KB
fio_generate_plots.1 2KB
make.bat 8KB
options.c 122KB
stat.c 72KB
init.c 67KB
server.c 56KB
backend.c 55KB
gfio.c 51KB
io_u.c 50KB
client.c 48KB
verify.c 43KB
filesetup.c 41KB
gclient.c 41KB
goptions.c 38KB
libmtd.c 33KB
rdma.c 33KB
iolog.c 33KB
net.c 30KB
parse.c 27KB
cconv.c 25KB
posix.c 24KB
btrace2fio.c 23KB
graph.c 23KB
sg.c 21KB
diskutil.c 18KB
gettime.c 16KB
time-test.c 16KB
eta.c 16KB
libpmem.c 15KB
rbd.c 14KB
read-to-pipe-async.c 14KB
xxhash.c 14KB
ioengines.c 13KB
blktrace.c 13KB
pattern.c 12KB
prio_tree.c 12KB
dedupe.c 12KB
idletime.c 11KB
windowsaio.c 11KB
rados.c 11KB
sync.c 11KB
axmap.c 10KB
act.c 10KB
libhdfs.c 10KB
sha256.c 10KB
pmemblk.c 10KB
smalloc.c 9KB
libfio.c 9KB
libmtd_legacy.c 9KB
libaio.c 9KB
steadystate.c 9KB
memory.c 9KB
binject.c 9KB
json.c 8KB
genzipf.c 8KB
dev-dax.c 8KB
lfsr.c 8KB
workqueue.c 7KB
test.c 7KB
rbtree.c 7KB
sha512.c 7KB
splice.c 6KB
crc64.c 6KB
mutex.c 6KB
mmap.c 6KB
glusterfs.c 6KB
guasi.c 6KB
null.c 6KB
sha1.c 6KB
rate-submit.c 5KB
posixaio.c 5KB
mtd.c 5KB
crc32c.c 5KB
ghelpers.c 5KB
skeleton_external.c 5KB
solarisaio.c 5KB
md5.c 5KB
e4defrag.c 5KB
fusion-aw.c 5KB
rand.c 5KB
memcpy.c 4KB
printing.c 4KB
filelock.c 4KB
crc32.c 4KB
helper_thread.c 4KB
getopt_long.c 4KB
sha3.c 4KB
glusterfs_async.c 4KB
cgroup.c 4KB
flist_sort.c 3KB
lfsr-test.c 3KB
log.c 3KB
optgroup.c 3KB
verify-state.c 3KB
time.c 3KB
tickmarks.c 3KB
tiobench.c 3KB
共 418 条
- 1
- 2
- 3
- 4
- 5
资源评论
Rudy,Zhao
- 粉丝: 104
- 资源: 1
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于Python的EducationCRM管理系统前端设计源码
- 基于Django4.0+Python3.10的在线学习系统Scss设计源码
- 基于activiti6和jeesite4的dreamFlow工作流管理设计源码
- 基于Python实现的简单植物大战僵尸脚本设计源码
- 基于Java及Web技术的医药管理系统设计源码
- 基于Objective-C的cordova-plugin-wechat插件开发源码研究
- 基于Python语言的SocialNetworkBackend社交数据分析系统后端设计源码
- 基于Python的pytracking-master目标跟踪dimp方法设计源码
- 基于PHP、JavaScript、CSS的zibll主题美化插件设计源码
- 本页包含特定于 FT600Q-B / FT601Q-B SuperSpeed USB3.0 系列的示例应用程序
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功