pfiles for Linux

Problem

Someone asked if there is a Linux equivalent of the Solaris pfiles tool. pfiles is a Solaris proc utility that reports information of all open files by the process id. Eugene decided to write a similar tool for Linux using SystemTap.

Scripts

The script is too long to be listed here. Get it here http://sources.redhat.com/git/gitweb.cgi?p=systemtap.git;a=blob;f=testsuite/systemtap.examples/process/pfiles.stp;h=3b96862530d7cbc38e8e02d2beca9ff63dae8b8b;hb=HEAD

It is based on the example outputs in:

TODO:

Output

$ pfiles
usage:  pfiles pid ...
  (report open files of each process)
$ pfiles `pgrep firefox-bin` | head -24
4118:  firefox-bin
  Current rlimit: 256 file descriptors
   0: S_IFCHR mode:0666 dev:0,16 ino:205 uid:500 gid:500 rdev:1,3
      O_RDONLY|O_LARGEFILE
      /dev/null
   1: S_IFCHR mode:0666 dev:0,16 ino:205 uid:500 gid:500 rdev:1,3
      O_WRONLY|O_LARGEFILE
      /dev/null
   2: S_IFCHR mode:0666 dev:0,16 ino:205 uid:500 gid:500 rdev:1,3
      O_WRONLY|O_LARGEFILE
      /dev/null
   3: S_IFSOCK mode:0777 dev:0,5 ino:45113 uid:500 gid:500 rdev:0,0
      O_RDWR|O_NONBLOCK FD_CLOEXEC
      socket:[45113]
   4: S_IFIFO mode:0600 dev:0,6 ino:45115 uid:500 gid:500 rdev:0,0
      O_RDONLY
      pipe:[45115]
   5: S_IFIFO mode:0600 dev:0,6 ino:45115 uid:500 gid:500 rdev:0,0
      O_WRONLY
      pipe:[45115]
   6: S_IFREG mode:0664 dev:253,0 ino:17105675 uid:500 gid:500 rdev:0,0
      O_WRONLY
      advisory write lock set by process 4118
      /home/eteo/.mozilla/firefox/abcdefgh.default/.parentlock
$ pfiles `pgrep thunderbird-bin` | grep advisory -A1 -B2
   6: S_IFREG mode:0664 dev:253,0 ino:15729244 uid:500 gid:500 rdev:0,0
      O_WRONLY
      advisory write lock set by process 3610
      /home/eteo/.thunderbird/abcdefgh.default/.parentlock

List all sockets opened by ntpd:

$ pfiles `pgrep ntpd` | grep -i port\:
      sockname: AF_INET 0.0.0.0  port: 123
      sockname: AF_INET6 0000:0000:0000:0000:0000:0000:0000:0000  port: 123
      sockname: AF_INET6 0000:0000:0000:0000:0000:0000:0000:0001  port: 123
      sockname: AF_INET6 fe80:0000:0000:0000:0218:8bff:febf:XXXX  port: 123
      sockname: AF_INET 127.0.0.1  port: 123
      sockname: AF_INET 192.168.1.X  port: 123
      sockname: AF_INET6 fe80:0000:0000:0000:0200:00ff:XXXX:0000  port: 123
      sockname: AF_INET 192.168.122.X  port: 123
      sockname: AF_INET 10.64.68.X  port: 123

List all AF_UNIX sockets with paths binded by pidgin:

$ pfiles `pgrep pidgin` | grep -i unix\ \/
       peername: AF_UNIX /tmp/orbit-eteo/linc-c7b-0-13f16bda309e6
       peername: AF_UNIX /var/run/dbus/system_bus_socket
       peername: AF_UNIX /tmp/.ICE-unix/3105
       sockname: AF_UNIX /tmp/orbit-eteo/linc-6a1b-0-3c1dac62998f6
       sockname: AF_UNIX /tmp/orbit-eteo/linc-6a1b-0-3c1dac62998f6

Compare pidgin’s output with the following. Now I know why nothing happens when I try to press ctrl+space in my pidgin chat window. Something is broken.

$ pfiles `pgrep firefox-bin` | grep -i unix\ \/ | grep scim
       peername: AF_UNIX /tmp/scim-bridge-0.3.0.socket-500@localhost:0.0

List opened files that are locked:

$ pfiles 2676 | grep advisory -A1 -B2
  3: S_IFREG mode:0644 dev:253,0 ino:459459 uid:0 gid:0 rdev:0,0
     O_RDWR FD_CLOEXEC
     advisory write lock set by process 2675
     /var/run/crond.pid

bind() was called with INADDR_ANY as its IP address:

$ pfiles `pgrep dnsmasq` | tail -4
 11: S_IFSOCK mode:0777 dev:0,5 ino:8996 uid:99 gid:40 rdev:0,0
     O_RDWR|O_NONBLOCK
     socket:[8996]
       sockname: AF_INET 0.0.0.0  port: 32771

Lessons

You can write very useful systems tools that are not available in Linux with SystemTap. pfiles and plimit are excellent examples.

Reference


WarStories