亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 988 | 回復(fù): 0
打印 上一主題 下一主題

Solaris內(nèi)核目錄 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2006-01-09 21:02 |只看該作者 |倒序?yàn)g覽
--------------------------------------------------------------------------
◆ /proc/目錄簡(jiǎn)介
進(jìn)程文件系統(tǒng),procfs,是一個(gè)偽文件系統(tǒng),它允許對(duì)一些非傳統(tǒng)意義上的文件
通過(guò)標(biāo)準(zhǔn)文件I/O接口進(jìn)行訪問(wèn)。procfs將Solaris內(nèi)核進(jìn)程架構(gòu)進(jìn)行了抽象,比如當(dāng)前系統(tǒng)中所有運(yùn)行著的進(jìn)程會(huì)在/proc/目錄下有所體現(xiàn)。系統(tǒng)中每個(gè)進(jìn)程對(duì)應(yīng)/proc/目錄下的一個(gè)子目錄,子目錄名即相應(yīng)進(jìn)程號(hào)(PID),所有進(jìn)程號(hào)子目錄構(gòu)成了/proc/目錄的全部?jī)?nèi)容。
許多提供進(jìn)程數(shù)據(jù)和控制點(diǎn)的內(nèi)核數(shù)據(jù)結(jié)構(gòu)在/proc//子目錄下有相應(yīng)反映,
比如,多線程進(jìn)程中每個(gè)LWP的相關(guān)數(shù)據(jù)和控制結(jié)構(gòu)體現(xiàn)在/proc//lwp/
中。 /proc/目錄下的對(duì)象不是真實(shí)磁盤文件,這些對(duì)象位于內(nèi)核內(nèi)存中,用戶執(zhí)行l(wèi)s(1)命令顯示/proc/目錄結(jié)構(gòu)時(shí),系統(tǒng)讀取內(nèi)核內(nèi)存并返回相應(yīng)內(nèi)容。
通過(guò)/proc,相對(duì)簡(jiǎn)便地就可以獲取進(jìn)程信息,比如進(jìn)程執(zhí)行環(huán)境、內(nèi)核資源利
用率。進(jìn)程控制和procfs直接相關(guān),procfs最初的設(shè)計(jì)目的很簡(jiǎn)單,就是為編寫(xiě)調(diào)試器提供一組接口,現(xiàn)在已經(jīng)有了相當(dāng)大的改進(jìn)。
Solaris系統(tǒng)在/usr/proc/bin/目錄下提供了一組工具從/proc中析取進(jìn)程信息,
同時(shí)可以進(jìn)行簡(jiǎn)單的進(jìn)程控制。可以參看proc(1)手冊(cè)頁(yè)。進(jìn)程狀態(tài)命令ps(1)也利用了procfs接口。
下面列舉可以通過(guò)/proc文件系統(tǒng)獲取的控制和信息數(shù)據(jù),關(guān)于這些文件的詳細(xì)
信息參看proc(4)手冊(cè)頁(yè)。
/proc -- procfs的根目錄
/proc/ -- 某一確定進(jìn)程的根目錄,進(jìn)程PID正是子目錄名
/proc//as -- 進(jìn)程地址空間,即struct proc結(jié)構(gòu)中p_as成員。換句話說(shuō),進(jìn)
程地址空間以/proc//as文件的形式展現(xiàn)出來(lái),通過(guò)這個(gè)偽文件系統(tǒng)接口可以訪
問(wèn)相應(yīng)進(jìn)程地址空間。
struct as * p_as; /* 進(jìn)程地址空間指針 */
# ls -l /proc/53/as
-rw------- 1 root root 1458176 2月 8 17:34 /proc/53/as
struct proc結(jié)構(gòu)定義在/usr/include/sys/proc.h文件中。
/proc//ctl -- 一個(gè)進(jìn)程控制文件?梢灾粚(xiě)打開(kāi)該文件,然后給相應(yīng)進(jìn)程發(fā)
送控制信息。可以停止、啟動(dòng)進(jìn)程,設(shè)置進(jìn)程停止于某一特殊事件。這演示了procfs的強(qiáng)大和便捷。進(jìn)程控制、事件跟蹤可以通過(guò)打開(kāi)相應(yīng)進(jìn)程的控制文件完成,只需要寫(xiě)入期待行為的控制信息。參看proc(4)手冊(cè)了解控制信息和控制函數(shù)的詳細(xì)介紹。
/proc//status -- 進(jìn)程狀態(tài)信息。對(duì)應(yīng)/usr/include/sys/procfs.h文件里定
義的struct pstatus結(jié)構(gòu)。proc(4)手冊(cè)頁(yè)里也有描述。這個(gè)結(jié)構(gòu)中有一個(gè)成員
lwpstatus_t pr_lwp; /* status of the representative lwp */
該成員對(duì)應(yīng)一個(gè)有代表性的LWP(輕量級(jí)進(jìn)程)。單線程進(jìn)程只有一個(gè)LWP,很容易選定這個(gè)有代表性的LWP。那些多線程進(jìn)程通常有多個(gè)LWPs,一個(gè)內(nèi)核函數(shù)遍歷當(dāng)前進(jìn)程的所有LWPs,根據(jù)他們的狀態(tài)選取這個(gè)有代表性的LWP。首先選取正在執(zhí)行中的LWP,如果不存在這樣的LWP,按照可運(yùn)行、休眠、停止的順序選取LWP。
/proc//lstatus -- lwpstatus結(jié)構(gòu)數(shù)組,進(jìn)程中每個(gè)LWP對(duì)應(yīng)一個(gè)lwpstatus結(jié)構(gòu)。struct lwpstatus結(jié)構(gòu)定義在/usr/include/sys/procfs.h文件中。
/proc//psinfo -- 類似ps(1)命令提供的進(jìn)程信息。對(duì)應(yīng)struct psinfo結(jié)構(gòu),
類似struct pstatus結(jié)構(gòu),struct psinfo結(jié)構(gòu)中有一個(gè)成員
lwpsinfo_t pr_lwp; /* information for representative lwp */
該成員的對(duì)應(yīng)一個(gè)有代表性的LWP。
/proc//lpsinfo -- lwpsinfo結(jié)構(gòu)數(shù)組,進(jìn)程中每個(gè)LWP對(duì)應(yīng)一個(gè)lwpsinfo結(jié)構(gòu)
/proc//map -- 地址空間映射信息,可以用pmap(1)命令顯示這些數(shù)據(jù)信息。
/proc//rmap -- 進(jìn)程中保留地址空間段。用pmap -r命令顯示這些數(shù)據(jù)信息。
/proc//xmap -- 擴(kuò)展地址空間映射信息。用pmap -x命令顯示這些數(shù)據(jù)信息。
/proc//cred -- 進(jìn)程身份驗(yàn)證信息,對(duì)應(yīng)/usr/include/sys/procfs.h文件中
定義的struct prcred結(jié)構(gòu)。
/proc//sigact -- sigaction結(jié)構(gòu)數(shù)組,描述和本進(jìn)程相關(guān)的所有信號(hào)設(shè)置。
struct sigaction結(jié)構(gòu)定義在/usr/include/sys/signal.h文件中。
/proc//auxv -- auxv_t結(jié)構(gòu)數(shù)組,包含進(jìn)程執(zhí)行時(shí)傳遞給動(dòng)態(tài)鏈接器的初始值。
auxv_t結(jié)構(gòu)定義在/usr/include/sys/auxv.h文件中。
/proc//ldt -- 局部描述符表(LDT),僅存于Intel x86架構(gòu)。
/proc//usage -- 進(jìn)程資源利用率的相關(guān)數(shù)據(jù),對(duì)應(yīng)struct prusage結(jié)構(gòu),該
結(jié)構(gòu)定義在/usr/include/sys/procfs.h文件中。
/proc//lusage -- prusage結(jié)構(gòu)數(shù)組,對(duì)應(yīng)各個(gè)LWP資源利用狀況。
/proc//pagedata -- 進(jìn)程地址空間的另外一種表現(xiàn)方式,可以用于跟蹤頁(yè)面級(jí)
的引用和修改。參看struct prpageheader結(jié)構(gòu)定義。
/proc//watch -- prwatch結(jié)構(gòu)數(shù)組。通過(guò)寫(xiě)控制文件/proc//ctl可以設(shè)
置PCWATCH操作,此時(shí)建立該文件。允許監(jiān)視一個(gè)或多個(gè)地址空間范圍,當(dāng)訪問(wèn)這些
被監(jiān)視頁(yè)面時(shí),產(chǎn)生一次陷入。
scz注:這個(gè)功能和SoftIce的BPR功能類似,adb支持這種陷入,不知是否利用了
procfs
/proc//cwd -- 到進(jìn)程當(dāng)前工作目錄的符號(hào)鏈接
/proc//root -- 到進(jìn)程根目錄的符號(hào)鏈接(和上面那個(gè)什么區(qū)別)
/proc//fd -- 這是一個(gè)子目錄,包含進(jìn)程打開(kāi)的文件句柄
/proc//fd/nn -- 對(duì)應(yīng)進(jìn)程打開(kāi)的某個(gè)確定的文件句柄
/proc//object -- 這是一個(gè)子目錄,包含進(jìn)程相關(guān)的可執(zhí)行文件以及動(dòng)態(tài)鏈接
庫(kù)。
/proc//object/nn -- 二進(jìn)制目標(biāo)文件。進(jìn)程對(duì)應(yīng)的可執(zhí)行文件名為a.out,其
余是進(jìn)程相關(guān)的動(dòng)態(tài)鏈接庫(kù)文件。
object目錄提供的信息是進(jìn)程級(jí)的,每個(gè)/proc//目錄有一個(gè)lwp子目錄,提供
了LWP級(jí)的信息:
/proc//lwp -- 這是一個(gè)子目錄,包含進(jìn)程中所有LWPs的信息
/proc//lwp/ -- 這是一個(gè)子目錄,包含對(duì)應(yīng)lwpid的LWP信息
/proc//lwp//lwpctl -- 一個(gè)控制文件,通過(guò)它可以在LWP級(jí)上針對(duì)每
個(gè)LWP發(fā)布控制操作
/proc//lwp//lwpstatus -- LWP狀態(tài)信息,對(duì)應(yīng)lwpstatus結(jié)構(gòu),該結(jié)
構(gòu)定義在/usr/include/sys/procfs.h文件中
/proc//lwp//lwpsinfo -- 對(duì)應(yīng)lwpsinfo結(jié)構(gòu),同樣定義在
/usr/include/sys/procfs.h文件中
/proc//lwp//lwpusage -- LWP資源利用信息,對(duì)應(yīng)prusage結(jié)構(gòu)
/proc//lwp//xregs -- 這個(gè)文件是處理器架構(gòu)相關(guān)的,某些平臺(tái)上可
能沒(méi)有這個(gè)文件。對(duì)于SPARC系統(tǒng),這個(gè)文對(duì)應(yīng)/usr/include/sys/procfs_isa.h文件中定義的prxregset結(jié)構(gòu)。
/proc//lwp//gwindows -- 常規(guī)寄存器窗口。這個(gè)文件僅存于SPARC架
構(gòu)的系統(tǒng),描述LWP使用的常規(guī)寄存器組(硬件上下文的一部分),對(duì)應(yīng)gwindows結(jié)構(gòu),該結(jié)構(gòu)定義在/usr/include/sys/regset.h文件中。
/proc//lwp//asrs -- 輔助寄存器組,僅存于SPARC V9(UltraSPARC)架
構(gòu),專為SPARC V9架構(gòu)定義的一組額外的硬件寄存器,要求sun4u、64-bit內(nèi)核(Solaris 7及其后續(xù)版本)、64-bit進(jìn)程。注意,64-bit內(nèi)核可以運(yùn)行32-bit進(jìn)程,但是32-bit進(jìn)程沒(méi)有這樣一個(gè)文件與之對(duì)應(yīng)。
--------------------------------------------------------------------------
◆ procfs的實(shí)現(xiàn)
procfs是通過(guò)動(dòng)態(tài)可加載內(nèi)核模塊的方式實(shí)現(xiàn)的。系統(tǒng)啟動(dòng)時(shí)自動(dòng)加載
/kernel/fs/procfs,/etc/vfstab文件中存在缺省/proc入口,系統(tǒng)啟動(dòng)過(guò)程中/proc將被mount上來(lái)。mount過(guò)程中將調(diào)用procfs的prinit()和prmount()函數(shù),它們?yōu)閜rocfs初始化vfs(虛擬文件系統(tǒng))結(jié)構(gòu),為根目錄/proc/創(chuàng)建并初始化一個(gè)vnode。vfs結(jié)構(gòu)定義在/usr/include/sys/vfs.h文件中,vnode結(jié)構(gòu)定義在/usr/include/sys/vnode.h文件中。
/proc目錄所涉及的內(nèi)核內(nèi)存空間絕大部分是動(dòng)態(tài)分配的。但是系統(tǒng)支持的最大
進(jìn)程數(shù)(可以通過(guò)/etc/system的max_nprocs參數(shù)配置)決定了/proc下子目錄插槽數(shù)目,這個(gè)是靜態(tài)分配初始化的。內(nèi)核變量procdir是一個(gè)指向procent結(jié)構(gòu)數(shù)組的指針,每個(gè)procent結(jié)構(gòu)對(duì)應(yīng)一個(gè)procfs目錄入口,procent結(jié)構(gòu)數(shù)組元素?cái)?shù)量源自系統(tǒng)啟動(dòng)時(shí)初始化的v.v_proc變量的值,也就是系統(tǒng)支持的最大進(jìn)程數(shù)。
scz注:在Solaris Kernel Hacking過(guò)程中,應(yīng)該習(xí)慣使用下面這兩種命令,很多未公開(kāi)內(nèi)核數(shù)據(jù)結(jié)構(gòu)在/usr/include下的頭文件中有相當(dāng)體現(xiàn),然后利用nm命
令確認(rèn)當(dāng)前內(nèi)核正在使用這些內(nèi)核數(shù)據(jù)結(jié)構(gòu)或者內(nèi)核函數(shù)。
# find /usr/include -name "*" | xargs grep -i "procdir"
# /usr/ccs/bin/nm -x /dev/ksyms | grep -i "|procdir"
[1433] |0x0000104570d0|0x000000000008|OBJT |LOCL |0 |ABS |procdir
# /usr/ccs/bin/nm -x /dev/ksyms | grep -i "|v$"
[8741] |0x00001041e1f4|0x00000000003c|OBJT |GLOB |0 |ABS |v
[6634] |0x00001041e1f4|0x00000000003c|OBJT |GLOB |0 |ABS |v
每個(gè)procent結(jié)構(gòu)中pe_proc成員指向?qū)?yīng)的proc結(jié)構(gòu),pe_next成員指向數(shù)組的下一個(gè)元素(scz:不但是數(shù)組,也形成鏈表)。整個(gè)procdir數(shù)組由進(jìn)程PID結(jié)構(gòu)的pid_prslot成員索引。創(chuàng)建進(jìn)程時(shí)(fork())系統(tǒng)在procdir數(shù)組中為之分配一個(gè)元素,參看圖1。
--------------------------------------------------------------------------
+--------+ +---->+---------+ +------------+ | +---------+ | |
內(nèi) +--------+ | pid_prslot |----+ | pe_proc |+---------+ | |
程 | p_pidp |----> +------------+ | | pe_proc |+-------------+ +->+----------+ procdir |
| proc | | | pr_next ----|--+ | | prc_slot ---->+---------+ |
| structure | /proc | | pr_common --|--|-+ +----------+ | pe_proc --+
| +---------+ | /| | pr_files ---|--|----------------+ | pe_next |
| | | | vnode | | pr_vnode | | | +---------+
一 | | p_trace -------------->+---------+ | | | | pe_proc |
| | p_plist | | | | |vnode | | | | | pe_next |
個(gè) | | | | | | |structure| | | | +---------+
| +---------+ | | | | | | | | | pe_proc |
多 | | +--|-|v_data | | | | | pe_next |
| kthread LWP | /proc | +---------+ | | | +---------+
線 | +---------+ | / +-------------+ | | | pe_proc |
| | | | /lwp/ vnode | | | pe_next |
程 | | t_trace -----+ prnode | | +---------+
| | | | | +->+-------------++----------+| +---------+
程 | kthread LWP | | | | pr_files | | | prc_slot || | |
| +---------+ | | | | pr_vnode | | +----------+| | |
| | | | +-------->+---------+ | | | | |
| | t_trace -----+ | | |vnode | | | |
| | | | | | | |structure| | | |
| +---------+ | | | | | | | | +-->+---+ array of
+-------------+ | +--|-|v_data | | | | | pointers
| | +---------+ | | +---+ to vnodes
| +-------------+ | | | for all files
/proc//lwp | | +---+ within the
/ vnode | prnode | | | directory
| +->+-------------++----------+ +---+
| | | pr_files | | prc_slot | | |
| | | pr_vnode | +----------+ +---+
+-------->+---------+ |
| | |vnode | |
| | |structure| |
| | | | |
+--|-|v_data | |
| +---------+ |
+-------------+
圖3. 一個(gè)多線程進(jìn)程所涉及結(jié)構(gòu)之間的關(guān)聯(lián)
--------------------------------------------------------------------------
下面是在我的Sun工作站上找到的相應(yīng)頭文件內(nèi)容:
/usr/include/sys/proc/prdata.h
typedef struct prnode
{
vnode_t * pr_next; /* list of all vnodes for process */
prcommon_t * pr_common; /* common data structure */
prcommon_t * pr_pcommon; /*
* process common data structure
* 和上面那個(gè)成員什么區(qū)別
*/
vnode_t ** pr_files; /* contained files array (directory) */
vnode_t pr_vnode; /* embedded vnode 這里不是指針 */
} prnode_t;
/*
* Common file object to which all /proc vnodes for a specific process
* or lwp refer. One for the process, one for each lwp.
*/
typedef struct prcommon
{
int prc_slot; /* process slot number */
} prcommon_t;
/usr/include/sys/vnode.h
/*
* All of the fields in the vnode are read-only once they are initialized
* (created) except for:
* v_flag: protected by v_lock
* v_count: protected by v_lock
* v_pages: file system must keep page list in sync with file size
* v_filocks: protected by flock_lock in flock.c
* v_shrlocks: protected by v_lock
*/
typedef struct vnode
{
caddr_t v_data; /* private data for fs */
} vnode_t;
/usr/include/sys/thread.h
typedef struct _kthread
{
struct vnode * t_trace; /* pointer to /proc lwp vnode */
} kthread_t;
圖3演示了打開(kāi)一個(gè)procfs文件進(jìn)行讀寫(xiě)時(shí)部分相關(guān)procfs數(shù)據(jù)結(jié)構(gòu)和它們之間
的關(guān)聯(lián)。注意到一個(gè)進(jìn)程相關(guān)的所有vnodes通過(guò)prnode結(jié)構(gòu)的pr_next成員鏈接起來(lái)。當(dāng)引用一個(gè)procfs目錄以及目錄下的文件對(duì)象時(shí),內(nèi)核動(dòng)態(tài)創(chuàng)建必要的數(shù)據(jù)結(jié)構(gòu)支持這種文件I/O請(qǐng)求,同時(shí)也是動(dòng)態(tài)銷毀相關(guān)數(shù)據(jù)結(jié)構(gòu)。無(wú)論什么時(shí)候針對(duì)procfs目錄或文件做open(2)請(qǐng)求或者列舉procfs目錄或文件,它們似乎總是在那里,類似冰箱里的燈,當(dāng)你打開(kāi)冰箱的時(shí)候它總是亮著的,但是關(guān)上冰箱門之后它事實(shí)上關(guān)閉著。
通過(guò)procfs所能訪問(wèn)到的數(shù)據(jù)顯然總是位于內(nèi)核proc結(jié)構(gòu)以及其他一些數(shù)據(jù)結(jié)構(gòu)
中,這些數(shù)據(jù)結(jié)構(gòu)共同構(gòu)成了Solaris內(nèi)核中完整的進(jìn)程模型。應(yīng)用程序通過(guò)procfs可以獲取進(jìn)程數(shù)據(jù),控制進(jìn)程執(zhí)行。這樣做的好處是隱藏了內(nèi)核進(jìn)程模型的底層細(xì)節(jié),以一種相對(duì)普通的方式析取感興趣的數(shù)據(jù)、進(jìn)行進(jìn)程控制。請(qǐng)求發(fā)生時(shí)建立這種動(dòng)態(tài)抽象,只要針對(duì)特定文件的訪問(wèn)存在,這種動(dòng)態(tài)抽象就一直保持著。
針對(duì)procfs的文件I/O操作遵循傳統(tǒng)方式,打開(kāi)文件獲取文件句柄,讀寫(xiě),關(guān)閉
文件句柄。通過(guò)vnode開(kāi)關(guān)表機(jī)制進(jìn)行procfs相關(guān)vnode操作時(shí),創(chuàng)建并初始化prnode和prcommon結(jié)構(gòu),這通常是應(yīng)用程序文件請(qǐng)求導(dǎo)致的結(jié)果。實(shí)際的procfs vnode操作由相關(guān)的查找、讀寫(xiě)函數(shù)處理/proc目錄下的對(duì)象。
procfs遍歷和讀取請(qǐng)求采用一組函數(shù)指針實(shí)現(xiàn),這組函數(shù)實(shí)現(xiàn)procfs文件類型相
關(guān)操作。文件類型分兩層維護(hù)。在vnode的v_type成員中,procfs文件類型定義成VPROC。而prnode結(jié)構(gòu)的pr_type成員定義了這個(gè)特定procfs文件的類型。procfs文件類型直接描述了/proc目錄結(jié)構(gòu),參看/usr/include/sys/proc/prdata.h文件。
/*
* Node types for /proc files (directories and files contained therein).
*/
typedef enum prnodetype
{
PR_PROCDIR, /* /proc */
PR_PIDDIR, /* /proc/ */
PR_AS, /* /proc//as */
PR_CTL, /* /proc//ctl */
PR_STATUS, /* /proc//status */
PR_LSTATUS, /* /proc//lstatus */
PR_PSINFO, /* /proc//psinfo */
PR_LPSINFO, /* /proc//lpsinfo */
PR_MAP, /* /proc//map */
} prnodetype_t;
打開(kāi)一個(gè)procfs文件時(shí)的基本流程如圖4所示。
--------------------------------------------------------------------------
open( "/proc//", O_RDONLY );
| Specific procfs directory object
代| vn_open() lookup functions are invoked
| through the pr_lookup_function[]
碼| +----> lookupxxx() array
| | VOP_LOOKUP() -> prlookup()
流| | index based on type
| | pr_lookup_function +-----------------------+
程| | | pr_lookup_piddir() |\
| | Construct full path name, +-----------------------+ \
| | looking up each element | pr_lookup_lwpdir() | \
| | in the path. +-----------------------+ prgetnode()
| | | pr_lookup_objectdir() | /
| | +-----------------------+ /
| | | | |/
| | ...... | ......
| | |
| +-------------------------------------------+
| VOP_OPEN() -> propen()
V
圖4. 打開(kāi)一個(gè)procfs文件時(shí)的基本流程
--------------------------------------------------------------------------
圖4中流程從應(yīng)用程序開(kāi)始,針對(duì)一個(gè)procfs文件做open(2)系統(tǒng)調(diào)用。進(jìn)入
vnode內(nèi)核層(vn_open()),完成一系列查找以構(gòu)建目標(biāo)/proc文件的完整路徑名。通過(guò)vnode層的宏進(jìn)入文件系統(tǒng)相關(guān)操作。在上面的圖例中,VOP_LOOKUP()解析成procfs的pr_lookup()函數(shù)。pr_lookup()完成訪問(wèn)權(quán)限檢查并根據(jù)目錄文件類型調(diào)用相應(yīng)的procfs函數(shù),比如pr_lookup_piddir()針對(duì)/proc/目錄進(jìn)行查找工作。每個(gè)pr_lookup_xxx()目錄查找函數(shù)完成某些目錄類型相關(guān)的工作,然后調(diào)用prgetnode()獲取prnode。
prgetnode()為/proc文件創(chuàng)建prnode(其中內(nèi)嵌了vnode),并初始化prnode和vnode結(jié)構(gòu)的某些成員。對(duì)于/proc/和/proc//lwp/,還會(huì)創(chuàng)建
prcommon結(jié)構(gòu),掛接到prnode結(jié)構(gòu)上,并部分初始化。注意,對(duì)于/proc下的目錄文件,為了正確反映目錄文件類型,vnode類型從VPROC(初始設(shè)置)改變成VDIR,表示這是一個(gè)procfs目錄文件。
一旦完整路徑名構(gòu)建完畢,通過(guò)VOP_OPEN()宏進(jìn)入文件系統(tǒng)相關(guān)的open()函數(shù)。procfs的propen()函數(shù)完成prnode和vnode結(jié)構(gòu)的其余初始化以及針對(duì)特定文件類型的訪問(wèn)測(cè)試工作。一旦propen()完成,控制返回到vn_open()。最終一個(gè)代表procfs文件的文件句柄返回給主調(diào)者。
讀取一個(gè)procfs數(shù)據(jù)文件(和目錄文件相對(duì))類型打開(kāi)流程,read()系統(tǒng)調(diào)用最終
進(jìn)入procfs的prread()函數(shù)。procfs實(shí)現(xiàn)為每個(gè)可用文件對(duì)象(不同的數(shù)據(jù)結(jié)構(gòu))定義了一個(gè)數(shù)據(jù)文件對(duì)象相關(guān)的讀函數(shù),比如pr_read_psinfo()、pr_read_pstatus()、
pr_read_lwpsinfo()等等。這些函數(shù)指針構(gòu)成一個(gè)數(shù)組,以文件類型做下標(biāo)進(jìn)行索引,prread()最終調(diào)用了它們。整個(gè)流程類似lookup操作。
Solaris 7 的procfs實(shí)現(xiàn)是基于64-bit內(nèi)核的,但是同時(shí)支持32-bit和64-bit應(yīng)
用,在/proc層次結(jié)構(gòu)上提供了32-bit版本的可用數(shù)據(jù)文件。在64-bit Solaris 7內(nèi)核中,描述每個(gè)/proc文件對(duì)象內(nèi)容的數(shù)據(jù)結(jié)構(gòu)同時(shí)擁有32-bit版本和64-bit版本,比如lwpstatus和lwpstatus32、psinfo和psinfo32等等。針對(duì)每個(gè)32-bit版本的結(jié)構(gòu)定義,相應(yīng)pr_read_xxx()函數(shù)做了支持32-bit數(shù)據(jù)模式的編碼。
procfs用戶并不會(huì)意識(shí)到64-bit內(nèi)核中多種數(shù)據(jù)模式實(shí)現(xiàn)。調(diào)用到prread()時(shí),
它會(huì)檢查主調(diào)者使用的數(shù)據(jù)模式,并激活相應(yīng)數(shù)據(jù)模式的函數(shù)。這里有一個(gè)例外,讀取/proc//as(地址空間)文件時(shí),主調(diào)者必須擁有與/proc//as文件一樣的
數(shù)據(jù)模式,換句話說(shuō),64-bit內(nèi)核中32-bit應(yīng)用程序可以讀取另外一個(gè)32-bit進(jìn)程的AS(地址空間)文件,但是不能讀取另外一個(gè)64-bit進(jìn)程的AS文件。
scz注:我覺(jué)得這里倒不如說(shuō),/proc//as本身是擁有單一數(shù)據(jù)模式的,要么
32-bit,要么64-bit,不可得兼。而其他/proc數(shù)據(jù)文件對(duì)象可能同時(shí)支持兩
種數(shù)據(jù)模式。
pr_read_xxxx()函數(shù)從內(nèi)核里讀取相關(guān)數(shù)據(jù),然后寫(xiě)入相應(yīng)的procfs數(shù)據(jù)結(jié)構(gòu),最終返回給主調(diào)者。例如,pr_read_psinfo()從目標(biāo)進(jìn)程的proc結(jié)構(gòu)、cred結(jié)構(gòu)和as結(jié)構(gòu)讀取數(shù)據(jù),寫(xiě)入psinfo結(jié)構(gòu)中相應(yīng)成員。訪問(wèn)內(nèi)核數(shù)據(jù)時(shí)靠proc結(jié)構(gòu)的p_lockp成員確定的互斥鎖進(jìn)行同步,這樣確保每次只有一個(gè)客戶線程能夠訪問(wèn)per-process或per-lwp內(nèi)核數(shù)據(jù)。
很少需要寫(xiě)訪問(wèn)procfs文件。姑且不考慮寫(xiě)目錄創(chuàng)建數(shù)據(jù)文件,典型的寫(xiě)操作就
是為了發(fā)出某些控制消息寫(xiě)進(jìn)程或LWP控制文件?刂葡(參看proc(1))包括stop/start消息,信號(hào)跟蹤和控制,故障管理,執(zhí)行控制(比如進(jìn)入/退出某個(gè)系統(tǒng)調(diào)用時(shí)暫停)以及地址空間訪問(wèn)監(jiān)視。
迄今為止,我們討論的都是用標(biāo)準(zhǔn)系統(tǒng)調(diào)用對(duì)procfs文件進(jìn)行I/O操作,目前從
普通應(yīng)用級(jí)程序員編程訪問(wèn)/proc文件來(lái)說(shuō)這是唯一的辦法。然而另外有一組特定針對(duì)procfs的訪問(wèn)接口,proc(1)中介紹的/usr/proc/bin/下的命令(隨Solaris分發(fā))使用了這組接口。這組接口位于libproc.so動(dòng)態(tài)鏈接庫(kù),屬于未公開(kāi)的接口。Sun公司正在著手準(zhǔn)備關(guān)于這組接口的文檔,做為標(biāo)準(zhǔn)Solaris APIs提供出來(lái)。圖5展示了以前討論過(guò)的內(nèi)核中procfs模塊與各層之間的接口關(guān)系。
--------------------------------------------------------------------------
+---------------------+--------------------------+
| custom /proc code | /usr/proc/bin/ |
+------------------+ | +-----------------------+
| stdio interfaces | | |\\\\\\\\libproc\\\\\\\\|
+------------------+--+--+--------------+\\\\\\\\|
| system calls |\\\\\\\\| user
-----------------------------------------------------------------
+---------------------------------------+\\\\\\\\| kernel
| vnode layer |\\\\\\\\|
+---------------------------------------+--------+
| procfs |
+------------------------------------------------+
圖5. procfs模塊與各層之間的接口關(guān)系
--------------------------------------------------------------------------
圖5演示了多條到達(dá)procfs內(nèi)核例程的路徑。開(kāi)發(fā)者通常通過(guò)系統(tǒng)調(diào)用進(jìn)入vnode層,這是前面過(guò)介紹的方式。而proc(1)命令更多構(gòu)建在libproc.so提供的接口上。為什么需要這組動(dòng)態(tài)鏈接庫(kù)接口呢,提供一組簡(jiǎn)單易用的例程用于應(yīng)用程序開(kāi)發(fā),減少直接使用內(nèi)核機(jī)制帶來(lái)的復(fù)雜性?刂埔粋(gè)進(jìn)程的執(zhí)行,尤其是多線程進(jìn)程,非常復(fù)雜,需要一組真正屬于API層的編碼接口,而不是內(nèi)核層的編碼接口。
向控制文件的頭8個(gè)字節(jié)(如果是LP64內(nèi)核,就是頭16個(gè)字節(jié))寫(xiě)入一個(gè)操作碼和
可選的操作數(shù),完成進(jìn)程控制。寫(xiě)進(jìn)程控制文件的路徑也要經(jīng)過(guò)vnode層,最終調(diào)用了procfs的prwritectl()函數(shù)。允許在一次寫(xiě)調(diào)用中向控制文件寫(xiě)入多個(gè)控制消息(操作碼和操作數(shù)),prwritectl()會(huì)將一次寫(xiě)入的多個(gè)控制消息分成獨(dú)立的操作碼/操作數(shù)對(duì),順序提交給內(nèi)核的pr_control()函數(shù),pr_control()函數(shù)將設(shè)置進(jìn)程或LWP相應(yīng)的標(biāo)志,以指明控制機(jī)制啟動(dòng),比如某一事件發(fā)生時(shí)暫停。控制函數(shù)在proc(4)手冊(cè)頁(yè)中介紹。
進(jìn)程/LWP控制的實(shí)現(xiàn)與內(nèi)核中進(jìn)程/LWP子系統(tǒng)緊密結(jié)合,P區(qū)、U區(qū)、LWP和內(nèi)核線程結(jié)構(gòu)中各種域一起協(xié)作完成通過(guò)procfs進(jìn)行的進(jìn)程管理和控制。建立進(jìn)程控制包括設(shè)置標(biāo)志和位掩碼字段,用于跟蹤那些導(dǎo)致進(jìn)程、線程進(jìn)入、離開(kāi)內(nèi)核的事件,包括信號(hào)、系統(tǒng)調(diào)用、故障情形。對(duì)應(yīng)這些事件的進(jìn)入、離開(kāi)內(nèi)核的點(diǎn)定義得比較充分,為進(jìn)程狀態(tài)改變提供了自然的控制機(jī)制。
系統(tǒng)調(diào)用、信號(hào)和故障分別對(duì)應(yīng)數(shù)據(jù)類型sysset_t、sigset_t和fltset_t。如果
指定發(fā)生某系統(tǒng)調(diào)用時(shí)暫停,此時(shí)尚未從進(jìn)程讀取提供給該系統(tǒng)調(diào)用的參數(shù)。如果指定離開(kāi)某系統(tǒng)調(diào)用時(shí)暫停,此時(shí)來(lái)自系統(tǒng)調(diào)用的返回值已經(jīng)提交給進(jìn)程。可以指定發(fā)生某種故障時(shí)進(jìn)入內(nèi)核陷門處理程序。可以指定接收到某個(gè)信號(hào)時(shí)暫;蛘邚南到y(tǒng)調(diào)用、內(nèi)核陷門處理程序返回,可以通過(guò)信號(hào)喚醒進(jìn)程。
可以在進(jìn)程虛擬地址空間中指定一片區(qū)域處在監(jiān)視中,當(dāng)針對(duì)這片區(qū)域進(jìn)行被監(jiān)
視類型的操作(比如讀、寫(xiě)訪問(wèn)),也就是監(jiān)視事件發(fā)生時(shí),產(chǎn)生一次監(jiān)視點(diǎn)陷入,典型地導(dǎo)致進(jìn)程、LWP暫停,這通過(guò)跟蹤FLTWATCH故障或者捕捉非阻塞的SIGTRAP信號(hào)實(shí)現(xiàn)。
某些情況下為了析取進(jìn)程信息、進(jìn)行進(jìn)程控制,控制進(jìn)程可能需要目標(biāo)進(jìn)程臨時(shí)
完成某種特殊的操作。例如,pfiles(1)命令可以列出目標(biāo)進(jìn)程打開(kāi)的每個(gè)文件的信息,這需要目標(biāo)進(jìn)程針對(duì)每個(gè)打開(kāi)的文件句柄做stat(2)系統(tǒng)調(diào)用。運(yùn)行在Solaris系統(tǒng)上的進(jìn)程典型地花費(fèi)大量時(shí)間阻塞在某個(gè)系統(tǒng)調(diào)用上,為了獲得目標(biāo)進(jìn)程的控制權(quán)完成控制進(jìn)程提交的任務(wù),需要在目標(biāo)進(jìn)程阻塞時(shí)搶奪CPU,保護(hù)當(dāng)前系統(tǒng)調(diào)用狀態(tài),當(dāng)控制進(jìn)程提交的任務(wù)完成后恢復(fù)保存的系統(tǒng)調(diào)用狀態(tài)繼續(xù)執(zhí)行目標(biāo)進(jìn)程原來(lái)的任務(wù)。
為了達(dá)到這個(gè)目的,procfs實(shí)現(xiàn)了另外一個(gè)代理LWP,而不是使用目標(biāo)進(jìn)程中現(xiàn)
有LWP,否則狀態(tài)保存、恢復(fù)更加復(fù)雜。procfs提供了一種機(jī)制創(chuàng)建代理LWP(注意PCAGENT控制消息)。代理LWP創(chuàng)建成功后將是目標(biāo)進(jìn)程中唯一可運(yùn)行LWP,直到它消亡。
目標(biāo)進(jìn)程中執(zhí)行代理LWP以完成控制進(jìn)程提交的任務(wù),比如在目標(biāo)進(jìn)程中執(zhí)行系統(tǒng)調(diào)用。然后銷毀代理LWP,恢復(fù)保存的進(jìn)程/LWP狀態(tài)。proc結(jié)構(gòu)中有一個(gè)成員p_agenttp,指向創(chuàng)建的代理LWP。內(nèi)核代碼通過(guò)檢查該指針判斷目標(biāo)進(jìn)程中是否存在代理LWP。
kthread_t * p_agenttp; /* thread ptr for /proc agent lwp */
proc(4)手冊(cè)頁(yè)介紹了進(jìn)程控制的更多細(xì)節(jié)。
--------------------------------------------------------------------------
后記:
本篇與都是的一部分,由于很多東西缺乏內(nèi)核Hacking經(jīng)驗(yàn)和常用術(shù)語(yǔ)約定,翻譯得相當(dāng)牽強(qiáng),好在可以對(duì)照/usr/include/下的頭文件反復(fù)理解。>和>是對(duì)理解很好的補(bǔ)充。此外可以在comp.unix.programmer和comp.unix.solaris上向Sun開(kāi)發(fā)人員請(qǐng)教。


本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/5214/showart_66583.html
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP