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

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

深究Runc源碼-3-Init流程分析

2022-11-15 12:31 作者:黑暗光影DIY  | 我要投稿

代碼基于1.1.0

runc init并不通過(guò)runc 命令行暴露,而是runc內(nèi)部調(diào)用,如在create流程中parentProcess 通過(guò)Cmd.start,由于runc init.go導(dǎo)入了_ "github.com/opencontainers/runc/libcontainer/nsenter",所以運(yùn)行前首先會(huì)執(zhí)行nsenter,nsenter會(huì)首先執(zhí)行nsexec函數(shù)。

nsenter.go

nsenter的核心業(yè)務(wù)是設(shè)置runc init的Linux namespaces,首先需要了解一下Linux namespaces和相關(guān)的三個(gè)調(diào)用函數(shù),Linux Namespace是Linux提供的一種內(nèi)核級(jí)別環(huán)境隔離的方法,提供了對(duì)UTS、IPC、mount、PID、network、User等的隔離機(jī)制

對(duì)于的path如下:

系統(tǒng)調(diào)用如下:

nsexec核心流程是通過(guò)clone生成3個(gè)進(jìn)程,并通過(guò)管道pipe進(jìn)行進(jìn)程間同步

setup_logpipe根據(jù)_LIBCONTAINTER_LOGPIPE和_LIBCONTAINER_LOGLEVEL確定log fd和level,從啟動(dòng)Cmd環(huán)境變量帶入。update_oom_score_adj 通過(guò)/proc/self/oom_score_adj寫(xiě)入config.oom_score_adj。

clone_parent函數(shù)調(diào)用clone,子進(jìn)程跳轉(zhuǎn)到標(biāo)記處,父進(jìn)程返回clone子進(jìn)程pid

在STAGE_PARENT case中parent進(jìn)程中clone_parent生成child進(jìn)程,獲取child子進(jìn)程pid,child進(jìn)程立刻跳轉(zhuǎn)到STAGE_CHILD case運(yùn)行,同理在CHILD_STAGE中調(diào)用clone_parent生成grandchil進(jìn)程,獲取grandchild pid,grandchild立刻跳轉(zhuǎn)到STAGE_INIT case運(yùn)行。

STAGE_PARENT 完成child進(jìn)程clone后,主要有2段核心邏輯

1 與child進(jìn)程同步,并等待child進(jìn)程完成,在源碼中理解為stage1

2 與grandchild進(jìn)程同步,并等待grandchild完成,源碼中理解為stage2

stage1邏輯包含在parent和child中,分為3段case邏輯

1 SYNC_USERMAP

在child中,如果配置了config.namespaces首先執(zhí)行join_namespaces,通過(guò)setns設(shè)置child的namespaces,創(chuàng)建流程中為null,不執(zhí)行join_namespaces。首先執(zhí)行unshare(CLONE_NEWUSER)設(shè)置新的user namespace,根據(jù)源碼注釋,首先設(shè)置設(shè)置user namespace是因?yàn)槠鋾?huì)對(duì)其他namespaces unshare產(chǎn)生影響,并影響權(quán)限檢查,并且不同時(shí)unshare所有namespaces,是因?yàn)閗ernal存在bug,具體情況待進(jìn)一步深究

完成后發(fā)送SYNC_USERMAP_PLS到parent,parent SYNC_USERMAP_PLS case核心是根據(jù)config設(shè)置/proc/$child_pid/uid_map|gid_map,完成后發(fā)送SYNC_USERMAP_ACK,流程繼續(xù)到child,child執(zhí)行unshare除cgroup namespace之外的所有namespace,然后進(jìn)入另一個(gè)case邏輯

2 SYNC_MOUNTSOURCES

child發(fā)送 SYNC_MOUNTSOURCES_PLS到parent,parent中執(zhí)行send_mountresources分別獲區(qū)父進(jìn)程所在主機(jī)mnt namespace fd /proc/self/ns/mnt, 和child進(jìn)程mnt namespace fd /proc/$child_pid/ns/mnt, 通過(guò)setns將parent mount namespace加入到child mount namespace,然后讀取config.mountsources,并獲區(qū)對(duì)應(yīng)fd發(fā)送到child,child通過(guò)receive_mountsources獲取mount fd, 最后通過(guò)SYNC_MOUNTSOURCES_ACK結(jié)束SYNC_MOUNT流程

mountresources是什么待進(jìn)一步研究

3 SYNC_RECVPID

child通過(guò)clone_parent(STAGE_INIT)生成grandchild,并得到grandchild_pid,parent通過(guò)pipe將child_pid和grandchild_pid發(fā)送到runc create進(jìn)程,然后發(fā)送SYNC_RECVPID_PLS到parent,parent收到后發(fā)送SYNC_RECVPID_ACK到child,child收到后發(fā)送SYNC_CHILD_FINISH后結(jié)束進(jìn)程,parent收到SYNC_CHILD_FINISH結(jié)束stage1流程,進(jìn)入stage2

stage2主要流程是parent發(fā)送SYNC_GRANDCHILD,grandchild收到后調(diào)用unshare設(shè)置cgroup namespace,完成后發(fā)送SYNC_CHILD_FINISH,父進(jìn)程退出,grandchild return,流程返回到go runtime。

返回go runtime流程,代碼進(jìn)入init.go init方法

主要是構(gòu)建一個(gè)initer,create流程中實(shí)例化linuxStandInit,然后執(zhí)行Init方法

initConfig實(shí)例為

此時(shí)需要結(jié)合runc create和runc init流程同時(shí)分析,因?yàn)榱鞒贪瑀unc create與runc init之間的進(jìn)程同步和通信,主要通過(guò)INITPIPE進(jìn)行,是一個(gè)socket pair

流程來(lái)到linuxStandInit.Init,首先根據(jù)config設(shè)置網(wǎng)絡(luò)和路由 setupNetwork/setupRoute,然后調(diào)用prepareRootfs完成容器rootfs的設(shè)置,此邏輯較為關(guān)鍵。

在展開(kāi)rootfs邏輯前,先補(bǔ)充一下bind mount和shared subtree 兩個(gè)Mount基礎(chǔ)

參考https://man7.org/linux/man-pages/man8/mount.8.html https://man7.org/linux/man-pages/man7/mount_namespaces.7.html

一句話簡(jiǎn)述bind mount是將olddir掛載到newdir上,shared subtree主要是是控制mount事件的傳遞性,包括4種參數(shù),簡(jiǎn)單描述:

MS_SHARD:雙向傳遞

MS_PRIVATE:不傳遞

MS_SLAVE:向下傳遞

MS_UNBINDABLE:不能執(zhí)行bind mount

prepareRoot將rootfs的父掛載點(diǎn)設(shè)置為MS_PRIVATE,然后執(zhí)行bind mount Rootfs,結(jié)果如下

mountToRootfs依次掛在configs.Mount到rootfs,默認(rèn)幾個(gè)掛在/proc /sys /dev等,結(jié)果如下

mountConfig對(duì)象示例

configs.Mount對(duì)象示例

setUpDev判斷中createDevices根據(jù)configs.Devices創(chuàng)建設(shè)備,例如gpu,默認(rèn)情況下沒(méi)有Device設(shè)備,setupDevSyslinks設(shè)置標(biāo)準(zhǔn)輸入輸出鏈接等。

syncParentHooks通知runc create進(jìn)程 parentProcess.start執(zhí)行configs.Hooks下配置的Prestart/CreateRuntime Hook。

將目錄切換到rootfs執(zhí)行createContainer Hooks

然后默認(rèn)請(qǐng)繼續(xù)執(zhí)行pivotRoot,pivot_root是linux 系統(tǒng)調(diào)用,參考https://man7.org/linux/man-pages/man2/pivot_root.2.html,簡(jiǎn)單來(lái)講就是切換init進(jìn)程mount namespace root目錄到rootfs,完成后runc init的mountinfo變成如下形態(tài):

finalizeRootfs將/dev /等重新掛為ReadOnly。

Console/Seccomp/AppArmor/Selinux等邏輯再分析,先看主流程。流程來(lái)到unix.Open FIFOFd,runc init 進(jìn)程會(huì)在此處被阻塞住,runc create流程到此基本結(jié)束,由runc start觸發(fā)runc init繼續(xù)執(zhí)行process定義的命令。


開(kāi)源的東西,轉(zhuǎn)發(fā)不需要出處,就說(shuō)你自己寫(xiě)的

深究Runc源碼-3-Init流程分析的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
庐江县| 太和县| 陈巴尔虎旗| 秦安县| 习水县| 沈丘县| 明星| 望城县| 日土县| 舒兰市| 安新县| 湟源县| 德庆县| 永丰县| 射洪县| 南安市| 汶川县| 太白县| 齐齐哈尔市| 镇赉县| 河津市| 宣化县| 扬中市| 蒙自县| 调兵山市| 武隆县| 大丰市| 宁国市| 叶城县| 尖扎县| 招远市| 启东市| 同心县| 宜宾县| 沅陵县| 厦门市| 霍州市| 襄城县| 陵川县| 海阳市| 镇巴县|