Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Working With The Process Table (AIX)

by Limbic~Region (Chancellor)
on Aug 05, 2011 at 13:31 UTC ( [id://918757]=perlquestion: print w/replies, xml ) Need Help??

Limbic~Region has asked for the wisdom of the Perl Monks concerning the following question:

I am currently working on building a library of tools so that others at the office can more easily write robust scripts. One of the problems I am working on is "determining if a script is running" which is often poorly implemented as:
ps -ef | grep $script | grep -v grep

As you know, this will generate false results in a variety of situations. For instance, if $script is a substring of another process or someone happens to be editing the script. The real problem boils down to two variations: Is this specific script running /path/to/script and Is this specific script running /path/to/script "with these arguments".

At first I reached for Proc::ProcessTable but discovered it will not compile in my environment (AIX 6.1). I then found this example from IBM of "roll-your-own ps". While I looked forward to writing some Inline::C to convert to XS, I discovered the C struct you get only provides access to the executable file name and not the command line arguments. Next I started looking at /proc (AIX is trying to ease the transition from linux :-). There is a psinfo file that contains the argument list (thanks to bart, ambrus and others in the CB who pointed out the very cool Convert::Binary::C). Unfortunately, it is truncated.

At this point, I am beginning to think I need to just parse ps. Unfortunately, that is leading to another problem. While ps can get me access to the full argument list (at least in all the situations I care about), it seems to be impossible to tell if /path/to/script is running with certainty. Here is an example:

/tmp/myscripts/ # one I want to know about # cd /tmp; perl myscripts/ &

As you can see, I won't know if the that is running is /tmp/myscripts/ or /some/other/dir/myscripts/ The /proc filesystem does provide a cwd of the process which combined with a rel2abs() could provide the information desired but since it changes if the script changes - it too is unreliable.

There is no lsof on the system. I need this to be usable by non-privileged users (though I could setgrpid if necessary). I can't really see a way to improve upon the crappy solution people have been getting by with just fine up till now. Am I missing something obvious?

Cheers - L~R

Replies are listed 'Best First'.
Re: Working With The Process Table (AIX)
by Tux (Canon) on Aug 05, 2011 at 13:48 UTC

    What were the problems with Proc::ProcessTable? I'm using that almost exclusively (AIX' ps sucks just as most AIX stuff) on AIX 5.2 and AIX 5.3.

    My px script has not changed since June 2007 and is based on this module. (Feel free to copy/use/modify, it doesn't try to mimic ps, but to make a ps that I like).

    Enjoy, Have FUN! H.Merijn
      Even if I could get Proc::ProcessTable to compile, it wouldn't provide access to the full command line arguments. I have read the source code and it is using the same library that the IBM "roll your own ps" does. pi_comm is truncated. Essentially, Proc::ProcessTable is using a struct that is no longer supported in 64 bit mode. The /usr/include/procinfo.h says "procinfo, userinfo, and uicredinfo structures represent obsolete interfaces. These would not compile correctly in 64-bit mode. I hacked away at the code to use the new structs but found out that pi_comm represents the truncated program name (not the full argument list).

      By the way, my corporate firewall will not allow me to access your px script - the site is not on the approved list of allowable websites. If you are willing to email it to me, /msg me and I will give you my info.

      Cheers - L~R

Re: Working With The Process Table (AIX)
by zentara (Archbishop) on Aug 05, 2011 at 14:48 UTC
    I'm not familiar with Aix, but googling for "Aix proc filesystem" shows it exists. Can't you just loop thru all the pid entries? Each pid has it's own directory named the numeric pid. For example: /proc/$pid/cmdline will give you the command line name of the $pid. All sorts of useful information is in there. It probably isn't real efficient to loop through all the pid directories, but neither is Proc::ProcessTable. :-)

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
      but googling for "Aix proc filesystem" shows it exists

      I referenced AIX's /proc file system in my original post. Not all /proc filesystems are created equal. AIX does not support the cmdline file. In fact, the only useful information I have found is in psinfo (described above) which has a partial command line argument.

      Cheers - L~R

        <meditation mode>

        There is no lsof .... minimal proc filesystem

        It seems you have been given a task, which the AIX operating system has been designed to prevent. What the rational behind their OS design? Security of processes? It seems they require you to know the pid, and only the launcher of the process will know it.

        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh
Re: Working With The Process Table (AIX)
by thenaz (Beadle) on Aug 05, 2011 at 13:42 UTC

    I'm not familiar with AIX, but have you considered writing a "driver" that links to the kernel to pull the information you want directly from the kernel datastructures?

      I believe the reason ps works is because it has the setgrpid bit set and is reading kernel memory. I am not opposed to doing that myself provided I know what I am doing (which at the moment, I don't).

      Cheers - L~R

Re: Working With The Process Table (AIX)
by jffry (Hermit) on Aug 05, 2011 at 22:50 UTC
    The /proc filesystem does provide a cwd of the process which combined with a rel2abs() could provide the information desired but since it changes if the script changes - it too is unreliable.

    I think is your only option, especially for scripts.

    Scripts are really just arguments to proper binary executables. There is no kernel process structure to store the full path to arguments that happen to be file name values.

    Also, I hate to bear bad news but, the shell guys can still drive you crazy if they don't put the she-bang at the top of their scripts. Take a look at this:

    me@mybox:/home/me/sandbox $ ./ & [1] 417964 me@mybox:/home/me/sandbox $ ps -o pid,args -p 417964 PID COMMAND 417964 -bash me@mybox:/home/me/sandbox $ ./ & [2] 430266 me@mybox:/home/me/sandbox $ ps -o pid,args -p 430266 PID COMMAND 430266 /usr/bin/bash ./
    me@mybox:/home/me/sandbox $ cat #!/usr/bin/bash sleep 600 me@mybox:/home/me/sandbox $ cat sleep 600

    Yes, I use bash on AIX. Linux has spoiled me.

      This will only work if the script doesn't ever chdir/cd/etc. I am aware of the shebang problem which is why I caveated by saying "at least in all the situations I care about".

      Cheers - L~R

Re: Working With The Process Table (AIX)
by Anonymous Monk on Aug 05, 2011 at 13:43 UTC
      Anonymous Monk,
      I didn't go into the littany of things I tried, but I went through the entire RT queue and nothing resolved the issue. I emailed the author since they haven't responded to any of the tickets for some time. I also did my own research into the problem and the solution requires an extensive re-write (see my response to Tux below if interested).

      Cheers - L~R

Re: Working With The Process Table (AIX)
by Anonymous Monk on Aug 06, 2011 at 05:53 UTC

    Not a Perl question. Did you bother to read the part in Proc::ProcessTable where they explain you need to read the README.aix where the author explains that you can't get that info without reading /proc/kmem and he doesn't want to do that so you can run it without root privileges.

    Sure, okay, you want to do this in Perl and there are probably a few AIX guys around here so it's sort of okay. But then you just ignore je44ery when he says "There is no kernel process structure to store the full path to arguments that happen to be file name values." But hey, why would that be an issue when all you want is the full path to the arguments?

      Anonymous Monk,
      I read the README.aix about a dozen times and it doesn't mention anywhere that this information is not available - only that he used undocumented function calls and that he avoided reading the kernel memory.

      Cheers - L~R

        Look, if you choose to ignore the fact that AIX doesn't provide this information, feel free to carry on but you're pissing in the ocean.

        Of course Jens has some nice insight but it's not because AIX is helping you out. As I said, this is not a Perl question ... because it's about low level AIX kernel structures ... maybe IBM would know?

Re: Working With The Process Table (AIX)
by sundialsvc4 (Abbot) on Aug 05, 2011 at 15:04 UTC

    Maybe you can do it another way.   Perhaps you can use a lock-file ... something which the process you’re looking for does when it starts, and un-does when it ends.   Locking operations are known to be atomic, and maybe they get a little bit closer to what you might actually want to know:   “Can I do this right now, or not?   At this immediate instant, is the doorway open or closed?”

      Maybe I can do what another way?

      As I indicated in my original post, I am writing a general purpose library for interacting with the process table. Perhaps you assumed I am trying to make sure there is only one instance of a process running? Even if that is what I was attempting to do (it isn't), using locks on a file have their own limitations. For instance, on most *nix platforms the lock is advisory and not enforced by the kernel. Additionally, you can delete a locked file.

      Again, I need to be able to answer the questions:

      • Is this specific script at this absolute path currently running?
      • Is there a process in the process table with X in the command line arguments?

      Cheers - L~R

        I would agree with sundialsvc4 that a mechanism where a script writes to a file at startup, and cleans up when it exits, is the way to go. Write the PID to the file. We generally use this mechanism to ensure only one instance of a program is running, but there is nothing to stop you putting multiple PIDs in the file. Either name the PID file according to some convention (e.g. replace "/" in the script path with "-" or some such), or for full generality create a directory tree, on the fly, matching the script path (e.g. a script "/abc/xyz/foo" having PID file "/tmp/pidfiles/abc/xyz/").

        File locking in this scenario is required, and I don't really understand your concerns about this--after all the script only needs to cooperate with other identical instances of itself, all of which would use the convention of using flock on the PID file. Or put your PIDs in a database.

        The only other comment I would make is that you need to handle the case where a script dies before it can remove its PID from the PID file. So check whether a PID is still in use when you start up new instance of a script, and if not, clean up that entry.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://918757]
Approved by marto
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (1)
As of 2024-04-24 13:59 GMT
Find Nodes?
    Voting Booth?

    No recent polls found