linux Proc文件系统介绍及运用总结

引言

先说一个刚刚发现的问题:

前两天打开测试机发现速度非常慢,top一看,发现java占用CPU 99%

查看对应pid,发现这个是新的话单采集程序gather:

#ps -ef | grep java

Root 5762 1 99 14:41 pts/0 00:00:01 java -Xmx2048m -jar Gather-jar-with-dependencies.jar

采集程序的工作是启动4个线程,不断从FTP上读取文件。查看日志,发现FTP上并没有文件,4个线程每隔一段时间去检查一下FTP,所有线程都在正常写日志。看上去一切正常。

查看进程状态:

#cat /proc/5762/status

Name:   java

State:  S (sleeping)

……

Threads: 5689

……

看到threads为5689的时候,真正冒了身冷汗。只启动了4个线程,怎么会出现这么多线程呢?

由于这个进程已经运行了比较久的时间,测试目录又比较多,这个进程是从哪个目录开始的呢?

#ll /proc/9323/cwd

lrwxrwxrwx 1 root root 0 Jun  8 11:51 /proc/9323/cwd -> /home/admin/work/BLTransfer/src/gather/20110509_56847_taobao-bn_2

到这个目录,查看版本的gather代码,发现FTP调用后在某个返回路径上没有调用close方法。

查看FTP4j源码,发现FTP在调用setAutoNoopTimeout和Login后会调用startAutoNoopTimer()新启一个线程定时处理无操作的情况。此外,在传输数据时FTPDataTransfer也会新开线程。

修改代码后,恢复正常。

 

PROC简介

上处查看的/proc/5762/status和/proc/9323/cwd正是proc文件系统下的文件。

与其它常见的文件系统不同的是,Proc文件系统并不是真正意义上的文件系统,它存在于内存中,并不占用磁盘空间,它包含一些结构化的目录和虚拟文件,向用户呈现内核中的一些信息,也可以用作一种从用户空间向内核发送信息的手段。

这些虚拟文件使用查看命令查看时会返回大量信息,但文件本身的大小却会显示为0字节。此外,这些特殊文件中大多数文件的时间及日期属性通常为当前系统时间和日期。

事实上,如ps、top等很多shell命令正是从proc系统中读取信息,且更具可读性。

接下来,将详细介绍proc文件系统中每个文件的信息情况。

 

一、常见PROC文件含义

/proc目录下,每个进程都会有一个以PID命名的目录,存放关于这个进程的信息,同时还有许多相对固定的目录,以存放与系统相关的信息:

[admin@ccbuqa147160x proc]$ ls /proc/

1 10 2331 ……(每个进程一个目录,略去)

buddyinfo  execdomains  kallsyms   misc        stat           vmstat

bus        fb           kcore      modules     swaps          xen

cmdline    filesystems  keys       mounts      sys            zoneinfo

cpuinfo    fs           key-users  net         sysrq-trigger

crypto     ide          kmsg       partitions  sysvipc

devices    interrupts   loadavg    schedstat   tty

diskstats  iomem        locks      scsi        uptime

dma        ioports      mdstat     self        version

driver     irq          meminfo    slabinfo    vmcore

通过这些文件,可以查看大量系统信息,例如CPU信息、内存信息、linux版本信息等:

[admin@ccbuqa147160x ~]$ cat /proc/cpuinfo

processor       : 0

vendor_id       : GenuineIntel

cpu family      : 6

model           : 26

model name      : Intel(R) Xeon(R) CPU           E5504  @ 2.00GHz

stepping        : 5

cpu MHz         : 2000.070

cache size      : 4096 KB

……

[admin@ccbuqa147160x ~]$ cat /proc/version

Linux version 2.6.18-131.el5.customxen (root@cfengine2)

(gcc version 4.1.2 20071124 (Red Hat 4.1.2-42))

#1 SMP Tue Sep 15 15:46:11 CST 2009

先来看一下进程目录的子目录:

[admin@ccbuqa147160x proc]$ ls /proc/22567

attr  cmdline  cpuset  environ  fd      loginuid  mem     mountstats oom_score

schedstat  stat   status  wchan auxv  coredump_filter  cwd exe      limits 

maps      mounts  oom_adj     root       smaps      statm  task

主要文件的含义总结如下:

文件名

内容

文件名

内容

cmdline

进程启动时的命令行参数

root

指向进程根目录

environ

环境变更的值

stat

进程状态

cwd

当前工作路径

status

进程状态(友好)

exe

进程相关的可执行文件

stack

栈记录(需CONFIG_STACKTRACE)

fd

文件描述符目录

smaps

Maps扩展,显示每个mapping的内存

maps

可执行文件和库文件图

mem

进程占用的内存

例如:以目前的通话服务器程序ECPWORKER为例,它的当前目录和可执行文件相关信息如下:

[admin@ccbuqa147160x proc]$ ll /proc/22559/cwd /proc/22559/exe

lrwxrwxrwx 1 admin admin 0 06-09 09:00 /proc/22559/cwd -> /home/admin/work/ecpworker/bin

lrwxrwxrwx 1 admin admin 0 06-09 09:00 /proc/22559/exe -> /home/admin/work/ecpworker/bin/ecp-master-worker

它所有打开的文件描述符为:

[admin@ccbuqa147160x proc]$ ll /proc/22559/fd

lr-x------ 1 admin admin 64 06-09 08:58 0 -> /dev/null

l-wx------ 1 admin admin 64 06-09 08:58 1 -> /home/admin/work/ecpworker/log/debug.log

l-wx------ 1 admin admin 64 06-09 08:58 3 -> /home/admin/work/ecpworker/log/status/ecp_status.log

l-wx------ 1 admin admin 64 06-09 08:58 4 -> /home/admin/work/ecpworker/log/error/ecp_error.log

l-wx------ 1 admin admin 64 06-09 08:58 5 -> /home/admin/work/ecpworker/log/epollstatus/ecp_epoll_status.log

lrwx------ 1 admin admin 64 06-09 08:58 10 -> socket:[79444512]

lrwx------ 1 admin admin 64 06-09 08:58 12 -> socket:[79444514]

lrwx------ 1 admin admin 64 06-09 08:58 14 -> socket:[79444516]

lrwx------ 1 admin admin 64 06-09 08:58 16 -> socket:[79444518]

lrwx------ 1 admin admin 64 06-09 08:58 18 -> socket:[79444520]

lrwx------ 1 admin admin 64 06-09 08:58 20 -> socket:[79444522]

lrwx------ 1 admin admin 64 06-09 08:58 22 -> socket:[79444524]

lrwx------ 1 admin admin 64 06-09 08:58 24 -> socket:[79444526]

lrwx------ 1 admin admin 64 06-09 08:58 26 -> socket:[79444528]

lrwx------ 1 admin admin 64 06-09 08:58 28 -> socket:[79444530]

lrwx------ 1 admin admin 64 06-09 08:58 30 -> socket:[79444532]

lrwx------ 1 admin admin 64 06-09 08:58 32 -> socket:[79444534]

lrwx------ 1 admin admin 64 06-09 08:58 34 -> socket:[79444536]

lrwx------ 1 admin admin 64 06-09 08:58 36 -> socket:[79444538]

lr-x------ 1 admin admin 64 06-09 08:58 6 -> eventpoll:[79444508]

lrwx------ 1 admin admin 64 06-09 08:58 7 -> socket:[79444509]

lrwx------ 1 admin admin 64 06-09 08:58 8 -> socket:[79444510]

从中可以看出,它打开了4个日志文件,16个socket连接,以及一个eventpoll。而我们程序的设计方案,正是1个主进程开启15个等待进程,主进程通过1个socket接收各子进程消息,各子进程各开1个socket接收请求,通过epoll来调度响应。

 

二、文件描述符限制修改

由于我们每接收一个请求,都会新分配一块内存给它,并新开一个socket连接到电信,因此我们非常关心最大连接数。

这里需要区分一下:

1、 系统最大文件数可在/proc/sys/fs/file-max文件中查询(数值确实很大,但需要知道系统有这样一个总数限制),而目前系统使用的文件句柄数则在/proc/sys/fs/file-nr中:

[admin@ccbuqa147160x SOURCES]$ cat /proc/sys/fs/file-max

544202

[admin@ccbuqa147160x SOURCES]$ cat /proc/sys/fs/file-nr

2040    0       544202

2、 一个进程允许打开的最大文件数,可以用ulimit命令查看:

[admin@ccbuqa147160x SOURCES]$ ulimit –n

core file size          (blocks, -c) 0

data seg size           (kbytes, -d) unlimited

scheduling priority             (-e) 0

file size               (blocks, -f) unlimited

pending signals                 (-i) 44064

max locked memory       (kbytes, -l) 32

max memory size         (kbytes, -m) unlimited

open files                      (-n) 10240

pipe size            (512 bytes, -p) 8

POSIX message queues     (bytes, -q) 819200

real-time priority              (-r) 0

stack size              (kbytes, -s) 10240

cpu time               (seconds, -t) unlimited

max user processes              (-u) 44064

virtual memory          (kbytes, -v) unlimited

file locks                      (-x) unlimited

这个表中同时还包含了用户最大进程数,消息队列最大数等。

当然,也可以在每个进程的proc目录中找到更详细的值:

[admin@ccbuqa147160x proc]$ cat /proc/22559/limits

Limit                     Soft Limit           Hard Limit           Units    

Max cpu time            unlimited            unlimited            seconds  

Max file size             unlimited            unlimited            bytes    

Max data size            unlimited            unlimited            bytes    

Max stack size            10485760             unlimited            bytes    

Max core file size         0                    unlimited            bytes    

Max resident set          unlimited            unlimited            bytes    

Max processes             44064                44064            processes

Max open files            10240                10240               files    

Max locked memory         32768                32768             bytes    

Max address space         unlimited            unlimited            bytes    

Max file locks            unlimited            unlimited             locks    

Max pending signals       44064                44064                signals  

Max msgqueue size         819200               819200               bytes 

可以看出,目前,我们系统中已经将值设置为较大的10240。如果你发现你机子上的这些值为默认的1024,那么最好还是调大一些,这个值对于服务器来说很容易不够用的。通过在文件/etc/security/limits.conf中增加下面两行可以设置此值,重新登陆生效:

* soft nofile 10240

* hard nofile 20480

当然,一般来说,如果需要增大系统设置的socket最大连接数,还需要修改源文件并重新编译:

1、修改/usr/src/kernels/2.6.18-131.el5.custom-x86_64/include/linux/posix_types.h

#undef __FD_SETSIZE

#define __FD_SETSIZE 10240 原值为1024

2、修改/usr/src/kernels/2.6.18-131.el5.custom-x86_64/include/linux/limits.h

#define NR_OPEN 90240 原值为1024

#define OPEN_MAX 10240 原值为1024

3、修改/usr/src/kernels/2.6.18-131.el5.custom-x86_64/include/linux/fs.h

#define INR_OPEN 10240 原值为1024

#define NR_FILE 65536 原值为8192

#define NR_RESERVED_FILES 128 原值为10.

4、修改/usr/src/kernels/2.6.18-131.el5.custom-x86_64/include/net /tcp.h

#define TCP_LHTABLE_SIZE 128 原值为32

5、重新编译内核即可。

 

三、进程内存映射与动态库加载

可以使用/proc/PID/maps和/proc/PID/smaps来查看进程的内存映射,包括库文件和堆、栈等。

#cat /proc/23698/maps

00400000-00424000 r-xp ca:01 14778415 /home/admin/levy/SMSServer/trunk/bin/SMSServer

00625000-00626000 rw-p 00625000 00:00 0

1236a000-1238b000 rw-p 1236a000 00:00 0

3ce7e00000-3ce7e1c000 r-xp 00000000 ca:01 2097322 /lib64/ld-2.5.so

3ce8551000-3ce8556000 rw-p 3ce8551000 00:00 0

3ce8600000-3ce8602000 r-xp 00000000 ca:01 2097447 /lib64/libdl-2.5.so

3ce8e00000-3ce8e16000 r-xp 00000000 ca:01 2097462 /lib64/libpthread-2.5.so

3ce9017000-3ce901b000 rw-p 3ce9017000 00:00 0

3ce9600000-3ce9607000 r-xp 00000000 ca:01 2097463 /lib64/librt-2.5.so

3cfa000000-3cfa00d000 r-xp 00000000 ca:01 2097461 /lib64/libgcc_s-4.1.2-20080825.so.1

3cfac00000-3cface6000 r-xp 00000000 ca:01 10596444 /usr/lib64/libstdc++.so.6.0.8

3cfaeee000-3cfaf00000 rw-p 3cfaeee000 00:00 0

2b9ce3c77000-2b9ce3c79000 rw-p 2b9ce3c77000 00:00 0

2b9ce3c8d000-2b9ce3c8e000 rw-p 2b9ce3c8d000 00:00 0

2b9ce3c8e000-2b9ce3d7c000 r-xp ca:01 14583150 /home/admin/local/lib/libPocoNet.so.9

2b9ce41f2000-2b9ce41f3000 rw-p 2b9ce41f2000 00:00 0

2b9ce41f3000-2b9ce420f000 r-xp ca:01 14583172 /home/admin/local/lib/libPocoMySQL.so.9

2b9ce4410000-2b9ce445c000 r-xp ca:01 14583166 /home/admin/local/lib/libPocoUtil.so.9

2b9ce465e000-2b9ce4660000 rw-p 2b9ce465e000 00:00 0

2b9ce4660000-2b9ce47f4000 r-xp ca:01 14583165 /home/admin/local/lib/libPocoFoundation.so.9

2b9ce4a02000-2b9ce4a03000 rw-p 2b9ce4a02000 00:00 0

2b9ce4a03000-2b9ce4b1b000 r-xp ca:01 14583068 /home/admin/local/lib/libmysql.so.16.0.0

7fffc6e1d000-7fffc6e32000 rw-p 7ffffffea000 00:00 0 [stack]

ffffffffff600000-ffffffffffe00000 ---p 00000000 00:00 0 [vdso]

以SMSSERVER为例,它详细显示了SMSSERVER运行时的库文件内存映射,以及stack的地址:

也有一些内存映射后面是空的,说明这是匿名内存映射。可以通过/proc/PID/smaps查看更详细的信息,例如查看上述stack使用情况:

#cat /proc/23698/smaps

……

7fffc6e1d000-7fffc6e32000 rw-p 7ffffffea000 00:00 0                [stack]

Size:              84 kB

Rss:              16 kB

Shared_Clean:       0 kB

Shared_Dirty:       0  kB

Private_Clean:       0 kB

Private_Dirty:       16 kB

Swap:              0 kB

……

其中rw-p表示权限,权限共有以下几种:

r = read

w = write

x = execute

s = shared

p = private (copy on write)

SIZE表示了这个映射的大小,RSS表示正在RAM中的数据大小。

Shared/Private_Clean/Dirty分别表示共享和私有库有效页和脏数据的大小。

这里要注意的是,即使是共享库,但如果使用者只有此一个进程时,也被统计在Private项里。

 

那么库文件是怎么加载进入内存的呢?这里也做一个简单的介绍。

linux下的库有两种:静态库和共享库(动态库)。

二者的不同点在于代码被载入的时刻不同。  静态库的代码在编译过程中已经被载入可执行程序,因此体积较大。共享库的代码是在可执行程序运行时才载入内存的,在编译过程中仅简单的引用,因此代码体积较小。共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。

一般静态库的后缀是.a,它由源文件编译生成一堆.o,每个.o里都包含这个编译单元的符号表,然后用ar命令将很多.o转换成.a形成。而动态库的后缀为.so,由gcc加特定参数编译产生。

对于一个可执行文件,可以用如下命令查看它的依赖库,以短信服务器SMSSERVER为例:

 

那么编译程序是如何找到这些库文件,并加载进来的呢?编译器将先后搜索:

1) elf文件的DT_RPATH段(在编译时指定目录);

2) 环境变量LD_LIBRARY_PATH中指定的路径;

3) /etc/ld.so.cache文件列表;

4) /lib/,/usr/lib目录;

如果找不到则会链接失败。因此,如果出现找不到库的情况,可以:

1)在编译时-rpath指定目录;

2)修改.bash_profile文件在LD_LIBRARY_PATH中加入指定目录;

3)修改/etc/ld.so.conf加入指定目录,然后调用ldconfig重新生成/etc/ld.so.cache;

4)将动态库放入/lib/,/usr/lib两个默认路径;

 

四、 系统调优相关文件(/proc/sys目录)

通常而言,/proc/sys目录下的文件是可读可写的,其它目录大多只可读,。由于用户可以通过修改值来达到修改运行时系统状态的目的,我们有时也可以此来优化系统状态。当然,修改proc值只会影响当前运行状态,重启后将失效。通常可以采用echo x > filename的方法来将值直接改入文件。例如:

[admin@ccbuqa147160x ~]$ cat /proc/sys/vm/swappiness

10

[admin@ccbuqa147160x ~]$ echo 20 > /proc/sys/vm/swappiness

下面对一些常见内核参数进行说明:

1、/proc/sys/kernel目录:

文件名

含义

默认值

/proc/sys/kernel/msgmax

进程间传递消息的最大长度

8192

/proc/sys/kernel/msgmnb

一个消息队列的最大长度

16384

/proc/sys/kernel/msgmni

消息队列的最大数目

16

/proc/sys/kernel/shmall

共享内存可使用总量

2097152

/proc/sys/kernel/shmmax

内核所允许的最大共享内存段的大小

 

/proc/sys/kernel/threads-max

内核所能使用的线程的最大数目

2048

/proc/sys/kernel/sem

4个值,分别表示每个信号集的最大信号量数目,系统范围内的最大信号量总数目,每个信号发生时的最大系统操作数目,系统范围内的最大信号集总数目

 

2、/proc/sys/vm目录

文件名

含义

备注

/proc/sys/vm/swapiness

系统进行交换行为的程度,数值(0-100)越高,越可能发生磁盘交换

60

/proc/sys/vm/page-cluster

写一次到swap区的时候写入的页面数量,0表示1页,1表示2页,2表示4页

3

/proc/sys/vm/nr_pdflush_threads

当前正在运行的pdflush进程数量,在I/O负载高的情况下,内核会自动增加更多的pdflush进程。Pdflush用于页面置换时将数据写回磁盘

 

/proc/sys/vm/min_free_kbytes

强制Linux VM最低保留多少空闲内存

 

/proc/sys/vm/dirty_writeback_centisecs

pdflush进程周期性间隔多久把脏数据写回磁盘

500ms

/proc/sys/vm/dirty_ratio

如果进程产生的脏数据到达系统整体内存的百分比,此时进程自行把脏数据写回磁盘

40

/proc/sys/vm/dirty_expire_centisecs

如果脏数据在内存中驻留时间超过该值,pdflush进程在下一次将这些数据写回磁盘

3000ms

/proc/sys/vm/dirty_background_ratio

脏数据到达系统整体内存的百分比,此时触发pdflush进程把脏数据写回磁盘

10

3、/proc/sys/net目录

文件名

含义

默认值

/proc/sys/net/core/message_burst

写新的警告消息所需的时间,在这个时间内系统接收到的其它警告消息会被丢弃。这用于防止某些企图用消息“淹没”系统的人所使用的拒绝服务(Denial of Service)攻击。

50(5秒)

/proc/sys/net/core/netdev_max_backlog

在每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目

300

/proc/sys/net/core/optmem_max

每个套接字所允许的最大缓冲区大小

10240

/proc/sys/net/core/rmem_default

接收套接字缓冲区大小的缺省值

110592

/proc/sys/net/core/rmem_max

接收套接字缓冲区大小的最大值

131071

/proc/sys/net/core/wmem_default

发送套接字缓冲区大小的缺省值

110592

/proc/sys/net/core/wmem_max

发送套接字缓冲区大小的最大值

 

4、/proc/sys/net/ipv4目录

涉及TCP/IP相关参数特别多,这里只列举一些常见的参数:

文件

含义

默认值

/proc/sys/net/ipv4/ip_forward

是否打开IP转发

0禁止 1转发

/proc/sys/net/ipv4/ip_default_ttl

一个数据报的生存周期(Time To Live),即最多经过多少路由器

64

/proc/sys/net/ipv4/ip_no_pmtu_disc

在全局范围内关闭路径MTU探测功能

0

/proc/sys/net/ipv4/route/min_pmtu

最小路径MTU的大小

552

/proc/sys/net/ipv4/ipfrag_time

一个IP分段在内存中保留多少秒

30

/proc/sys/net/ipv4/tcp_syn_retries

本机向外发起TCP SYN连接超时重传的次数;

该值仅仅针对外出的连接,对于进来的连接由tcp_retries1控制

5

/proc/sys/net/ipv4/tcp_keepalive_probes

丢弃TCP连接前,进行最大TCP保持连接侦测的次数

9

/proc/sys/net/ipv4/tcp_retries2

放弃在已经建立通讯状态下的一个TCP数据包前进行重传的次数

15

/proc/sys/net/ipv4/tcp_fin_timeout

对于本端断开的socket连接,TCP保持在FIN-WAIT-2状态的时间

60

/proc/sys/net/ipv4/tcp_max_tw_buckets

系统在同时所处理的最大timewait sockets 数目。纯粹为了抵御那些简单的 DoS 攻击

180000

/proc/sys/net/ipv4/tcp_tw_reuse

是否允许重新应用处于TIME-WAIT状态的socket用于新的TCP连接

0

/proc/sys/net/ipv4/tcp_max_syn_backlog

对于那些依然还未获得客户端确认的连接请求,需要保存在队列中最大数目

1024

/proc/sys/net/ipv4/tcp_window_scaling

设置tcp/ip会话的滑动窗口大小是否可变

1

/proc/sys/net/ipv4/tcp_reordering

TCP流中重排序的数据报最大数量

3

5、常用网络优化策略:

1)优化系统套接字缓冲区

net.core.rmem_max=16777216  

net.core.wmem_max=16777216

2)优化TCP接收/发送缓冲区

net.ipv4.tcp_rmem=4096 87380 16777216 

net.ipv4.tcp_wmem=4096 65536 16777216

3)优化网络设备接收队列

net.core.netdev_max_backlog=3000

4)关闭路由相关功能

net.ipv4.conf.lo.accept_source_route=0

net.ipv4.conf.all.accept_source_route=0

net.ipv4.conf.eth0.accept_source_route=0

net.ipv4.conf.default.accept_source_route=0

net.ipv4.conf.lo.accept_redirects=0

net.ipv4.conf.all.accept_redirects=0

net.ipv4.conf.eth0.accept_redirects=0

net.ipv4.conf.default.accept_redirects=0

net.ipv4.conf.lo.secure_redirects=0

net.ipv4.conf.all.secure_redirects=0

net.ipv4.conf.eth0.secure_redirects=0

net.ipv4.conf.default.secure_redirects=0

net.ipv4.conf.lo.send_redirects=0

net.ipv4.conf.all.send_redirects=0

net.ipv4.conf.eth0.send_redirects=0

net.ipv4.conf.default.send_redirects=0

5)优化TCP协议栈

打开TCP SYN cookie选项,有助于保护服务器免受SyncFlood攻击。

net.ipv4.tcp_syncookies=1

打开TIME-WAIT套接字重用功能,对于存在大量连接的Web服务器非常有效。

net.ipv4.tcp_tw_recyle=1

net.ipv4.tcp_tw_reuse=1

减少处于FIN-WAIT-2连接状态的时间,使系统可以处理更多的连接。

net.ipv4.tcp_fin_timeout=30

减少TCP KeepAlive连接侦测的时间,使系统可以处理更多的连接。

net.ipv4.tcp_keepalive_time=1800

增加TCP SYN队列长度,使系统可以处理更多的并发连接。

net.ipv4.tcp_max_syn_backlog=8192

 

五、自定义PROC文件和管理

如果你想自定义一个Proc项,可以采用如下方法:

struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent)

其中,第一个参数为需要创建的文件名,第二个参数为权限设置,第三个参数为父节点名字。如果为空,则创建在/proc/目录下。create_proc_entry实际工作是生成proc_dir_entry,并将它注册到文件系统,链接上默认的文件操作集file_operation。

当然,如果只是想要创建一个只读的 proc 文件,可以采用 create_proc_read_entry() 这个接口。这个接口其实就是给 proc_dir_entry 多赋了两个值,其中 read_proc 是一个函数指针, data 是 read_proc 调用时传给它一个参数。

static inline 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项、读文件、写文件等方法,它们的定义如下:

struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)

void remove_proc_entry(const char *name, struct proc_dir_entry *parent)

static ssize_t proc_file_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)

static ssize_t proc_file_write(struct file *file,  const char __user *buffer,size_t count, loff_t *ppos)

proc_file_read为了读到/proc系统中的数据,需要做如下三步:

1.申请内存页 2.读取数据填充到此内存页 3.把数据从内核空间拷贝到用户空间。

proc 文件的读需要自己提供一个 read_proc_t 类型的函数放在 proc_dir_entry 结构中供 proc_file_read() 函数调用。同样,写也需要提供write_proc_t类型的函数。它们的定义分别是:

typedef int (read_proc_t)(char *page, char **start, off_t off, int count,int *eof, void *data);

typedef int (write_proc_t)(struct file *file, const char __user *buffer, unsigned long count, void *data);

 

后记

/proc文件系统包含了系统信息和内核参数,内容非常丰富,有许多参数的理解和修改需要对linux原理、进程调度、内存管理等有很深的了解,才可以对其做出更好的分析和优化。本文提到的均为较常见的参数,更详细的说明可以查看linux帮助文档和网站。

 

感兴趣的同学可以一起讨论。如有错误,请指正。

谢谢大家。

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值