- 论坛徽章:
- 0
|
回指到proc结构
<-------------+
prnode prcommon |
+-------------+ +->+-------------+ +->+----------+ 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 |
个 | | | | | | |structure| | | | +---------+
| +---------+ | | | | | | | | | pe_proc |
多 | | +--|-|v_data | | | | | pe_next |
| kthread LWP | /proc | +---------+ | | | +---------+
线 | +---------+ | / +-------------+ | | | pe_proc |
| | | | /lwp/ vnode | | | pe_next |
程 | | t_trace -----+ prnode | | +---------+
| | | | | +->+-------------+<-+ | | pe_proc |
进 | +---------+ | | | | pr_next ----|--+ prcommon | | pe_next |
| | | | | pr_common --|--|--->+----------+| +---------+
程 | 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_next | prcommon | |
| | | pr_common --|------>+----------+ +---+
| | | pr_files | | prc_slot | | |
| | | pr_vnode | +----------+ +---+
+-------->+---------+ |
| | |vnode | |
| | |structure| |
| | | | |
+--|-|v_data | |
| +---------+ |
+-------------+
图3. 一个多线程进程所涉及结构之间的关联
--------------------------------------------------------------------------
下面是在我的Sun工作站上找到的相应头文件内容:
/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
* 和上面那个成员什么区别
*/
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演示了打开一个procfs文件进行读写时部分相关procfs数据结构和它们之间
的关联。注意到一个进程相关的所有vnodes通过prnode结构的pr_next成员链接起来。当引用一个procfs目录以及目录下的文件对象时,内核动态创建必要的数据结构支持这种文件I/O请求,同时也是动态销毁相关数据结构。无论什么时候针对procfs目录或文件做open(2)请求或者列举procfs目录或文件,它们似乎总是在那里,类似冰箱里的灯,当你打开冰箱的时候它总是亮着的,但是关上冰箱门之后它事实上关闭着。
通过procfs所能访问到的数据显然总是位于内核proc结构以及其他一些数据结构
中,这些数据结构共同构成了Solaris内核中完整的进程模型。应用程序通过procfs可以获取进程数据,控制进程执行。这样做的好处是隐藏了内核进程模型的底层细节,以一种相对普通的方式析取感兴趣的数据、进行进程控制。请求发生时建立这种动态抽象,只要针对特定文件的访问存在,这种动态抽象就一直保持着。
针对procfs的文件I/O操作遵循传统方式,打开文件获取文件句柄,读写,关闭
文件句柄。通过vnode开关表机制进行procfs相关vnode操作时,创建并初始化prnode和prcommon结构,这通常是应用程序文件请求导致的结果。实际的procfs vnode操作由相关的查找、读写函数处理/proc目录下的对象。
procfs遍历和读取请求采用一组函数指针实现,这组函数实现procfs文件类型相
关操作。文件类型分两层维护。在vnode的v_type成员中,procfs文件类型定义成VPROC。而prnode结构的pr_type成员定义了这个特定procfs文件的类型。procfs文件类型直接描述了/proc目录结构,参看/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;
打开一个procfs文件时的基本流程如图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. 打开一个procfs文件时的基本流程 |
|