最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Linux fd 系列“匿名句柄” 是一切皆文件背后功臣

2022-04-27 17:13 作者:補(bǔ)給站Linux內(nèi)核  | 我要投稿



匿名 fd 的樣子?

  • 我們經(jīng)常在 /proc/${pid}/fd/ 下面能看到 anon_inode : 前綴的句柄,如下:

如果是正常的文件句柄,一般顯式的是一個(gè)路徑:

  • 當(dāng)然 path 只是一個(gè)淺層次的感官,因?yàn)閷?duì)于 socket 句柄來(lái)說(shuō)也不算有人為理解上直觀的 path ,但是它有完整的 inode,所以這個(gè)匿名其實(shí)匿的是 inode 。


匿名 inode 的誕生?


  • 重點(diǎn)提一下匿名 fd 的事情,為什么會(huì)有匿名 fd ? 什么是匿名?

  1. 在 Linux 里一切皆文件,你理解的常見(jiàn)“文件”有什么特性?是路徑,也就是 path ,匿名的意思說(shuō)的就是沒(méi)有路徑。匿名 fd 其實(shí)說(shuō)的是匿名 inode 。

  2. 在 Linux 的文件體系中,一個(gè)文件句柄,對(duì)應(yīng)一個(gè) file 結(jié)構(gòu)體,關(guān)聯(lián)一個(gè) inode 。file/dentry/inode ?這三駕馬車是一定要配齊的,就算是匿名的(無(wú) path,無(wú)效 dentry ),對(duì)于 file 結(jié)構(gòu)體來(lái)說(shuō),一定要綁定 inode 和 dentry ,哪怕是偽造的、不完整的 inode。

  3. anon_inodefs 就應(yīng)運(yùn)而生了,內(nèi)核就幫你搞出來(lái)一個(gè)公共的 inode ,這就節(jié)省了所有有這樣需求的內(nèi)核模塊,避免了內(nèi)存的浪費(fèi),省了冗余重復(fù)的 inode 初始化代碼。

  4. 匿名 fd 背后的是一個(gè)叫做 anon_inodefs 的內(nèi)核文件系統(tǒng)( 位于 fs/anon_inodes.c ),這個(gè)文件系統(tǒng)極其簡(jiǎn)單,整個(gè)文件系統(tǒng)只有一個(gè) inode ,這個(gè) inode 是文件系統(tǒng)初始化的時(shí)候創(chuàng)建好的。之后,所有需要一個(gè)匿名 inode 的句柄都直接跟這個(gè) inode 關(guān)聯(lián)即可。

原理剖析

1、anon_inodefs 的初始化

  • 上面提到了,匿名 inode 是一個(gè)公共需求,我們不需要一個(gè)完整功能的 inode,而只是需要一個(gè) inode 而已,綁定到到 dentry ,file 等結(jié)構(gòu)體。

  • anon_inodes.c 用來(lái)創(chuàng)建一個(gè)綁定匿名 inode 的 file 結(jié)構(gòu)體。

  • 整個(gè) anon_inodefs 就只有一個(gè)文件,操作系統(tǒng)初始化的時(shí)候會(huì)調(diào)用初始化函數(shù) fs_initcall(anon_inode_init) ,其中 anon_inode_init 只做兩件事:

  1. 創(chuàng)建出一個(gè) vfsmount 實(shí)例,創(chuàng)建出來(lái)之后賦值給全局變量 anon_inode_mnt ;

  2. 創(chuàng)建出一個(gè) inode 實(shí)例,創(chuàng)建出來(lái)之后賦值給全局變量 anon_inode_inode ;

  • 這兩個(gè)變量就是 anon_inodefs 這個(gè)文件系統(tǒng)的全部家當(dāng)了。

【文章福利】小編推薦自己的Linux內(nèi)核技術(shù)交流群:【891587639】整理了一些個(gè)人覺(jué)得比較好的學(xué)習(xí)書(shū)籍、視頻資料共享在群文件里面,有需要的可以自行添加哦!?。∏?00名進(jìn)群領(lǐng)取,額外贈(zèng)送一份價(jià)值699的內(nèi)核資料包(含視頻教程、電子書(shū)、實(shí)戰(zhàn)項(xiàng)目及代碼)?



  • anon_inodefs 只提供了 2 個(gè)實(shí)用函數(shù),一個(gè)獲取到一個(gè)綁定匿名 inode 的 file 實(shí)例,另一個(gè)更多一些封裝,返回的是 fd 句柄。如下:

  • anon_inode_getfile

  • 這個(gè)函數(shù)非常簡(jiǎn)單,只做兩件事:

  1. 獲取一個(gè) inode ( 獲取全局的 inode 變量 anon_inode_inode ,當(dāng)然也可以通過(guò)一個(gè)參數(shù)控制來(lái)創(chuàng)建新的 inode );

  2. 創(chuàng)建一個(gè) file 結(jié)構(gòu)體實(shí)例,并且把這個(gè) inode 關(guān)聯(lián)起來(lái);

  • anon_inode_getfd

  • 這個(gè)函數(shù)非常簡(jiǎn)單,只做兩件事情:

  1. 創(chuàng)建一個(gè)新的 fd 句柄,返回的是一個(gè)非負(fù)整數(shù);

  2. 創(chuàng)建一個(gè) file 實(shí)例( 調(diào)用的是 anon_inode_getfile 來(lái)獲取 ),然后把這個(gè) fd 和 file 關(guān)聯(lián)起來(lái);

  • 這兩個(gè)函數(shù)就是 anon_inodefs 提供的兩個(gè)對(duì)外的函數(shù)接口。獲取到一個(gè) file 實(shí)例,這個(gè)實(shí)例綁定到 anon_inodefs 公共的 inode 實(shí)例。

  • 關(guān)于 anon_inodefs 的功能,其實(shí)在函數(shù)的注釋中也提到了,太直白了,如下:

3、為什么叫這個(gè)名字 "anon_inode:${dentry_name}" ?

  • 為什么常見(jiàn)的匿名 fd 都有以 "anon_inode:" 這樣開(kāi)頭?

  • 其實(shí)這種看得到的字符串都是 path ,這個(gè)是和 dentry 對(duì)應(yīng)起來(lái)的,對(duì)于這種匿名 inode 的 dentry ,有著統(tǒng)一的名字:

  • 那 dentry->d_name.name 又是怎么賦值的呢?來(lái)看一眼完整的調(diào)用棧,以 epoll fd 來(lái)舉個(gè)例子:

  • epoll_create 函數(shù)入口

創(chuàng)建一個(gè)匿名句柄

創(chuàng)建出一個(gè)偽 file 實(shí)例

創(chuàng)建一個(gè)偽 dentry 實(shí)例

創(chuàng)建并初始化 dentry 實(shí)例

  • 所以,epoll fd 的名字組合起來(lái)就是 "anon_inode:[eventpoll]" 嘍。

  • 問(wèn)題來(lái)了,那這個(gè)一般用在哪些地方呢?

  • 其實(shí)就是個(gè)人性化的名字而已,最常見(jiàn)的就是在 proc 文件系統(tǒng)中。

  • 我們?cè)?proc 文件系統(tǒng)中,ls 的時(shí)候,其實(shí)就像想看名字,這個(gè)名字其實(shí)就是 path ,就會(huì)出發(fā)調(diào)用到哪步的 d_path 函數(shù),這個(gè)函數(shù)就是把 dentry 轉(zhuǎn)換成人類可讀的字符串 path 的名字。

4、inode 可以對(duì)應(yīng)多個(gè) dentry


  • 在 Linux 中是一個(gè)倒掛樹(shù)的設(shè)計(jì),從根目錄( / )開(kāi)始,葉子結(jié)點(diǎn)為文件或者目錄,從根節(jié)點(diǎn)到葉子結(jié)點(diǎn)這一段就稱為 path 路徑,在內(nèi)存里面這顆倒掛的樹(shù)就體現(xiàn)為 dentry 樹(shù),節(jié)點(diǎn)就是 dentry 結(jié)構(gòu)體。

  • 這里就有個(gè)重要的知識(shí)點(diǎn):

  • 劃重點(diǎn):一個(gè) inode 上可以掛多個(gè) dentry ,一個(gè) dentry 只能屬于一個(gè) inode 。

  • 還記得軟鏈接和硬鏈接嗎?

  • 軟鏈接就是創(chuàng)建了一個(gè)新的文件,鏈接文件里就是路徑。inode,dentry 都創(chuàng)建了一個(gè)新的。

  • 硬鏈接則沒(méi)有創(chuàng)建新的 inode,而是只在目錄文件中創(chuàng)建了一個(gè) dirent ,在目錄樹(shù)中添加了一個(gè) dentry 。硬鏈接的場(chǎng)景就是一個(gè) inode 對(duì)應(yīng)了多個(gè) dentry 節(jié)點(diǎn)。

  • 換句話說(shuō),一個(gè) inode 可以出現(xiàn)在目錄樹(shù)的多個(gè)位置。

  • 每個(gè)文件或者目錄都會(huì)在這棵樹(shù)上有自己的位置,內(nèi)存用 struct path 結(jié)構(gòu)體來(lái)表示唯一的位置。

  • 這里順便再說(shuō)另一個(gè)重要知識(shí)點(diǎn):為什么內(nèi)核之中,需要用 struct path 這個(gè)復(fù)合結(jié)構(gòu)體來(lái)標(biāo)識(shí)唯一的一個(gè)目錄樹(shù)位置呢?

  • 文件系統(tǒng)的掛載最關(guān)鍵的就是把一個(gè)文件系統(tǒng)的實(shí)例和目錄樹(shù)上的一個(gè) dentry 關(guān)聯(lián)起來(lái),而一個(gè) dentry 可以關(guān)聯(lián)多個(gè)文件系統(tǒng)實(shí)例。

  • 換句話說(shuō):對(duì)于一個(gè)目錄樹(shù)路徑其實(shí)是可以掛載多個(gè)文件系統(tǒng)實(shí)例。比如 /mnt/path 這么一個(gè)路徑,其實(shí)是可以掛載多個(gè)文件系統(tǒng)的,不會(huì)報(bào)錯(cuò),后面的掛載直接覆蓋前面的。


5、其實(shí)還有一類匿名

  • 為了知識(shí)的完善,這里補(bǔ)充一個(gè)知識(shí)點(diǎn)。其實(shí)關(guān)于匿名 inode 還有一種方式,這種方式以 alloc_anon_inode 函數(shù)提供,該函數(shù)傳入一個(gè)超級(jí)塊作為參數(shù)用于創(chuàng)建一個(gè)匿名 inode 。這個(gè)函數(shù)創(chuàng)建一個(gè)新的內(nèi)存 inode 實(shí)例,這個(gè) inode 不具備完備的功能,也是用來(lái)做匿名之用。

  • 這種匿名 inode 就不是 anon_inodefs 的那個(gè)了,而是具體文件系統(tǒng)實(shí)例上的匿名 inode 。


6、誰(shuí)用到了匿名 inode


  • 隨便列舉一些 eventfd,eventpoll,timerfd,signalfd,inotifyfd,io_uring fd 等等,還有很多,但比較偏僻了,就不再舉例了。童鞋們驚訝嗎?


總結(jié)

  1. anon_inodefs 是為了公共需求抽離出來(lái)的一個(gè)內(nèi)核文件系統(tǒng),只有一個(gè) inode ,為了節(jié)省內(nèi)存,抽象重復(fù)代碼之用;

  2. 匿名句柄是因?yàn)?fd 對(duì)應(yīng)的 file 實(shí)例背靠著的是匿名 inode ,anon_inodefs 提供了兩個(gè)功能函數(shù),都是用來(lái)獲取匿名 fd 的;

  3. inode 上可以掛多個(gè) dentry 節(jié)點(diǎn),換句話說(shuō),一個(gè) inode 可以出現(xiàn)在 Linux 目錄樹(shù)的多個(gè)位置;

  4. dentry 對(duì)應(yīng)目錄樹(shù)的一個(gè)節(jié)點(diǎn)位置,最直觀的是對(duì)應(yīng) path 路徑的一個(gè)位置;

  5. 一個(gè)掛載路徑可以掛多個(gè)文件系統(tǒng)實(shí)例,后面的覆蓋前面的,所以光靠 dentry 無(wú)法唯一定位一個(gè)“文件”,Linux 內(nèi)核才用兩元組 < vfsmount, dentry > 來(lái)唯一定位一個(gè)“文件”;


Linux fd 系列“匿名句柄” 是一切皆文件背后功臣的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
长乐市| 庄浪县| 松滋市| 台山市| 昆明市| 绵阳市| 灌云县| 万年县| 蓬溪县| 岳池县| 马山县| 威海市| 乌兰察布市| 乃东县| 获嘉县| 肇源县| 池州市| 凤翔县| 宜阳县| 东丽区| 楚雄市| 大田县| 嫩江县| 伊金霍洛旗| 临澧县| 和林格尔县| 桑日县| 芦溪县| 梨树县| 镇坪县| 云霄县| 福建省| 上虞市| 新晃| 宁安市| 公主岭市| 平山县| 临沂市| 诸暨市| 定兴县| 龙游县|