static unsigned int srvproc3info[24], srvproc3info_old[24]; /* NFSv3 call counts ([0] == 22) */
static unsigned int cltproc3info[24], cltproc3info_old[24]; /* NFSv3 call counts ([0] == 22) */
static unsigned int srvproc4info[4], srvproc4info_old[4]; /* NFSv4 call counts ([0] == 2) */
-static unsigned int cltproc4info[37], cltproc4info_old[37]; /* NFSv4 call counts ([0] == 35) */
-static unsigned int srvproc4opsinfo[42], srvproc4opsinfo_old[42]; /* NFSv4 call counts ([0] == 40) */
+static unsigned int cltproc4info[49], cltproc4info_old[49]; /* NFSv4 call counts ([0] == 35) */
+static unsigned int srvproc4opsinfo[61], srvproc4opsinfo_old[61]; /* NFSv4 call counts ([0] == 40) */
static unsigned int srvnetinfo[5], srvnetinfo_old[5]; /* 0 # of received packets
* 1 UDP packets
* 2 TCP packets
"compound",
};
-static const char * nfscltproc4name[35] = {
+static const char * nfscltproc4name[47] = {
"null", "read", "write", "commit", "open", "open_conf",
"open_noat", "open_dgrd", "close", "setattr", "fsinfo", "renew",
"setclntid", "confirm", "lock",
"lockt", "locku", "access", "getattr", "lookup", "lookup_root",
"remove", "rename", "link", "symlink", "create", "pathconf",
"statfs", "readlink", "readdir", "server_caps", "delegreturn", "getacl",
- "setacl", "fs_locations"
+ "setacl", "fs_locations",
+ /* nfsv4.1 client ops */
+ "exchange_id",
+ "create_ses",
+ "destroy_ses",
+ "sequence",
+ "get_lease_t",
+ "layoutget",
+ "layoutcommit",
+ "layoutreturn",
+ "getdevlist",
+ "getdevinfo",
+ /* nfsv4.1 pnfs client ops to data server only */
+ "ds_write",
+ "ds_commit",
};
-static const char * nfssrvproc4opname[40] = {
+static const char * nfssrvproc4opname[59] = {
"op0-unused", "op1-unused", "op2-future", "access", "close", "commit",
"create", "delegpurge", "delegreturn", "getattr", "getfh", "link",
"lock", "lockt", "locku", "lookup", "lookup_root", "nverify",
"open", "openattr", "open_conf", "open_dgrd", "putfh", "putpubfh",
"putrootfh", "read", "readdir", "readlink", "remove", "rename",
"renew", "restorefh", "savefh", "secinfo", "setattr", "setcltid",
- "setcltidconf", "verify", "write", "rellockowner"
+ "setcltidconf", "verify", "write", "rellockowner",
+ /* nfsv4.1 server ops */
+ "bc_ctl",
+ "bind_conn",
+ "exchange_id",
+ "create_ses",
+ "destroy_ses",
+ "free_stateid",
+ "getdirdeleg",
+ "getdevinfo",
+ "getdevlist",
+ "layoutcommit",
+ "layoutget",
+ "layoutreturn",
+ "secinfononam",
+ "sequence",
+ "set_ssv",
+ "test_stateid",
+ "want_deleg",
+ "destroy_clid",
+ "reclaim_comp",
};
#define LABEL_srvnet "Server packet stats:\n"
DECLARE_CLT(cltinfo);
DECLARE_CLT(cltinfo, _old);
+static void print_all_stats(int, int, int);
+static void print_server_stats(int, int);
+static void print_client_stats(int, int);
+static void print_stats_list(int, int, int);
static void print_numbers(const char *, unsigned int *,
unsigned int);
static void print_callstats(const char *, const char **,
unsigned int *, unsigned int);
+static void print_callstats_list(const char *, const char **,
+ unsigned int *, unsigned int);
static int parse_raw_statfile(const char *, struct statinfo *);
static int parse_pretty_statfile(const char *, struct statinfo *);
static void get_stats(const char *, struct statinfo *, int *, int,
int);
static int has_stats(const unsigned int *);
+static int has_rpcstats(const unsigned int *, int);
static void diff_stats(struct statinfo *, struct statinfo *, int);
static void unpause(int);
+static void update_old_counters(struct statinfo *, struct statinfo *);
static time_t starttime;
{
printf("Usage: %s [OPTION]...\n\
\n\
- -m, --mounts\t\tShow statistics on mounted NFS filesystems\n\
- -c, --client\t\tShow NFS client statistics\n\
- -s, --server\t\tShow NFS server statistics\n\
- -2\t\t\tShow NFS version 2 statistics\n\
- -3\t\t\tShow NFS version 3 statistics\n\
- -4\t\t\tShow NFS version 4 statistics\n\
- -o [facility]\t\tShow statistics on particular facilities.\n\
- nfs\tNFS protocol information\n\
- rpc\tGeneral RPC information\n\
- net\tNetwork layer statistics\n\
- fh\t\tUsage information on the server's file handle cache\n\
- rc\t\tUsage information on the server's request reply cache\n\
- all\tSelect all of the above\n\
- -v, --verbose, --all\tSame as '-o all'\n\
- -r, --rpc\t\tShow RPC statistics\n\
- -n, --nfs\t\tShow NFS statistics\n\
- -Z, --sleep\t\tSaves stats, pauses, diffs current and saved\n\
- -S, --since file\tShows difference between current stats and those in 'file'\n\
- --version\t\tShow program version\n\
- --help\t\tWhat you just did\n\
+ -m, --mounts Show statistics on mounted NFS filesystems\n\
+ -c, --client Show NFS client statistics\n\
+ -s, --server Show NFS server statistics\n\
+ -2 Show NFS version 2 statistics\n\
+ -3 Show NFS version 3 statistics\n\
+ -4 Show NFS version 4 statistics\n\
+ -o [facility] Show statistics on particular facilities.\n\
+ nfs NFS protocol information\n\
+ rpc General RPC information\n\
+ net Network layer statistics\n\
+ fh Usage information on the server's file handle cache\n\
+ rc Usage information on the server's request reply cache\n\
+ all Select all of the above\n\
+ -v, --verbose, --all Same as '-o all'\n\
+ -r, --rpc Show RPC statistics\n\
+ -n, --nfs Show NFS statistics\n\
+ -Z[#], --sleep[=#] Collects stats until interrupted.\n\
+ Cumulative stats are then printed\n\
+ If # is provided, stats will be output every\n\
+ # seconds.\n\
+ -S, --since file Shows difference between current stats and those in 'file'\n\
+ -l, --list Prints stats in list format\n\
+ --version Show program version\n\
+ --help What you just did\n\
\n", name);
exit(0);
}
{ "zero", 0, 0, 'z' },
{ "help", 0, 0, '\1' },
{ "version", 0, 0, '\2' },
- { "sleep", 0, 0, 'Z' },
+ { "sleep", 2, 0, 'Z' },
{ "since", 1, 0, 'S' },
+ { "list", 0, 0, 'l' },
{ NULL, 0, 0, 0 }
};
+int opt_sleep;
int
main(int argc, char **argv)
opt_srv = 0,
opt_clt = 0,
opt_prt = 0,
- opt_sleep = 0,
+ sleep_time = 0,
+ opt_list =0,
opt_since = 0;
int c;
char *progname,
else
progname = argv[0];
- while ((c = getopt_long(argc, argv, "234acmno:ZS:vrsz\1\2", longopts, NULL)) != EOF) {
+ while ((c = getopt_long(argc, argv, "234acmno:Z::S:vrslz\1\2", longopts, NULL)) != EOF) {
switch (c) {
case 'a':
fprintf(stderr, "nfsstat: nfs acls are not yet supported.\n");
break;
case 'Z':
opt_sleep = 1;
+ if (optarg) {
+ sleep_time = atoi(optarg);
+ }
break;
case 'S':
opt_since = 1;
case 's':
opt_srv = 1;
break;
+ case 'l':
+ opt_list = 1;
+ break;
case 'z':
fprintf(stderr, "nfsstat: zeroing of nfs statistics "
"not yet supported\n");
if (opt_clt)
get_stats(clientfile, clientinfo, &opt_clt, opt_srv, 0);
- if (opt_sleep) {
+ if (opt_sleep && !sleep_time) {
starttime = time(NULL);
printf("Collecting statistics; press CTRL-C to view results from interval (i.e., from pause to CTRL-C).\n");
if (sigaction(SIGINT, &act, NULL) != 0) {
diff_stats(clientinfo_tmp, clientinfo, 0);
}
}
+ if(sleep_time) {
+ while(1) {
+ if (opt_srv) {
+ get_stats(NFSSRVSTAT, serverinfo_tmp , &opt_srv, opt_clt, 1);
+ diff_stats(serverinfo_tmp, serverinfo, 1);
+ }
+ if (opt_clt) {
+ get_stats(NFSCLTSTAT, clientinfo_tmp, &opt_clt, opt_srv, 0);
+ diff_stats(clientinfo_tmp, clientinfo, 0);
+ }
+ if (opt_list) {
+ print_stats_list(opt_srv, opt_clt, opt_prt);
+ } else {
+ print_all_stats(opt_srv, opt_clt, opt_prt);
+ }
+ fflush(stdout);
+
+ if (opt_srv)
+ update_old_counters(serverinfo_tmp, serverinfo);
+ if (opt_clt)
+ update_old_counters(clientinfo_tmp, clientinfo);
+
+ sleep(sleep_time);
+ }
+ } else {
+ if (opt_list) {
+ print_stats_list(opt_srv, opt_clt, opt_prt);
+ } else {
+ print_all_stats(opt_srv, opt_clt, opt_prt);
+ }
+ }
- if (opt_srv) {
- if (opt_prt & PRNT_NET) {
- print_numbers(
- LABEL_srvnet
- "packets udp tcp tcpconn\n",
- srvnetinfo, 4
- );
+ return 0;
+}
+
+static void
+print_all_stats (int opt_srv, int opt_clt, int opt_prt)
+{
+ print_server_stats(opt_srv, opt_prt);
+ print_client_stats(opt_clt, opt_prt);
+}
+
+static void
+print_server_stats(int opt_srv, int opt_prt)
+{
+ if (!opt_srv)
+ return;
+
+ if (opt_prt & PRNT_NET) {
+ if (opt_sleep && !has_rpcstats(srvnetinfo, 4)) {
+ } else {
+ print_numbers( LABEL_srvnet
+ "packets udp tcp tcpconn\n",
+ srvnetinfo, 4);
printf("\n");
}
- if (opt_prt & PRNT_RPC) {
- print_numbers(
- LABEL_srvrpc
- "calls badcalls badauth badclnt xdrcall\n",
- srvrpcinfo, 5
- );
+ }
+ if (opt_prt & PRNT_RPC) {
+ if (opt_sleep && !has_rpcstats(srvrpcinfo, 5)) {
+ ;
+ } else {
+ print_numbers(LABEL_srvrpc
+ "calls badcalls badauth badclnt xdrcall\n",
+ srvrpcinfo, 5);
printf("\n");
}
- if (opt_prt & PRNT_RC) {
- print_numbers(
- LABEL_srvrc
- "hits misses nocache\n",
- srvrcinfo, 3
- );
+ }
+ if (opt_prt & PRNT_RC) {
+ if (opt_sleep && !has_rpcstats(srvrcinfo, 3)) {
+ ;
+ } else {
+ print_numbers(LABEL_srvrc
+ "hits misses nocache\n",
+ srvrcinfo, 3);
printf("\n");
}
+ }
- /*
- * 2.2 puts all fh-related info after the 'rc' header
- * 2.4 puts all fh-related info after the 'fh' header, but relocates
- * 'stale' to the start and swaps dir and nondir :-(
- * We preseve the 2.2 order
- */
- if (opt_prt & PRNT_FH) {
- if (get_stat_info("fh", srvinfo)) { /* >= 2.4 */
- int t = srvfhinfo[3];
- srvfhinfo[3]=srvfhinfo[4];
- srvfhinfo[4]=t;
-
- srvfhinfo[5]=srvfhinfo[0]; /* relocate 'stale' */
-
- print_numbers(
- LABEL_srvfh
- "lookup anon ncachedir ncachedir stale\n",
- srvfhinfo + 1, 5);
- } else /* < 2.4 */
- print_numbers(
- LABEL_srvfh
- "lookup anon ncachedir ncachedir stale\n",
- srvrcinfo + 3, 5);
- printf("\n");
+ /*
+ * 2.2 puts all fh-related info after the 'rc' header
+ * 2.4 puts all fh-related info after the 'fh' header, but relocates
+ * 'stale' to the start and swaps dir and nondir :-(
+ * We preseve the 2.2 order
+ */
+ if (opt_prt & PRNT_FH) {
+ if (get_stat_info("fh", srvinfo)) { /* >= 2.4 */
+ int t = srvfhinfo[3];
+ srvfhinfo[3]=srvfhinfo[4];
+ srvfhinfo[4]=t;
+
+ srvfhinfo[5]=srvfhinfo[0]; /* relocate 'stale' */
+
+ print_numbers(
+ LABEL_srvfh
+ "lookup anon ncachedir ncachedir stale\n",
+ srvfhinfo + 1, 5);
+ } else /* < 2.4 */
+ print_numbers(
+ LABEL_srvfh
+ "lookup anon ncachedir ncachedir stale\n",
+ srvrcinfo + 3, 5);
+ printf("\n");
+ }
+ if (opt_prt & PRNT_CALLS) {
+ if ((opt_prt & PRNT_V2) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(srvproc2info))) {
+ if (opt_sleep && !has_stats(srvproc2info)) {
+ ;
+ } else {
+ print_callstats(LABEL_srvproc2,
+ nfsv2name, srvproc2info + 1,
+ sizeof(nfsv2name)/sizeof(char *));
+ }
+ }
+ if ((opt_prt & PRNT_V3) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(srvproc3info))) {
+ if (opt_sleep && !has_stats(srvproc3info)) {
+ ;
+ } else {
+ print_callstats(LABEL_srvproc3,
+ nfsv3name, srvproc3info + 1,
+ sizeof(nfsv3name)/sizeof(char *));
+ }
}
- if (opt_prt & PRNT_CALLS) {
- if ((opt_prt & PRNT_V2) || ((opt_prt & PRNT_AUTO) && has_stats(srvproc2info)))
- print_callstats(
- LABEL_srvproc2,
- nfsv2name, srvproc2info + 1, sizeof(nfsv2name)/sizeof(char *)
- );
- if ((opt_prt & PRNT_V3) || ((opt_prt & PRNT_AUTO) && has_stats(srvproc3info)))
- print_callstats(
- LABEL_srvproc3,
- nfsv3name, srvproc3info + 1, sizeof(nfsv3name)/sizeof(char *)
- );
- if ((opt_prt & PRNT_V4) || ((opt_prt & PRNT_AUTO) && has_stats(srvproc4info))) {
- print_callstats(
- LABEL_srvproc4,
- nfssrvproc4name, srvproc4info + 1, sizeof(nfssrvproc4name)/sizeof(char *)
- );
- print_callstats(
- LABEL_srvproc4ops,
- nfssrvproc4opname, srvproc4opsinfo + 1, sizeof(nfssrvproc4opname)/sizeof(char *)
- );
+ if ((opt_prt & PRNT_V4) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(srvproc4info))) {
+ if (opt_sleep && !has_stats(srvproc4info)) {
+ ;
+ } else {
+ print_callstats( LABEL_srvproc4,
+ nfssrvproc4name, srvproc4info + 1,
+ sizeof(nfssrvproc4name)/sizeof(char *));
+ print_callstats(LABEL_srvproc4ops,
+ nfssrvproc4opname, srvproc4opsinfo + 1,
+ sizeof(nfssrvproc4opname)/sizeof(char *));
}
}
}
-
- if (opt_clt) {
- if (opt_prt & PRNT_NET) {
- print_numbers(
- LABEL_cltnet
- "packets udp tcp tcpconn\n",
- cltnetinfo, 4
- );
+}
+static void
+print_client_stats(int opt_clt, int opt_prt)
+{
+ if (!opt_clt)
+ return;
+
+ if (opt_prt & PRNT_NET) {
+ if (opt_sleep && !has_rpcstats(cltnetinfo, 4)) {
+ ;
+ } else {
+ print_numbers(LABEL_cltnet
+ "packets udp tcp tcpconn\n",
+ cltnetinfo, 4);
printf("\n");
}
- if (opt_prt & PRNT_RPC) {
- print_numbers(
- LABEL_cltrpc
- "calls retrans authrefrsh\n",
- cltrpcinfo, 3
- );
+ }
+ if (opt_prt & PRNT_RPC) {
+ if (opt_sleep && !has_rpcstats(cltrpcinfo, 3)) {
+ ;
+ } else {
+ print_numbers(LABEL_cltrpc
+ "calls retrans authrefrsh\n",
+ cltrpcinfo, 3);
printf("\n");
}
- if (opt_prt & PRNT_CALLS) {
- if ((opt_prt & PRNT_V2) || ((opt_prt & PRNT_AUTO) && has_stats(cltproc2info)))
- print_callstats(
- LABEL_cltproc2,
- nfsv2name, cltproc2info + 1, sizeof(nfsv2name)/sizeof(char *)
- );
- if ((opt_prt & PRNT_V3) || ((opt_prt & PRNT_AUTO) && has_stats(cltproc3info)))
- print_callstats(
- LABEL_cltproc3,
- nfsv3name, cltproc3info + 1, sizeof(nfsv3name)/sizeof(char *)
- );
- if ((opt_prt & PRNT_V4) || ((opt_prt & PRNT_AUTO) && has_stats(cltproc4info)))
- print_callstats(
- LABEL_cltproc4,
- nfscltproc4name, cltproc4info + 1, sizeof(nfscltproc4name)/sizeof(char *)
- );
+ }
+ if (opt_prt & PRNT_CALLS) {
+ if ((opt_prt & PRNT_V2) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(cltproc2info))) {
+ if (opt_sleep && !has_stats(cltproc2info)) {
+ ;
+ } else {
+ print_callstats(LABEL_cltproc2,
+ nfsv2name, cltproc2info + 1,
+ sizeof(nfsv2name)/sizeof(char *));
+ }
+ }
+ if ((opt_prt & PRNT_V3) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(cltproc3info))) {
+ if (opt_sleep && !has_stats(cltproc3info)) {
+ ;
+ } else {
+ print_callstats(LABEL_cltproc3,
+ nfsv3name, cltproc3info + 1,
+ sizeof(nfsv3name)/sizeof(char *));
+ }
+ }
+ if ((opt_prt & PRNT_V4) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(cltproc4info))) {
+ if (opt_sleep && !has_stats(cltproc4info)) {
+ ;
+ } else {
+ print_callstats(LABEL_cltproc4,
+ nfscltproc4name, cltproc4info + 1,
+ sizeof(nfscltproc4name)/sizeof(char *));
+ }
}
}
+}
- return 0;
+static void
+print_clnt_list(int opt_prt)
+{
+ if (opt_prt & PRNT_CALLS) {
+ if ((opt_prt & PRNT_V2) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(cltproc2info))) {
+ if (opt_sleep && !has_stats(cltproc2info)) {
+ ;
+ } else {
+ print_callstats_list("nfs v2 client",
+ nfsv2name, cltproc2info + 1,
+ sizeof(nfsv2name)/sizeof(char *));
+ }
+ }
+ if ((opt_prt & PRNT_V3) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(cltproc3info))) {
+ if (opt_sleep && !has_stats(cltproc3info)) {
+ ;
+ } else {
+ print_callstats_list("nfs v3 client",
+ nfsv3name, cltproc3info + 1,
+ sizeof(nfsv3name)/sizeof(char *));
+ }
+ }
+ if ((opt_prt & PRNT_V4) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(cltproc4info))) {
+ if (opt_sleep && !has_stats(cltproc4info)) {
+ ;
+ } else {
+ print_callstats_list("nfs v4 ops",
+ nfssrvproc4opname, srvproc4opsinfo + 1,
+ sizeof(nfssrvproc4opname)/sizeof(char *));
+ print_callstats_list("nfs v4 client",
+ nfscltproc4name, cltproc4info + 1,
+ sizeof(nfscltproc4name)/sizeof(char *));
+ }
+ }
+ }
+}
+static void
+print_serv_list(int opt_prt)
+{
+ if (opt_prt & PRNT_CALLS) {
+ if ((opt_prt & PRNT_V2) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(srvproc2info))) {
+ if (opt_sleep && !has_stats(srvproc2info)) {
+ ;
+ } else {
+ print_callstats_list("nfs v2 server",
+ nfsv2name, srvproc2info + 1,
+ sizeof(nfsv2name)/sizeof(char *));
+ }
+ }
+ if ((opt_prt & PRNT_V3) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(srvproc3info))) {
+ if (opt_sleep && !has_stats(srvproc3info)) {
+ ;
+ } else {
+ print_callstats_list("nfs v3 server",
+ nfsv3name, srvproc3info + 1,
+ sizeof(nfsv3name)/sizeof(char *));
+ }
+ }
+ if ((opt_prt & PRNT_V4) ||
+ ((opt_prt & PRNT_AUTO) && has_stats(srvproc4opsinfo))) {
+ if (opt_sleep && !has_stats(srvproc4info)) {
+ ;
+ } else {
+ print_callstats_list("nfs v4 ops",
+ nfssrvproc4opname, srvproc4opsinfo + 1,
+ sizeof(nfssrvproc4opname)/sizeof(char *));
+ }
+ }
+ }
+}
+static void
+print_stats_list(int opt_srv, int opt_clt, int opt_prt)
+{
+ if (opt_srv)
+ print_serv_list(opt_prt);
+
+ if (opt_clt)
+ print_clnt_list(opt_prt);
}
static statinfo *
fputs(hdr, stdout);
for (i = 0; i < nr; i++)
- printf("%s%-8d", i? " " : "", info[i]);
+ printf("%s%-8u", i? " " : "", info[i]);
printf("\n");
}
printf("\n");
for (j = 0; j < 6 && i + j < nr; j++) {
pct = ((unsigned long long) info[i+j]*100)/total;
- printf("%-8d%3llu%% ", info[i+j], pct);
+ printf("%-8u%3llu%% ", info[i+j], pct);
}
printf("\n");
}
printf("\n");
}
+static void
+print_callstats_list(const char *hdr, const char **names,
+ unsigned int *callinfo, unsigned int nr)
+{
+ unsigned long long calltotal;
+ int i;
+
+ for (i = 0, calltotal = 0; i < nr; i++) {
+ calltotal += callinfo[i];
+ }
+ if (!calltotal)
+ return;
+ printf("%13s %13s %8llu \n", hdr, "total:", calltotal);
+ printf("------------- ------------- --------\n");
+ for (i = 0; i < nr; i++) {
+ if (callinfo[i])
+ printf("%13s %12s: %8u \n", hdr, names[i], callinfo[i]);
+ }
+ printf("\n");
+
+}
+
+
/* returns 0 on success, 1 otherwise */
static int
parse_raw_statfile(const char *name, struct statinfo *statp)
for (i = 0; i < cnt; i++) {
if (!(sp = strtok(NULL, " \t")))
break;
- ip->valptr[i] = atoi(sp);
+ ip->valptr[i] = (unsigned int) strtoul(sp, NULL, 0);
total += ip->valptr[i];
}
ip->valptr[cnt - 1] = total;
static int
parse_pretty_statfile(const char *filename, struct statinfo *info)
{
- int numvals, curindex, numconsumed, n, sum, err = 1;
+ int numvals, curindex, numconsumed, n, err = 1;
+ unsigned int sum;
char buf[4096], *bufp, *fmt, is_proc;
FILE *fp = NULL;
struct statinfo *ip;
if (!(type = strtok(NULL, " \t")))
continue;
- if (strcmp(type, "nfs")) {
+ if (strcmp(type, "nfs") && strcmp(type,"nfs4")) {
continue;
}
{
return (info[0] && info[info[0] + 1] > info[0]);
}
+static int
+has_rpcstats(const unsigned int *info, int size)
+{
+ int i, cnt;
+
+ for (i=0, cnt=0; i < size; i++)
+ cnt += info[i];
+ return cnt;
+}
/*
* take the difference of each individual stat value in 'new' and 'old'
seconds = (int)time_diff % 60;
printf("Signal received; displaying (only) statistics gathered over the last %d minutes, %d seconds:\n\n", minutes, seconds);
}
+
+static void
+update_old_counters(struct statinfo *new, struct statinfo *old)
+{
+ int z, i;
+ for (z = 0; old[z].tag; z++)
+ for (i = 0; i <= old[z].nrvals; i++)
+ old[z].valptr[i] += new[z].valptr[i];
+
+}