查找侦听指定端口的进程,对于系统管理员来说,是个永恒的话题。历史上Solaris 可以用第三方的lsof,也可以用自带的pfiles。后来,还可以用mdb达成任务。本文 主要是演示mdb的高阶用法之一。
关于mdb的入门,不在此赘述。
# netstat -na -P tcp -f inet | grep LISTEN *.111 *.* 0 0 49152 0 LISTEN *.32771 *.* 0 0 49152 0 LISTEN *.4045 *.* 0 0 49152 0 LISTEN *.32772 *.* 0 0 49152 0 LISTEN *.32773 *.* 0 0 49152 0 LISTEN *.32774 *.* 0 0 49152 0 LISTEN *.32775 *.* 0 0 49152 0 LISTEN *.32776 *.* 0 0 49152 0 LISTEN *.23 *.* 0 0 49152 0 LISTEN *.22 *.* 0 0 49152 0 LISTEN *.21 *.* 0 0 49152 0 LISTEN *.79 *.* 0 0 49152 0 LISTEN *.513 *.* 0 0 49152 0 LISTEN *.514 *.* 0 0 49152 0 LISTEN *.7100 *.* 0 0 49152 0 LISTEN *.32777 *.* 0 0 49152 0 LISTEN *.5987 *.* 0 0 49152 0 LISTEN *.898 *.* 0 0 49152 0 LISTEN *.32778 *.* 0 0 49152 0 LISTEN *.5988 *.* 0 0 49152 0 LISTEN *.32779 *.* 0 0 49152 0 LISTEN *.6788 *.* 0 0 49152 0 LISTEN *.6789 *.* 0 0 49152 0 LISTEN *.32785 *.* 0 0 49152 0 LISTEN *.32786 *.* 0 0 49152 0 LISTEN *.32787 *.* 0 0 49152 0 LISTEN *.6000 *.* 0 0 49152 0 LISTEN *.6000 *.* 0 0 49152 0 LISTEN 127.0.0.1.32782 *.* 0 0 49152 0 LISTEN *.32794 *.* 0 0 49152 0 LISTEN
现在想知道谁在侦听”127.0.0.1.32782″。
对于Solaris,第三方的lsof是首选:
# lsof -ni tcp:32782 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 1646 noaccess 11u IPv4 0x3000052b500 0t0 TCP 127.0.0.1:32782 (LISTEN) # /usr/ucb/ps axunw 1646 UID PID %CPU %MEM SZ RSS TT S START TIME COMMAND 60002 1646 0.1 5.213912050696 ? S Jun 13 27:08 /usr/jdk/instances/jdk1.5.0/bin/java -server -XX:+BackgroundCompilation -Djava.security.manager -Djava.security.policy==/var/opt/webconsole/policy/console.policy -classpath /usr/apache/tomcat/bin/bootstrap.jar:/usr/jdk/instances/jdk1.5.0/lib/tools.jar:/usr/jdk/instances/jdk1.5.0/jre/lib/jsse.jar:/usr/lib/audit/Audit.jar:/usr/jdk/packages/javax.help-2.0/lib/jhall.jar -Djavax.net.ssl.trustStore=/etc/opt/webconsole/keystore -Dcatalina.home=/usr/apache/tomcat -Dcatalina.base=/var/opt/webconsole -Dcom.sun.web.console.home=/usr/share/webconsole -Dcom.sun.web.console.base=/var/opt/webconsole -Dcom.sun.web.console.appbase=/var/opt/webconsole/webapps -Dcom.sun.web.console.secureport=6789 -Dcom.sun.web.console.unsecureport=6788 -Dcom.sun.web.console.unsecurehost=127.0.0.1 -Dcom.sun.web.console.logdir=/var/log/webconsole -Dwebconsole.default.file=/etc/default/webconsole -Dwebconsole.config.file=/etc/opt/webconsole/webconsole -Dcom.sun.web.console.startfile=/var/tmp/webconsole.tmp -Djava.awt.headless=true -Djava.security.auth.login.config=/var/opt/webconsole/conf/consolelogin.conf org.apache.catalina.startup.Bootstrap start # /usr/bin/ps -opid,ppid,uid,addr,fname,comm,args -p 1646 PID PPID UID ADDR COMMAND COMMAND COMMAND 1646 1 60002 3000069db88 java /usr/jdk/instances/jdk1.5.0/bin/java /usr/jdk/instances/jdk1.5.0/bin/java -server -XX:+BackgroundCompilation -Djava. # lsof -n -p 1646 | grep TCP java 1646 noaccess 7u IPv4 0x3000052c0c0 0t0 TCP *:6788 (LISTEN) java 1646 noaccess 8u IPv4 0x3000052ae80 0t0 TCP *:32784 (BOUND) java 1646 noaccess 9u IPv4 0x3000053a0c0 0t0 TCP *:6789 (LISTEN) java 1646 noaccess 11u IPv4 0x3000052b500 0t0 TCP 127.0.0.1:32782 (LISTEN)
/usr/bin/pfiles也可以,但不能直接用,得写脚本。只能将所有进程、端口的对应 关系枚举完,再从中找我们关心的端口。
# pfiles 1646 1646: /usr/jdk/instances/jdk1.5.0/bin/java -server -XX:+BackgroundCompilatio Current rlimit: 65536 file descriptors 0: S_IFCHR mode:0666 dev:287,0 ino:6815752 uid:0 gid:3 rdev:13,2 O_RDONLY|O_LARGEFILE /devices/pseudo/mm@0:null 1: S_IFREG mode:0644 dev:32,0 ino:36555 uid:60002 gid:60002 size:37269 O_WRONLY|O_LARGEFILE /var/log/webconsole/console_debug_log 2: S_IFREG mode:0644 dev:32,0 ino:36555 uid:60002 gid:60002 size:37269 O_WRONLY|O_LARGEFILE /var/log/webconsole/console_debug_log 3: S_IFCHR mode:0666 dev:287,0 ino:6815772 uid:0 gid:3 rdev:13,12 O_RDWR FD_CLOEXEC /devices/pseudo/mm@0:zero 4: S_IFDOOR mode:0444 dev:296,0 ino:61 uid:0 gid:0 size:0 O_RDONLY|O_LARGEFILE FD_CLOEXEC door to nscd[89] /var/run/name_service_door 5: S_IFCHR mode:0644 dev:287,0 ino:99614724 uid:0 gid:3 rdev:190,0 O_RDONLY|O_LARGEFILE /devices/pseudo/random@0:random 6: S_IFCHR mode:0644 dev:287,0 ino:99614726 uid:0 gid:3 rdev:190,1 O_RDONLY|O_LARGEFILE /devices/pseudo/random@0:urandom 7: S_IFSOCK mode:0666 dev:293,0 ino:4736 uid:0 gid:0 size:0 O_RDWR SOCK_STREAM SO_REUSEADDR,SO_SNDBUF(49152),SO_RCVBUF(49152),IP_NEXTHOP(0.0.192.0) sockname: AF_INET 0.0.0.0 port: 6788 8: S_IFSOCK mode:0666 dev:293,0 ino:4736 uid:0 gid:0 size:0 O_RDWR SOCK_STREAM SO_SNDBUF(49152),SO_RCVBUF(49152),IP_NEXTHOP(0.0.192.0) sockname: AF_INET 0.0.0.0 port: 6788 9: S_IFSOCK mode:0666 dev:293,0 ino:28574 uid:0 gid:0 size:0 O_RDWR SOCK_STREAM SO_REUSEADDR,SO_SNDBUF(49152),SO_RCVBUF(49152),IP_NEXTHOP(0.0.192.0) sockname: AF_INET 0.0.0.0 port: 6789 11: S_IFSOCK mode:0666 dev:293,0 ino:28564 uid:0 gid:0 size:0 O_RDWR SOCK_STREAM SO_REUSEADDR,SO_SNDBUF(49152),SO_RCVBUF(49152),IP_NEXTHOP(0.0.192.0) sockname: AF_INET 127.0.0.1 port: 32782 # pfiles -n 1646 1646: /usr/jdk/instances/jdk1.5.0/bin/java -server -XX:+BackgroundCompilatio Current rlimit: 65536 file descriptors 0: S_IFCHR mode:0666 dev:287,0 ino:6815752 uid:0 gid:3 rdev:13,2 1: S_IFREG mode:0644 dev:32,0 ino:36555 uid:60002 gid:60002 size:37269 2: S_IFREG mode:0644 dev:32,0 ino:36555 uid:60002 gid:60002 size:37269 3: S_IFCHR mode:0666 dev:287,0 ino:6815772 uid:0 gid:3 rdev:13,12 4: S_IFDOOR mode:0444 dev:296,0 ino:61 uid:0 gid:0 size:0 5: S_IFCHR mode:0644 dev:287,0 ino:99614724 uid:0 gid:3 rdev:190,0 6: S_IFCHR mode:0644 dev:287,0 ino:99614726 uid:0 gid:3 rdev:190,1 7: S_IFSOCK mode:0666 dev:293,0 ino:4736 uid:0 gid:0 size:0 8: S_IFSOCK mode:0666 dev:293,0 ino:4736 uid:0 gid:0 size:0 9: S_IFSOCK mode:0666 dev:293,0 ino:28574 uid:0 gid:0 size:0 11: S_IFSOCK mode:0666 dev:293,0 ino:28564 uid:0 gid:0 size:0 # pfiles 1646 | grep sockname sockname: AF_INET 0.0.0.0 port: 6788 sockname: AF_INET 0.0.0.0 port: 32784 sockname: AF_INET 0.0.0.0 port: 6789 sockname: AF_INET 127.0.0.1 port: 32782
还可以用mdb,比pfiles要直接些:
# ndd /dev/tcp tcp_listen_hash TCP zone IP addr port seqnum backlog (q0/q/max) 000 30000530280 0 ::ffff:0.0.0.0 00514 00000000 0/0/16 ... 142 3000052b700 0 ::ffff:127.0.0.1 32782 00000000 0/0/2 ... > 3000052b700 ::print tcp_t tcp_rq | ::q2stream | ::stdata -v ADDR WRQ FLAGS VNODE N/A REF 000003000306ee50 0000030003060478 00000000 0000030003073c40 0/0 0 > 0000030003073c40 ::whereopen file 3000467c550 3000069db88
获取vnode的另一种方案:
> 3000052b700 ::print tcp_t tcp_rq | ::q2stream | ::print -at stdata_t sd_vnode 3000306ee60 struct vnode *sd_vnode = 0x30003073c40 > 3000052b700 ::print tcp_t tcp_rq | ::q2stream | ::print -at stdata_t sd_vnode | ::whereopen file 3000467c550 3000069db88 3000069db88是proc_t: > 3000069db88 ::ps -f S PID PPID PGID SID UID FLAGS ADDR NAME R 1646 1 7 7 60002 0x4a004000 000003000069db88 /usr/jdk/instances/jdk1.5.0/bin/java -server -XX:+BackgroundCompilation -Djava.