承接自上一篇文章编译静态文件系统测试工具【FIO】并在QEMU中运行,光有个FIO可能还不够,我们继续将Filebench这个文件系统测试工具也移植到我们的QEMU中
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
还是一样的,博主是一个喜欢自动化的人,能用脚本来做的事就用脚本做吧~千万不要动手,当大家生成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,再次起飞