新聞中心
Devicemapper是內(nèi)核中支持邏輯卷管理的通用設(shè)備映射機(jī)制,它為實(shí)現(xiàn)用于存儲(chǔ)資源管理的塊設(shè)備驅(qū)動(dòng)提供了一個(gè)高度模塊化的內(nèi)核架構(gòu),它包含三個(gè)重要的對(duì)象概念,Mapped Device、Mapping Table、Target device。

創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營(yíng)銷推廣、網(wǎng)站重做改版、代縣網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5、商城網(wǎng)站建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為代縣等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。
在內(nèi)核中它通過(guò)一個(gè)一個(gè)模塊化的 target driver 插件實(shí)現(xiàn)對(duì) IO 請(qǐng)求的過(guò)濾或者重新定向等工作,當(dāng)前已經(jīng)實(shí)現(xiàn)的 target driver 插件包括軟 raid、軟加密、邏輯卷?xiàng)l帶、多路徑、鏡像、快照等,圖中 linear、mirror、snapshot、multipath 表示的就是這些 target driver。Device mapper 進(jìn)一步體現(xiàn)了在 Linux 內(nèi)核設(shè)計(jì)中策略和機(jī)制分離的原則,將所有與策略相關(guān)的工作放到用戶空間完成,內(nèi)核中主要提供完成這些策略所需要的機(jī)制。Device mapper 用戶空間相關(guān)部分主要負(fù)責(zé)配置具體的策略和控制邏輯,比如邏輯設(shè)備和哪些物理設(shè)備建立映射,怎么建立這些映射關(guān)系等等,而具體過(guò)濾和重定向 IO 請(qǐng)求的工作由內(nèi)核中相關(guān)代碼完成。因此整個(gè) device mapper 機(jī)制由兩部分組成–內(nèi)核空間的 device mapper 驅(qū)動(dòng)、用戶空間的device mapper 庫(kù)以及它提供的 dmsetup 工具。在下文中,我們分內(nèi)核和用戶空間兩部分進(jìn)行介紹。
內(nèi)核部分
Device mapper 的內(nèi)核相關(guān)代碼已經(jīng)作為 Linux 2.6 內(nèi)核發(fā)布版的一部分集成到內(nèi)核源碼中了,相關(guān)代碼在內(nèi)核源碼的 driver/md/ 目錄中,其代碼文件可以劃分為實(shí)現(xiàn) device mapper 內(nèi)核中基本架構(gòu)的文件和實(shí)現(xiàn)具體映射工作的 target driver 插件文件兩部分。文章下面的分析結(jié)果主要是基于上述源碼文件得到的。
重要概念
Device mapper 在內(nèi)核中作為一個(gè)塊設(shè)備驅(qū)動(dòng)被注冊(cè)的,它包含三個(gè)重要的對(duì)象概念,mapped device、映射表、target device。Mapped device 是一個(gè)邏輯抽象,可以理解成為內(nèi)核向外提供的邏輯設(shè)備,它通過(guò)映射表描述的映射關(guān)系和 target device 建立映射。從 Mapped device 到一個(gè) target device 的映射表由一個(gè)多元組表示,該多元組由表示 mapped device 邏輯的起始地址、范圍、和表示在 target device 所在物理設(shè)備的地址偏移量以及target 類型等變量組成(這些地址和偏移量都是以磁盤的扇區(qū)為單位的,即 512 個(gè)字節(jié)大?。?。Target device 表示的是 mapped device 所映射的物理空間段,對(duì) mapped device 所表示的邏輯設(shè)備來(lái)說(shuō),就是該邏輯設(shè)備映射到的一個(gè)物理設(shè)備。Device mapper 中這三個(gè)對(duì)象和 target driver 插件一起構(gòu)成了一個(gè)可迭代的設(shè)備樹(shù)。在該樹(shù)型結(jié)構(gòu)中的頂層根節(jié)點(diǎn)是最終作為邏輯設(shè)備向外提供的 mapped device,葉子節(jié)點(diǎn)是 target device 所表示的底層物理設(shè)備。最小的設(shè)備樹(shù)由單個(gè) mapped device 和 target device 組成。每個(gè) target device 都是被mapped device 獨(dú)占的,只能被一個(gè) mapped device 使用。一個(gè) mapped device 可以映射到一個(gè)或者多個(gè) target device 上,而一個(gè) mapped device 又可以作為它上層 mapped device的 target device 被使用,該層次在理論上可以在 device mapper 架構(gòu)下無(wú)限迭代下去。
從上圖中我們可以看到 mapped device1 通過(guò)映射表和 a、b、c 三個(gè) target device 建立了映射關(guān)系,而 target device a 又是通過(guò) mapped device 2 演化過(guò)來(lái),mapped device 2 通過(guò)映射表和 target device d 建立映射關(guān)系。
我們進(jìn)一步看一下上圖中三個(gè)對(duì)象在代碼中的具體實(shí)現(xiàn),dm.c 文件定義的 mapped_device 結(jié)構(gòu)用于表示 mapped device,它主要包括該 mapped device 相關(guān)的鎖,注冊(cè)的請(qǐng)求隊(duì)列和一些內(nèi)存池以及指向它所對(duì)應(yīng)映射表的指針等域。
Mapped device 對(duì)應(yīng)的映射表是由 dm_table.c 文件中定義的 dm_table 結(jié)構(gòu)表示的,該結(jié)構(gòu)中包含一個(gè) dm_target結(jié)構(gòu)數(shù)組,dm_target 結(jié)構(gòu)具體描述了 mapped_device 到它某個(gè) target device 的映射關(guān)系。
而在 dm_table 結(jié)構(gòu)中將這些 dm_target 按照 B 樹(shù)的方式組織起來(lái)方便 IO 請(qǐng)求映射時(shí)的查找操作。Dm_target 結(jié)構(gòu)具體記錄該結(jié)構(gòu)對(duì)應(yīng) target device 所映射的 mapped device 邏輯區(qū)域的開(kāi)始地址和范圍,同時(shí)還包含指向具體 target device 相關(guān)操作的 target_type 結(jié)構(gòu)的指針。
Target_type 結(jié)構(gòu)主要包含了 target device 對(duì)應(yīng)的 target driver 插件的名字、定義的構(gòu)建和刪除該類型target device的方法、該類target device對(duì)應(yīng)的IO請(qǐng)求重映射和結(jié)束IO的方法等。而表示具體的target device的域是dm_target中的private域,該指針指向mapped device所映射的具體target device對(duì)應(yīng)的結(jié)構(gòu)。表示target device的具體結(jié)構(gòu)由于不同的target 類型而不同,比如最簡(jiǎn)單的線性映射target類型對(duì)應(yīng)target device的結(jié)構(gòu)是dm-linear.c文件中定義的linear_c結(jié)構(gòu)。其定義如下:
struct linear_c { struct dm_dev *dev; sector_t start; };
該target device的定義相當(dāng)簡(jiǎn)單,就只包括了表示對(duì)應(yīng)物理設(shè)備的dm_dev結(jié)構(gòu)指針和在該物理設(shè)備中以扇區(qū)為單位的偏移地址start。上述幾個(gè)數(shù)據(jù)結(jié)構(gòu)關(guān)系如圖所示:
內(nèi)核中建立過(guò)程
在下面我們結(jié)合具體的代碼簡(jiǎn)要介紹下在內(nèi)核中創(chuàng)建一個(gè)mapped device的過(guò)程:
-
根據(jù)內(nèi)核向用戶空間提供的ioctl 接口傳來(lái)的參數(shù),用dm-ioctl.c文件中的dev_create函數(shù)創(chuàng)建相應(yīng)的mapped device結(jié)構(gòu)。這個(gè)過(guò)程很簡(jiǎn)單,主要是向內(nèi)核申請(qǐng)必要的內(nèi)存資源,包括mapped device和為進(jìn)行IO操作預(yù)申請(qǐng)的內(nèi)存池,通過(guò)內(nèi)核提供的blk_queue_make_request函數(shù)注冊(cè)該mapped device對(duì)應(yīng)的請(qǐng)求隊(duì)列dm_request。并將該mapped device作為磁盤塊設(shè)備注冊(cè)到內(nèi)核中。
-
調(diào)用dm_hash_insert將創(chuàng)建好的mapped device插入到device mapper中的一個(gè)全局hash表中,該表中保存了內(nèi)核中當(dāng)前創(chuàng)建的所有mapped device。
-
用戶空間命令通過(guò)ioctl調(diào)用table_load函數(shù),該函數(shù)根據(jù)用戶空間傳來(lái)的參數(shù)構(gòu)建指定mapped device的映射表和所映射的target device。該函數(shù)先構(gòu)建相應(yīng)的dm_table、dm_target結(jié)構(gòu),再調(diào)用dm-table.c中的dm_table_add_target函數(shù)根據(jù)用戶傳入的參數(shù)初始化這些結(jié)構(gòu),并且根據(jù)參數(shù)所指定的target類型,調(diào)用相應(yīng)的target類型的構(gòu)建函數(shù)ctr在內(nèi)存中構(gòu)建target device對(duì)應(yīng)的結(jié)構(gòu),然后再根據(jù)所建立的dm_target結(jié)構(gòu)更新dm_table中維護(hù)的B樹(shù)。上述過(guò)程完畢后,再將建立好的dm_table添加到mapped device的全局hash表對(duì)應(yīng)的hash_cell結(jié)構(gòu)中。
-
最后通過(guò)ioctl調(diào)用do_resume函數(shù)建立mapped device和映射表之間的綁定關(guān)系,事實(shí)上該過(guò)程就是通過(guò)dm_swap_table函數(shù)將當(dāng)前dm_table結(jié)構(gòu)指針值賦予mapped_device相應(yīng)的map域中,然后再修改mapped_device表示當(dāng)前狀態(tài)的域。
通過(guò)上述的4個(gè)主要步驟,device mapper在內(nèi)核中就建立一個(gè)可以提供給用戶使用的mapped device邏輯塊設(shè)備。
IO流
Device mapper本質(zhì)功能就是根據(jù)映射關(guān)系和target driver描述的IO處理規(guī)則,將IO請(qǐng)求從邏輯設(shè)備mapped device轉(zhuǎn)發(fā)相應(yīng)的target device上。Device mapper處理所有從內(nèi)核中塊一級(jí)IO子系統(tǒng)的generic_make_request和submit_bio接口[兩個(gè)接口具體的描述可以查看參考文獻(xiàn)[1]和[2],這兩本書對(duì)內(nèi)核中的塊IO層有比較詳盡的講解。] 中定向到mapped device的所有塊讀寫IO請(qǐng)求。IO請(qǐng)求在device mapper的設(shè)備樹(shù)中通過(guò)請(qǐng)求轉(zhuǎn)發(fā)從上到下地進(jìn)行處理。當(dāng)一個(gè)bio請(qǐng)求在設(shè)備樹(shù)中的mapped deivce向下層轉(zhuǎn)發(fā)時(shí),一個(gè)或者多個(gè)bio的克隆被創(chuàng)建并發(fā)送給下層target device。然后相同的過(guò)程在設(shè)備樹(shù)的每一個(gè)層次上重復(fù),只要設(shè)備樹(shù)足夠大理論上這種轉(zhuǎn)發(fā)過(guò)程可以無(wú)限進(jìn)行下去。在設(shè)備樹(shù)上某個(gè)層次中,target driver結(jié)束某個(gè)bio請(qǐng)求后,將表示結(jié)束該bio請(qǐng)求的事件上報(bào)給它上層的mapped device,該過(guò)程在各個(gè)層次上進(jìn)行直到該事件最終上傳到根mapped device的為止,然后device mapper結(jié)束根mapped device上原始bio請(qǐng)求,結(jié)束整個(gè)IO請(qǐng)求過(guò)程。
Bio在device mapper的設(shè)備樹(shù)進(jìn)行逐層的轉(zhuǎn)發(fā)時(shí),最終轉(zhuǎn)發(fā)到一個(gè)或多個(gè)葉子target節(jié)點(diǎn)終止。因?yàn)橐粋€(gè)bio請(qǐng)求不可以跨多個(gè)target device(亦即物理空間段), 因此在每一個(gè)層次上,device mapper根據(jù)用戶預(yù)先告知的mapped device 的target映射信息克隆一個(gè)或者多個(gè)bio,將bio進(jìn)行拆分后轉(zhuǎn)發(fā)到對(duì)應(yīng)的target device上。這些克隆的bio先交給mapped device上對(duì)應(yīng)的target driver上進(jìn)行處理,根據(jù)target driver中定義的IO處理規(guī)則進(jìn)行IO請(qǐng)求的過(guò)濾等處理,然后再提交給target device完成。上述過(guò)程在dm.c文件中的dm_request函數(shù)中完成。Target driver可以對(duì)這些bio做如下處理:
-
將這些bio在本驅(qū)動(dòng)內(nèi)部排隊(duì)等待以后進(jìn)行處理;
-
將bio重新定向到一個(gè)或多個(gè)target device上或者每個(gè)target device上的不同扇區(qū);
-
向device mapper返回error 狀態(tài)。
IO請(qǐng)求就按照上文中描述的過(guò)程在圖2中所示的設(shè)備樹(shù)中逐層進(jìn)行處理,直到IO請(qǐng)求結(jié)束。
小結(jié)
Device mapper在內(nèi)核中向外提供了一個(gè)從邏輯設(shè)備到物理設(shè)備的映射架構(gòu),只要用戶在用戶空間制定好映射策略,按照自己的需要編寫處理具體IO請(qǐng)求的target driver插件,就可以很方便的實(shí)現(xiàn)一個(gè)類似LVM的邏輯卷管理器。Device mapper以ioctl的方式向外提供接口,用戶通過(guò)用戶空間的device mapper庫(kù),向device mapper的字符設(shè)備發(fā)送ioctl命令,完成向內(nèi)的通信。它還通過(guò)ioctl提供向往的事件通知機(jī)制,允許target driver將IO相關(guān)的某些事件傳送到用戶空間。
當(dāng)前標(biāo)題:詳解Linux中DeviceMapper內(nèi)核空間
分享路徑:http://fisionsoft.com.cn/article/dppsdpi.html


咨詢
建站咨詢
