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);
}

Reply via email to