2016-12-28 36 views
2

FIO支持一大堆IO引擎 - 所有支持的引擎是目前的位置:https://github.com/axboe/fio/tree/master/enginesfio如何在啓動時加載各種io引擎?

我一直在試圖瞭解FIO作品的內部和就死在負載如何FIO所有IO引擎。

例如我看到每一個發動機具有使用以下方法

fio_syncio_register註冊和註銷本身,例如sync.c寄存器和註銷的方法:https://github.com/axboe/fio/blob/master/engines/sync.c#L448

fio_syncio_unregisterhttps://github.com/axboe/fio/blob/master/engines/sync.c#L461

我的問題是誰調用這些方法?

爲了找到答案,我試圖運行FIO在gdb下 - 放置一個破發點中fio_syncio_register和主要功能,fio_syncio_register被連前主告訴我它是與__libc_csu_init 和回溯證實稱那

(gdb) bt 
#0 fio_syncio_register() at engines/sync.c:450 
#1 0x000000000047fb9d in __libc_csu_init() 
#2 0x00007ffff6ee27bf in __libc_start_main (main=0x40cd90 <main>, argc=2, argv=0x7fffffffe608, init=0x47fb50 <__libc_csu_init>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe5f8) 
    at ../csu/libc-start.c:247 
#3 0x000000000040ce79 in _start() 

我花了一段時間閱讀有關__libc_csu_init__libc_csu_fini和關於被飾以__attribute__((constructor))方法每一個描述會談之前主要被調用,但在FIO sync.c的情況下,我沒有看到裝飾fio_syncio_register與__attribute__

有人可以幫助我理解這個流程的工作原理嗎?是否有其他材料我應該閱讀來理解這一點?

謝謝

回答

0

有趣的問題。我找不到答案,所以這裏是我採取的步驟:

$ make 
$ find . -name 'sync.o' 
./engines/sync.o 

$ readelf -WS engines/sync.o | grep '\.init' 
    [12] .init_array  INIT_ARRAY  0000000000000000 0021f0 000008 00 WA 0 0 8 
    [13] .rela.init_array RELA   0000000000000000 0132a0 000018 18  36 12 8 

這告訴我們,全局初始值設定項存在於此對象中。這些在程序啓動時調用。他們是什麼?

$ objdump -Dr engines/sync.o | grep -A4 '\.init' 
Disassembly of section .init_array: 

0000000000000000 <.init_array>: 
    ... 
      0: R_X86_64_64 .text.startup 

有趣。顯然有一個特殊的.text.startup部分。這裏面是什麼?

$ objdump -dr engines/sync.o | less 
... 
Disassembly of section .text.startup: 

0000000000000000 <fio_syncio_register>: 
    0: 48 83 ec 08    sub $0x8,%rsp 
    4: bf 00 00 00 00   mov $0x0,%edi 
         5: R_X86_64_32 .data+0x380 
    9: e8 00 00 00 00   callq e <fio_syncio_register+0xe> 
         a: R_X86_64_PC32  register_ioengine-0x4 
... 

爲什麼,這正是我們正在尋找的功能。但是這個特殊部分最終如何呢?要回答這個問題,我們可以看看預處理源(回想起來,我應該用開始)。

我們怎麼得到它?隱藏編譯sync.o的命令行。查看Makefile,我們可以用QUIET_CC=''取消隱藏命令行。

$ rm engines/sync.o && make QUIET_CC='' 
gcc -o engines/sync.o -std=gnu99 -Wwrite-strings -Wall -Wdeclaration-after-statement -g -ffast-math -D_GNU_SOURCE -include config-host.h -I. -I. -O3 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -DBITS_PER_LONG=64 -DFIO_VERSION='"fio-2.16-5-g915ca"' -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DFIO_INTERNAL -DFIO_INC_DEBUG -c engines/sync.c 
    LINK fio 

現在我們知道了命令行,並能產生預處理的文件:在/tmp/sync.i

$ gcc -E -dD -std=gnu99 -ffast-math -D_GNU_SOURCE -include config-host.h -I. -I. -O3 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -DBITS_PER_LONG=64 -DFIO_VERSION='"fio-2.16-5-g915ca"' -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -DFIO_INTERNAL -DFIO_INC_DEBUG engines/sync.c -o /tmp/sync.i 

來看,我們可以看到:

static void __attribute__((constructor)) fio_syncio_register(void) 
{ 
register_ioengine(&ioengine_rw); 
register_ioengine(&ioengine_prw); 
... 

嗯,__attribute__((constructor))畢竟。但它是如何到達那裏的?啊哈!我錯過this linefio_init

static void fio_init fio_syncio_register(void) 

是什麼fio_init立場?同樣是在/tmp/sync.i

#define fio_init __attribute__((constructor)) 

所以是如何工作的。

+0

哇我從來沒有想過這個,非常感謝你的努力。 – nachiappan

相關問題