2016-12-28 4 views
2

FIO IOエンジンの全体の束をサポート - サポートされているすべてのエンジンがここに存在している:https://github.com/axboe/fio/tree/master/engines起動時にさまざまなioエンジンがどのようにロードされるのですか?

私はどのようにFIO作品とどのようにFIO負荷すべてのIOエンジンで捕まってしまったの内部を理解しようとしています。 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_syncio_registerを用い例sync.cレジスタ及び登録解除のために、それ自身を登録し、登録解除する方法を持っている参照たとえば

私の質問は、誰がこれらのメソッドを呼び出すのですか?

私はgdbの下FIOを実行しようとした答えを見つけるためには - fio_syncio_registerで、main関数にブレークポイントを置き、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を逃した:fio_init

static void fio_init fio_syncio_register(void) 

何の略ですか?再び/tmp/sync.iに:

#define fio_init __attribute__((constructor)) 

のでことは、それがどのように動作するかです。

+0

私はこれを理解したことがないでしょう。この努力のために大変ありがとうございます。 – nachiappan

関連する問題