17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57752631cSth199096 * Common Development and Distribution License (the "License"). 67752631cSth199096 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217752631cSth199096 227c478bd9Sstevel@tonic-gate /* LINTLIBRARY */ 237c478bd9Sstevel@tonic-gate /* PROTOLIB1 */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate /* 2626fd7700SKrishnendu Sadhukhan - Sun Microsystems * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 277c478bd9Sstevel@tonic-gate * Use is subject to license terms. 28*bd93c05dSAlexander Eremin * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 297c478bd9Sstevel@tonic-gate */ 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate /* 327c478bd9Sstevel@tonic-gate * nfsstat: Network File System statistics 337c478bd9Sstevel@tonic-gate * 347c478bd9Sstevel@tonic-gate */ 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <stdio.h> 377c478bd9Sstevel@tonic-gate #include <stdlib.h> 387c478bd9Sstevel@tonic-gate #include <unistd.h> 397c478bd9Sstevel@tonic-gate #include <stdarg.h> 407c478bd9Sstevel@tonic-gate #include <string.h> 417c478bd9Sstevel@tonic-gate #include <errno.h> 427c478bd9Sstevel@tonic-gate #include <fcntl.h> 437c478bd9Sstevel@tonic-gate #include <kvm.h> 447c478bd9Sstevel@tonic-gate #include <kstat.h> 457c478bd9Sstevel@tonic-gate #include <sys/param.h> 467c478bd9Sstevel@tonic-gate #include <sys/types.h> 477c478bd9Sstevel@tonic-gate #include <sys/t_lock.h> 487c478bd9Sstevel@tonic-gate #include <sys/tiuser.h> 497c478bd9Sstevel@tonic-gate #include <sys/statvfs.h> 507c478bd9Sstevel@tonic-gate #include <sys/mntent.h> 517c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 527c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 537c478bd9Sstevel@tonic-gate #include <sys/mkdev.h> 547c478bd9Sstevel@tonic-gate #include <rpc/types.h> 557c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 567c478bd9Sstevel@tonic-gate #include <rpc/auth.h> 577c478bd9Sstevel@tonic-gate #include <rpc/clnt.h> 587c478bd9Sstevel@tonic-gate #include <nfs/nfs.h> 597c478bd9Sstevel@tonic-gate #include <nfs/nfs_clnt.h> 607c478bd9Sstevel@tonic-gate #include <nfs/nfs_sec.h> 617c478bd9Sstevel@tonic-gate #include <inttypes.h> 627c478bd9Sstevel@tonic-gate #include <signal.h> 637c478bd9Sstevel@tonic-gate #include <time.h> 647c478bd9Sstevel@tonic-gate #include <sys/time.h> 657c478bd9Sstevel@tonic-gate #include <strings.h> 667c478bd9Sstevel@tonic-gate #include <ctype.h> 6726fd7700SKrishnendu Sadhukhan - Sun Microsystems #include <locale.h> 687c478bd9Sstevel@tonic-gate 6926fd7700SKrishnendu Sadhukhan - Sun Microsystems #include "statcommon.h" 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate static kstat_ctl_t *kc = NULL; /* libkstat cookie */ 727c478bd9Sstevel@tonic-gate static kstat_t *rpc_clts_client_kstat, *rpc_clts_server_kstat; 737c478bd9Sstevel@tonic-gate static kstat_t *rpc_cots_client_kstat, *rpc_cots_server_kstat; 747c478bd9Sstevel@tonic-gate static kstat_t *rpc_rdma_client_kstat, *rpc_rdma_server_kstat; 757c478bd9Sstevel@tonic-gate static kstat_t *nfs_client_kstat, *nfs_server_v2_kstat, *nfs_server_v3_kstat; 767c478bd9Sstevel@tonic-gate static kstat_t *nfs4_client_kstat, *nfs_server_v4_kstat; 777c478bd9Sstevel@tonic-gate static kstat_t *rfsproccnt_v2_kstat, *rfsproccnt_v3_kstat, *rfsproccnt_v4_kstat; 787c478bd9Sstevel@tonic-gate static kstat_t *rfsreqcnt_v2_kstat, *rfsreqcnt_v3_kstat, *rfsreqcnt_v4_kstat; 797c478bd9Sstevel@tonic-gate static kstat_t *aclproccnt_v2_kstat, *aclproccnt_v3_kstat; 807c478bd9Sstevel@tonic-gate static kstat_t *aclreqcnt_v2_kstat, *aclreqcnt_v3_kstat; 817c478bd9Sstevel@tonic-gate static kstat_t *ksum_kstat; 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate static void handle_sig(int); 847c478bd9Sstevel@tonic-gate static int getstats_rpc(void); 857c478bd9Sstevel@tonic-gate static int getstats_nfs(void); 867c478bd9Sstevel@tonic-gate static int getstats_rfsproc(int); 877c478bd9Sstevel@tonic-gate static int getstats_rfsreq(int); 887c478bd9Sstevel@tonic-gate static int getstats_aclproc(void); 897c478bd9Sstevel@tonic-gate static int getstats_aclreq(void); 907c478bd9Sstevel@tonic-gate static void putstats(void); 917c478bd9Sstevel@tonic-gate static void setup(void); 927c478bd9Sstevel@tonic-gate static void cr_print(int); 937c478bd9Sstevel@tonic-gate static void sr_print(int); 947c478bd9Sstevel@tonic-gate static void cn_print(int, int); 957c478bd9Sstevel@tonic-gate static void sn_print(int, int); 967c478bd9Sstevel@tonic-gate static void ca_print(int, int); 977c478bd9Sstevel@tonic-gate static void sa_print(int, int); 987c478bd9Sstevel@tonic-gate static void req_print(kstat_t *, kstat_t *, int, int, int); 997c478bd9Sstevel@tonic-gate static void req_print_v4(kstat_t *, kstat_t *, int, int); 1007c478bd9Sstevel@tonic-gate static void stat_print(const char *, kstat_t *, kstat_t *, int, int); 10126fd7700SKrishnendu Sadhukhan - Sun Microsystems static void nfsstat_kstat_sum(kstat_t *, kstat_t *, kstat_t *); 1027c478bd9Sstevel@tonic-gate static void stats_timer(int); 1037c478bd9Sstevel@tonic-gate static void safe_zalloc(void **, uint_t, int); 1047c478bd9Sstevel@tonic-gate static int safe_strtoi(char const *, char *); 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate 10726fd7700SKrishnendu Sadhukhan - Sun Microsystems static void nfsstat_kstat_copy(kstat_t *, kstat_t *, int); 1087c478bd9Sstevel@tonic-gate static kid_t safe_kstat_read(kstat_ctl_t *, kstat_t *, void *); 1097c478bd9Sstevel@tonic-gate static kid_t safe_kstat_write(kstat_ctl_t *, kstat_t *, void *); 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate static void usage(void); 1127c478bd9Sstevel@tonic-gate static void mi_print(void); 1137c478bd9Sstevel@tonic-gate static int ignore(char *); 1147c478bd9Sstevel@tonic-gate static int interval; /* interval between stats */ 1157c478bd9Sstevel@tonic-gate static int count; /* number of iterations the stat is printed */ 1167c478bd9Sstevel@tonic-gate #define MAX_COLUMNS 80 1177c478bd9Sstevel@tonic-gate #define MAX_PATHS 50 /* max paths that can be taken by -m */ 1187c478bd9Sstevel@tonic-gate 119b9238976Sth199096 /* 120b9238976Sth199096 * MI4_MIRRORMOUNT is canonically defined in nfs4_clnt.h, but we cannot 1212f172c55SRobert Thurlow * include that file here. Same with MI4_REFERRAL. 122b9238976Sth199096 */ 123b9238976Sth199096 #define MI4_MIRRORMOUNT 0x4000 1242f172c55SRobert Thurlow #define MI4_REFERRAL 0x8000 125b9238976Sth199096 #define NFS_V4 4 126b9238976Sth199096 1277c478bd9Sstevel@tonic-gate static int req_width(kstat_t *, int); 1287c478bd9Sstevel@tonic-gate static int stat_width(kstat_t *, int); 1297c478bd9Sstevel@tonic-gate static char *path [MAX_PATHS] = {NULL}; /* array to store the multiple paths */ 1307c478bd9Sstevel@tonic-gate 1317c478bd9Sstevel@tonic-gate /* 1327c478bd9Sstevel@tonic-gate * Struct holds the previous kstat values so 1337c478bd9Sstevel@tonic-gate * we can compute deltas when using the -i flag 1347c478bd9Sstevel@tonic-gate */ 1357c478bd9Sstevel@tonic-gate typedef struct old_kstat 1367c478bd9Sstevel@tonic-gate { 1377c478bd9Sstevel@tonic-gate kstat_t kst; 1387c478bd9Sstevel@tonic-gate int tot; 1397c478bd9Sstevel@tonic-gate } old_kstat_t; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate static old_kstat_t old_rpc_clts_client_kstat, old_rpc_clts_server_kstat; 1427c478bd9Sstevel@tonic-gate static old_kstat_t old_rpc_cots_client_kstat, old_rpc_cots_server_kstat; 1437c478bd9Sstevel@tonic-gate static old_kstat_t old_rpc_rdma_client_kstat, old_rpc_rdma_server_kstat; 1447c478bd9Sstevel@tonic-gate static old_kstat_t old_nfs_client_kstat, old_nfs_server_v2_kstat; 1457c478bd9Sstevel@tonic-gate static old_kstat_t old_nfs_server_v3_kstat, old_ksum_kstat; 1467c478bd9Sstevel@tonic-gate static old_kstat_t old_nfs4_client_kstat, old_nfs_server_v4_kstat; 1477c478bd9Sstevel@tonic-gate static old_kstat_t old_rfsproccnt_v2_kstat, old_rfsproccnt_v3_kstat; 1487c478bd9Sstevel@tonic-gate static old_kstat_t old_rfsproccnt_v4_kstat, old_rfsreqcnt_v2_kstat; 1497c478bd9Sstevel@tonic-gate static old_kstat_t old_rfsreqcnt_v3_kstat, old_rfsreqcnt_v4_kstat; 1507c478bd9Sstevel@tonic-gate static old_kstat_t old_aclproccnt_v2_kstat, old_aclproccnt_v3_kstat; 1517c478bd9Sstevel@tonic-gate static old_kstat_t old_aclreqcnt_v2_kstat, old_aclreqcnt_v3_kstat; 1527c478bd9Sstevel@tonic-gate 15326fd7700SKrishnendu Sadhukhan - Sun Microsystems static uint_t timestamp_fmt = NODATE; 1547c478bd9Sstevel@tonic-gate 15526fd7700SKrishnendu Sadhukhan - Sun Microsystems #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 15626fd7700SKrishnendu Sadhukhan - Sun Microsystems #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't */ 15726fd7700SKrishnendu Sadhukhan - Sun Microsystems #endif 1587c478bd9Sstevel@tonic-gate 15911606941Sjwahlig int 1607c478bd9Sstevel@tonic-gate main(int argc, char *argv[]) 1617c478bd9Sstevel@tonic-gate { 1627c478bd9Sstevel@tonic-gate int c, go_forever, j; 1637c478bd9Sstevel@tonic-gate int cflag = 0; /* client stats */ 1647c478bd9Sstevel@tonic-gate int sflag = 0; /* server stats */ 1657c478bd9Sstevel@tonic-gate int nflag = 0; /* nfs stats */ 1667c478bd9Sstevel@tonic-gate int rflag = 0; /* rpc stats */ 1677c478bd9Sstevel@tonic-gate int mflag = 0; /* mount table stats */ 1687c478bd9Sstevel@tonic-gate int aflag = 0; /* print acl statistics */ 1697c478bd9Sstevel@tonic-gate int vflag = 0; /* version specified, 0 specifies all */ 1707c478bd9Sstevel@tonic-gate int zflag = 0; /* zero stats after printing */ 1717c478bd9Sstevel@tonic-gate char *split_line = "*******************************************" 1727c478bd9Sstevel@tonic-gate "*************************************"; 1737c478bd9Sstevel@tonic-gate 1747c478bd9Sstevel@tonic-gate interval = 0; 1757c478bd9Sstevel@tonic-gate count = 0; 1767c478bd9Sstevel@tonic-gate go_forever = 0; 1777c478bd9Sstevel@tonic-gate 17826fd7700SKrishnendu Sadhukhan - Sun Microsystems (void) setlocale(LC_ALL, ""); 17926fd7700SKrishnendu Sadhukhan - Sun Microsystems (void) textdomain(TEXT_DOMAIN); 18026fd7700SKrishnendu Sadhukhan - Sun Microsystems 18126fd7700SKrishnendu Sadhukhan - Sun Microsystems while ((c = getopt(argc, argv, "cnrsmzav:T:")) != EOF) { 1827c478bd9Sstevel@tonic-gate switch (c) { 1837c478bd9Sstevel@tonic-gate case 'c': 1847c478bd9Sstevel@tonic-gate cflag++; 1857c478bd9Sstevel@tonic-gate break; 1867c478bd9Sstevel@tonic-gate case 'n': 1877c478bd9Sstevel@tonic-gate nflag++; 1887c478bd9Sstevel@tonic-gate break; 1897c478bd9Sstevel@tonic-gate case 'r': 1907c478bd9Sstevel@tonic-gate rflag++; 1917c478bd9Sstevel@tonic-gate break; 1927c478bd9Sstevel@tonic-gate case 's': 1937c478bd9Sstevel@tonic-gate sflag++; 1947c478bd9Sstevel@tonic-gate break; 1957c478bd9Sstevel@tonic-gate case 'm': 1967c478bd9Sstevel@tonic-gate mflag++; 1977c478bd9Sstevel@tonic-gate break; 1987c478bd9Sstevel@tonic-gate case 'z': 1997c478bd9Sstevel@tonic-gate if (geteuid()) 2007c478bd9Sstevel@tonic-gate fail(0, "Must be root for z flag\n"); 2017c478bd9Sstevel@tonic-gate zflag++; 2027c478bd9Sstevel@tonic-gate break; 2037c478bd9Sstevel@tonic-gate case 'a': 2047c478bd9Sstevel@tonic-gate aflag++; 2057c478bd9Sstevel@tonic-gate break; 2067c478bd9Sstevel@tonic-gate case 'v': 2077c478bd9Sstevel@tonic-gate vflag = atoi(optarg); 2087c478bd9Sstevel@tonic-gate if ((vflag < 2) || (vflag > 4)) 2097c478bd9Sstevel@tonic-gate fail(0, "Invalid version number\n"); 2107c478bd9Sstevel@tonic-gate break; 21126fd7700SKrishnendu Sadhukhan - Sun Microsystems case 'T': 21226fd7700SKrishnendu Sadhukhan - Sun Microsystems if (optarg) { 21326fd7700SKrishnendu Sadhukhan - Sun Microsystems if (*optarg == 'u') 21426fd7700SKrishnendu Sadhukhan - Sun Microsystems timestamp_fmt = UDATE; 21526fd7700SKrishnendu Sadhukhan - Sun Microsystems else if (*optarg == 'd') 21626fd7700SKrishnendu Sadhukhan - Sun Microsystems timestamp_fmt = DDATE; 21726fd7700SKrishnendu Sadhukhan - Sun Microsystems else 21826fd7700SKrishnendu Sadhukhan - Sun Microsystems usage(); 21926fd7700SKrishnendu Sadhukhan - Sun Microsystems } else { 22026fd7700SKrishnendu Sadhukhan - Sun Microsystems usage(); 22126fd7700SKrishnendu Sadhukhan - Sun Microsystems } 22226fd7700SKrishnendu Sadhukhan - Sun Microsystems break; 2237c478bd9Sstevel@tonic-gate case '?': 2247c478bd9Sstevel@tonic-gate default: 2257c478bd9Sstevel@tonic-gate usage(); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate if (((argc - optind) > 0) && !mflag) { 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate interval = safe_strtoi(argv[optind], "invalid interval"); 2327c478bd9Sstevel@tonic-gate if (interval < 1) 2337c478bd9Sstevel@tonic-gate fail(0, "invalid interval\n"); 2347c478bd9Sstevel@tonic-gate optind++; 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate if ((argc - optind) > 0) { 2377c478bd9Sstevel@tonic-gate count = safe_strtoi(argv[optind], "invalid count"); 2387c478bd9Sstevel@tonic-gate if ((count <= 0) || (count == NULL)) 2397c478bd9Sstevel@tonic-gate fail(0, "invalid count\n"); 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate optind++; 2427c478bd9Sstevel@tonic-gate 2437c478bd9Sstevel@tonic-gate if ((argc - optind) > 0) 2447c478bd9Sstevel@tonic-gate usage(); 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate /* 2477c478bd9Sstevel@tonic-gate * no count number was set, so we will loop infinitely 2487c478bd9Sstevel@tonic-gate * at interval specified 2497c478bd9Sstevel@tonic-gate */ 2507c478bd9Sstevel@tonic-gate if (!count) 2517c478bd9Sstevel@tonic-gate go_forever = 1; 2527c478bd9Sstevel@tonic-gate stats_timer(interval); 2537c478bd9Sstevel@tonic-gate } else if (mflag) { 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate if (cflag || rflag || sflag || zflag || nflag || aflag || vflag) 256b9238976Sth199096 fail(0, 257b9238976Sth199096 "The -m flag may not be used with any other flags"); 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate for (j = 0; (argc - optind > 0) && (j < (MAX_PATHS - 1)); j++) { 2607c478bd9Sstevel@tonic-gate path[j] = argv[optind]; 2617c478bd9Sstevel@tonic-gate if (*path[j] != '/') 2627c478bd9Sstevel@tonic-gate fail(0, "Please fully qualify your pathname " 2637c478bd9Sstevel@tonic-gate "with a leading '/'"); 2647c478bd9Sstevel@tonic-gate optind++; 2657c478bd9Sstevel@tonic-gate } 2667c478bd9Sstevel@tonic-gate path[j] = NULL; 2677c478bd9Sstevel@tonic-gate if (argc - optind > 0) 2687c478bd9Sstevel@tonic-gate fprintf(stderr, "Only the first 50 paths " 2697c478bd9Sstevel@tonic-gate "will be searched for\n"); 2707c478bd9Sstevel@tonic-gate } 2717c478bd9Sstevel@tonic-gate 2727c478bd9Sstevel@tonic-gate setup(); 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate do { 2757c478bd9Sstevel@tonic-gate if (mflag) { 2767c478bd9Sstevel@tonic-gate mi_print(); 2777c478bd9Sstevel@tonic-gate } else { 27826fd7700SKrishnendu Sadhukhan - Sun Microsystems if (timestamp_fmt != NODATE) 27926fd7700SKrishnendu Sadhukhan - Sun Microsystems print_timestamp(timestamp_fmt); 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate if (sflag && 2827c478bd9Sstevel@tonic-gate (rpc_clts_server_kstat == NULL || 2837c478bd9Sstevel@tonic-gate nfs_server_v4_kstat == NULL)) { 2847c478bd9Sstevel@tonic-gate fprintf(stderr, 2857c478bd9Sstevel@tonic-gate "nfsstat: kernel is not configured with " 2867c478bd9Sstevel@tonic-gate "the server nfs and rpc code.\n"); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate /* if s and nothing else, all 3 prints are called */ 2907c478bd9Sstevel@tonic-gate if (sflag || (!sflag && !cflag)) { 2917c478bd9Sstevel@tonic-gate if (rflag || (!rflag && !nflag && !aflag)) 2927c478bd9Sstevel@tonic-gate sr_print(zflag); 2937c478bd9Sstevel@tonic-gate if (nflag || (!rflag && !nflag && !aflag)) 2947c478bd9Sstevel@tonic-gate sn_print(zflag, vflag); 2957c478bd9Sstevel@tonic-gate if (aflag || (!rflag && !nflag && !aflag)) 2967c478bd9Sstevel@tonic-gate sa_print(zflag, vflag); 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate if (cflag && 2997c478bd9Sstevel@tonic-gate (rpc_clts_client_kstat == NULL || 3007c478bd9Sstevel@tonic-gate nfs_client_kstat == NULL)) { 3017c478bd9Sstevel@tonic-gate fprintf(stderr, 3027c478bd9Sstevel@tonic-gate "nfsstat: kernel is not configured with" 3037c478bd9Sstevel@tonic-gate " the client nfs and rpc code.\n"); 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate if (cflag || (!sflag && !cflag)) { 3067c478bd9Sstevel@tonic-gate if (rflag || (!rflag && !nflag && !aflag)) 3077c478bd9Sstevel@tonic-gate cr_print(zflag); 3087c478bd9Sstevel@tonic-gate if (nflag || (!rflag && !nflag && !aflag)) 3097c478bd9Sstevel@tonic-gate cn_print(zflag, vflag); 3107c478bd9Sstevel@tonic-gate if (aflag || (!rflag && !nflag && !aflag)) 3117c478bd9Sstevel@tonic-gate ca_print(zflag, vflag); 3127c478bd9Sstevel@tonic-gate } 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate if (zflag) 3167c478bd9Sstevel@tonic-gate putstats(); 3177c478bd9Sstevel@tonic-gate if (interval) 3187c478bd9Sstevel@tonic-gate printf("%s\n", split_line); 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate if (interval > 0) 3217c478bd9Sstevel@tonic-gate (void) pause(); 3227c478bd9Sstevel@tonic-gate } while ((--count > 0) || go_forever); 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate kstat_close(kc); 3257c478bd9Sstevel@tonic-gate free(ksum_kstat); 3267c478bd9Sstevel@tonic-gate return (0); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate static int 3317c478bd9Sstevel@tonic-gate getstats_rpc(void) 3327c478bd9Sstevel@tonic-gate { 3337c478bd9Sstevel@tonic-gate int field_width = 0; 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate if (rpc_clts_client_kstat != NULL) { 3367c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rpc_clts_client_kstat, NULL); 3377c478bd9Sstevel@tonic-gate field_width = stat_width(rpc_clts_client_kstat, field_width); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate if (rpc_cots_client_kstat != NULL) { 3417c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rpc_cots_client_kstat, NULL); 3427c478bd9Sstevel@tonic-gate field_width = stat_width(rpc_cots_client_kstat, field_width); 3437c478bd9Sstevel@tonic-gate } 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate if (rpc_rdma_client_kstat != NULL) { 3467c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rpc_rdma_client_kstat, NULL); 3477c478bd9Sstevel@tonic-gate field_width = stat_width(rpc_rdma_client_kstat, field_width); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate if (rpc_clts_server_kstat != NULL) { 3517c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rpc_clts_server_kstat, NULL); 3527c478bd9Sstevel@tonic-gate field_width = stat_width(rpc_clts_server_kstat, field_width); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate if (rpc_cots_server_kstat != NULL) { 3557c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rpc_cots_server_kstat, NULL); 3567c478bd9Sstevel@tonic-gate field_width = stat_width(rpc_cots_server_kstat, field_width); 3577c478bd9Sstevel@tonic-gate } 3587c478bd9Sstevel@tonic-gate if (rpc_rdma_server_kstat != NULL) { 3597c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rpc_rdma_server_kstat, NULL); 3607c478bd9Sstevel@tonic-gate field_width = stat_width(rpc_rdma_server_kstat, field_width); 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate return (field_width); 3637c478bd9Sstevel@tonic-gate } 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate static int 3667c478bd9Sstevel@tonic-gate getstats_nfs(void) 3677c478bd9Sstevel@tonic-gate { 3687c478bd9Sstevel@tonic-gate int field_width = 0; 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate if (nfs_client_kstat != NULL) { 3717c478bd9Sstevel@tonic-gate safe_kstat_read(kc, nfs_client_kstat, NULL); 3727c478bd9Sstevel@tonic-gate field_width = stat_width(nfs_client_kstat, field_width); 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate if (nfs4_client_kstat != NULL) { 3757c478bd9Sstevel@tonic-gate safe_kstat_read(kc, nfs4_client_kstat, NULL); 3767c478bd9Sstevel@tonic-gate field_width = stat_width(nfs4_client_kstat, field_width); 3777c478bd9Sstevel@tonic-gate } 3787c478bd9Sstevel@tonic-gate if (nfs_server_v2_kstat != NULL) { 3797c478bd9Sstevel@tonic-gate safe_kstat_read(kc, nfs_server_v2_kstat, NULL); 3807c478bd9Sstevel@tonic-gate field_width = stat_width(nfs_server_v2_kstat, field_width); 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate if (nfs_server_v3_kstat != NULL) { 3837c478bd9Sstevel@tonic-gate safe_kstat_read(kc, nfs_server_v3_kstat, NULL); 3847c478bd9Sstevel@tonic-gate field_width = stat_width(nfs_server_v3_kstat, field_width); 3857c478bd9Sstevel@tonic-gate } 3867c478bd9Sstevel@tonic-gate if (nfs_server_v4_kstat != NULL) { 3877c478bd9Sstevel@tonic-gate safe_kstat_read(kc, nfs_server_v4_kstat, NULL); 3887c478bd9Sstevel@tonic-gate field_width = stat_width(nfs_server_v4_kstat, field_width); 3897c478bd9Sstevel@tonic-gate } 3907c478bd9Sstevel@tonic-gate return (field_width); 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate static int 3947c478bd9Sstevel@tonic-gate getstats_rfsproc(int ver) 3957c478bd9Sstevel@tonic-gate { 3967c478bd9Sstevel@tonic-gate int field_width = 0; 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate if ((ver == 2) && (rfsproccnt_v2_kstat != NULL)) { 3997c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rfsproccnt_v2_kstat, NULL); 4007c478bd9Sstevel@tonic-gate field_width = req_width(rfsproccnt_v2_kstat, field_width); 4017c478bd9Sstevel@tonic-gate } 4027c478bd9Sstevel@tonic-gate if ((ver == 3) && (rfsproccnt_v3_kstat != NULL)) { 4037c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rfsproccnt_v3_kstat, NULL); 4047c478bd9Sstevel@tonic-gate field_width = req_width(rfsproccnt_v3_kstat, field_width); 4057c478bd9Sstevel@tonic-gate } 4067c478bd9Sstevel@tonic-gate if ((ver == 4) && (rfsproccnt_v4_kstat != NULL)) { 4077c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rfsproccnt_v4_kstat, NULL); 4087c478bd9Sstevel@tonic-gate field_width = req_width(rfsproccnt_v4_kstat, field_width); 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate return (field_width); 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate static int 4147c478bd9Sstevel@tonic-gate getstats_rfsreq(int ver) 4157c478bd9Sstevel@tonic-gate { 4167c478bd9Sstevel@tonic-gate int field_width = 0; 4177c478bd9Sstevel@tonic-gate if ((ver == 2) && (rfsreqcnt_v2_kstat != NULL)) { 4187c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rfsreqcnt_v2_kstat, NULL); 4197c478bd9Sstevel@tonic-gate field_width = req_width(rfsreqcnt_v2_kstat, field_width); 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate if ((ver == 3) && (rfsreqcnt_v3_kstat != NULL)) { 4227c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rfsreqcnt_v3_kstat, NULL); 4237c478bd9Sstevel@tonic-gate field_width = req_width(rfsreqcnt_v3_kstat, field_width); 4247c478bd9Sstevel@tonic-gate } 4257c478bd9Sstevel@tonic-gate if ((ver == 4) && (rfsreqcnt_v4_kstat != NULL)) { 4267c478bd9Sstevel@tonic-gate safe_kstat_read(kc, rfsreqcnt_v4_kstat, NULL); 4277c478bd9Sstevel@tonic-gate field_width = req_width(rfsreqcnt_v4_kstat, field_width); 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate return (field_width); 4307c478bd9Sstevel@tonic-gate } 4317c478bd9Sstevel@tonic-gate 4327c478bd9Sstevel@tonic-gate static int 4337c478bd9Sstevel@tonic-gate getstats_aclproc(void) 4347c478bd9Sstevel@tonic-gate { 4357c478bd9Sstevel@tonic-gate int field_width = 0; 4367c478bd9Sstevel@tonic-gate if (aclproccnt_v2_kstat != NULL) { 4377c478bd9Sstevel@tonic-gate safe_kstat_read(kc, aclproccnt_v2_kstat, NULL); 4387c478bd9Sstevel@tonic-gate field_width = req_width(aclproccnt_v2_kstat, field_width); 4397c478bd9Sstevel@tonic-gate } 4407c478bd9Sstevel@tonic-gate if (aclproccnt_v3_kstat != NULL) { 4417c478bd9Sstevel@tonic-gate safe_kstat_read(kc, aclproccnt_v3_kstat, NULL); 4427c478bd9Sstevel@tonic-gate field_width = req_width(aclproccnt_v3_kstat, field_width); 4437c478bd9Sstevel@tonic-gate } 4447c478bd9Sstevel@tonic-gate return (field_width); 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate 4477c478bd9Sstevel@tonic-gate static int 4487c478bd9Sstevel@tonic-gate getstats_aclreq(void) 4497c478bd9Sstevel@tonic-gate { 4507c478bd9Sstevel@tonic-gate int field_width = 0; 4517c478bd9Sstevel@tonic-gate if (aclreqcnt_v2_kstat != NULL) { 4527c478bd9Sstevel@tonic-gate safe_kstat_read(kc, aclreqcnt_v2_kstat, NULL); 4537c478bd9Sstevel@tonic-gate field_width = req_width(aclreqcnt_v2_kstat, field_width); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate if (aclreqcnt_v3_kstat != NULL) { 4567c478bd9Sstevel@tonic-gate safe_kstat_read(kc, aclreqcnt_v3_kstat, NULL); 4577c478bd9Sstevel@tonic-gate field_width = req_width(aclreqcnt_v3_kstat, field_width); 4587c478bd9Sstevel@tonic-gate } 4597c478bd9Sstevel@tonic-gate return (field_width); 4607c478bd9Sstevel@tonic-gate } 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate static void 4637c478bd9Sstevel@tonic-gate putstats(void) 4647c478bd9Sstevel@tonic-gate { 4657c478bd9Sstevel@tonic-gate if (rpc_clts_client_kstat != NULL) 4667c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rpc_clts_client_kstat, NULL); 4677c478bd9Sstevel@tonic-gate if (rpc_cots_client_kstat != NULL) 4687c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rpc_cots_client_kstat, NULL); 4697c478bd9Sstevel@tonic-gate if (rpc_rdma_client_kstat != NULL) 4707c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rpc_rdma_client_kstat, NULL); 4717c478bd9Sstevel@tonic-gate if (nfs_client_kstat != NULL) 4727c478bd9Sstevel@tonic-gate safe_kstat_write(kc, nfs_client_kstat, NULL); 4737c478bd9Sstevel@tonic-gate if (nfs4_client_kstat != NULL) 4747c478bd9Sstevel@tonic-gate safe_kstat_write(kc, nfs4_client_kstat, NULL); 4757c478bd9Sstevel@tonic-gate if (rpc_clts_server_kstat != NULL) 4767c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rpc_clts_server_kstat, NULL); 4777c478bd9Sstevel@tonic-gate if (rpc_cots_server_kstat != NULL) 4787c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rpc_cots_server_kstat, NULL); 4797c478bd9Sstevel@tonic-gate if (rpc_rdma_server_kstat != NULL) 4807c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rpc_rdma_server_kstat, NULL); 4817c478bd9Sstevel@tonic-gate if (nfs_server_v2_kstat != NULL) 4827c478bd9Sstevel@tonic-gate safe_kstat_write(kc, nfs_server_v2_kstat, NULL); 4837c478bd9Sstevel@tonic-gate if (nfs_server_v3_kstat != NULL) 4847c478bd9Sstevel@tonic-gate safe_kstat_write(kc, nfs_server_v3_kstat, NULL); 4857c478bd9Sstevel@tonic-gate if (nfs_server_v4_kstat != NULL) 4867c478bd9Sstevel@tonic-gate safe_kstat_write(kc, nfs_server_v4_kstat, NULL); 4877c478bd9Sstevel@tonic-gate if (rfsproccnt_v2_kstat != NULL) 4887c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rfsproccnt_v2_kstat, NULL); 4897c478bd9Sstevel@tonic-gate if (rfsproccnt_v3_kstat != NULL) 4907c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rfsproccnt_v3_kstat, NULL); 4917c478bd9Sstevel@tonic-gate if (rfsproccnt_v4_kstat != NULL) 4927c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rfsproccnt_v4_kstat, NULL); 4937c478bd9Sstevel@tonic-gate if (rfsreqcnt_v2_kstat != NULL) 4947c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rfsreqcnt_v2_kstat, NULL); 4957c478bd9Sstevel@tonic-gate if (rfsreqcnt_v3_kstat != NULL) 4967c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rfsreqcnt_v3_kstat, NULL); 4977c478bd9Sstevel@tonic-gate if (rfsreqcnt_v4_kstat != NULL) 4987c478bd9Sstevel@tonic-gate safe_kstat_write(kc, rfsreqcnt_v4_kstat, NULL); 4997c478bd9Sstevel@tonic-gate if (aclproccnt_v2_kstat != NULL) 5007c478bd9Sstevel@tonic-gate safe_kstat_write(kc, aclproccnt_v2_kstat, NULL); 5017c478bd9Sstevel@tonic-gate if (aclproccnt_v3_kstat != NULL) 5027c478bd9Sstevel@tonic-gate safe_kstat_write(kc, aclproccnt_v3_kstat, NULL); 5037c478bd9Sstevel@tonic-gate if (aclreqcnt_v2_kstat != NULL) 5047c478bd9Sstevel@tonic-gate safe_kstat_write(kc, aclreqcnt_v2_kstat, NULL); 5057c478bd9Sstevel@tonic-gate if (aclreqcnt_v3_kstat != NULL) 5067c478bd9Sstevel@tonic-gate safe_kstat_write(kc, aclreqcnt_v3_kstat, NULL); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate static void 5107c478bd9Sstevel@tonic-gate setup(void) 5117c478bd9Sstevel@tonic-gate { 5127c478bd9Sstevel@tonic-gate if ((kc = kstat_open()) == NULL) 5137c478bd9Sstevel@tonic-gate fail(1, "kstat_open(): can't open /dev/kstat"); 5147c478bd9Sstevel@tonic-gate 51538f92303SMarcel Telka /* alloc space for our temporary kstat */ 51638f92303SMarcel Telka safe_zalloc((void **)&ksum_kstat, sizeof (kstat_t), 0); 5177c478bd9Sstevel@tonic-gate rpc_clts_client_kstat = kstat_lookup(kc, "unix", 0, "rpc_clts_client"); 5187c478bd9Sstevel@tonic-gate rpc_clts_server_kstat = kstat_lookup(kc, "unix", 0, "rpc_clts_server"); 5197c478bd9Sstevel@tonic-gate rpc_cots_client_kstat = kstat_lookup(kc, "unix", 0, "rpc_cots_client"); 5207c478bd9Sstevel@tonic-gate rpc_cots_server_kstat = kstat_lookup(kc, "unix", 0, "rpc_cots_server"); 5217c478bd9Sstevel@tonic-gate rpc_rdma_client_kstat = kstat_lookup(kc, "unix", 0, "rpc_rdma_client"); 5227c478bd9Sstevel@tonic-gate rpc_rdma_server_kstat = kstat_lookup(kc, "unix", 0, "rpc_rdma_server"); 5237c478bd9Sstevel@tonic-gate nfs_client_kstat = kstat_lookup(kc, "nfs", 0, "nfs_client"); 5247c478bd9Sstevel@tonic-gate nfs4_client_kstat = kstat_lookup(kc, "nfs", 0, "nfs4_client"); 5257c478bd9Sstevel@tonic-gate nfs_server_v2_kstat = kstat_lookup(kc, "nfs", 2, "nfs_server"); 5267c478bd9Sstevel@tonic-gate nfs_server_v3_kstat = kstat_lookup(kc, "nfs", 3, "nfs_server"); 5277c478bd9Sstevel@tonic-gate nfs_server_v4_kstat = kstat_lookup(kc, "nfs", 4, "nfs_server"); 5287c478bd9Sstevel@tonic-gate rfsproccnt_v2_kstat = kstat_lookup(kc, "nfs", 0, "rfsproccnt_v2"); 5297c478bd9Sstevel@tonic-gate rfsproccnt_v3_kstat = kstat_lookup(kc, "nfs", 0, "rfsproccnt_v3"); 5307c478bd9Sstevel@tonic-gate rfsproccnt_v4_kstat = kstat_lookup(kc, "nfs", 0, "rfsproccnt_v4"); 5317c478bd9Sstevel@tonic-gate rfsreqcnt_v2_kstat = kstat_lookup(kc, "nfs", 0, "rfsreqcnt_v2"); 5327c478bd9Sstevel@tonic-gate rfsreqcnt_v3_kstat = kstat_lookup(kc, "nfs", 0, "rfsreqcnt_v3"); 5337c478bd9Sstevel@tonic-gate rfsreqcnt_v4_kstat = kstat_lookup(kc, "nfs", 0, "rfsreqcnt_v4"); 5347c478bd9Sstevel@tonic-gate aclproccnt_v2_kstat = kstat_lookup(kc, "nfs_acl", 0, "aclproccnt_v2"); 5357c478bd9Sstevel@tonic-gate aclproccnt_v3_kstat = kstat_lookup(kc, "nfs_acl", 0, "aclproccnt_v3"); 5367c478bd9Sstevel@tonic-gate aclreqcnt_v2_kstat = kstat_lookup(kc, "nfs_acl", 0, "aclreqcnt_v2"); 5377c478bd9Sstevel@tonic-gate aclreqcnt_v3_kstat = kstat_lookup(kc, "nfs_acl", 0, "aclreqcnt_v3"); 5387c478bd9Sstevel@tonic-gate if (rpc_clts_client_kstat == NULL && rpc_cots_server_kstat == NULL && 5397c478bd9Sstevel@tonic-gate rfsproccnt_v2_kstat == NULL && rfsreqcnt_v3_kstat == NULL) 5407c478bd9Sstevel@tonic-gate fail(0, "Multiple kstat lookups failed." 5417752631cSth199096 "Your kernel module may not be loaded\n"); 5427c478bd9Sstevel@tonic-gate } 5437c478bd9Sstevel@tonic-gate 5447c478bd9Sstevel@tonic-gate static int 5457c478bd9Sstevel@tonic-gate req_width(kstat_t *req, int field_width) 5467c478bd9Sstevel@tonic-gate { 5477c478bd9Sstevel@tonic-gate int i, nreq, per, len; 5487c478bd9Sstevel@tonic-gate char fixlen[128]; 5497c478bd9Sstevel@tonic-gate kstat_named_t *knp; 5507c478bd9Sstevel@tonic-gate uint64_t tot; 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate tot = 0; 5537c478bd9Sstevel@tonic-gate knp = KSTAT_NAMED_PTR(req); 5547c478bd9Sstevel@tonic-gate for (i = 0; i < req->ks_ndata; i++) 5557c478bd9Sstevel@tonic-gate tot += knp[i].value.ui64; 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate knp = kstat_data_lookup(req, "null"); 5587c478bd9Sstevel@tonic-gate nreq = req->ks_ndata - (knp - KSTAT_NAMED_PTR(req)); 5597c478bd9Sstevel@tonic-gate 5607c478bd9Sstevel@tonic-gate for (i = 0; i < nreq; i++) { 5617c478bd9Sstevel@tonic-gate len = strlen(knp[i].name) + 1; 5627c478bd9Sstevel@tonic-gate if (field_width < len) 5637c478bd9Sstevel@tonic-gate field_width = len; 5647c478bd9Sstevel@tonic-gate if (tot) 5657c478bd9Sstevel@tonic-gate per = (int)(knp[i].value.ui64 * 100 / tot); 5667c478bd9Sstevel@tonic-gate else 5677c478bd9Sstevel@tonic-gate per = 0; 5687c478bd9Sstevel@tonic-gate (void) sprintf(fixlen, "%" PRIu64 " %d%%", 5697c478bd9Sstevel@tonic-gate knp[i].value.ui64, per); 5707c478bd9Sstevel@tonic-gate len = strlen(fixlen) + 1; 5717c478bd9Sstevel@tonic-gate if (field_width < len) 5727c478bd9Sstevel@tonic-gate field_width = len; 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate return (field_width); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate static int 5787c478bd9Sstevel@tonic-gate stat_width(kstat_t *req, int field_width) 5797c478bd9Sstevel@tonic-gate { 5807c478bd9Sstevel@tonic-gate int i, nreq, len; 5817c478bd9Sstevel@tonic-gate char fixlen[128]; 5827c478bd9Sstevel@tonic-gate kstat_named_t *knp; 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate knp = KSTAT_NAMED_PTR(req); 5857c478bd9Sstevel@tonic-gate nreq = req->ks_ndata; 5867c478bd9Sstevel@tonic-gate 5877c478bd9Sstevel@tonic-gate for (i = 0; i < nreq; i++) { 5887c478bd9Sstevel@tonic-gate len = strlen(knp[i].name) + 1; 5897c478bd9Sstevel@tonic-gate if (field_width < len) 5907c478bd9Sstevel@tonic-gate field_width = len; 5917c478bd9Sstevel@tonic-gate (void) sprintf(fixlen, "%" PRIu64, knp[i].value.ui64); 5927c478bd9Sstevel@tonic-gate len = strlen(fixlen) + 1; 5937c478bd9Sstevel@tonic-gate if (field_width < len) 5947c478bd9Sstevel@tonic-gate field_width = len; 5957c478bd9Sstevel@tonic-gate } 5967c478bd9Sstevel@tonic-gate return (field_width); 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate 5997c478bd9Sstevel@tonic-gate static void 6007c478bd9Sstevel@tonic-gate cr_print(int zflag) 6017c478bd9Sstevel@tonic-gate { 6027c478bd9Sstevel@tonic-gate int field_width; 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate field_width = getstats_rpc(); 6057752631cSth199096 if (field_width == 0) 6067752631cSth199096 return; 6077752631cSth199096 6087c478bd9Sstevel@tonic-gate stat_print("\nClient rpc:\nConnection oriented:", 6097c478bd9Sstevel@tonic-gate rpc_cots_client_kstat, 610b9238976Sth199096 &old_rpc_cots_client_kstat.kst, field_width, zflag); 6117c478bd9Sstevel@tonic-gate stat_print("Connectionless:", rpc_clts_client_kstat, 612b9238976Sth199096 &old_rpc_clts_client_kstat.kst, field_width, zflag); 6137c478bd9Sstevel@tonic-gate stat_print("RDMA based:", rpc_rdma_client_kstat, 614b9238976Sth199096 &old_rpc_rdma_client_kstat.kst, field_width, zflag); 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate 6177c478bd9Sstevel@tonic-gate static void 6187c478bd9Sstevel@tonic-gate sr_print(int zflag) 6197c478bd9Sstevel@tonic-gate { 6207c478bd9Sstevel@tonic-gate int field_width; 6217c478bd9Sstevel@tonic-gate 6227c478bd9Sstevel@tonic-gate field_width = getstats_rpc(); 6237752631cSth199096 if (field_width == 0) 6247752631cSth199096 return; 6257752631cSth199096 6267c478bd9Sstevel@tonic-gate stat_print("\nServer rpc:\nConnection oriented:", rpc_cots_server_kstat, 627b9238976Sth199096 &old_rpc_cots_server_kstat.kst, field_width, zflag); 6287c478bd9Sstevel@tonic-gate stat_print("Connectionless:", rpc_clts_server_kstat, 629b9238976Sth199096 &old_rpc_clts_server_kstat.kst, field_width, zflag); 6307c478bd9Sstevel@tonic-gate stat_print("RDMA based:", rpc_rdma_server_kstat, 631b9238976Sth199096 &old_rpc_rdma_server_kstat.kst, field_width, zflag); 6327c478bd9Sstevel@tonic-gate } 6337c478bd9Sstevel@tonic-gate 6347c478bd9Sstevel@tonic-gate static void 6357c478bd9Sstevel@tonic-gate cn_print(int zflag, int vflag) 6367c478bd9Sstevel@tonic-gate { 6377c478bd9Sstevel@tonic-gate int field_width; 6387c478bd9Sstevel@tonic-gate 6397c478bd9Sstevel@tonic-gate field_width = getstats_nfs(); 6407752631cSth199096 if (field_width == 0) 6417752631cSth199096 return; 6427c478bd9Sstevel@tonic-gate 6437c478bd9Sstevel@tonic-gate if (vflag == 0) { 64426fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_sum(nfs_client_kstat, nfs4_client_kstat, 64526fd7700SKrishnendu Sadhukhan - Sun Microsystems ksum_kstat); 6467c478bd9Sstevel@tonic-gate stat_print("\nClient nfs:", ksum_kstat, &old_ksum_kstat.kst, 6477c478bd9Sstevel@tonic-gate field_width, zflag); 6487c478bd9Sstevel@tonic-gate } 6497c478bd9Sstevel@tonic-gate 6507c478bd9Sstevel@tonic-gate if (vflag == 2 || vflag == 3) { 6517c478bd9Sstevel@tonic-gate stat_print("\nClient nfs:", nfs_client_kstat, 652b9238976Sth199096 &old_nfs_client_kstat.kst, field_width, zflag); 6537c478bd9Sstevel@tonic-gate } 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate if (vflag == 4) { 6567c478bd9Sstevel@tonic-gate stat_print("\nClient nfs:", nfs4_client_kstat, 657b9238976Sth199096 &old_nfs4_client_kstat.kst, field_width, zflag); 6587c478bd9Sstevel@tonic-gate } 6597c478bd9Sstevel@tonic-gate 6607c478bd9Sstevel@tonic-gate if (vflag == 2 || vflag == 0) { 6617c478bd9Sstevel@tonic-gate field_width = getstats_rfsreq(2); 6627c478bd9Sstevel@tonic-gate req_print(rfsreqcnt_v2_kstat, &old_rfsreqcnt_v2_kstat.kst, 6637c478bd9Sstevel@tonic-gate 2, field_width, zflag); 6647c478bd9Sstevel@tonic-gate } 6657c478bd9Sstevel@tonic-gate 6667c478bd9Sstevel@tonic-gate if (vflag == 3 || vflag == 0) { 6677c478bd9Sstevel@tonic-gate field_width = getstats_rfsreq(3); 6687c478bd9Sstevel@tonic-gate req_print(rfsreqcnt_v3_kstat, &old_rfsreqcnt_v3_kstat.kst, 3, 6697c478bd9Sstevel@tonic-gate field_width, zflag); 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate 6727c478bd9Sstevel@tonic-gate if (vflag == 4 || vflag == 0) { 6737c478bd9Sstevel@tonic-gate field_width = getstats_rfsreq(4); 6747c478bd9Sstevel@tonic-gate req_print_v4(rfsreqcnt_v4_kstat, &old_rfsreqcnt_v4_kstat.kst, 6757c478bd9Sstevel@tonic-gate field_width, zflag); 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate 6797c478bd9Sstevel@tonic-gate static void 6807c478bd9Sstevel@tonic-gate sn_print(int zflag, int vflag) 6817c478bd9Sstevel@tonic-gate { 6827c478bd9Sstevel@tonic-gate int field_width; 6837c478bd9Sstevel@tonic-gate 6847c478bd9Sstevel@tonic-gate field_width = getstats_nfs(); 6857752631cSth199096 if (field_width == 0) 6867752631cSth199096 return; 6877752631cSth199096 6887c478bd9Sstevel@tonic-gate if (vflag == 2 || vflag == 0) { 6897c478bd9Sstevel@tonic-gate stat_print("\nServer NFSv2:", nfs_server_v2_kstat, 690b9238976Sth199096 &old_nfs_server_v2_kstat.kst, field_width, zflag); 6917c478bd9Sstevel@tonic-gate } 6927c478bd9Sstevel@tonic-gate 6937c478bd9Sstevel@tonic-gate if (vflag == 3 || vflag == 0) { 6947c478bd9Sstevel@tonic-gate stat_print("\nServer NFSv3:", nfs_server_v3_kstat, 695b9238976Sth199096 &old_nfs_server_v3_kstat.kst, field_width, zflag); 6967c478bd9Sstevel@tonic-gate } 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate if (vflag == 4 || vflag == 0) { 6997c478bd9Sstevel@tonic-gate stat_print("\nServer NFSv4:", nfs_server_v4_kstat, 700b9238976Sth199096 &old_nfs_server_v4_kstat.kst, field_width, zflag); 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate 7037c478bd9Sstevel@tonic-gate if (vflag == 2 || vflag == 0) { 7047c478bd9Sstevel@tonic-gate field_width = getstats_rfsproc(2); 7057c478bd9Sstevel@tonic-gate req_print(rfsproccnt_v2_kstat, &old_rfsproccnt_v2_kstat.kst, 7067c478bd9Sstevel@tonic-gate 2, field_width, zflag); 7077c478bd9Sstevel@tonic-gate } 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate if (vflag == 3 || vflag == 0) { 7107c478bd9Sstevel@tonic-gate field_width = getstats_rfsproc(3); 7117c478bd9Sstevel@tonic-gate req_print(rfsproccnt_v3_kstat, &old_rfsproccnt_v3_kstat.kst, 7127c478bd9Sstevel@tonic-gate 3, field_width, zflag); 7137c478bd9Sstevel@tonic-gate } 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate if (vflag == 4 || vflag == 0) { 7167c478bd9Sstevel@tonic-gate field_width = getstats_rfsproc(4); 7177c478bd9Sstevel@tonic-gate req_print_v4(rfsproccnt_v4_kstat, &old_rfsproccnt_v4_kstat.kst, 7187c478bd9Sstevel@tonic-gate field_width, zflag); 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate } 7217c478bd9Sstevel@tonic-gate 7227c478bd9Sstevel@tonic-gate static void 7237c478bd9Sstevel@tonic-gate ca_print(int zflag, int vflag) 7247c478bd9Sstevel@tonic-gate { 7257c478bd9Sstevel@tonic-gate int field_width; 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate field_width = getstats_aclreq(); 7287752631cSth199096 if (field_width == 0) 7297752631cSth199096 return; 7307752631cSth199096 7317c478bd9Sstevel@tonic-gate printf("\nClient nfs_acl:\n"); 7327c478bd9Sstevel@tonic-gate 7337c478bd9Sstevel@tonic-gate if (vflag == 2 || vflag == 0) { 7347c478bd9Sstevel@tonic-gate req_print(aclreqcnt_v2_kstat, &old_aclreqcnt_v2_kstat.kst, 2, 7357c478bd9Sstevel@tonic-gate field_width, zflag); 7367c478bd9Sstevel@tonic-gate } 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate if (vflag == 3 || vflag == 0) { 7397c478bd9Sstevel@tonic-gate req_print(aclreqcnt_v3_kstat, &old_aclreqcnt_v3_kstat.kst, 7407c478bd9Sstevel@tonic-gate 3, field_width, zflag); 7417c478bd9Sstevel@tonic-gate } 7427c478bd9Sstevel@tonic-gate } 7437c478bd9Sstevel@tonic-gate 7447c478bd9Sstevel@tonic-gate static void 7457c478bd9Sstevel@tonic-gate sa_print(int zflag, int vflag) 7467c478bd9Sstevel@tonic-gate { 7477c478bd9Sstevel@tonic-gate int field_width; 7487c478bd9Sstevel@tonic-gate 7497c478bd9Sstevel@tonic-gate field_width = getstats_aclproc(); 7507752631cSth199096 if (field_width == 0) 7517752631cSth199096 return; 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate printf("\nServer nfs_acl:\n"); 7547c478bd9Sstevel@tonic-gate 7557c478bd9Sstevel@tonic-gate if (vflag == 2 || vflag == 0) { 7567c478bd9Sstevel@tonic-gate req_print(aclproccnt_v2_kstat, &old_aclproccnt_v2_kstat.kst, 7577c478bd9Sstevel@tonic-gate 2, field_width, zflag); 7587c478bd9Sstevel@tonic-gate } 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate if (vflag == 3 || vflag == 0) { 7617c478bd9Sstevel@tonic-gate req_print(aclproccnt_v3_kstat, &old_aclproccnt_v3_kstat.kst, 7627c478bd9Sstevel@tonic-gate 3, field_width, zflag); 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate } 7657c478bd9Sstevel@tonic-gate 7667c478bd9Sstevel@tonic-gate #define MIN(a, b) ((a) < (b) ? (a) : (b)) 7677c478bd9Sstevel@tonic-gate 7687c478bd9Sstevel@tonic-gate static void 7697c478bd9Sstevel@tonic-gate req_print(kstat_t *req, kstat_t *req_old, int ver, int field_width, 7707c478bd9Sstevel@tonic-gate int zflag) 7717c478bd9Sstevel@tonic-gate { 7727c478bd9Sstevel@tonic-gate int i, j, nreq, per, ncolumns; 7737c478bd9Sstevel@tonic-gate uint64_t tot, old_tot; 7747c478bd9Sstevel@tonic-gate char fixlen[128]; 7757c478bd9Sstevel@tonic-gate kstat_named_t *knp; 7767c478bd9Sstevel@tonic-gate kstat_named_t *kptr; 7777c478bd9Sstevel@tonic-gate kstat_named_t *knp_old; 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate if (req == NULL) 7807c478bd9Sstevel@tonic-gate return; 7817c478bd9Sstevel@tonic-gate 7827752631cSth199096 if (field_width == 0) 7837752631cSth199096 return; 7847752631cSth199096 7857c478bd9Sstevel@tonic-gate ncolumns = (MAX_COLUMNS -1)/field_width; 7867c478bd9Sstevel@tonic-gate knp = kstat_data_lookup(req, "null"); 7877c478bd9Sstevel@tonic-gate knp_old = KSTAT_NAMED_PTR(req_old); 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate kptr = KSTAT_NAMED_PTR(req); 7907c478bd9Sstevel@tonic-gate nreq = req->ks_ndata - (knp - KSTAT_NAMED_PTR(req)); 7917c478bd9Sstevel@tonic-gate 7927c478bd9Sstevel@tonic-gate tot = 0; 7937c478bd9Sstevel@tonic-gate old_tot = 0; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate if (knp_old == NULL) { 7967c478bd9Sstevel@tonic-gate old_tot = 0; 7977c478bd9Sstevel@tonic-gate } 7987c478bd9Sstevel@tonic-gate 7997c478bd9Sstevel@tonic-gate for (i = 0; i < req->ks_ndata; i++) 8007c478bd9Sstevel@tonic-gate tot += kptr[i].value.ui64; 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate if (interval && knp_old != NULL) { 8037c478bd9Sstevel@tonic-gate for (i = 0; i < req_old->ks_ndata; i++) 8047c478bd9Sstevel@tonic-gate old_tot += knp_old[i].value.ui64; 8057c478bd9Sstevel@tonic-gate tot -= old_tot; 8067c478bd9Sstevel@tonic-gate } 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate printf("Version %d: (%" PRIu64 " calls)\n", ver, tot); 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate for (i = 0; i < nreq; i += ncolumns) { 8117c478bd9Sstevel@tonic-gate for (j = i; j < MIN(i + ncolumns, nreq); j++) { 8127c478bd9Sstevel@tonic-gate printf("%-*s", field_width, knp[j].name); 8137c478bd9Sstevel@tonic-gate } 8147c478bd9Sstevel@tonic-gate printf("\n"); 8157c478bd9Sstevel@tonic-gate for (j = i; j < MIN(i + ncolumns, nreq); j++) { 8167c478bd9Sstevel@tonic-gate if (tot && interval && knp_old != NULL) 8177c478bd9Sstevel@tonic-gate per = (int)((knp[j].value.ui64 - 8187c478bd9Sstevel@tonic-gate knp_old[j].value.ui64) * 100 / tot); 8197c478bd9Sstevel@tonic-gate else if (tot) 8207c478bd9Sstevel@tonic-gate per = (int)(knp[j].value.ui64 * 100 / tot); 8217c478bd9Sstevel@tonic-gate else 8227c478bd9Sstevel@tonic-gate per = 0; 8237c478bd9Sstevel@tonic-gate (void) sprintf(fixlen, "%" PRIu64 " %d%% ", 8247c478bd9Sstevel@tonic-gate ((interval && knp_old != NULL) ? 8257c478bd9Sstevel@tonic-gate (knp[j].value.ui64 - knp_old[j].value.ui64) 8267c478bd9Sstevel@tonic-gate : knp[j].value.ui64), per); 8277c478bd9Sstevel@tonic-gate printf("%-*s", field_width, fixlen); 8287c478bd9Sstevel@tonic-gate } 829d006063eSgt29601 printf("\n"); 830d006063eSgt29601 } 8317c478bd9Sstevel@tonic-gate if (zflag) { 8327c478bd9Sstevel@tonic-gate for (i = 0; i < req->ks_ndata; i++) 8337c478bd9Sstevel@tonic-gate knp[i].value.ui64 = 0; 8347c478bd9Sstevel@tonic-gate } 8357c478bd9Sstevel@tonic-gate if (knp_old != NULL) 83626fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_copy(req, req_old, 1); 8377c478bd9Sstevel@tonic-gate else 83826fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_copy(req, req_old, 0); 8397c478bd9Sstevel@tonic-gate } 8407c478bd9Sstevel@tonic-gate 8417c478bd9Sstevel@tonic-gate /* 8427c478bd9Sstevel@tonic-gate * Separate version of the req_print() to deal with V4 and its use of 8437c478bd9Sstevel@tonic-gate * procedures and operations. It looks odd to have the counts for 8447c478bd9Sstevel@tonic-gate * both of those lumped into the same set of statistics so this 8457c478bd9Sstevel@tonic-gate * function (copy of req_print() does the separation and titles). 8467c478bd9Sstevel@tonic-gate */ 8477c478bd9Sstevel@tonic-gate 8487c478bd9Sstevel@tonic-gate #define COUNT 2 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate static void 8517c478bd9Sstevel@tonic-gate req_print_v4(kstat_t *req, kstat_t *req_old, int field_width, int zflag) 8527c478bd9Sstevel@tonic-gate { 8537c478bd9Sstevel@tonic-gate int i, j, nreq, per, ncolumns; 8547c478bd9Sstevel@tonic-gate uint64_t tot, tot_ops, old_tot, old_tot_ops; 8557c478bd9Sstevel@tonic-gate char fixlen[128]; 8567c478bd9Sstevel@tonic-gate kstat_named_t *kptr; 8577c478bd9Sstevel@tonic-gate kstat_named_t *knp; 8587c478bd9Sstevel@tonic-gate kstat_named_t *kptr_old; 8597c478bd9Sstevel@tonic-gate 8607c478bd9Sstevel@tonic-gate if (req == NULL) 8617c478bd9Sstevel@tonic-gate return; 8627c478bd9Sstevel@tonic-gate 8637752631cSth199096 if (field_width == 0) 8647752631cSth199096 return; 8657752631cSth199096 8667c478bd9Sstevel@tonic-gate ncolumns = (MAX_COLUMNS)/field_width; 8677c478bd9Sstevel@tonic-gate kptr = KSTAT_NAMED_PTR(req); 8687c478bd9Sstevel@tonic-gate kptr_old = KSTAT_NAMED_PTR(req_old); 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate if (kptr_old == NULL) { 8717c478bd9Sstevel@tonic-gate old_tot_ops = 0; 8727c478bd9Sstevel@tonic-gate old_tot = 0; 8737c478bd9Sstevel@tonic-gate } else { 8747c478bd9Sstevel@tonic-gate old_tot = kptr_old[0].value.ui64 + kptr_old[1].value.ui64; 8757c478bd9Sstevel@tonic-gate for (i = 2, old_tot_ops = 0; i < req_old->ks_ndata; i++) 8767c478bd9Sstevel@tonic-gate old_tot_ops += kptr_old[i].value.ui64; 8777c478bd9Sstevel@tonic-gate } 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate /* Count the number of operations sent */ 8807c478bd9Sstevel@tonic-gate for (i = 2, tot_ops = 0; i < req->ks_ndata; i++) 8817c478bd9Sstevel@tonic-gate tot_ops += kptr[i].value.ui64; 8827c478bd9Sstevel@tonic-gate /* For v4 NULL/COMPOUND are the only procedures */ 8837c478bd9Sstevel@tonic-gate tot = kptr[0].value.ui64 + kptr[1].value.ui64; 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate if (interval) { 8867c478bd9Sstevel@tonic-gate tot -= old_tot; 8877c478bd9Sstevel@tonic-gate tot_ops -= old_tot_ops; 8887c478bd9Sstevel@tonic-gate } 8897c478bd9Sstevel@tonic-gate 8907c478bd9Sstevel@tonic-gate printf("Version 4: (%" PRIu64 " calls)\n", tot); 8917c478bd9Sstevel@tonic-gate 8927c478bd9Sstevel@tonic-gate knp = kstat_data_lookup(req, "null"); 8937c478bd9Sstevel@tonic-gate nreq = req->ks_ndata - (knp - KSTAT_NAMED_PTR(req)); 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate for (i = 0; i < COUNT; i += ncolumns) { 8967c478bd9Sstevel@tonic-gate for (j = i; j < MIN(i + ncolumns, 2); j++) { 8977c478bd9Sstevel@tonic-gate printf("%-*s", field_width, knp[j].name); 8987c478bd9Sstevel@tonic-gate } 8997c478bd9Sstevel@tonic-gate printf("\n"); 9007c478bd9Sstevel@tonic-gate for (j = i; j < MIN(i + ncolumns, 2); j++) { 9017c478bd9Sstevel@tonic-gate if (tot && interval && kptr_old != NULL) 9027c478bd9Sstevel@tonic-gate per = (int)((knp[j].value.ui64 - 9037c478bd9Sstevel@tonic-gate kptr_old[j].value.ui64) * 100 / tot); 9047c478bd9Sstevel@tonic-gate else if (tot) 9057c478bd9Sstevel@tonic-gate per = (int)(knp[j].value.ui64 * 100 / tot); 9067c478bd9Sstevel@tonic-gate else 9077c478bd9Sstevel@tonic-gate per = 0; 9087c478bd9Sstevel@tonic-gate (void) sprintf(fixlen, "%" PRIu64 " %d%% ", 9097c478bd9Sstevel@tonic-gate ((interval && kptr_old != NULL) ? 9107c478bd9Sstevel@tonic-gate (knp[j].value.ui64 - kptr_old[j].value.ui64) 9117c478bd9Sstevel@tonic-gate : knp[j].value.ui64), per); 9127c478bd9Sstevel@tonic-gate printf("%-*s", field_width, fixlen); 9137c478bd9Sstevel@tonic-gate } 9147c478bd9Sstevel@tonic-gate printf("\n"); 9157c478bd9Sstevel@tonic-gate } 9167c478bd9Sstevel@tonic-gate 9177c478bd9Sstevel@tonic-gate printf("Version 4: (%" PRIu64 " operations)\n", tot_ops); 9187c478bd9Sstevel@tonic-gate for (i = 2; i < nreq; i += ncolumns) { 9197c478bd9Sstevel@tonic-gate for (j = i; j < MIN(i + ncolumns, nreq); j++) { 9207c478bd9Sstevel@tonic-gate printf("%-*s", field_width, knp[j].name); 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate printf("\n"); 9237c478bd9Sstevel@tonic-gate for (j = i; j < MIN(i + ncolumns, nreq); j++) { 9247c478bd9Sstevel@tonic-gate if (tot_ops && interval && kptr_old != NULL) 9257c478bd9Sstevel@tonic-gate per = (int)((knp[j].value.ui64 - 9267c478bd9Sstevel@tonic-gate kptr_old[j].value.ui64) * 100 / tot_ops); 9277c478bd9Sstevel@tonic-gate else if (tot_ops) 9287c478bd9Sstevel@tonic-gate per = (int)(knp[j].value.ui64 * 100 / tot_ops); 9297c478bd9Sstevel@tonic-gate else 9307c478bd9Sstevel@tonic-gate per = 0; 9317c478bd9Sstevel@tonic-gate (void) sprintf(fixlen, "%" PRIu64 " %d%% ", 9327c478bd9Sstevel@tonic-gate ((interval && kptr_old != NULL) ? 9337c478bd9Sstevel@tonic-gate (knp[j].value.ui64 - kptr_old[j].value.ui64) 9347c478bd9Sstevel@tonic-gate : knp[j].value.ui64), per); 9357c478bd9Sstevel@tonic-gate printf("%-*s", field_width, fixlen); 9367c478bd9Sstevel@tonic-gate } 9377c478bd9Sstevel@tonic-gate printf("\n"); 9387c478bd9Sstevel@tonic-gate } 9397c478bd9Sstevel@tonic-gate if (zflag) { 9407c478bd9Sstevel@tonic-gate for (i = 0; i < req->ks_ndata; i++) 9417c478bd9Sstevel@tonic-gate kptr[i].value.ui64 = 0; 9427c478bd9Sstevel@tonic-gate } 9437c478bd9Sstevel@tonic-gate if (kptr_old != NULL) 94426fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_copy(req, req_old, 1); 9457c478bd9Sstevel@tonic-gate else 94626fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_copy(req, req_old, 0); 9477c478bd9Sstevel@tonic-gate } 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate static void 9507c478bd9Sstevel@tonic-gate stat_print(const char *title_string, kstat_t *req, kstat_t *req_old, 9517c478bd9Sstevel@tonic-gate int field_width, int zflag) 9527c478bd9Sstevel@tonic-gate { 9537c478bd9Sstevel@tonic-gate int i, j, nreq, ncolumns; 9547c478bd9Sstevel@tonic-gate char fixlen[128]; 9557c478bd9Sstevel@tonic-gate kstat_named_t *knp; 9567c478bd9Sstevel@tonic-gate kstat_named_t *knp_old; 9577c478bd9Sstevel@tonic-gate 9587c478bd9Sstevel@tonic-gate if (req == NULL) 9597c478bd9Sstevel@tonic-gate return; 9607c478bd9Sstevel@tonic-gate 9617752631cSth199096 if (field_width == 0) 9627752631cSth199096 return; 9637752631cSth199096 9647c478bd9Sstevel@tonic-gate printf("%s\n", title_string); 9657c478bd9Sstevel@tonic-gate ncolumns = (MAX_COLUMNS -1)/field_width; 9667c478bd9Sstevel@tonic-gate 9677c478bd9Sstevel@tonic-gate /* MEANS knp = (kstat_named_t *)req->ks_data */ 9687c478bd9Sstevel@tonic-gate knp = KSTAT_NAMED_PTR(req); 9697c478bd9Sstevel@tonic-gate nreq = req->ks_ndata; 9707c478bd9Sstevel@tonic-gate knp_old = KSTAT_NAMED_PTR(req_old); 9717c478bd9Sstevel@tonic-gate 9727c478bd9Sstevel@tonic-gate for (i = 0; i < nreq; i += ncolumns) { 9737c478bd9Sstevel@tonic-gate /* prints out the titles of the columns */ 9747c478bd9Sstevel@tonic-gate for (j = i; j < MIN(i + ncolumns, nreq); j++) { 9757c478bd9Sstevel@tonic-gate printf("%-*s", field_width, knp[j].name); 9767c478bd9Sstevel@tonic-gate } 9777c478bd9Sstevel@tonic-gate printf("\n"); 9787c478bd9Sstevel@tonic-gate /* prints out the stat numbers */ 9797c478bd9Sstevel@tonic-gate for (j = i; j < MIN(i + ncolumns, nreq); j++) { 9807c478bd9Sstevel@tonic-gate (void) sprintf(fixlen, "%" PRIu64 " ", 9817c478bd9Sstevel@tonic-gate (interval && knp_old != NULL) ? 9827c478bd9Sstevel@tonic-gate (knp[j].value.ui64 - knp_old[j].value.ui64) 9837c478bd9Sstevel@tonic-gate : knp[j].value.ui64); 9847c478bd9Sstevel@tonic-gate printf("%-*s", field_width, fixlen); 9857c478bd9Sstevel@tonic-gate } 9867c478bd9Sstevel@tonic-gate printf("\n"); 9877c478bd9Sstevel@tonic-gate 9887c478bd9Sstevel@tonic-gate } 9897c478bd9Sstevel@tonic-gate if (zflag) { 9907c478bd9Sstevel@tonic-gate for (i = 0; i < req->ks_ndata; i++) 9917c478bd9Sstevel@tonic-gate knp[i].value.ui64 = 0; 9927c478bd9Sstevel@tonic-gate } 9937c478bd9Sstevel@tonic-gate 9947c478bd9Sstevel@tonic-gate if (knp_old != NULL) 99526fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_copy(req, req_old, 1); 9967c478bd9Sstevel@tonic-gate else 99726fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_copy(req, req_old, 0); 9987c478bd9Sstevel@tonic-gate } 9997752631cSth199096 10007c478bd9Sstevel@tonic-gate static void 100126fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_sum(kstat_t *kstat1, kstat_t *kstat2, kstat_t *sum) 10027c478bd9Sstevel@tonic-gate { 10037c478bd9Sstevel@tonic-gate int i; 10047c478bd9Sstevel@tonic-gate kstat_named_t *knp1, *knp2, *knpsum; 10057c478bd9Sstevel@tonic-gate if (kstat1 == NULL || kstat2 == NULL) 10067c478bd9Sstevel@tonic-gate return; 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate knp1 = KSTAT_NAMED_PTR(kstat1); 10097c478bd9Sstevel@tonic-gate knp2 = KSTAT_NAMED_PTR(kstat2); 10107c478bd9Sstevel@tonic-gate if (sum->ks_data == NULL) 101126fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_copy(kstat1, sum, 0); 10127c478bd9Sstevel@tonic-gate knpsum = KSTAT_NAMED_PTR(sum); 10137c478bd9Sstevel@tonic-gate 10147c478bd9Sstevel@tonic-gate for (i = 0; i < (kstat1->ks_ndata); i++) 10157c478bd9Sstevel@tonic-gate knpsum[i].value.ui64 = knp1[i].value.ui64 + knp2[i].value.ui64; 10167c478bd9Sstevel@tonic-gate } 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate /* 10197c478bd9Sstevel@tonic-gate * my_dir and my_path could be pointers 10207c478bd9Sstevel@tonic-gate */ 10217c478bd9Sstevel@tonic-gate struct myrec { 10227c478bd9Sstevel@tonic-gate ulong_t my_fsid; 10237c478bd9Sstevel@tonic-gate char my_dir[MAXPATHLEN]; 10247c478bd9Sstevel@tonic-gate char *my_path; 10257c478bd9Sstevel@tonic-gate char *ig_path; 10267c478bd9Sstevel@tonic-gate struct myrec *next; 10277c478bd9Sstevel@tonic-gate }; 10287c478bd9Sstevel@tonic-gate 10297c478bd9Sstevel@tonic-gate /* 10307c478bd9Sstevel@tonic-gate * Print the mount table info 10317c478bd9Sstevel@tonic-gate */ 10327c478bd9Sstevel@tonic-gate static void 10337c478bd9Sstevel@tonic-gate mi_print(void) 10347c478bd9Sstevel@tonic-gate { 10357c478bd9Sstevel@tonic-gate FILE *mt; 10367c478bd9Sstevel@tonic-gate struct extmnttab m; 10377c478bd9Sstevel@tonic-gate struct myrec *list, *mrp, *pmrp; 10387c478bd9Sstevel@tonic-gate char *flavor; 10397c478bd9Sstevel@tonic-gate int ignored = 0; 10407c478bd9Sstevel@tonic-gate seconfig_t nfs_sec; 10417c478bd9Sstevel@tonic-gate kstat_t *ksp; 10427c478bd9Sstevel@tonic-gate struct mntinfo_kstat mik; 10437c478bd9Sstevel@tonic-gate int transport_flag = 0; 10447c478bd9Sstevel@tonic-gate int path_count; 10457c478bd9Sstevel@tonic-gate int found; 10467c478bd9Sstevel@tonic-gate char *timer_name[] = { 10477c478bd9Sstevel@tonic-gate "Lookups", 10487c478bd9Sstevel@tonic-gate "Reads", 10497c478bd9Sstevel@tonic-gate "Writes", 10507c478bd9Sstevel@tonic-gate "All" 10517c478bd9Sstevel@tonic-gate }; 10527c478bd9Sstevel@tonic-gate 10537c478bd9Sstevel@tonic-gate mt = fopen(MNTTAB, "r"); 10547c478bd9Sstevel@tonic-gate if (mt == NULL) { 10557c478bd9Sstevel@tonic-gate perror(MNTTAB); 10567c478bd9Sstevel@tonic-gate exit(0); 10577c478bd9Sstevel@tonic-gate } 10587c478bd9Sstevel@tonic-gate 10597c478bd9Sstevel@tonic-gate list = NULL; 10607c478bd9Sstevel@tonic-gate resetmnttab(mt); 10617c478bd9Sstevel@tonic-gate 10627c478bd9Sstevel@tonic-gate while (getextmntent(mt, &m, sizeof (struct extmnttab)) == 0) { 10637c478bd9Sstevel@tonic-gate /* ignore non "nfs" and save the "ignore" entries */ 10647c478bd9Sstevel@tonic-gate if (strcmp(m.mnt_fstype, MNTTYPE_NFS) != 0) 10657c478bd9Sstevel@tonic-gate continue; 10667c478bd9Sstevel@tonic-gate /* 10677c478bd9Sstevel@tonic-gate * Check to see here if user gave a path(s) to 10687c478bd9Sstevel@tonic-gate * only show the mount point they wanted 10697c478bd9Sstevel@tonic-gate * Iterate through the list of paths the user gave and see 1070b9238976Sth199096 * if any of them match our current nfs mount 10717c478bd9Sstevel@tonic-gate */ 10727c478bd9Sstevel@tonic-gate if (path[0] != NULL) { 10737c478bd9Sstevel@tonic-gate found = 0; 10747c478bd9Sstevel@tonic-gate for (path_count = 0; path[path_count] != NULL; 10757c478bd9Sstevel@tonic-gate path_count++) { 10767c478bd9Sstevel@tonic-gate if (strcmp(path[path_count], m.mnt_mountp) 10777c478bd9Sstevel@tonic-gate == 0) { 10787c478bd9Sstevel@tonic-gate found = 1; 10797c478bd9Sstevel@tonic-gate break; 10807c478bd9Sstevel@tonic-gate } 10817c478bd9Sstevel@tonic-gate } 10827c478bd9Sstevel@tonic-gate if (!found) 10837c478bd9Sstevel@tonic-gate continue; 10847c478bd9Sstevel@tonic-gate } 10857c478bd9Sstevel@tonic-gate 10867c478bd9Sstevel@tonic-gate if ((mrp = malloc(sizeof (struct myrec))) == 0) { 10877c478bd9Sstevel@tonic-gate fprintf(stderr, "nfsstat: not enough memory\n"); 10887c478bd9Sstevel@tonic-gate exit(1); 10897c478bd9Sstevel@tonic-gate } 10907c478bd9Sstevel@tonic-gate mrp->my_fsid = makedev(m.mnt_major, m.mnt_minor); 10917c478bd9Sstevel@tonic-gate if (ignore(m.mnt_mntopts)) { 10927c478bd9Sstevel@tonic-gate /* 10937c478bd9Sstevel@tonic-gate * ignored entries cannot be ignored for this 10947c478bd9Sstevel@tonic-gate * option. We have to display the info for this 10957c478bd9Sstevel@tonic-gate * nfs mount. The ignore is an indication 10967c478bd9Sstevel@tonic-gate * that the actual mount point is different and 10977c478bd9Sstevel@tonic-gate * something is in between the nfs mount. 10987c478bd9Sstevel@tonic-gate * So save the mount point now 10997c478bd9Sstevel@tonic-gate */ 11007c478bd9Sstevel@tonic-gate if ((mrp->ig_path = malloc( 11017c478bd9Sstevel@tonic-gate strlen(m.mnt_mountp) + 1)) == 0) { 11027c478bd9Sstevel@tonic-gate fprintf(stderr, "nfsstat: not enough memory\n"); 11037c478bd9Sstevel@tonic-gate exit(1); 11047c478bd9Sstevel@tonic-gate } 11057c478bd9Sstevel@tonic-gate (void) strcpy(mrp->ig_path, m.mnt_mountp); 11067c478bd9Sstevel@tonic-gate ignored++; 11077c478bd9Sstevel@tonic-gate } else { 11087c478bd9Sstevel@tonic-gate mrp->ig_path = 0; 11097c478bd9Sstevel@tonic-gate (void) strcpy(mrp->my_dir, m.mnt_mountp); 11107c478bd9Sstevel@tonic-gate } 11117c478bd9Sstevel@tonic-gate if ((mrp->my_path = strdup(m.mnt_special)) == NULL) { 11127c478bd9Sstevel@tonic-gate fprintf(stderr, "nfsstat: not enough memory\n"); 11137c478bd9Sstevel@tonic-gate exit(1); 11147c478bd9Sstevel@tonic-gate } 11157c478bd9Sstevel@tonic-gate mrp->next = list; 11167c478bd9Sstevel@tonic-gate list = mrp; 11177c478bd9Sstevel@tonic-gate } 11187c478bd9Sstevel@tonic-gate 1119*bd93c05dSAlexander Eremin (void) fclose(mt); 1120*bd93c05dSAlexander Eremin 11217c478bd9Sstevel@tonic-gate if (ignored) { 11227c478bd9Sstevel@tonic-gate /* 11237c478bd9Sstevel@tonic-gate * Now ignored entries which do not have 11247c478bd9Sstevel@tonic-gate * the my_dir initialized are really ignored; This never 11257c478bd9Sstevel@tonic-gate * happens unless the mnttab is corrupted. 11267c478bd9Sstevel@tonic-gate */ 11277c478bd9Sstevel@tonic-gate for (pmrp = 0, mrp = list; mrp; mrp = mrp->next) { 11287c478bd9Sstevel@tonic-gate if (mrp->ig_path == 0) 11297c478bd9Sstevel@tonic-gate pmrp = mrp; 11307c478bd9Sstevel@tonic-gate else if (pmrp) 11317c478bd9Sstevel@tonic-gate pmrp->next = mrp->next; 11327c478bd9Sstevel@tonic-gate else 11337c478bd9Sstevel@tonic-gate list = mrp->next; 11347c478bd9Sstevel@tonic-gate } 11357c478bd9Sstevel@tonic-gate } 11367c478bd9Sstevel@tonic-gate 11377c478bd9Sstevel@tonic-gate for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { 11387c478bd9Sstevel@tonic-gate int i; 11397c478bd9Sstevel@tonic-gate 11407c478bd9Sstevel@tonic-gate if (ksp->ks_type != KSTAT_TYPE_RAW) 11417c478bd9Sstevel@tonic-gate continue; 11427c478bd9Sstevel@tonic-gate if (strcmp(ksp->ks_module, "nfs") != 0) 11437c478bd9Sstevel@tonic-gate continue; 11447c478bd9Sstevel@tonic-gate if (strcmp(ksp->ks_name, "mntinfo") != 0) 11457c478bd9Sstevel@tonic-gate continue; 11467c478bd9Sstevel@tonic-gate 11477c478bd9Sstevel@tonic-gate for (mrp = list; mrp; mrp = mrp->next) { 11487c478bd9Sstevel@tonic-gate if ((mrp->my_fsid & MAXMIN) == ksp->ks_instance) 11497c478bd9Sstevel@tonic-gate break; 11507c478bd9Sstevel@tonic-gate } 11517c478bd9Sstevel@tonic-gate if (mrp == 0) 11527c478bd9Sstevel@tonic-gate continue; 11537c478bd9Sstevel@tonic-gate 11547c478bd9Sstevel@tonic-gate if (safe_kstat_read(kc, ksp, &mik) == -1) 11557c478bd9Sstevel@tonic-gate continue; 11567c478bd9Sstevel@tonic-gate 11577c478bd9Sstevel@tonic-gate printf("%s from %s\n", mrp->my_dir, mrp->my_path); 11587c478bd9Sstevel@tonic-gate 11597c478bd9Sstevel@tonic-gate /* 11607c478bd9Sstevel@tonic-gate * for printing rdma transport and provider string. 11617c478bd9Sstevel@tonic-gate * This way we avoid modifying the kernel mntinfo_kstat 11627c478bd9Sstevel@tonic-gate * struct for protofmly. 11637c478bd9Sstevel@tonic-gate */ 11647c478bd9Sstevel@tonic-gate if (strcmp(mik.mik_proto, "ibtf") == 0) { 11657c478bd9Sstevel@tonic-gate printf(" Flags: vers=%u,proto=rdma", 11667c478bd9Sstevel@tonic-gate mik.mik_vers); 11677c478bd9Sstevel@tonic-gate transport_flag = 1; 11687c478bd9Sstevel@tonic-gate } else { 11697c478bd9Sstevel@tonic-gate printf(" Flags: vers=%u,proto=%s", 11707c478bd9Sstevel@tonic-gate mik.mik_vers, mik.mik_proto); 11717c478bd9Sstevel@tonic-gate transport_flag = 0; 11727c478bd9Sstevel@tonic-gate } 11737c478bd9Sstevel@tonic-gate 11747c478bd9Sstevel@tonic-gate /* 11757c478bd9Sstevel@tonic-gate * get the secmode name from /etc/nfssec.conf. 11767c478bd9Sstevel@tonic-gate */ 11777c478bd9Sstevel@tonic-gate if (!nfs_getseconfig_bynumber(mik.mik_secmod, &nfs_sec)) { 11787c478bd9Sstevel@tonic-gate flavor = nfs_sec.sc_name; 11797c478bd9Sstevel@tonic-gate } else 11807c478bd9Sstevel@tonic-gate flavor = NULL; 11817c478bd9Sstevel@tonic-gate 11827c478bd9Sstevel@tonic-gate if (flavor != NULL) 11837c478bd9Sstevel@tonic-gate printf(",sec=%s", flavor); 11847c478bd9Sstevel@tonic-gate else 11857c478bd9Sstevel@tonic-gate printf(",sec#=%d", mik.mik_secmod); 11867c478bd9Sstevel@tonic-gate 11877c478bd9Sstevel@tonic-gate printf(",%s", (mik.mik_flags & MI_HARD) ? "hard" : "soft"); 11887c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_PRINTED) 11897c478bd9Sstevel@tonic-gate printf(",printed"); 11907c478bd9Sstevel@tonic-gate printf(",%s", (mik.mik_flags & MI_INT) ? "intr" : "nointr"); 11917c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_DOWN) 11927c478bd9Sstevel@tonic-gate printf(",down"); 11937c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_NOAC) 11947c478bd9Sstevel@tonic-gate printf(",noac"); 11957c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_NOCTO) 11967c478bd9Sstevel@tonic-gate printf(",nocto"); 11977c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_DYNAMIC) 11987c478bd9Sstevel@tonic-gate printf(",dynamic"); 11997c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_LLOCK) 12007c478bd9Sstevel@tonic-gate printf(",llock"); 12017c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_GRPID) 12027c478bd9Sstevel@tonic-gate printf(",grpid"); 12037c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_RPCTIMESYNC) 12047c478bd9Sstevel@tonic-gate printf(",rpctimesync"); 12057c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_LINK) 12067c478bd9Sstevel@tonic-gate printf(",link"); 12077c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_SYMLINK) 12087c478bd9Sstevel@tonic-gate printf(",symlink"); 1209e798f60bSth199096 if (mik.mik_vers < NFS_V4 && mik.mik_flags & MI_READDIRONLY) 12107c478bd9Sstevel@tonic-gate printf(",readdironly"); 12117c478bd9Sstevel@tonic-gate if (mik.mik_flags & MI_ACL) 12127c478bd9Sstevel@tonic-gate printf(",acl"); 121347985242SMarcel Telka if (mik.mik_flags & MI_DIRECTIO) 121447985242SMarcel Telka printf(",forcedirectio"); 12157c478bd9Sstevel@tonic-gate 1216b9238976Sth199096 if (mik.mik_vers >= NFS_V4) { 1217b9238976Sth199096 if (mik.mik_flags & MI4_MIRRORMOUNT) 1218b9238976Sth199096 printf(",mirrormount"); 12192f172c55SRobert Thurlow if (mik.mik_flags & MI4_REFERRAL) 12202f172c55SRobert Thurlow printf(",referral"); 1221b9238976Sth199096 } 1222b9238976Sth199096 12237c478bd9Sstevel@tonic-gate printf(",rsize=%d,wsize=%d,retrans=%d,timeo=%d", 12247c478bd9Sstevel@tonic-gate mik.mik_curread, mik.mik_curwrite, mik.mik_retrans, 12257c478bd9Sstevel@tonic-gate mik.mik_timeo); 12267c478bd9Sstevel@tonic-gate printf("\n"); 12277c478bd9Sstevel@tonic-gate printf(" Attr cache: acregmin=%d,acregmax=%d" 12287c478bd9Sstevel@tonic-gate ",acdirmin=%d,acdirmax=%d\n", mik.mik_acregmin, 12297c478bd9Sstevel@tonic-gate mik.mik_acregmax, mik.mik_acdirmin, mik.mik_acdirmax); 12307c478bd9Sstevel@tonic-gate 12317c478bd9Sstevel@tonic-gate if (transport_flag) { 12327c478bd9Sstevel@tonic-gate printf(" Transport: proto=rdma, plugin=%s\n", 12337c478bd9Sstevel@tonic-gate mik.mik_proto); 12347c478bd9Sstevel@tonic-gate } 12357c478bd9Sstevel@tonic-gate 12367c478bd9Sstevel@tonic-gate #define srtt_to_ms(x) x, (x * 2 + x / 2) 12377c478bd9Sstevel@tonic-gate #define dev_to_ms(x) x, (x * 5) 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate for (i = 0; i < NFS_CALLTYPES + 1; i++) { 12407c478bd9Sstevel@tonic-gate int j; 12417c478bd9Sstevel@tonic-gate 12427c478bd9Sstevel@tonic-gate j = (i == NFS_CALLTYPES ? i - 1 : i); 12437c478bd9Sstevel@tonic-gate if (mik.mik_timers[j].srtt || 12447c478bd9Sstevel@tonic-gate mik.mik_timers[j].rtxcur) { 1245b9238976Sth199096 printf(" %s: srtt=%d (%dms), " 1246b9238976Sth199096 "dev=%d (%dms), cur=%u (%ums)\n", 12477c478bd9Sstevel@tonic-gate timer_name[i], 12487c478bd9Sstevel@tonic-gate srtt_to_ms(mik.mik_timers[i].srtt), 12497c478bd9Sstevel@tonic-gate dev_to_ms(mik.mik_timers[i].deviate), 12507c478bd9Sstevel@tonic-gate mik.mik_timers[i].rtxcur, 12517c478bd9Sstevel@tonic-gate mik.mik_timers[i].rtxcur * 20); 12527c478bd9Sstevel@tonic-gate } 12537c478bd9Sstevel@tonic-gate } 12547c478bd9Sstevel@tonic-gate 12557c478bd9Sstevel@tonic-gate if (strchr(mrp->my_path, ',')) 12567c478bd9Sstevel@tonic-gate printf( 12577c478bd9Sstevel@tonic-gate " Failover: noresponse=%d,failover=%d," 12587c478bd9Sstevel@tonic-gate "remap=%d,currserver=%s\n", 12597c478bd9Sstevel@tonic-gate mik.mik_noresponse, mik.mik_failover, 12607c478bd9Sstevel@tonic-gate mik.mik_remap, mik.mik_curserver); 12617c478bd9Sstevel@tonic-gate printf("\n"); 12627c478bd9Sstevel@tonic-gate } 12637c478bd9Sstevel@tonic-gate } 12647c478bd9Sstevel@tonic-gate 12657c478bd9Sstevel@tonic-gate static char *mntopts[] = { MNTOPT_IGNORE, MNTOPT_DEV, NULL }; 12667c478bd9Sstevel@tonic-gate #define IGNORE 0 12677c478bd9Sstevel@tonic-gate #define DEV 1 12687c478bd9Sstevel@tonic-gate 12697c478bd9Sstevel@tonic-gate /* 12707c478bd9Sstevel@tonic-gate * Return 1 if "ignore" appears in the options string 12717c478bd9Sstevel@tonic-gate */ 12727c478bd9Sstevel@tonic-gate static int 12737c478bd9Sstevel@tonic-gate ignore(char *opts) 12747c478bd9Sstevel@tonic-gate { 12757c478bd9Sstevel@tonic-gate char *value; 12767c478bd9Sstevel@tonic-gate char *s; 12777c478bd9Sstevel@tonic-gate 12787c478bd9Sstevel@tonic-gate if (opts == NULL) 12797c478bd9Sstevel@tonic-gate return (0); 12807c478bd9Sstevel@tonic-gate s = strdup(opts); 12817c478bd9Sstevel@tonic-gate if (s == NULL) 12827c478bd9Sstevel@tonic-gate return (0); 12837c478bd9Sstevel@tonic-gate opts = s; 12847c478bd9Sstevel@tonic-gate 12857c478bd9Sstevel@tonic-gate while (*opts != '\0') { 12867c478bd9Sstevel@tonic-gate if (getsubopt(&opts, mntopts, &value) == IGNORE) { 12877c478bd9Sstevel@tonic-gate free(s); 12887c478bd9Sstevel@tonic-gate return (1); 12897c478bd9Sstevel@tonic-gate } 12907c478bd9Sstevel@tonic-gate } 12917c478bd9Sstevel@tonic-gate 12927c478bd9Sstevel@tonic-gate free(s); 12937c478bd9Sstevel@tonic-gate return (0); 12947c478bd9Sstevel@tonic-gate } 12957c478bd9Sstevel@tonic-gate 12967c478bd9Sstevel@tonic-gate void 12977c478bd9Sstevel@tonic-gate usage(void) 12987c478bd9Sstevel@tonic-gate { 12997c478bd9Sstevel@tonic-gate fprintf(stderr, "Usage: nfsstat [-cnrsza [-v version] " 130026fd7700SKrishnendu Sadhukhan - Sun Microsystems "[-T d|u] [interval [count]]\n"); 13017c478bd9Sstevel@tonic-gate fprintf(stderr, "Usage: nfsstat -m [pathname..]\n"); 13027c478bd9Sstevel@tonic-gate exit(1); 13037c478bd9Sstevel@tonic-gate } 13047c478bd9Sstevel@tonic-gate 130526fd7700SKrishnendu Sadhukhan - Sun Microsystems void 13067c478bd9Sstevel@tonic-gate fail(int do_perror, char *message, ...) 13077c478bd9Sstevel@tonic-gate { 13087c478bd9Sstevel@tonic-gate va_list args; 13097c478bd9Sstevel@tonic-gate 13107c478bd9Sstevel@tonic-gate va_start(args, message); 13117c478bd9Sstevel@tonic-gate fprintf(stderr, "nfsstat: "); 13127c478bd9Sstevel@tonic-gate vfprintf(stderr, message, args); 13137c478bd9Sstevel@tonic-gate va_end(args); 13147c478bd9Sstevel@tonic-gate if (do_perror) 13157c478bd9Sstevel@tonic-gate fprintf(stderr, ": %s", strerror(errno)); 13167c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 13177c478bd9Sstevel@tonic-gate exit(1); 13187c478bd9Sstevel@tonic-gate } 13197c478bd9Sstevel@tonic-gate 13207c478bd9Sstevel@tonic-gate kid_t 13217c478bd9Sstevel@tonic-gate safe_kstat_read(kstat_ctl_t *kc, kstat_t *ksp, void *data) 13227c478bd9Sstevel@tonic-gate { 13237c478bd9Sstevel@tonic-gate kid_t kstat_chain_id = kstat_read(kc, ksp, data); 13247c478bd9Sstevel@tonic-gate 13257c478bd9Sstevel@tonic-gate if (kstat_chain_id == -1) 13267c478bd9Sstevel@tonic-gate fail(1, "kstat_read(%x, '%s') failed", kc, ksp->ks_name); 13277c478bd9Sstevel@tonic-gate return (kstat_chain_id); 13287c478bd9Sstevel@tonic-gate } 13297c478bd9Sstevel@tonic-gate 13307c478bd9Sstevel@tonic-gate kid_t 13317c478bd9Sstevel@tonic-gate safe_kstat_write(kstat_ctl_t *kc, kstat_t *ksp, void *data) 13327c478bd9Sstevel@tonic-gate { 13337c478bd9Sstevel@tonic-gate kid_t kstat_chain_id = 0; 13347c478bd9Sstevel@tonic-gate 13357c478bd9Sstevel@tonic-gate if (ksp->ks_data != NULL) { 13367c478bd9Sstevel@tonic-gate kstat_chain_id = kstat_write(kc, ksp, data); 13377c478bd9Sstevel@tonic-gate 13387c478bd9Sstevel@tonic-gate if (kstat_chain_id == -1) 13397c478bd9Sstevel@tonic-gate fail(1, "kstat_write(%x, '%s') failed", kc, 13407c478bd9Sstevel@tonic-gate ksp->ks_name); 13417c478bd9Sstevel@tonic-gate } 13427c478bd9Sstevel@tonic-gate return (kstat_chain_id); 13437c478bd9Sstevel@tonic-gate } 13447c478bd9Sstevel@tonic-gate 13457c478bd9Sstevel@tonic-gate void 13467c478bd9Sstevel@tonic-gate stats_timer(int interval) 13477c478bd9Sstevel@tonic-gate { 13487c478bd9Sstevel@tonic-gate timer_t t_id; 13497c478bd9Sstevel@tonic-gate itimerspec_t time_struct; 13507c478bd9Sstevel@tonic-gate struct sigevent sig_struct; 13517c478bd9Sstevel@tonic-gate struct sigaction act; 13527c478bd9Sstevel@tonic-gate 13537c478bd9Sstevel@tonic-gate bzero(&sig_struct, sizeof (struct sigevent)); 13547c478bd9Sstevel@tonic-gate bzero(&act, sizeof (struct sigaction)); 13557c478bd9Sstevel@tonic-gate 13567c478bd9Sstevel@tonic-gate /* Create timer */ 13577c478bd9Sstevel@tonic-gate sig_struct.sigev_notify = SIGEV_SIGNAL; 13587c478bd9Sstevel@tonic-gate sig_struct.sigev_signo = SIGUSR1; 13597c478bd9Sstevel@tonic-gate sig_struct.sigev_value.sival_int = 0; 13607c478bd9Sstevel@tonic-gate 13617c478bd9Sstevel@tonic-gate if (timer_create(CLOCK_REALTIME, &sig_struct, &t_id) != 0) { 13627c478bd9Sstevel@tonic-gate fail(1, "Timer creation failed"); 13637c478bd9Sstevel@tonic-gate } 13647c478bd9Sstevel@tonic-gate 13657c478bd9Sstevel@tonic-gate act.sa_handler = handle_sig; 13667c478bd9Sstevel@tonic-gate 13677c478bd9Sstevel@tonic-gate if (sigaction(SIGUSR1, &act, NULL) != 0) { 13687c478bd9Sstevel@tonic-gate fail(1, "Could not set up signal handler"); 13697c478bd9Sstevel@tonic-gate } 13707c478bd9Sstevel@tonic-gate 13717c478bd9Sstevel@tonic-gate time_struct.it_value.tv_sec = interval; 13727c478bd9Sstevel@tonic-gate time_struct.it_value.tv_nsec = 0; 13737c478bd9Sstevel@tonic-gate time_struct.it_interval.tv_sec = interval; 13747c478bd9Sstevel@tonic-gate time_struct.it_interval.tv_nsec = 0; 13757c478bd9Sstevel@tonic-gate 13767c478bd9Sstevel@tonic-gate /* Arm timer */ 13777c478bd9Sstevel@tonic-gate if ((timer_settime(t_id, 0, &time_struct, NULL)) != 0) { 13787c478bd9Sstevel@tonic-gate fail(1, "Setting timer failed"); 13797c478bd9Sstevel@tonic-gate } 13807c478bd9Sstevel@tonic-gate } 13817c478bd9Sstevel@tonic-gate 13827c478bd9Sstevel@tonic-gate void 13837c478bd9Sstevel@tonic-gate handle_sig(int x) 13847c478bd9Sstevel@tonic-gate { 13857c478bd9Sstevel@tonic-gate } 13867c478bd9Sstevel@tonic-gate 13877c478bd9Sstevel@tonic-gate static void 138826fd7700SKrishnendu Sadhukhan - Sun Microsystems nfsstat_kstat_copy(kstat_t *src, kstat_t *dst, int fr) 13897c478bd9Sstevel@tonic-gate { 13907c478bd9Sstevel@tonic-gate 13917c478bd9Sstevel@tonic-gate if (fr) 13927c478bd9Sstevel@tonic-gate free(dst->ks_data); 13937c478bd9Sstevel@tonic-gate 13947c478bd9Sstevel@tonic-gate *dst = *src; 13957c478bd9Sstevel@tonic-gate 13967c478bd9Sstevel@tonic-gate if (src->ks_data != NULL) { 13977c478bd9Sstevel@tonic-gate safe_zalloc(&dst->ks_data, src->ks_data_size, 0); 13987c478bd9Sstevel@tonic-gate (void) memcpy(dst->ks_data, src->ks_data, src->ks_data_size); 13997c478bd9Sstevel@tonic-gate } else { 14007c478bd9Sstevel@tonic-gate dst->ks_data = NULL; 14017c478bd9Sstevel@tonic-gate dst->ks_data_size = 0; 14027c478bd9Sstevel@tonic-gate } 14037c478bd9Sstevel@tonic-gate } 14047c478bd9Sstevel@tonic-gate 14057c478bd9Sstevel@tonic-gate /* 140638f92303SMarcel Telka * "Safe" allocators - if we return we're guaranteed to have the desired space 140738f92303SMarcel Telka * allocated and zero-filled. We exit via fail if we can't get the space. 14087c478bd9Sstevel@tonic-gate */ 14097c478bd9Sstevel@tonic-gate void 14107c478bd9Sstevel@tonic-gate safe_zalloc(void **ptr, uint_t size, int free_first) 14117c478bd9Sstevel@tonic-gate { 141238f92303SMarcel Telka if (ptr == NULL) 14137c478bd9Sstevel@tonic-gate fail(1, "invalid pointer"); 14147c478bd9Sstevel@tonic-gate if (free_first && *ptr != NULL) 14157c478bd9Sstevel@tonic-gate free(*ptr); 14167c478bd9Sstevel@tonic-gate if ((*ptr = (void *)malloc(size)) == NULL) 14177c478bd9Sstevel@tonic-gate fail(1, "malloc failed"); 14187c478bd9Sstevel@tonic-gate (void) memset(*ptr, 0, size); 14197c478bd9Sstevel@tonic-gate } 14207c478bd9Sstevel@tonic-gate 14217c478bd9Sstevel@tonic-gate static int 14227c478bd9Sstevel@tonic-gate safe_strtoi(char const *val, char *errmsg) 14237c478bd9Sstevel@tonic-gate { 14247c478bd9Sstevel@tonic-gate char *end; 14257c478bd9Sstevel@tonic-gate long tmp; 14267c478bd9Sstevel@tonic-gate errno = 0; 14277c478bd9Sstevel@tonic-gate tmp = strtol(val, &end, 10); 14287c478bd9Sstevel@tonic-gate if (*end != '\0' || errno) 14297c478bd9Sstevel@tonic-gate fail(0, "%s %s", errmsg, val); 14307c478bd9Sstevel@tonic-gate return ((int)tmp); 14317c478bd9Sstevel@tonic-gate } 1432