分享
 
 
 

理解/proc文件系统

王朝other·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

不只一次的有人问我关于/proc文件系统,那是什么,那些巨大的文件在那里做

什么?我可以删除它们吗?本文将详细介绍/proc文件系统,描述一些工具,你可以

通过这些工具领略/proc的威力。最后有一个例子程序,演示了系统管理员如何与

/proc交互。

◆ 介绍/proc

在过去那些糟糕的日子里,只能通过直接访问内核内存(/dev/kmem)获取进程数

据,比如运行ps(1)命令时。为了实现这种访问,需要超级用户权限,而且步骤相当

复杂。Sun公司从UNIX SVR4开始解决了进程数据访问问题,现在,可以简单地通过

/proc访问进程数据。

/proc文件系统不是普通意义上的文件系统,它是一个到运行中进程地址空间的

访问接口。通过/proc,可以用标准Unix系统调用(比如open()、read()、write()、

ioctl()等等)访问进程地址空间。事实上,Solaris ps(1)命令正是利用/proc获取进

程状态。

S (l) 进程状态:

O 正在运行

S 休眠: 进程正在等待某个事件发生/完成

R 可运行: 进程位于运行队列中

Z 僵尸状态: 进程结束了,但是其父进程未处理SIGCHLD信号

T 进程暂停: 可能是任务控制信号所致,或者正在被

跟踪调试

/proc下的大文件对应运行中进程的地址空间,不是标准Unix文件。事实上每个文件

名对应运行中进程的PID,文件属主、属组对应进程拥有者的real-uid和primary-gid。

权限控制与普通Unix文件一样。文件大小是最令人迷惑的地方,事实上相当好理解,

对应进程内存映像大小,并不真正占用硬盘空间,所以你不必担心空间浪费的问题。

不要企图删除这些文件!观察图A中列举的/proc例子:

--------------------------------------------------------------------------

$ ls -l /proc

total 43384

-rw------- 1 root root 0 Apr 2 20:07 00000

-rw------- 1 root root 393216 Apr 2 20:07 00001

-rw------- 1 root root 0 Apr 2 20:07 00002

-rw------- 1 root root 0 Apr 2 20:07 00003

-rw------- 1 root root 1695744 Apr 2 20:07 00081

-rw------- 1 root root 1597440 Apr 2 20:07 00083

-rw------- 1 root root 1777664 Apr 2 20:08 00096

-rw------- 1 root root 1683456 Apr 2 20:08 00099

-rw------- 1 root root 1589248 Apr 2 20:08 00101

-rw------- 1 root root 1445888 Apr 2 20:08 00116

-rw------- 1 root root 1404928 Apr 2 20:08 00126

-rw------- 1 root root 798720 Apr 2 20:08 00135

-rw------- 1 root root 1368064 Apr 2 20:08 00195

-rw------- 1 root root 1585152 Apr 2 20:08 00197

-rw------- 1 root root 1368064 Apr 2 20:08 00200

-rw------- 1 root other 225280 Apr 2 20:08 00201

-rw------- 1 root root 1454080 Apr 2 20:08 00203

-rw------- 1 root root 1519616 Apr 2 20:14 00243

-rw------- 1 rthomas wheel 1499136 Apr 2 20:14 00245

-rw------- 1 rthomas wheel 806912 Apr 2 20:16 00261

$

图A: /proc例子

--------------------------------------------------------------------------

操作/proc下文件的方式和操作普通Unix文件一样,可以使用所有你熟悉的系统

调用,包括ioctl()。在内核中,针对/proc下文件的vnode操作被转向procfs。这意

味着操作vnode的系统调用(比如lookuppn())实际上最终转向procfs-savvy系统调用(

比如prlookup())。

◆ /proc能告诉我什么

Solaris下使用/proc的工具相当完善,位于/usr/proc/bin目录中。这些工具提

供了一种访问任意指定进程临界数据的简捷办法。比如,想知道一个进程已经打开了

多少文件,你可以使用crash(1M)(见鬼,我不会),但是你是root吗?不必担心,可

以用/usr/proc/bin/pfiles获取这种信息,图B演示了pfiles(1)命令的使用:

--------------------------------------------------------------------------

[scz@ /export/home/scz]> ps

PID TTY TIME CMD

637 pts/3 0:00 bash

[scz@ /export/home/scz]> pfiles 637

637: -bash

Current rlimit: 64 file descriptors

0: S_IFCHR mode:0620 dev:151,0 ino:196787 uid:500 gid:7 rdev:24,3

O_RDWR

1: S_IFCHR mode:0620 dev:151,0 ino:196787 uid:500 gid:7 rdev:24,3

O_RDWR

2: S_IFCHR mode:0620 dev:151,0 ino:196787 uid:500 gid:7 rdev:24,3

O_RDWR

3: S_IFDOOR mode:0444 dev:191,0 ino:1618164880 uid:0 gid:0 size:0

O_RDONLY|O_LARGEFILE FD_CLOEXEC door to nscd[213]

63: S_IFCHR mode:0620 dev:151,0 ino:196787 uid:500 gid:7 rdev:24,3

O_RDWR FD_CLOEXEC

[scz@ /export/home/scz]>

图B: 使用pfiles(1)命令

--------------------------------------------------------------------------

正如上面演示的,/usr/proc/bin下的命令使用很简单,只需要在命令行上指定PID。

然而,留心权限许可设置,与所有普通Unix文件一样,你无权访问那些权限设置上

禁止访问的指定PID的进程数据。

花点事件看看proc(1)手册页,熟悉其中介绍的命令,你将学会列举指定进程相关的

库、进程信号设置、进程信任设置,你甚至可以暂停、重启进程。

◆ 编写/proc工具

/proc的魅力在于它包含了你可能想知道的关于一个进程的任何信息,你只需要

简单地从中获取。/usr/include/sys/procfs.h文件中定义了两个结构,prstatus和

prpsinfo,从中可以获取指定进程的很多信息。下面是个例子,开发者想知道他的应

用程序究竟占用了多少内存。简单!ls /proc就可以知道了。但是,他还想知道更多

细节,他需要知道总的映像大小、常驻部分的大小、堆区(heap)大小、栈区(stack)

大小。此外,他希望能够定期跟踪这些数据信息,类似vmstat(1M)那种方式。如上所

述,听起来象是一个令人生畏的任务。

译者: Solaris 2.6开始这两个结构定义在/usr/include/sys/old_procfs.h文件中

然而,通过使用/proc文件系统,我们可以使这项编程挑战变得容易些。我们写

的这个工具称做memlook,将显示指定PID对应的内存统计信息。此外,可以在命令行

上指定一个时间间隔,以便定期重新检测内存利用信息。图C演示了一次简单的输出:

--------------------------------------------------------------------------

$ memlook 245

PID IMAGE RSS HEAP STACK

245 1499136 1044480 24581 8192

$

图C: memlook的输出举例

--------------------------------------------------------------------------

下面是memlook.c的源代码

--------------------------------------------------------------------------

/*

* @(#)memlook.c 1.0 10 Nov 1997

* Robert Owen Thomas robt@cymru.com

* memlook.c -- A process memory utilization reporting tool.

*

* gcc -Wall -O3 -o memlook memlook.c

*/

#pragma ident "@(#)memlook.c 1.0 10 Nov 1997 Robert Owen Thomas robt@cymru.com"

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

int counter = 10;

int showUsage ( const char * );

void getInfo ( int, int );

int main ( int argc, char * argv[] )

{

int fd, pid, timeloop = 0;

char pidpath[BUFSIZ]; /* /usr/include/stdio.h: #define BUFSIZ 1024 */

switch ( argc )

{

case 2:

break;

case 3:

timeloop = atoi( argv[2] );

break;

default:

showUsage( argv[0] );

break;

} /* end of switch */

pid = atoi( argv[1] );

sprintf( pidpath, "/proc/%-d", pid ); /* -表示向左靠 */

if ( ( fd = open( pidpath, O_RDONLY ) ) < 0 )

{

perror( pidpath );

exit( 1 );

}

if ( 0 < timeloop )

{

for ( ; ; )

{

getInfo( fd, pid );

sleep( timeloop );

}

}

getInfo( fd, pid );

close( fd );

exit( 0 );

} /* end of main */

int showUsage ( const char * progname )

{

fprintf( stderr, "%s: usage: %s < PID > [time delay]\n", progname, progname );

exit( 3 );

} /* end of showUsage */

void getInfo ( int fd, int pid )

{

prpsinfo_t prp;

prstatus_t prs;

if ( ioctl( fd, PIOCPSINFO, &prp ) < 0 )

{

perror( "ioctl" );

exit( 5 );

}

if ( ioctl( fd, PIOCSTATUS, &prs ) < 0 )

{

perror( "ioctl" );

exit( 7 );

}

if ( counter > 9 )

{

fprintf( stdout, "PID\tIMAGE\t\tRSS\t\tHEAP\t\tSTACK\n" );

counter = 0;

}

fprintf( stdout, "%u\t%-9u\t%-9u\t%-15u\t%-15u\n", pid,

( unsigned int )prp.pr_bysize, ( unsigned int )prp.pr_byrssize,

( unsigned int )prs.pr_brksize, ( unsigned int )prs.pr_stksize );

counter++;

} /* end of getInfo */

--------------------------------------------------------------------------

译者: 作者这里利用了ioctl(),而不是直接读取/proc下文件,这样做的好处在于即

使系统升级后/proc布局改变,内核中相应ioctl cmd支持也随之改变,对于应

用层的开发者,接口一样,源代码可平稳移植。事实上从作者前面举例来看,

memlook.c是在Solaris 2.6以前的版本上开发的,但我并未修改就可以直接用

在Solaris 2.6上,虽然此时/proc布局已经发生重大变化。

仔细阅读prstatus和prpsinfo结构,寻找那些你敢兴趣的成员。在未能真正掌握这种

技术之前不要针对/proc文件系统使用write()或者ioctl()。针对特定进程胡乱做

write()调用,结果未知。

◆ 结论

当痛苦调试程序或者试图获取指定进程状态的时候,/proc文件系统将是你强有

力的支持者。通过它可以创建更强大的工具,获取更多信息。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有