溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

GlusterFS Translator API怎么使用

發(fā)布時間:2022-01-04 17:45:37 來源:億速云 閱讀:151 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容介紹了“GlusterFS Translator API怎么使用”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

GlusterFS Translator API

簡介

在深入translator api前,我們必須理解關(guān)于此api所在上下文的兩個概念。

一個是文件系統(tǒng)api,主要通過分配表xlator_fops,來展露大多數(shù)文件系統(tǒng)功能。xlator_fops,就是組合linux vfs的file_operations, inode_operations, and super_operations三類操作在一個數(shù)組。要理解xlator如何工作,必須理解這些調(diào)用做什么,相互關(guān)系是什么,比如open/lookup/close,read/write,opendir/readdir,truncate,symlink等。

一個是xlator api的基礎(chǔ):是異步的并是基于回調(diào)的。意思是處理某個請求的代碼必須分為兩部分,一部分是在進(jìn)入下一個xlator前的處理,一部分是待下一個xlator處理完成請求后。用另一種方式解說,就是你的分配函數(shù)(xlator_fops的前半部分)調(diào)用下一個xlator的分配函數(shù),然后直接返回,并不阻塞。你的回調(diào)函數(shù)(后半部分)也許當(dāng)你調(diào)用下一個xlator的分配函數(shù)時就很快被調(diào)用,或者后面某個時間從某個完全不同的線程中被調(diào)用(常常是網(wǎng)絡(luò)傳輸?shù)膒oll線程)。在兩種情況下,回調(diào)都不能僅僅是從棧中取得上下文。Glusterfs確實提供了多種方式來在分配函數(shù)和回調(diào)函數(shù)間保持和傳遞上下文,但是不能僅僅依靠棧,需要我們編碼處理一些事情。

分配表和默認(rèn)函數(shù)

一個xlator的主要的分配表常常是fops(xlator動態(tài)庫加載代碼利用dlsym查找操作op名)。fops包含指向所有正常文件系統(tǒng)的操作的指針。僅僅需要填充在本xlator我們感興趣的操作。任何其他的操作在運行時基于默認(rèn)值來填充,并確定個回調(diào)函數(shù),并直接把此請求發(fā)到下一個xlator。

默認(rèn)函數(shù)和回調(diào)函數(shù)除了提供默認(rèn)功能,也有其他目的。當(dāng)我們需要添加某個新函數(shù)時到一個xlator時,我們可以拷貝和修改那些相同操作的默認(rèn)函數(shù)等。這保證了正確的參數(shù)列表和合理的默認(rèn)行為。每個xlator也許有另外的分配表,比如cbk表,此表用來管理inode和文件描述子的生命周期(看inode和file descriptor context部分)

STACK_WIND 和STACK_UNWIND宏

STACK_WIND and STACK_UNWIND是基于回調(diào)機(jī)制來實現(xiàn)的。這兩個函數(shù)不作用于gdb里類似的調(diào)用棧,而是一個獨立維護(hù)的棧,每個棧幀表示對xlators的調(diào)用。當(dāng)某個fop從內(nèi)核傳遞過來要調(diào)用時,這個調(diào)用就作為一個request請求,從FUSE xlator 經(jīng)過DHT/AFR等到client xlator 直到server xlator 最后到posix xlator。 我們可以在用戶空間fop入口點做任何需要的處理(這里應(yīng)該就是fuse xlator),然后使用STACK_WIND沿著volume 文件設(shè)置的xlator 路徑,傳遞此請求。

define STACK_WIND(frame, rfn, obj, fn, params …)

STACK_WIND (frame, default_setxattr_cbk, FIRST_CHILD(this), FIRST_CHILD(this)→fops→setxattr, loc, dict, flags, xdata);

此函數(shù)的參數(shù)解釋如下:

  • frame:表示此請求的棧幀 stack frame。

  • rfn:當(dāng)下一個xlator或者其他xlator完成了此請求(包括前半部分和后半部分)后,要調(diào)用的回調(diào)函數(shù)。

  • obj:要傳遞到的那個xlator對象,也即下一個xlator,不是調(diào)用STACK_WIND的本xlator。多個子的情況如何處理?

  • fn:要調(diào)用的具體的xlator的操作,來自下一個xlator的fops分配表。

  • params …任何其他的入口點相關(guān)的參數(shù)(比如針對此fop的inodes, file descriptors, offsets, data buffers等)如前敘,rfn回調(diào)函數(shù)也許在STACK_WIND的調(diào)用內(nèi)部被調(diào)用,也或者后來在另一個環(huán)境中被調(diào)用。不調(diào)用下一個xlator就完成請求比如從cache中讀數(shù)據(jù),或者當(dāng)本xlator層完成對req的處理,要從本層的回調(diào)中把請求傳回上一個xlator時,我們使用STACK_UNWIND。實際上,我們最好使用 STACK_UNWIND_STRICT。這個函數(shù)允許我們確定請求的種類,比如是open還是close等。

#define STACK_UNWIND_STRICT(op, frame, params …)

STACK_UNWIND_STRICT (symlink, frame, op_ret, op_errno, inode, buf, preparent, postparent, xdata);

參數(shù)解釋

  • 參數(shù)op:操作類型,是open/還是其他。用來檢查額外參數(shù)是否匹配此fop。

  • params …:此請求的一些額外的參數(shù)

  • 另外,在op和params直接,還有兩個參數(shù)op_ret和op_errno.雖然沒有在宏定義中出現(xiàn)。但在調(diào)用時還是要有的。

    • op_ret:fop的到目前的狀態(tài)(讀的字節(jié)數(shù)或者寫的字節(jié)數(shù),常常0表示fop成功,-1表示失?。?/p>

    • op_errno:標(biāo)準(zhǔn)錯誤碼,在fop失敗的情況下

  • 具體fop相關(guān)的參數(shù)有其他特殊的參數(shù),我們可以在params …中實現(xiàn)。但是我們也經(jīng)常需要這兩個參數(shù)

    • frame:當(dāng)前請求的stack frame。

    • this:表示此xlator實例的xlator對象

回調(diào)函數(shù)跟分配函數(shù)類似,除了在這兩個參數(shù)間有一個額外的參數(shù)cookie。是一個未定義數(shù)據(jù)類型的指針,由相應(yīng)的STACK_WIND存儲。默認(rèn)情況下,這是一個由STACK_WIND生成的stack frame的指針,但是STACK_WIND_COOKIE可以允許我們確定一個不同的值。在這種情況下,這個處于rfn和obj直接的額外參數(shù),可以從分配函數(shù)到其回調(diào)函數(shù)傳遞某些上下文。注意這個指針不能指向棧上的任何內(nèi)容,因為當(dāng)回調(diào)函數(shù)調(diào)用時,stack可能已經(jīng)不存在了。

另一個需要注意的:STACK_UNWIND也許會導(dǎo)致整個調(diào)用棧退出,此時,最后的那個STACK_UNWIND調(diào)用將會釋放所有的frames。因此,永遠(yuǎn)不要期望在調(diào)用STACK_UNWIND后,當(dāng)前的frame內(nèi)容還是完好的。

Per Request Context請求上下文私有變量

每個xlator 棧幀有一個local 指針,是用來保存xlator相關(guān)的上下文。這是最基本的機(jī)制,用來在分配函數(shù)和回調(diào)間保存上下文。因此我們應(yīng)該習(xí)慣如下代碼模式

/* in dispatch function */

local = (my_locals_t *)GF_CALLOC(1,sizeof(*local),...);
if (!local) {
/* STACK_UNWIND with ENOMEM eror */
}
/* fill in my_locals_t fields */
frame->local = local;
/* in callback */
local = frame->local;

要記住:每個幀frame的非NULL的local域當(dāng)要毀棧時要用GF_FREE來釋放,不用做其他的清理工作。如果local結(jié)構(gòu)里包含指針或?qū)ζ渌麑ο蟮囊?,需要我們自己進(jìn)行這些資源的清理。在毀棧前,內(nèi)存或者其他資源先清理是個好的習(xí)慣,為此就不能依靠GF_FREE來自動清理。最安全的方式是定義我們自己的xlator相關(guān)的destructor,在調(diào)用STACK_UNWIND前手動調(diào)用。

Inode and File Descriptor Context

大多數(shù)分配函數(shù)和回調(diào)以文件描述子或節(jié)點inode為參數(shù)。file descriptor (fd_t) or an inode (inode_t)。常常,xlator需要保存一些這些對象的一些關(guān)于此xlator的一些上下文,以此,在一個請求的完整生命周期內(nèi)信息可以保持。例如,DHT xlator需要保存目錄的layout map和某些inode的已知的位置。有一套函數(shù)來存儲操作此類上下文。在每個函數(shù)中,第二個參數(shù)是此value相關(guān)的xlator對象的指針。value是64位無符號×××。

inode_ctx_put (inode, xlator, value) /* NB: put, not set */把value放到inode里?

inode_ctx_get (inode, xlator, &value)從inode中獲取值到value。

inode_ctx_del (inode, xlator, &value)

fd_ctx_set (fd, xlator, value) /* NB: set, not put */

fd_ctx_get (fd, xlator, &value)

fd_ctx_del (fd, xlator, &value)

_del函數(shù)實際是破壞性get,先返回然后刪除值。inode函數(shù)有兩個value的形式,比如inode_ctx_put2,操作兩個值。使用xlator指針作為key/index并不僅僅是為了好看。當(dāng)要刪除inode_t or fd_t時, 刪除代碼要瀏覽上下文槽(估計就是遍歷所有xlator)。對于每個使用inode_t or fd_t的xlator的上下文槽,查看xlator的cbk表,調(diào)用其forget 或者release。如果上下文是個指針,需要手動釋放資源。傳遞到分配函數(shù)和回調(diào)的inode_t or fd_t pointer參數(shù),僅僅是個 borrowed reference。如果需要保證以后對象還在,需要調(diào)用inode_ref or fd_ref,來達(dá)到permanent reference。當(dāng)不再需要引用時可以 inode_unref or fd_unref。

Inode and File Descriptor Context 詞典和xlator選項

另一個常見的參數(shù)類型dict _t,是一種通用詞典或者h(yuǎn)ash-map的數(shù)據(jù)結(jié)構(gòu),用來以字符串key/索引的方式保存任意值。例如,值可以是可變大小的有無符號的×××,字符串,二進(jìn)制blob。字符串,二進(jìn)制blob也許可以用GLusterfs函數(shù)free,也可以用glibc free?;蛘卟挥胒ree。保存引用計數(shù)的值的dict_t* 和the *data_t 對象,在引用數(shù)為0的情況下釋放資源。和inode和文件描述子一樣,如果想在以后使用接受到dict_t的對象,需要使用add _ref and _unref來管理其生命周期。詞典不僅僅用于分配函數(shù)和回調(diào)函數(shù)。也用于傳遞options到模塊,比如xlator的init函數(shù)所用的options。事實上,目前的xlator的init函數(shù)主體大部分是來解釋包含在詞典里的options。要給xlator添加一個option,也需要向xlator的options 數(shù)組里添加一項。每個option可以是個boolean/整型/字符串/路徑/xlator 名字/其他類型。如果是個字符串,可以確定一個正確的值的列表。解析后的options,加上其他xlator級別的信息,將存儲在xlator_t structure結(jié)構(gòu)(在大多數(shù)上下中用this表示)的private的成員變量中。

Child Enumeration and Fan Out 子xlator枚舉和扇出

在一個xlator里的代碼,經(jīng)常需要枚舉其子xlator。要不找到一個滿足要求的子xlator的或者操作所有的子xlator。例如,對于DHT xlator,需要從所有的子xlator收集 hash-layout 映射,以確定文件應(yīng)該放到哪個子xlator;對于 AFR xlator,需要從子xlator中提取同一文件將要執(zhí)行的操作個數(shù)以便確定replication復(fù)制狀態(tài)。代碼范例如下: xlator_list_t *trav; xlator_t *xl;

for (trav = this->children; trav; trav = trav->next) {
    xl = trav->xlator;
    do_something(xl);
}

如果目的是扇出一個請求到所有的子xlator,則需要一些努力。在一個分配函數(shù)里最常用的方式是如下 local→call_count = priv→num_children;

    for (trav = this->children; trav; trav = trav->next) {
        xl = trav->xlator;
        STACK_WIND(frame,my_callback,xl,xl->fops->whatever,...);
    }
然后在回調(diào)函數(shù)中執(zhí)行
    LOCK(&frame->lock);
    call_cnt = --local->call_count;
    UNLOCK(&frame->lock);
/* Do whatever you do for every call */
if (!call_cnt) {
    /* Do last-call processing. */
    STACK_UNWIND(frame,op_ret,op_errno,...);
}
    return 0;
在某些情況下,可以使用STACK_WIND_COOKIE,這樣可以在回調(diào)中知道具體哪個調(diào)用返回了??梢圆榭碅FR。

Call Frames and Call Stacks

所有的xlator 函數(shù)使用類似SEDA和AT&T的STREAMS的異步調(diào)用規(guī)范。需要的調(diào)用幀和調(diào)用棧數(shù)據(jù)結(jié)構(gòu)功能上幾乎與Windows NT里的I/O requst packets 和irp 棧相同。許多xlator函數(shù)類似與fuse對應(yīng)的函數(shù),但是修改了或者添加了其他參數(shù)。

在xlator api里這是最基本的數(shù)據(jù)結(jié)構(gòu),call_frame_t and call_stack_txlators環(huán)境可以看作是個線程庫,每個請求有自己一個輕量級線程。這個線程有自己的棧,但是這些調(diào)用棧比c棧更加結(jié)構(gòu)化,同時常常偏離棧的嚴(yán)格的FIFO語義。每個調(diào)用幀表示一個函數(shù)調(diào)用,函數(shù)調(diào)用也許是嵌套的。但是這些函數(shù)在c里實際上兩個調(diào)用--初始部分執(zhí)行并在進(jìn)行任何嵌套調(diào)用前返回。收尾部分在嵌套的調(diào)用完成后執(zhí)行。

call_frame_t的成員如下:

  • root:指向內(nèi)嵌在call_stack_t里的假幀,不像其他單獨分配的frame。在stack里對所有的frame都相同。

  • parent指向調(diào)用此frame的那個frame。用c說就是調(diào)用函數(shù) calling 函數(shù)。

  • next /prev指向下一個/前一個要完成的frame。注意不是要調(diào)用的那個幀,

  • local 私有數(shù)據(jù),針對此幀調(diào)用的私有數(shù)據(jù)。是xlagor函數(shù)的本地變量,保存在此,可以在分配函數(shù)和回調(diào)間保持。

  • this 指向xlator的私有全局狀態(tài)。

  • ret 指向調(diào)用者(上層xlator)的回調(diào)函數(shù),當(dāng)本xlator的req完成后執(zhí)行。

  • ref_count and complete 調(diào)度器用來跟蹤那個frame是active,哪個完成了,哪個需要恢復(fù)執(zhí)行。

  • lock and cookie:

正常情況下,新frame push到棧后,next就跟parent就相同了。但是,一個frame(幀)可以分支。例如,stripe_writev請求的幀,在每個子xlator返回前生成一個新幀。假設(shè)有3個子xlator,即3個子卷。next就只與第一個新幀相同。

根據(jù)線程庫模型,call_stack_t對應(yīng)的就是線程控制塊。

有用的成員變量有:

  • uid 和gid表示調(diào)用幀來自誰,用來鑒權(quán)和認(rèn)證。

  • pid表示發(fā)起此請求的進(jìn)程pid。

  • trans 指向請求相關(guān)的transport 結(jié)構(gòu)。在服務(wù)器端用來實現(xiàn)基于節(jié)點的存取控制,或者用來沿著失敗的連接跟蹤請求。在client用作啥用?

  • frames:假幀,指向請求的第一個真正的frame。

  • op /type?

  • call_pool_t?

STACK_WIND and STACK_UNWIND等價與函數(shù)的調(diào)用和返回。在本xlator的請求的執(zhí)行,分配表先執(zhí)行,wind后就停止只ing了。當(dāng)函數(shù)rfn回調(diào)函數(shù)執(zhí)行時,此操作就開始恢復(fù)執(zhí)行了。rfn也許被調(diào)用多次。(多個子卷)。

todo

  • call stack

  • call stub


Version 1.0
Last updated 2014-04-30 12:28:09 CST

“GlusterFS Translator API怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI