home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
- #
- # Simple script to implement "array ps".
- #
- # Usage: aps local <name>
- # or: aps merge <file....>
- # or: aps localonly [-Z]
- #
-
- #
- # The local variant: this should be run on each node in the array
- #
- if ($ARGV[0] eq "local") {
-
- #
- # Start up a "ps" command and trap its output, discarding the header
- #
- open(PS, "ps -ef |") || die "Couldn't run ps: $!\n";
- <PS>;
-
- #
- # Process each line of ps output
- #
- while (<PS>) {
-
- #
- # Split out individual fields
- #
- ($fields1, $fields2) = unpack("A39 A*", $_);
- ($uid, $pid, $ppid, $cpu, $stime, $tty) = split(" ", $fields1);
- ($time, $command) = split(" ", $fields2, 2);
-
- #
- # Determine the ASH of the current process
- #
- $ash = `ainfo ash -f 2 -i $pid`;
- chop $ash;
-
- #
- # Print the results neatly, tossing ASH "0" (which is normally
- # just system processes)
- #
- printf "%18s %12s %5s %8s %7s %s\n",
- $ash, $ARGV[1], $pid, $uid, $time, $command
- unless $ash eq "0x0000000000000000"
- }
- }
-
- #
- # The merge variant: this is run only on one node using the output
- # from "aps local" on each node as its input files
- #
- elsif ($ARGV[0] eq "merge") {
-
- #
- # Read all of the input files into a list
- #
- shift @ARGV;
- @all = <ARGV>;
-
- #
- # Sort the list using the "sortps" subroutine
- #
- @new = sort sortps @all;
-
- #
- # Print a nice header line
- #
- print " ASH Host PID User Time Command\n";
- print "----------------------------------------------------------------\n";
-
- #
- # Print every line except for those with no ASH (probably processes
- # that terminated before the we could find its ASH)
- #
- foreach $line (@new) {
- print $line unless $line =~ /UNAVAILABLE/;
- }
- }
-
- #
- # The localonly variant: essentially just a "ps" with ASHs, this would
- # be used by curious users or aview
- #
- elsif ($ARGV[0] eq "localonly") {
-
- #
- # Start up a "ps" command and trap its output, discarding the header
- #
- open(PS, "ps -ef |") || die "Couldn't run ps: $!\n";
- <PS>;
-
- #
- # Process each line of ps output
- #
- $i = 0;
- while (<PS>) {
-
- #
- # Split out individual fields
- #
- ($fields1, $fields2) = unpack("A39 A*", $_);
- ($uid, $pid, $ppid, $cpu, $stime, $tty) = split(" ", $fields1);
- ($time, $command) = split(" ", $fields2, 2);
-
- #
- # Determine the ASH of the current process
- #
- $ash = `ainfo ash -f 2 -i $pid`;
- chop $ash;
-
- #
- # Print the results neatly, tossing ASH "0" (which is normally
- # just system processes) and "UNAVAILABLE" (meaning the process
- # probably went away)
- #
- if ($ash ne "UNAVAILABLE" &&
- ($ARGV[1] ne "-Z" || $ash ne "0x0000000000000000"))
- {
- $new[$i] = sprintf("%18s %5s %8s %s\n", $ash, $pid, $uid, $command);
- $i = $i + 1;
- }
- }
-
- #
- # Sort the list using the "sortlocalonly" subroutine
- #
- @sorted = sort sortlocalonly @new;
-
- #
- # Print a header
- #
- print " ASH PID USER COMMAND\n";
-
- #
- # Dump the results
- #
- foreach $line (@sorted) {
- print $line;
- }
- }
-
-
- #
- # Sort function: sorts "aps local" lines first by ASH, then hostname, then PID
- #
- sub sortps {
- ($Aash, $Ahost, $Apid) = split(" ", $a);
- ($Bash, $Bhost, $Bpid) = split(" ", $b);
-
- (($Aash cmp $Bash) || ($Ahost cmp $Bhost) || ($Apid <=> $Bpid));
- }
-
-
- #
- # Sort function: sorts "aps localonly" lines first by ASH, then PID
- #
- sub sortlocalonly {
- ($Aash, $Apid) = split(" ", $a);
- ($Bash, $Bpid) = split(" ", $b);
-
- (($Bash cmp $Aash) || ($Bpid <=> $Apid));
- }
-