当前位置: 首页 > 工具软件 > Filebench > 使用案例 >

编译静态文件系统测试工具【Filebench】并在QEMU中运行

汪才
2023-12-01

承接自上一篇文章编译静态文件系统测试工具【FIO】并在QEMU中运行,光有个FIO可能还不够,我们继续将Filebench这个文件系统测试工具也移植到我们的QEMU中

1. 手动处理

Filebench不像FIO那样有--build-static选项可以配置为静态二进制文件,需要一些额外的操作。

首先,下载相应源码:

git clone https://github.com/filebench/filebench.git && cd filebench

接着,按照README处理,生成相应的configure文件:

libtoolize
aclocal
autoheader
automake --add-missing
autoconf

接下来运行configure,这里为了编译为静态可执行文件,我们加入了一堆FLAGS:

./configure LDFLAGS="-static -Wl,--gc-sections" CFLAGS="-static -ffunction-sections -fdata-sections" CPPFLAGS="-static-libstdc++" --prefix=/home/filebench-static

PS:接触GCC选项不久的童鞋可能并不知道为啥要加这些,其实博主本人也暂时一知半解,工具嘛,暂时会用就行。那么,我们就要充分运用手中的工具,例如,FIO可以编译静态可执行文件,那么它是如何实现这一步的?结果是添加了这些FLAG,于是我们自然地把这些FLAG搬过来即可。

好了,接下来运行

make && make install

然而,令人沮丧的是,用上述方法产生的二进制文件并不是静态可执行文件。观察make命令的输出,我发现一个奇怪的事情:

/bin/sh ./libtool  --tag=CC   --mode=link gcc -Wall -Wno-unknown-pragmas
 -static -ffunction-sections -fdata-sections  -static -Wl,--gc-sections 
 -o filebench eventgen.o fb_avl.o fb_localfs.o fb_random.o fileset.o 
 flowop.o flowop_library.o gamma_dist.o ipc.o misc.o multi_client_sync.o 
 parser_gram.o parser_lex.o procflow.o stats.o threadflow.o utils.o 
 vars.o ioprio.o fbtime.o fb_cvar.o aslr.o cvars/mtwist/mtwist.o  -ldl -
 lpthread -lm  

libtool: link: gcc -Wall -Wno-unknown-pragmas -ffunction-sections -
fdata-sections -Wl,--gc-sections -o filebench eventgen.o fb_avl.o 
fb_localfs.o fb_random.o fileset.o flowop.o flowop_library.o 
gamma_dist.o ipc.o misc.o multi_client_sync.o parser_gram.o parser_lex.o 
procflow.o stats.o threadflow.o utils.o vars.o ioprio.o fbtime.o 
fb_cvar.o aslr.o cvars/mtwist/mtwist.o  -ldl -lpthread -lm  

我的-static选项在进入./libtool工具后就全部消失了?WTF???

./libtool脚本里搜索static相关的语句,有了重大发现:

"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...

Link object files or libraries together to form another library, or to
create an executable program.

LINK-COMMAND is a command using the C compiler that you would use to create
a program from several object files.

The following components of LINK-COMMAND are treated specially:

  -all-static       do not do any dynamic linking at all
  -avoid-version    do not add a version suffix if possible
  -bindir BINDIR    specify path to binaries directory (for systems where
                    libraries must be found in the PATH setting at runtime)
  -dlopen FILE      '-dlpreopen' FILE if it cannot be dlopened at runtime
  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
  -export-symbols SYMFILE
  ...

原来如此,我们可以在--mode=link后面加上-all-static标志,这个被称作LINK-COMMAND。试一下加上-all-static后运行上面的命令:

./libtool  --tag=CC   --mode=link -all-static gcc -Wall -Wno-unknown-pragmas 
-static -ffunction-sections -fdata-sections  -static -Wl,--gc-sections 
-o filebench eventgen.o fb_avl.o fb_localfs.o fb_random.o fileset.o 
flowop.o flowop_library.o gamma_dist.o ipc.o misc.o multi_client_sync.o 
parser_gram.o parser_lex.o procflow.o stats.o threadflow.o utils.o 
vars.o ioprio.o fbtime.o fb_cvar.o aslr.o cvars/mtwist/mtwist.o  -ldl 
-lpthread -lm

报错,显示unrecognised xxx,急死我了。最后,经过一顿google操作,我发现官方文章这样写道:

	
$ libtool gcc -static -o hello main.c libhello.la
gcc -o hello main.c ./.libs/libhello.a

In this case, the ‘-static’ switch instructs 
libtool to choose the static component of 
any uninstalled Libtool library.

You could have specified ‘-all-static’ instead, 
which instructs libtool to link the executable with only static libraries (wherever possible), 
for any Libtool or native libraries used.

无语了,原来是加到gcc后面。OK,那现在就明白了,把-all-static换个位置就好了:

./libtool  --tag=CC  -all-static --mode=link  gcc -Wall -Wno-unknown-pragmas 
-static -ffunction-sections -fdata-sections  -static -Wl,--gc-sections 
-o filebench eventgen.o fb_avl.o fb_localfs.o fb_random.o fileset.o 
flowop.o flowop_library.o gamma_dist.o ipc.o misc.o multi_client_sync.o 
parser_gram.o parser_lex.o procflow.o stats.o threadflow.o utils.o 
vars.o ioprio.o fbtime.o fb_cvar.o aslr.o cvars/mtwist/mtwist.o  -ldl 
-lpthread -lm

好,运行完毕后就可以起飞了

我们将其与生成的.f文件一起放到QEMU的initramfs下,启动QEMU并运行相应命令(注意,这个fileserver.f是我自己修改了的),OK,Work Like A Charm。

/ # filebench -f fileserver.f 
Filebench Version 1.5-alpha3
0.000: Allocated 177MB of shared memory
0.001: Failed to open cvar directory around line 1
0.003: File-server Version 3.0 personality successfully loaded
0.003: Populating and pre-allocating filesets
0.045: bigfileset populated: 10000 files, avg. dir. width = 20, avg. dir. depth = 3.1, 0 leafdirs, 9.766MB total size
0.045: Removing bigfileset tree (if exists)
0.548: Pre-allocating directories in bigfileset tree
0.579: Pre-allocating files in bigfileset tree
1.363: Waiting for pre-allocation to finish (in case of a parallel pre-allocation)
1.364: Population and pre-allocation of filesets completed
1.370: Starting 1 filereader instances
2.481: Running...
3.482: Run took 1 seconds...
3.509: Per-Operation Breakdown
statfile1            1653ops     1652ops/s   0.0mb/s    0.369ms/op [0.010ms - 71.108ms]
deletefile1          1670ops     1669ops/s   0.0mb/s    1.623ms/op [0.033ms - 66.410ms]
closefile3           1676ops     1675ops/s   0.0mb/s    0.056ms/op [0.004ms - 40.506ms]
readfile1            1676ops     1675ops/s   1.7mb/s    0.490ms/op [0.010ms - 75.539ms]
openfile2            1681ops     1680ops/s   0.0mb/s    1.665ms/op [0.021ms - 96.120ms]
closefile2           1685ops     1684ops/s   0.0mb/s    0.219ms/op [0.004ms - 75.108ms]
appendfilerand1      1686ops     1685ops/s  13.0mb/s    1.176ms/op [0.014ms - 82.341ms]
openfile1            1692ops     1691ops/s   0.0mb/s    2.361ms/op [0.024ms - 129.976ms]
closefile1           1693ops     1692ops/s   0.0mb/s    0.372ms/op [0.004ms - 57.119ms]
wrtfile1             1694ops     1693ops/s   1.7mb/s    0.680ms/op [0.013ms - 64.137ms]
createfile1          1701ops     1700ops/s   0.0mb/s    5.940ms/op [0.049ms - 159.888ms]
3.512: IO Summary: 18507 ops 18495.015 ops/s 1675/3378 rd/wr  16.3mb/s 1.365ms/op
3.512: Shutting down processes

2. 自动处理

还是一样的,博主是一个喜欢自动化的人,能用脚本来做的事就用脚本做吧~千万不要动手,当大家生成configure文件后,就可以用下面的脚本(build_filebench.sh)来自动编译filebench的静态可执行文件了!

#!/bin/sh
# build_filebench.sh

./configure LDFLAGS="-static -Wl,--gc-sections" CFLAGS="-static -ffunction-sections -fdata-sections" CPPFLAGS="-static-libstdc++" --prefix=$1
orig='$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS)'
new='$(LIBTOOLFLAGS) --mode=link $(CCLD) -all-static $(AM_CFLAGS) $(CFLAGS)'
sed -i "s/$orig/$new/g" Makefile

make -j$(nproc) && make install

用法:
将该脚本放置在filebench根目录下,然后运行,其中,path是指定的安装目录:

chmod +x build_filebench.sh
./build_filebench.sh /path

OK,再次起飞

 类似资料: