Skip to content

Instantly share code, notes, and snippets.

@cabo
Created July 5, 2012 08:23
Show Gist options
  • Select an option

  • Save cabo/3052250 to your computer and use it in GitHub Desktop.

Select an option

Save cabo/3052250 to your computer and use it in GitHub Desktop.
nfsping: find out whether the NFS server is still answering requests
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <rpc/rpc.h>
#include <sys/time.h>
#include <string.h>
#include <arpa/inet.h>
#ifdef __svr4__
#define bcopy(s,d,len) memcpy((d),(s),(len))
#endif
long inet_name_to_addr();
void nfsping(char *hname, int n, int verbose, int timo1, int timo2);
void usage(n) char *n; {
fprintf(stderr, "Usage: %s host [num].\n", n);
exit(2);
}
void fatal(s) char *s; {
perror(s);
exit(1);
}
int main(ac, av) char **av; {
int n = 1;
int verbose = 0;
int i;
for (i = 1; i < ac; ++i) {
if (!strcmp(av[i], "-v"))
verbose = 1;
else if (strspn(av[i], "-0123456789") == strlen(av[i])) {
n = atoi(av[i]);
if (n < 0) {
verbose = 1;
n = -n;
}
} else
nfsping(av[i], n, n == 1 || verbose, 2000, 3000);
}
}
void nfsping(char *hname, int n, int verbose, int timo1, int timo2) {
CLIENT *clnt;
int sock = RPC_ANYSOCK;
int totaltime = 0, mintime = 2147483647, maxtime = 0, mytime;
struct timeval waittime, starttime, endtime;
struct sockaddr_in addr;
int i, j, rpc_stat, nn = 0;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_name_to_addr(hname);
if (addr.sin_addr.s_addr == 0) {
perror(hname);
return;
}
addr.sin_port = htons(2049);
waittime.tv_sec = timo1/1000;
waittime.tv_usec = timo1%1000*1000;
clnt = clntudp_create(&addr, 100003, 2, waittime, &sock);
waittime.tv_sec = timo2/1000;
waittime.tv_usec = timo2%1000*1000;
for (j = 0; j < n; ++j) {
gettimeofday(&starttime, (struct timezone *)0);
rpc_stat = CLNT_CALL(clnt, NULLPROC,
(xdrproc_t) xdr_void, (char*)0,
(xdrproc_t) xdr_void, (char*)0, waittime);
gettimeofday(&endtime, (struct timezone *)0);
endtime.tv_sec -= starttime.tv_sec;
if ((endtime.tv_usec -= starttime.tv_usec) < 0) {
endtime.tv_sec -= 1;
endtime.tv_usec += 1000000;
}
mytime = endtime.tv_sec * 1000000 + endtime.tv_usec;
if (verbose || rpc_stat != RPC_SUCCESS)
printf("%9s %-15s %s %d.%03d\n", hname, inet_ntoa(addr.sin_addr),
rpc_stat == RPC_SUCCESS ? "OK" : clnt_sperrno(rpc_stat),
mytime / 1000, mytime % 1000); // , addr.sin_addr.s_addr);
if (rpc_stat == RPC_SUCCESS) {
nn++;
totaltime += mytime;
if (mytime > maxtime) maxtime = mytime;
if (mytime < mintime) mintime = mytime;
}
}
CLNT_DESTROY(clnt);
if (n > 1) {
printf("%9s %-15s", hname, inet_ntoa(addr.sin_addr));
if (nn > 0) {
totaltime /= nn;
printf(" min/avg/max: %d.%03d/%d.%03d/%d.%03d",
mintime / 1000, mintime % 1000,
totaltime / 1000, totaltime % 1000,
maxtime / 1000, maxtime % 1000);
}
if (n != nn)
printf (" (%d failed = %d%%)", n - nn, (n - nn) * 100 / n);
printf("\n");
}
}
long inet_name_to_addr(hname) char *hname; {
long addr = inet_addr(hname);
if (addr == -1) {
struct hostent *he;
he = gethostbyname(hname);
if (!he)
return 0;
bcopy(he->h_addr_list[0], (char*)&addr, he->h_length);
}
return addr;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment