[Solaris]查找侦听指定端口的进程

查找侦听指定端口的进程,对于系统管理员来说,是个永恒的话题。历史上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.

Spread the word. Share this post!

Meet The Author

C/ASM程序员

Leave Comment