Messages in this thread |  | | From | Werner Almesberger <> | Subject | Re: Admin util wish list | Date | Thu, 18 Jul 1996 18:58:48 +0200 (MET DST) |
| |
lilo wrote: > I know nothing about the BSD utility, but this suggests a general utility > `fdstat' that would deal with files, sockets, etc. By user, filename, fd > number, interface address, etc., etc.
psmisc version 12 already supports socket (=port#+protocol) to process lookups. Note that mapping anything to a file name (unless the file name comes from a small set of names, such as /dev) is much harder than any of the other mappings due to the potentially very large number of files on a system.
Todd Graham Lewis wrote: > Not really, unless I'm missing something. BSD fstat gives the following: > > USER CMD PID FD MOUNT INUM MODE SZ|DV R/W > tlewis zsh 27363 wd /usr 20307 drwxr-xr-x 512 r > tlewis zsh 27363 0 / 4274 crw--w---- ttyp0 rw > tlewis zsh 27363 1 / 4274 crw--w---- ttyp0 rw
I assume that was a pid->open_files mapping ? Most of the information is already in /proc/<pid>, ready for lookup by the PID. You just need to build hash tables for mount points and for /dev (the DV field).
It's so easy that I've just implemented it. I've attached the Perl script.
- Werner
---------------------------------- fstat.pl -----------------------------------
#!/usr/bin/perl
sub handle { local ($path,$name) = @_; (local ($link) = readlink($path)) || return; local ($rw) = (lstat($path))[2]; local ($fdev,$ino) = $link =~ /\[(.+)\]:(\d+)/; (local ($mode,$rdev,$size) = (stat($path))[2,6,7]) || return; $rdev = $dev{$mode." ".$rdev}; printf("%-9s%-11s%5d%5s%9d %3o%9s%3s %-10s\n",$user,$cmd,$pid,$name,$ino, $mode & 0777,$rdev ? $rdev : $size, ($rw & 0400 ? "r" : "").($rw & 0200 ? "w" : ""), $mnt{hex($fdev)} ? $mnt{hex($fdev)} : "???"); }
opendir(DIR,"/dev") || die "opendir /dev: $!"; for (readdir DIR) { @s = stat("/dev/$_"); $type = (lstat("/dev/$_"))[2] >> 12; $dev{"".join(" ",@s[2,6])} = $_ if $type == 6 || $type == 2; } closedir DIR; open(MNT,"/proc/mounts") || die "open /proc/mounts: $!"; for (<MNT>) { $dir = (split(" ",$_))[1]; if (@s = stat($dir)) { $mnt{@s[0]} = $dir; } } close MNT; print "USER CMD PID FD INUM MODE SZ|DV R/W MOUNT\n"; for $pid (@ARGV) { if (!chdir "/proc/$pid") { print STDERR "$pid: no such process\n"; next; } if (!opendir(DIR,"fd")) { print STDERR "$pid: $!\n"; next; } @proc = stat("."); $user = getpwuid($proc[4]) ? getpwuid($proc[4]) : $proc[4]; open(CMD,"cmdline") || die "open cmdline: $!"; ($cmd) = (<CMD> =~ /^([^\000]*)(\000.*)?$/); close CMD; &handle("cwd","wd"); for (readdir DIR) { &handle("fd/$_",$_) unless $_ eq "." || $_ eq ".."; } closedir DIR; }
-- _________________________________________________________________________ / Werner Almesberger, DI-LRC,EPFL,CH werner.almesberger@lrc.di.epfl.ch / /_IN_R_133__Tel_+41_21_693_6621__Fax_+41_21_693_6610_____________________/
|  |