1. Proc file system
The Proc file system is a mechanism for checking the kernel state in the user State. The file content is dynamically created, not on the disk, but in the memory, and power loss occurs.
Cat/proc/meminfo/to view the current memory usage
Kernel description:
[Cpp]
<Span style = "font-size: 14px;"> struct proc_dir_entry {
Unsigned int low_ino;
Unsigned short namelen;
Const char * name;
Mode_t mode;
Nlink_t nlink;
Uid_t uid;
Gid_t gid;
Loff_t size;
Const struct inode_operations * proc_iops;
/*
* NULL-> proc_fops means "PVDF is going away RSN" or
* "PVDF is just created". In either case, e.g.-> read_proc won't be
* Called because it's too late or too early, respectively.
*
* If you're allocating-> proc_fops dynamically, save a pointer
* Somewhere.
*/
Const struct file_operations * proc_fops;
Struct proc_dir_entry * next, * parent, * subdir;
Void * data;
Read_proc_t * read_proc;
Write_proc_t * write_proc;
Atomic_t count;/* use count */
Int pde_users;/* number of callers into module in progress */
Spinlock_t pde_unload_lock;/* proc_fops checks and pde_users bumps */
Struct completion * pde_unload_completion;
Struct list_head pde_openers;/* who did-> open, but not-> release */
}; </Span>
1. Create a file:
[Cpp]
<Span style = "font-size: 14px;"> struct proc_dir_entry * create_proc_entry (const char * name, mode_t mode,
Struct proc_dir_entry * parent)
{
Struct proc_dir_entry * ent;
Nlink_t nlink;
If (S_ISDIR (mode )){
If (mode & S_IALLUGO) = 0)
Mode | = S_IRUGO | S_IXUGO;
Nlink = 2;
} Else {
If (mode & S_IFMT) = 0)
Mode | = S_IFREG;
If (mode & S_IALLUGO) = 0)
Mode | = S_IRUGO;
Nlink = 1;
}
Ent = _ proc_create (& parent, name, mode, nlink );
If (ent ){
If (proc_register (parent, ent) <0 ){
Kfree (ent );
Ent = NULL;
}
}
Return ent;
}
</Span>
2. Create a directory:
[Cpp]
<Span style = "font-size: 14px;"> struct proc_dir_entry * proc_mkdir (const char * name,
Struct proc_dir_entry * parent)
{
Return proc_mkdir_mode (name, S_IRUGO | S_IXUGO, parent );
} </Span>
[Cpp]
<Span style = "font-size: 14px;"> struct proc_dir_entry * proc_mkdir_mode (const char * name, mode_t mode,
Struct proc_dir_entry * parent)
{
Struct proc_dir_entry * ent;
Ent = _ proc_create (& parent, name, S_IFDIR | mode, 2 );
If (ent ){
If (proc_register (parent, ent) <0 ){
Kfree (ent );
Ent = NULL;
}
}
Return ent;
}
</Span>
3. delete a directory
[Cpp
<Span style = "font-size: 14px;"> void remove_proc_entry (const char * name, struct proc_dir_entry * parent)
{
Struct proc_dir_entry ** p;
Struct proc_dir_entry * de = NULL;
Const char * fn = name;
Int len;
If (xlate_proc_name (name, & parent, & fn )! = 0)
Return;
Len = strlen (fn );
Spin_lock (& proc_subdir_lock );
For (p = & parent-> subdir; * p; p = & (* p)-> next ){
If (proc_match (len, fn, * p )){
De = * p;
* P = de-> next;
De-> next = NULL;
Break;
}
}
Spin_unlock (& proc_subdir_lock );
If (! De)
Return;
Spin_lock (& de-> pde_unload_lock );
/*
* Stop accepting new callers into module. If you're
* Dynamically allocating-> proc_fops, save a pointer somewhere.
*/
De-> proc_fops = NULL;
/* Wait until all existing callers into module are done .*/
If (de-> pde_users> 0 ){
DECLARE_COMPLETION_ONSTACK (c );
If (! De-> pde_unload_completion)
De-> pde_unload_completion = & c;
Spin_unlock (& de-> pde_unload_lock );
Wait_for_completion (de-> pde_unload_completion );
Goto continue_removing;
}
Spin_unlock (& de-> pde_unload_lock );
Continue_removing:
Spin_lock (& de-> pde_unload_lock );
While (! List_empty (& de-> pde_openers )){
Struct pde_opener * pdeo;
Pdeo = list_first_entry (& de-> pde_openers, struct pde_opener, lh );
List_del (& pdeo-> lh );
Spin_unlock (& de-> pde_unload_lock );
Pdeo-> release (pdeo-> inode, pdeo-> file );
Kfree (pdeo );
Spin_lock (& de-> pde_unload_lock );
}
Spin_unlock (& de-> pde_unload_lock );
If (S_ISDIR (de-> mode ))
Parent-> nlink --;
De-> nlink = 0;
WARN (de-> subdir, KERN_WARNING "% s: removing non-empty directory"
"'% S/% s', leaking at least' % s' \ n", _ func __,
De-> parent-> name, de-> name, de-> subdir-> name );
If (atomic_dec_and_test (& de-> count ))
Free_proc_entry (de );
}
</Span>
Process:
<1> call creat_proc_entry to create a struct proc_dir_entry
<2> assign values to the created struct proc_dir_entry: read_proc, mode, owner, size, write_proc