On Fri, Alex wrote: > Hi! > > I've been wondering how to figure out which remote clients are mounting NFS > exports from my server. It seems that "/etc/rmtab" contains some of this > information, but since we use automountd with direct maps and so forth, we > end up with a lot of information in that file that doesn't appear valid > anymore. Hosts long gone etc. > > I'd like to be able to figure out which hosts have a mount on my NFS server > at any given time, not which clients have at one point or other mounted a > file system and possibly has relinquished the mount long ago. In fact, I'd > like to be able to tell the same for remote NIS bindings from my NIS server > as well. > > How can I most reliably get this kind of data?
If the clients are using TCP for NFS service, then you can capture the current list of active clients with something like this: #!/usr/bin/perl use Socket; open NS, "netstat -an 2>/dev/null |"; while (<NS>) { if (/(.*\..*\..*\..*)\.2049/) { ($server, $client, $other) = split; $_ = $client; if (/(.*\..*\..*\..*)\..*/) { printf ("NFS client: %s\n", gethostbyaddr(inet_aton($1), AF_INET)); } } } If you are using a Solaris 10 or later NFS server, then you can use the attached dtrace script to give you a list of active clients. Notice that the script truncates to 20 hosts so that would need to be changed to capture all.... Spencer -------------- next part -------------- #!/usr/sbin/dtrace -FCs #define AF_INET 2 #define AF_INET6 26 fbt::common_dispatch:entry { /* ca = (struct sockaddr *)svc_getrpccaller(req->rq_xprt)->buf; */ self->ca = (struct sockaddr *)(args[0]->rq_xprt->xp_xpc.xpc_rtaddr.buf); self->sin_addr = (uchar_t *)&((struct sockaddr_in *)self->ca)->sin_addr; self->in = 1; } fbt::common_dispatch:return /self->in && self->ca->sa_family == AF_INET/ { self->sin_addr = (uchar_t *)&((struct sockaddr_in *)self->ca)->sin_addr; @hosts[self->sin_addr[0], self->sin_addr[1], self->sin_addr[2], self->sin_addr[3]] = count(); self->in = 0; self->ca = 0; self->sin_addr = 0; } fbt::common_dispatch:return /self->in && self->ca->sa_family == AF_INET6/ { self->sin6 = (uchar_t *)&((struct sockaddr_in6 *)self->ca)->sin6_addr; @hosts6[self->sin6[0], self->sin6[1], self->sin6[2], self->sin6[3], self->sin6[4], self->sin6[5], self->sin6[6], self->sin6[7], self->sin6[8], self->sin6[9], self->sin6[10], self->sin6[11], self->sin6[12], self->sin6[13], self->sin6[14], self->sin6[15]] = count(); self->in = 0; self->ca = 0; self->sin6 = 0; } tick-3s { trunc (@hosts, 20); trunc (@hosts6, 20); printf("\033[H\033[2J"); printa("\nhost: %d.%d.%d.%d num nfs calls: %...@d", @hosts); printa("\nhost: %x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x num nfs calls: %...@d", @hosts6); trunc (@hosts); trunc (@hosts6); }