Executable Path – How to Identify Executable Path with Its PID on AIX 5 or More

aixpathps

On AIX 5 or 6, `ps -ef` shows the executable full path randomly. Why? And how to determine it?

I found many threads throughout the Internet and also Unix & Linux and this stack overflow post about finding the path of a process and so far I haven't succeeded in applying any method.
I keep falling into having proftpd shown instead of having a path.
I finally read the man ps of AIX and find this :

CMD

(-f, -l, and l flags) Contains the command name. Under the -f flag, ps tries to determine the current command name and arguments both of which may be changed asynchronously by
the process. These are then displayed. Failing this, the command name as it would appear without the option -f, is written in square brackets.

I want to be sure to understand what it means when I have the following output:

 ps -ef (truncate output)
root 44900     1   0 11:49:36      -  0:00 proftpd: (accepting connections)
nobody 31986 14976   0   13 feb      -  0:00 /usr/local/apache/bin/httpd -f /usr/local/apache/conf/httpd.conf

For the httpd daemon, it does show the full path but doesn't show the full path for proftpd.
First question is why are some processes shown with full path and some aren't?

The second question is for that case :

Can I assume that the path of the proftpd is the first I'll find typing whereis as root ?

In my case :

 whereis proftpd
 proftpd: /etc/proftpd.conf /usr/sbin/proftpd  

So I assume that the running deamon is /usr/sbin/protfpd ? Am I correct ?


Edit 2:

Let me answer that part: NO I can't make such an assumption — it is not relevant at all. I finally found out that the daemon was running from /opt/proftpd, which is not even in the root path.

The "why does ps -ef work that way" is still to determine, and also: is there any other way to find out what is the real path knowing the PID?


Edit 1:
Here's the proof that my AIX system are not supporting exe link in /proc/<PID>.
I test this against AIX versions 5.3.9.0 and 6.1.7.15:

ls -al /proc/44900/*
-rw-------    1 root     nobody            0 14 jan 09:42 /proc/44900/as
-r--------    1 root     nobody          128 14 jan 09:42 /proc/44900/cred
--w-------    1 root     nobody            0 14 jan 09:42 /proc/44900/ctl
lr-x------   53 root     nobody            0 13 jan 16:07 /proc/44900/cwd -> /
-r--------    1 root     nobody            0 14 jan 09:42 /proc/44900/map
-r--r--r--    1 root     nobody          448 14 jan 09:42 /proc/44900/psinfo
-r--------    1 root     nobody         1024 14 jan 09:42 /proc/44900/sigact
-r--------    1 root     nobody         1520 14 jan 09:42 /proc/44900/status
-r--r--r--    1 root     nobody            0 14 jan 09:42 /proc/44900/sysent

/proc/44900/fd:
total 5483376
dr-x------    1 root     nobody            0 14 jan 09:42 .
dr-xr-xr-x    1 root     nobody            0 14 jan 09:42 ..
-r--r--r--    1 root     nobody         5005 12 jul 2004  3
-r--r--r--    1 root     nobody         8655 13 nov 15:13 5
-r--r--r--    1 root     nobody         1607 13 nov 15:12 6
--w-------    1 root     nobody   2378419349 13 jan 16:06 7
--w-------    1 root     nobody    423405131 13 jan 16:06 8

/proc/44900/lwp:
total 0
dr-xr-xr-x    1 root     nobody            0 14 jan 09:42 .
dr-xr-xr-x    1 root     nobody            0 14 jan 09:42 ..
dr-xr-xr-x    1 root     nobody            0 14 jan 09:42 99075

/proc/44900/object:
total 90312
dr-x------    1 root     nobody            0 14 jan 09:42 .
dr-xr-xr-x    1 root     nobody            0 14 jan 09:42 ..
-rwxr-xr-x    1 root     system      1268973 16 okt 2012  a.out
-rwxr-xr-x    1 bin      bin           15265 12 jul 2004  jfs.10.5.12513
-r--r--r--    1 bin      bin         8587637 23 mei 2008  jfs.10.5.16405
-r-xr-xr-x    1 bin      bin         9281793 23 sep 2008  jfs.10.5.4131
-r-xr-xr-x    1 bin      bin           11019 01 okt 2007  jfs.10.5.4149
-r--r--r--    1 bin      bin          162078 19 jun 2008  jfs.10.5.4169
-r--r--r--    1 bin      bin         1161414 23 sep 2008  jfs.10.5.4171
-r--r--r--    1 bin      bin          379513 19 jun 2008  jfs.10.5.4943
-r-xr-xr-x    1 bin      bin           96495 19 jun 2008  jfs.10.5.5248
-rw-r--r--    1 root     system     17160842 05 okt 2011  jfs2.51.3.266241
-rwxr-xr-x    1 root     system       315783 11 mei 2006  jfs2.51.3.266246
-rw-r--r--    1 root     system      3237612 05 okt 2011  jfs2.51.3.266262
-rw-r--r--    1 root     system       125958 25 mrt 2008  jfs2.51.3.270769
-rwxr-xr-x    1 root     system      3140221 20 mei 2011  jfs2.51.3.282757
-rwxr-xr-x    1 root     system      1268973 16 okt 2012  jfs2.51.3.283899

No symbolic link at all.

Best Answer

Ok so here's my answers to my questions.

  • First: Can I assume that the path of the proftpd is the first I'll find typing whereis as root ?
    ==> NO, at least with my experience it shows no reliable information to determine the process executable path.

  • Second: How to determine executable path of a running process ?
    I found a stackoverflow topic that state this possibility which is so far the only one that showed me the correct answer:
    svmon -P <PID> -O format=nolimit,filename=on,filtertype=client
    Problem with this command is that you have to wait until it shows you the information you want but it will probably give you the answer after a while. Another problem is that, this method can't be use in a script.

  • Third: Concerning the "Why ps -ef is not showing neither a full nor a relative path"
    The answer is probably (but feel free to correct me) that it shows the actual command typed by the user so if root was in a folder containing proftpd then it will only show proftpd
    No idea so far.

That's so far the best answer I can came up with.


Edit 1:

Scriptable way of finding the path of a running executable (this method doesn't come from me but from an no longer online forum). Note that I will not provide a script because it's way over my capabilities and I have not the time right now.

  • First step is to get the inode of your executable binary

    ls -i /proc/<PID>/object/a.out  |  cut -f 1 -d " "
    

    This command will output a number.

  • Then you need to identify the device on which your file is for that take a look at that command:

    ls -li /proc/<PID>/object/ | egrep "<inode>$"
    

    This command while give you a name of file like this : jfs2.51.3.<inode>. jfs2 is the filesystem type, 51 the major device number and 3 the minor device number.

  • Once you identify the device info we need to identify the block device where the file is located with the following command :

    ls -l /dev/ | egrep "^b.*51, *3.+$"  
    

    ^b.*51, *3.+$ ^b is used to match block device
    51, *3 matches the major block 51 followed by a comma and any space and minor block number 3 find previously.
    This command while give you something like :
    brw-rw---- 1 root system 51, 3 24 feb 2009 myfilesystem

  • You can then identify the mount point of your block like this :

    df | grep myfilesystem
    /dev/myfilesystem     31457280    144544  100%   107442    81% /opts
    
  • You now know where you need to search your number:

    find /opts -inum <inode>
    

I admit this method is a bit complicated but it's the only one so far I found that is "easily scriptable". If someone ever write a script I'd glad to read it.

Related Question