3、调用proc_register把ent加入proc文件系统(即proc文件树)中。
4、返回ent;
proc_register函数
这个函数把一个proc文件加入到proc文件树中,其函数原型如下:
static int proc_register(struct proc_dir_entry *parent,struct
proc_dir_entry *ent)
其主要流程如下:
1、使用make_inode_number()函数动态的到一个节点号,并且设置low_ino.注意只是获得inod编号,并不是真的创建inode.该inode的创建会推迟到proc_lookup中。
2、将这个proc_dir_entry结构链接到它的父节点上。
3、根据文件类型(普通文件,目录,symbolic)的不同,设置不同的缺省操作函数集。
删除proc文件remove_proc_entry
这个函数用来删除一个proc文件,注意如果该文件正被使用那么只是设置deleted标志,该函数的原型:
void remove_proc_entry(const char *name,struct proc_dir_entry
*parent);
其中name是待删除的proc文件。parent是该文件的父目录.
其执行流程如下:
1、确定其父目录.乳沟parent有效,则执行2.否则(parent ==
NULL)尝试从name分析出parent,如果分析失败则函数返回失败,否则执行2.
2、在parent中找出待删的文件对应的proc_dir_entry实例ent.
3、把ent从proc文件树中删除,并更新树的状态。
4、如果该文件被使用则设置deleted标识(在其后的恰当时候会被释放),否则调用free_proc_entry
其他proc文件操作函数
struct proc_dir_entry *proc_mkdir(const char *name,struct
proc_dir_entry *parent);
这个函数用来在proc文件系统中创建一个设别文件,因此,在创建proc_dir_entry结构后,没有设置缺省操作,而是使用ent->rdev
= rdev指定了设备。最后,调用proc_registera函数将其注册。
struct proc_dir_entry *proc_symlink(const char *name,struct
proc_dir_entry *parent,const char
*dest)函数,该函数创建了一链接文件,使用ent->mode =
S_IFLNK|S_IRUGO|S_IXUGO来标志,它和其他文件的建立很相似,只是,它将链接的目标文件名放在了ent->data域中。最后,它同样调用proc_register函数将该结构注册。
struct proc_dir_entry *create_proc_read_entry(const char
*name,mode_t mode,struct proc_dir_entry *base,read_proc_t
*read_proc,void *data)
创建只读的proc文件,并且设置其对应的proc_dir_entry中的read_proc成员。
void create_seq_entry(char *name,mode_t mode ,struct
file_operations *f)
在/proc目录下创建一个文件,其文件操作函数由f指定
内核还定义了很多其他的创建proc文件的方式,可以参考源代码
假设现在有一个线程组,其TGID为32182,其包含了两个线程:32182,32255.那么:执行ls
/proc,则能看到有一个32182的目录;执行ls /proc/32182则能看到该线程组的信息;执行ls
/proc/32182/task则能看到两个32182,32255
;执行ls /proc/32182/task/32182则能看到该task实例的信息;但如果我们执行ls
/proc/32255也能得到和执行ls /proc/32182同样的效果
假设有一个线程组,其TGID为32243,其包含一个线程:32243.那么其效果类似上面的情况。
注意:针对/proc/TGID目录下的各个文件,内核定义了一个全局属祖tgid_base_stuff用来约定各个文件的基本信息,这个数据的元素的类型是pid_entry。同样,内核也为/proc/TGID/task/PID目录下的文件定义了全局数组tid_base_stuff.cd
ptg
/proc/tgid目录的创建时机
(/proc/下的进程目录)
当执行ls /proc是并不会创建线程组的相应目录,而只是告诉你这个时刻的线程组的存在。只有当执行ls
/proc/tgid时,才会创建线程组相应的inode。即相应的inode实例是动态创建的
事实上,当执行ls
/proc时会调用proc_root_readdir(通过proc_root_operations)列出/proc目录下的所有文件。针对/proc下的线程组,该函数会查询内核的tgid链表。得到所有的tgid。然后转化成字符串....
而当执行ls
/proc/TGID时最终会调用proc_root_lookup(通过proc_root_inode_operations),这个函数会为该目录创建inode(其实是proc_inode实例),然后设置相应的inode_op,file_op,dentry_op等等信息。然后再调用proc_tgid_base_readdir(通过proc_tgid_base_operations变量)。而该函数又调用proc_pident_readdir来获得/proc/TGID目录下的所有文件的名字。
即相应inode创建时机是:
proc_root_lookup----proc_pid_lookup---proc_pid_make_inode
注意:
proc_fs对进程目录与非进程目录的处理有很大区别。
ini