document:
aim at(probably):
- /home/ricky/glusterfs/xlators/protocol/server/src/authenticate.c
Setting the Stage
-在開始前, 有空可以研究一下cscope這個trace code tool
-必須依照他資料結構定義清楚, 他的translator-loading code才能找到你所有自己加的東東
-在這邊是透過 dlsym 從你的.so挖出來查看specific names, as follow (xlator.c):
xl is a pointer to the in-memory object for the translator we're loading
fops are dispatch tables containing pointers to many functions.
-xl 他會持續從剛load進來的.so查看各種的symbols (by name), 並且將這些symbol的指標存起來
-這些name有些是function, 像是init, 或是pointers to many functions, 像是fops
-你會常常在各個xlator最底下看到這些struct的宣告(init, fops, ..)
-我們現在就拿 rot-13 這個translator來當範例(just for fun), in rot-13.c
-fops是其中一個最重要的部分, 這個table包含了一個指標指向每個filesystem functions
(your translator might implement - - open, read, stat, chmod, and so on)
-fops的table很大(xlator.h), 但你可以指定你會用到的就好, 其餘的他會自行補上(default.c)
-以 rot-13 來說, an exceptionally simple translator, we only fill in two entries for readv and writev.
-實際上還有另外兩個table滿重要的, cbks 以及 dumpops
-cbks :they're destructors for objects in which your translator might have an interest
-dumpops :(純粹為了dump好看一點, 作者自己也沒用, 跳過)
-最後要提到的就是 option
-你可以看到這個table裡面有
- translator-specific option names
- some information about their types
-GlusterFS提供了很多type (volume_option_type_t in options.h)
(包含paths, translator names, percentages, and times以及常見的像是integers , string)
-此外, volume_option_t structure內有
(alternate names, min/max/default values, enumerated string values, and descriptions)
- rot-13太簡單所以沒看到這些東西, 來看一下 afr.c 裡面的 volume_option_t
-當你的translator被load時, 實際上從volfile來的所有的資訊, 會被用來parse option(怪)
-其結果會被轉成一個dictionary並且存在 xl->options
-這個dictionary之後會交由 init function來處理
-接下來再回過頭看 rot-13
-我們可以看到, 這邊在做 priv structure的初始化 (private data)
-接著繼續, 如果 encrypt-write option 成立 (表示有提供)
-我們就會convert 它並且把它存起來
-這邊是一個經典的範例, 使用 dict_get 來 fetch 一個dictionary
-然後用其中一個conversion function (common-utils.c) 來轉換 data->data 成 我們可以用的東西
-到目前為止, 我們介紹了一個translator如何地被load, 如何找到它的various parts, 如何處理它的options
how a translator gets loaded, how we find its various parts, and how we process its options
-下一章將更深入介紹 init 以及 finit 可能會做哪些事情
-以及常用的 xlator_t structure
init, fini, and private context
-上個章節, 我們認識了一些dispatch table並且使用 option 來處理一個translator
-接下來我們會介紹一個translator剩下的部分 ("shell")
i.e. the other global parts not specific to handling a particular request. (?)
-在開始之前, 我們要先想像一個translator和其shared library之間是什麼關係
-簡單說可以想成是object和class之間的關係那樣 (OOP)
-這邊的object就是 xlator_t
-很多的 xlator_t 可能會為了相同的daemon而被create
- 它們共享相同的code, init / fini
- dispatch tables
- 但不共享data (重要)
-Every function in your shared library will get an xlator_t as an argument, and should use it
-但跟OOP不像的地方是, 無class-level data, 無繼承
looked up and loaded using the type field in a volfile volume … end-volume block
((還是沒感覺建議看原文))
-在最上面我們看到一個function signature
we get a pointer to the xlator_t object that we're initializing, and we return an int32_t status
-這邊有個關於回傳值的議題, 在大多數translator API的function (如上例)
-我們通常回傳0表示成功, 回傳-1表示失敗
-但在dispatch-table functions, 回傳值是用來表示function call的status (而不是request)
A request error should be reflected as a callback with a non-zero op_ret value
but the dispatch function itself should still return zero
-所以如果以後遇到問題先看一下是不是回傳值造成的(亂掰)
-init function
-第一件做的事, 就是check其translator的環境是否設定好
-Translator被他的parents呼叫, 然後在由他去呼叫接續的children
-有些translator稱作"initial" translators
從別的地方inject(注射) request至system
e.g. mount/fuse injecting requests from the kernel, protocol/server injecting requests from the network
-這些translator就不需要parents, 但 rot-13 需要, 所以我們必須去check它的parents
-同樣的, 有些translator稱作"final" translators
terminate requests 而不是 passing them on
e.g. protocol/client passing them to another node, storage/posix passing them to a local filesystem
-其他的"multiplex" translator就可能有multiple children
- passing each parent request on to one (cluster/dht),
- some (cluster/stripe),
- or all (cluster/afr) of those children
-rot-13 跟上面的種類都不同, 它只需check一個child (exactly)
-這可能來的更方便或是更robust
因為如果translator shared libraries 有個共同的standard variables來描述requirements
, to be checked in a consistent way by the translator-loading infrastructure itself
instead of by each separate init function (但後面的方式仍是現在translator所用的方式)
去看一下afr.c的 init 你會看到很多 GF_OPTION_INIT, 很多priv->xxx要處理
-在程式碼的最後一部分, 我們可以看到他在allocate private data area
-This can literally be anything we want
priv pointer他們提供的infrastructure很方便, 要怎麼使用都可以
在這邊他搭配 GF_CALLOC 使用, 用來取得 rot_13_private_t structure
- 簡單的搭配我們可以很容易的偵測 GlusterFS是否memory-leak
- 但這個用法不太理想 (這邊只是提一下)
- 原因一, 前面兩個參數
the first two arguments - - from calloc(3) - - are kind of reversed (不懂)
- 原因二, 最後一個參數, 這邊是用0
實際上它可以是個 enum value, 告訴GlusterFS allocator現在正在allocating什麼
是一個非常有用的資訊(for memory profiling and leak detection), 可以follow任何 xxx-mem-type.h 當例子
所以不建議只回傳0, 儘管這個方法奏效
-最後來到這章的最後一個部分standard initialization/termination
-我們來看 init 的結尾以及 finit 的開頭
-在 init 的結尾, 我們將 priv 存進private-data pointer (of our xlator_t)
-回傳0, 表示initialization成功
-在一般的情況下, finit 甚至更簡單
-它所要做的事, 就是 GF_FREE 我們的private-data pointer
Note: 我們甚至沒給它回傳值, 因為如果 finit fail了, 我們也沒有明顯和有用的infrastructure可用
-到目前為止, 關於translator我們必須知道的幾乎都已經介紹了
- loading
- initialization
- options processing
- termination
-如果我們沒有define任何dispatch functions, 我們其實可以configure a daemon直接去用我們的translator
-讓它像是一個basic pass-through從它的parent到單一的child
我覺得可以稱作GlusterFS的Hello World啦
-下一章我們會介紹如何去build一個translator並且configure a daemon去用它
-然後一步一步到如何去debug它, 直到這統統都完成之後, 才開始加我們想要的功能
This Time For Real
-前兩章我們介紹了如何去寫一個最基本的translator的骨架
-它包括了loading, initialization, option processing
-接下來我們將介紹如何去build一個translator
-configure一個volume去使用它
-並且在glusterfs daemon的debug mode上跑
-很Lucky的是, 我們可以跳過一大段
-因為作者在那個年代要修改autotool產生的一大堆Makefile和autoconf
-在release 3.5之後新增了一個template xlator替我們省下不少功夫
template: A minimal example xlator to build on
This xlator is intended to save new GlusterFS developers
from fighting it with autotools.
-所以我們可以直接make, 取得.so
cd /home/ricky/glusterfs/xlators/playground/template/src
make