1*86d949f9SVitaliy Gusev /*
2*86d949f9SVitaliy Gusev * This file and its contents are supplied under the terms of the
3*86d949f9SVitaliy Gusev * Common Development and Distribution License ("CDDL"), version 1.0.
4*86d949f9SVitaliy Gusev * You may only use this file in accordance with the terms of version
5*86d949f9SVitaliy Gusev * 1.0 of the CDDL.
6*86d949f9SVitaliy Gusev *
7*86d949f9SVitaliy Gusev * A full copy of the text of the CDDL should have accompanied this
8*86d949f9SVitaliy Gusev * source. A copy of the CDDL is also available via the Internet at
9*86d949f9SVitaliy Gusev * http://www.illumos.org/license/CDDL.
10*86d949f9SVitaliy Gusev */
11*86d949f9SVitaliy Gusev /*
12*86d949f9SVitaliy Gusev * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
13*86d949f9SVitaliy Gusev */
14*86d949f9SVitaliy Gusev
15*86d949f9SVitaliy Gusev #include <sys/types.h>
16*86d949f9SVitaliy Gusev #include <sys/kstat.h>
17*86d949f9SVitaliy Gusev #include <sys/mdb_modapi.h>
18*86d949f9SVitaliy Gusev #include <rpc/clnt.h>
19*86d949f9SVitaliy Gusev #include <nfs/nfs_clnt.h>
20*86d949f9SVitaliy Gusev #include <nfs/nfs4_clnt.h>
21*86d949f9SVitaliy Gusev
22*86d949f9SVitaliy Gusev #include "svc.h"
23*86d949f9SVitaliy Gusev #include "rfs4.h"
24*86d949f9SVitaliy Gusev #include "nfssrv.h"
25*86d949f9SVitaliy Gusev #include "common.h"
26*86d949f9SVitaliy Gusev
27*86d949f9SVitaliy Gusev #define NFS4_MINOR_VERS_COUNT 0
28*86d949f9SVitaliy Gusev #define NFS_STAT_NUM_STATS 79
29*86d949f9SVitaliy Gusev
30*86d949f9SVitaliy Gusev /*
31*86d949f9SVitaliy Gusev * Structure used to group kstats we want to print.
32*86d949f9SVitaliy Gusev */
33*86d949f9SVitaliy Gusev typedef struct nfs_mdb_stats {
34*86d949f9SVitaliy Gusev struct nfs_stats nfsstats;
35*86d949f9SVitaliy Gusev struct rpcstat rpcstats;
36*86d949f9SVitaliy Gusev struct nfs_globals nfsglbls;
37*86d949f9SVitaliy Gusev uintptr_t clntstat;
38*86d949f9SVitaliy Gusev uintptr_t clntstat4; /* extend this for NFS4.X */
39*86d949f9SVitaliy Gusev uintptr_t callback_stats;
40*86d949f9SVitaliy Gusev } nfs_mdb_stats_t;
41*86d949f9SVitaliy Gusev
42*86d949f9SVitaliy Gusev static int nfs_stat_clnt(nfs_mdb_stats_t *, int, int);
43*86d949f9SVitaliy Gusev static int nfs_stat_srv(nfs_mdb_stats_t *, int, int);
44*86d949f9SVitaliy Gusev static int nfs_srvstat(nfs_mdb_stats_t *, int);
45*86d949f9SVitaliy Gusev static int nfs_srvstat_rpc(nfs_mdb_stats_t *);
46*86d949f9SVitaliy Gusev static int nfs_srvstat_acl(nfs_mdb_stats_t *, int);
47*86d949f9SVitaliy Gusev static int nfs_clntstat(nfs_mdb_stats_t *, int);
48*86d949f9SVitaliy Gusev static int nfs_clntstat_rpc(nfs_mdb_stats_t *);
49*86d949f9SVitaliy Gusev static int nfs_clntstat_acl(nfs_mdb_stats_t *, int);
50*86d949f9SVitaliy Gusev static int nfs_srvstat_cb(nfs_mdb_stats_t *);
51*86d949f9SVitaliy Gusev
52*86d949f9SVitaliy Gusev #define NFS_SRV_STAT 0x1
53*86d949f9SVitaliy Gusev #define NFS_CLNT_STAT 0x2
54*86d949f9SVitaliy Gusev #define NFS_CB_STAT 0x4
55*86d949f9SVitaliy Gusev #define NFS_NFS_STAT 0x1
56*86d949f9SVitaliy Gusev #define NFS_ACL_STAT 0x2
57*86d949f9SVitaliy Gusev #define NFS_RPC_STAT 0x4
58*86d949f9SVitaliy Gusev #define NFS_V2_STAT 0x1
59*86d949f9SVitaliy Gusev #define NFS_V3_STAT 0x2
60*86d949f9SVitaliy Gusev #define NFS_V4_STAT 0x4
61*86d949f9SVitaliy Gusev
62*86d949f9SVitaliy Gusev static int prt_nfs_stats(uintptr_t, char *);
63*86d949f9SVitaliy Gusev static void kstat_prtout(char *, uint64_t *, int);
64*86d949f9SVitaliy Gusev
65*86d949f9SVitaliy Gusev void
nfs_stat_help(void)66*86d949f9SVitaliy Gusev nfs_stat_help(void)
67*86d949f9SVitaliy Gusev {
68*86d949f9SVitaliy Gusev mdb_printf("Switches similar to those of nfsstat command.\n",
69*86d949f9SVitaliy Gusev " ::nfs_stat -a -> ACL Statistics.\n"
70*86d949f9SVitaliy Gusev " ::nfs_stat -b -> Callback Stats. (V4 only)\n"
71*86d949f9SVitaliy Gusev " ::nfs_stat -c -> Client Statistics.\n"
72*86d949f9SVitaliy Gusev " ::nfs_stat -n -> NFS Statistics.\n"
73*86d949f9SVitaliy Gusev " ::nfs_stat -r -> RPC Statistics.\n"
74*86d949f9SVitaliy Gusev " ::nfs_stat -s -> Server Statistics.\n"
75*86d949f9SVitaliy Gusev " ::nfs_stat -2 -> Version 2.\n"
76*86d949f9SVitaliy Gusev " ::nfs_stat -3 -> Version 3.\n"
77*86d949f9SVitaliy Gusev " ::nfs_stat -4 -> Version 4.\n");
78*86d949f9SVitaliy Gusev }
79*86d949f9SVitaliy Gusev
80*86d949f9SVitaliy Gusev int
nfs_stat_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)81*86d949f9SVitaliy Gusev nfs_stat_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
82*86d949f9SVitaliy Gusev {
83*86d949f9SVitaliy Gusev int host_flag = 0; /* host or client flag */
84*86d949f9SVitaliy Gusev int type_flag = 0; /* type acl, rpc of nfs */
85*86d949f9SVitaliy Gusev int vers_flag = 0; /* NFS version flag */
86*86d949f9SVitaliy Gusev nfs_mdb_stats_t mdb_stats;
87*86d949f9SVitaliy Gusev uintptr_t glbls;
88*86d949f9SVitaliy Gusev uintptr_t cb_glbls;
89*86d949f9SVitaliy Gusev uintptr_t zonep;
90*86d949f9SVitaliy Gusev
91*86d949f9SVitaliy Gusev if (argc == 1 && argv->a_type == MDB_TYPE_IMMEDIATE) {
92*86d949f9SVitaliy Gusev kstat_named_t ksts;
93*86d949f9SVitaliy Gusev int i;
94*86d949f9SVitaliy Gusev for (i = argv->a_un.a_val; i; i--) {
95*86d949f9SVitaliy Gusev if (mdb_vread(&ksts, sizeof (ksts), addr) < 0) {
96*86d949f9SVitaliy Gusev mdb_warn("failed to read kstat_name_t");
97*86d949f9SVitaliy Gusev return (DCMD_ERR);
98*86d949f9SVitaliy Gusev }
99*86d949f9SVitaliy Gusev mdb_printf(" %8s %30d\n", ksts.name, ksts.value.ui64);
100*86d949f9SVitaliy Gusev addr += sizeof (ksts);
101*86d949f9SVitaliy Gusev }
102*86d949f9SVitaliy Gusev return (DCMD_OK);
103*86d949f9SVitaliy Gusev }
104*86d949f9SVitaliy Gusev
105*86d949f9SVitaliy Gusev if (mdb_getopts(argc, argv,
106*86d949f9SVitaliy Gusev 'a', MDB_OPT_SETBITS, NFS_ACL_STAT, &type_flag,
107*86d949f9SVitaliy Gusev 'b', MDB_OPT_SETBITS, NFS_CB_STAT, &host_flag,
108*86d949f9SVitaliy Gusev 'c', MDB_OPT_SETBITS, NFS_CLNT_STAT, &host_flag,
109*86d949f9SVitaliy Gusev 'n', MDB_OPT_SETBITS, NFS_NFS_STAT, &type_flag,
110*86d949f9SVitaliy Gusev 'r', MDB_OPT_SETBITS, NFS_RPC_STAT, &type_flag,
111*86d949f9SVitaliy Gusev 's', MDB_OPT_SETBITS, NFS_SRV_STAT, &host_flag,
112*86d949f9SVitaliy Gusev '2', MDB_OPT_SETBITS, NFS_V2_STAT, &vers_flag,
113*86d949f9SVitaliy Gusev '3', MDB_OPT_SETBITS, NFS_V3_STAT, &vers_flag,
114*86d949f9SVitaliy Gusev '4', MDB_OPT_SETBITS, NFS_V4_STAT, &vers_flag,
115*86d949f9SVitaliy Gusev NULL) != argc) {
116*86d949f9SVitaliy Gusev return (DCMD_USAGE);
117*86d949f9SVitaliy Gusev }
118*86d949f9SVitaliy Gusev
119*86d949f9SVitaliy Gusev
120*86d949f9SVitaliy Gusev if (flags & DCMD_ADDRSPEC) {
121*86d949f9SVitaliy Gusev zonep = addr;
122*86d949f9SVitaliy Gusev } else {
123*86d949f9SVitaliy Gusev if (mdb_readsym(&zonep, sizeof (uintptr_t),
124*86d949f9SVitaliy Gusev "global_zone") == -1) {
125*86d949f9SVitaliy Gusev mdb_warn("Failed to find global_zone");
126*86d949f9SVitaliy Gusev return (DCMD_ERR);
127*86d949f9SVitaliy Gusev }
128*86d949f9SVitaliy Gusev }
129*86d949f9SVitaliy Gusev
130*86d949f9SVitaliy Gusev if (zoned_get_zsd(zonep, "nfssrv_zone_key", &glbls)) {
131*86d949f9SVitaliy Gusev mdb_warn("Failed to find nfssrv_zone_key");
132*86d949f9SVitaliy Gusev return (DCMD_ERR);
133*86d949f9SVitaliy Gusev }
134*86d949f9SVitaliy Gusev
135*86d949f9SVitaliy Gusev if (mdb_vread(&mdb_stats.nfsglbls, sizeof (struct nfs_globals),
136*86d949f9SVitaliy Gusev glbls) == -1) {
137*86d949f9SVitaliy Gusev mdb_warn("Failed to read nfs_stats at %p", glbls);
138*86d949f9SVitaliy Gusev return (DCMD_ERR);
139*86d949f9SVitaliy Gusev }
140*86d949f9SVitaliy Gusev
141*86d949f9SVitaliy Gusev if (zoned_get_zsd(zonep, "nfsstat_zone_key", &glbls)) {
142*86d949f9SVitaliy Gusev mdb_warn("Failed to find %s", "nfsstat_zone_key");
143*86d949f9SVitaliy Gusev return (DCMD_ERR);
144*86d949f9SVitaliy Gusev }
145*86d949f9SVitaliy Gusev
146*86d949f9SVitaliy Gusev if (mdb_vread(&mdb_stats.nfsstats, sizeof (struct nfs_stats),
147*86d949f9SVitaliy Gusev glbls) == -1) {
148*86d949f9SVitaliy Gusev mdb_warn("Failed to read nfs_stats at %p", glbls);
149*86d949f9SVitaliy Gusev return (DCMD_ERR);
150*86d949f9SVitaliy Gusev }
151*86d949f9SVitaliy Gusev
152*86d949f9SVitaliy Gusev if (zoned_get_zsd(zonep, "rpcstat_zone_key", &glbls)) {
153*86d949f9SVitaliy Gusev mdb_warn("Failed to find %s", "rpcstat_zone_key");
154*86d949f9SVitaliy Gusev return (DCMD_ERR);
155*86d949f9SVitaliy Gusev }
156*86d949f9SVitaliy Gusev
157*86d949f9SVitaliy Gusev if (mdb_vread(&mdb_stats.rpcstats, sizeof (struct rpcstat),
158*86d949f9SVitaliy Gusev glbls) == -1) {
159*86d949f9SVitaliy Gusev mdb_warn("Failed to read nfs_stats at %p", glbls);
160*86d949f9SVitaliy Gusev return (DCMD_ERR);
161*86d949f9SVitaliy Gusev }
162*86d949f9SVitaliy Gusev
163*86d949f9SVitaliy Gusev if (zoned_get_zsd(zonep, "nfsclnt_zone_key", &glbls)) {
164*86d949f9SVitaliy Gusev mdb_warn("Failed to find %s", "nfsclnt_zone_key");
165*86d949f9SVitaliy Gusev return (DCMD_ERR);
166*86d949f9SVitaliy Gusev }
167*86d949f9SVitaliy Gusev mdb_stats.clntstat = glbls + offsetof(struct nfs_clnt, nfscl_stat);
168*86d949f9SVitaliy Gusev
169*86d949f9SVitaliy Gusev if (zoned_get_zsd(zonep, "nfs4clnt_zone_key", &glbls)) {
170*86d949f9SVitaliy Gusev mdb_warn("Failed to find %s", "nfs4clnt_zone_key");
171*86d949f9SVitaliy Gusev return (DCMD_ERR);
172*86d949f9SVitaliy Gusev }
173*86d949f9SVitaliy Gusev /*
174*86d949f9SVitaliy Gusev * currently only have NFSv4.0 is availble. When NFSv4.1 and above are
175*86d949f9SVitaliy Gusev * available stats support will need to be added.
176*86d949f9SVitaliy Gusev */
177*86d949f9SVitaliy Gusev mdb_stats.clntstat4 = glbls + offsetof(struct nfs4_clnt, nfscl_stat);
178*86d949f9SVitaliy Gusev
179*86d949f9SVitaliy Gusev if (zoned_get_zsd(zonep, "nfs4_callback_zone_key",
180*86d949f9SVitaliy Gusev (uintptr_t *)&cb_glbls)) {
181*86d949f9SVitaliy Gusev mdb_warn("Failed to find %s", "nfs4_callback_zone_key");
182*86d949f9SVitaliy Gusev return (DCMD_ERR);
183*86d949f9SVitaliy Gusev }
184*86d949f9SVitaliy Gusev
185*86d949f9SVitaliy Gusev mdb_stats.callback_stats =
186*86d949f9SVitaliy Gusev (cb_glbls + offsetof(struct nfs4_callback_globals,
187*86d949f9SVitaliy Gusev nfs4_callback_stats));
188*86d949f9SVitaliy Gusev
189*86d949f9SVitaliy Gusev if (host_flag == 0)
190*86d949f9SVitaliy Gusev host_flag = NFS_SRV_STAT | NFS_CLNT_STAT | NFS_CB_STAT;
191*86d949f9SVitaliy Gusev if (vers_flag == 0)
192*86d949f9SVitaliy Gusev vers_flag = NFS_V2_STAT | NFS_V3_STAT | NFS_V4_STAT;
193*86d949f9SVitaliy Gusev if (type_flag == 0)
194*86d949f9SVitaliy Gusev type_flag = NFS_NFS_STAT | NFS_ACL_STAT | NFS_RPC_STAT;
195*86d949f9SVitaliy Gusev
196*86d949f9SVitaliy Gusev if (host_flag & NFS_CB_STAT)
197*86d949f9SVitaliy Gusev if (nfs_srvstat_cb(&mdb_stats))
198*86d949f9SVitaliy Gusev return (DCMD_ERR);
199*86d949f9SVitaliy Gusev if (host_flag & NFS_SRV_STAT)
200*86d949f9SVitaliy Gusev if (nfs_stat_srv(&mdb_stats, type_flag, vers_flag))
201*86d949f9SVitaliy Gusev return (DCMD_ERR);
202*86d949f9SVitaliy Gusev if (host_flag & NFS_CLNT_STAT)
203*86d949f9SVitaliy Gusev if (nfs_stat_clnt(&mdb_stats, type_flag, vers_flag))
204*86d949f9SVitaliy Gusev return (DCMD_ERR);
205*86d949f9SVitaliy Gusev return (DCMD_OK);
206*86d949f9SVitaliy Gusev }
207*86d949f9SVitaliy Gusev
208*86d949f9SVitaliy Gusev static int
nfs_srvstat_cb(nfs_mdb_stats_t * stptr)209*86d949f9SVitaliy Gusev nfs_srvstat_cb(nfs_mdb_stats_t *stptr)
210*86d949f9SVitaliy Gusev {
211*86d949f9SVitaliy Gusev int ret = 0;
212*86d949f9SVitaliy Gusev mdb_printf("CALLBACK STATISTICS:\n");
213*86d949f9SVitaliy Gusev
214*86d949f9SVitaliy Gusev ret = prt_nfs_stats(stptr->callback_stats, "nfs4_callback_stats_tmpl");
215*86d949f9SVitaliy Gusev
216*86d949f9SVitaliy Gusev return (ret);
217*86d949f9SVitaliy Gusev }
218*86d949f9SVitaliy Gusev
219*86d949f9SVitaliy Gusev static int
nfs_stat_srv(nfs_mdb_stats_t * stptr,int type_flag,int vers_flag)220*86d949f9SVitaliy Gusev nfs_stat_srv(nfs_mdb_stats_t *stptr, int type_flag, int vers_flag)
221*86d949f9SVitaliy Gusev {
222*86d949f9SVitaliy Gusev mdb_printf("NFS SERVER STATS:\n");
223*86d949f9SVitaliy Gusev if (type_flag & NFS_SRV_STAT) {
224*86d949f9SVitaliy Gusev if (nfs_srvstat(stptr, vers_flag) != 0)
225*86d949f9SVitaliy Gusev return (1);
226*86d949f9SVitaliy Gusev }
227*86d949f9SVitaliy Gusev if (type_flag & NFS_RPC_STAT) {
228*86d949f9SVitaliy Gusev if (nfs_srvstat_rpc(stptr) != 0)
229*86d949f9SVitaliy Gusev return (1);
230*86d949f9SVitaliy Gusev }
231*86d949f9SVitaliy Gusev if (type_flag & NFS_ACL_STAT) {
232*86d949f9SVitaliy Gusev if (nfs_srvstat_acl(stptr, vers_flag) != 0)
233*86d949f9SVitaliy Gusev return (1);
234*86d949f9SVitaliy Gusev }
235*86d949f9SVitaliy Gusev return (0);
236*86d949f9SVitaliy Gusev }
237*86d949f9SVitaliy Gusev
238*86d949f9SVitaliy Gusev static int
nfs_stat_clnt(nfs_mdb_stats_t * stptr,int type_flag,int vers_flag)239*86d949f9SVitaliy Gusev nfs_stat_clnt(nfs_mdb_stats_t *stptr, int type_flag, int vers_flag)
240*86d949f9SVitaliy Gusev {
241*86d949f9SVitaliy Gusev mdb_printf("CLIENT STATISTICS:\n");
242*86d949f9SVitaliy Gusev if (type_flag & NFS_CLNT_STAT) {
243*86d949f9SVitaliy Gusev if (nfs_clntstat(stptr, vers_flag))
244*86d949f9SVitaliy Gusev return (1);
245*86d949f9SVitaliy Gusev }
246*86d949f9SVitaliy Gusev if (type_flag & NFS_ACL_STAT) {
247*86d949f9SVitaliy Gusev if (nfs_clntstat_acl(stptr, vers_flag))
248*86d949f9SVitaliy Gusev return (1);
249*86d949f9SVitaliy Gusev }
250*86d949f9SVitaliy Gusev if (type_flag & NFS_RPC_STAT) {
251*86d949f9SVitaliy Gusev if (nfs_clntstat_rpc(stptr))
252*86d949f9SVitaliy Gusev return (1);
253*86d949f9SVitaliy Gusev }
254*86d949f9SVitaliy Gusev return (0);
255*86d949f9SVitaliy Gusev }
256*86d949f9SVitaliy Gusev
257*86d949f9SVitaliy Gusev
258*86d949f9SVitaliy Gusev static int
nfs_srvstat(nfs_mdb_stats_t * stptr,int flag)259*86d949f9SVitaliy Gusev nfs_srvstat(nfs_mdb_stats_t *stptr, int flag)
260*86d949f9SVitaliy Gusev {
261*86d949f9SVitaliy Gusev mdb_printf("NFS Statistics\n");
262*86d949f9SVitaliy Gusev if (flag & NFS_V2_STAT) {
263*86d949f9SVitaliy Gusev mdb_printf("NFSv2\n");
264*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->nfsglbls.svstat[2],
265*86d949f9SVitaliy Gusev "svstat_tmpl") ||
266*86d949f9SVitaliy Gusev prt_nfs_stats((uintptr_t)stptr->nfsglbls.rfsproccnt[2],
267*86d949f9SVitaliy Gusev "rfsproccnt_v2_tmpl"))
268*86d949f9SVitaliy Gusev return (-1);
269*86d949f9SVitaliy Gusev }
270*86d949f9SVitaliy Gusev if (flag & NFS_V3_STAT) {
271*86d949f9SVitaliy Gusev mdb_printf("NFSv3\n");
272*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->nfsglbls.svstat[3],
273*86d949f9SVitaliy Gusev "svstat_tmpl") ||
274*86d949f9SVitaliy Gusev prt_nfs_stats((uintptr_t)stptr->nfsglbls.rfsproccnt[3],
275*86d949f9SVitaliy Gusev "rfsproccnt_v3_tmpl"))
276*86d949f9SVitaliy Gusev return (-1);
277*86d949f9SVitaliy Gusev }
278*86d949f9SVitaliy Gusev if (flag & NFS_V4_STAT) {
279*86d949f9SVitaliy Gusev mdb_printf("NFSv4\n");
280*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->nfsglbls.svstat[4],
281*86d949f9SVitaliy Gusev "svstat_tmpl") ||
282*86d949f9SVitaliy Gusev prt_nfs_stats((uintptr_t)stptr->nfsglbls.rfsproccnt[4],
283*86d949f9SVitaliy Gusev "rfsproccnt_v4_tmpl"))
284*86d949f9SVitaliy Gusev return (-1);
285*86d949f9SVitaliy Gusev }
286*86d949f9SVitaliy Gusev return (0);
287*86d949f9SVitaliy Gusev }
288*86d949f9SVitaliy Gusev
289*86d949f9SVitaliy Gusev
290*86d949f9SVitaliy Gusev static int
nfs_srvstat_rpc(nfs_mdb_stats_t * stptr)291*86d949f9SVitaliy Gusev nfs_srvstat_rpc(nfs_mdb_stats_t *stptr)
292*86d949f9SVitaliy Gusev {
293*86d949f9SVitaliy Gusev mdb_printf("NFS RPC Statistics\n");
294*86d949f9SVitaliy Gusev mdb_printf("ConnectionLess\n");
295*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->rpcstats.rpc_clts_server,
296*86d949f9SVitaliy Gusev "clts_rsstat_tmpl"))
297*86d949f9SVitaliy Gusev return (-1);
298*86d949f9SVitaliy Gusev mdb_printf("ConnectionOriented\n");
299*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->rpcstats.rpc_cots_server,
300*86d949f9SVitaliy Gusev "cots_rsstat_tmpl"))
301*86d949f9SVitaliy Gusev return (-1);
302*86d949f9SVitaliy Gusev return (0);
303*86d949f9SVitaliy Gusev }
304*86d949f9SVitaliy Gusev
305*86d949f9SVitaliy Gusev
306*86d949f9SVitaliy Gusev static int
nfs_srvstat_acl(nfs_mdb_stats_t * stptr,int flags)307*86d949f9SVitaliy Gusev nfs_srvstat_acl(nfs_mdb_stats_t *stptr, int flags)
308*86d949f9SVitaliy Gusev {
309*86d949f9SVitaliy Gusev mdb_printf("NFS ACL Statistics\n");
310*86d949f9SVitaliy Gusev if (flags & NFS_V2_STAT) {
311*86d949f9SVitaliy Gusev mdb_printf("NFSv2\n");
312*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->nfsglbls.aclproccnt[2],
313*86d949f9SVitaliy Gusev "aclproccnt_v2_tmpl"))
314*86d949f9SVitaliy Gusev return (-1);
315*86d949f9SVitaliy Gusev }
316*86d949f9SVitaliy Gusev if (flags & NFS_V3_STAT) {
317*86d949f9SVitaliy Gusev mdb_printf("NFSv3\n");
318*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->nfsglbls.aclproccnt[3],
319*86d949f9SVitaliy Gusev "aclproccnt_v3_tmpl"))
320*86d949f9SVitaliy Gusev return (-1);
321*86d949f9SVitaliy Gusev }
322*86d949f9SVitaliy Gusev if (flags & NFS_V4_STAT) {
323*86d949f9SVitaliy Gusev mdb_printf("NFSv4\n");
324*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->nfsglbls.aclproccnt[4],
325*86d949f9SVitaliy Gusev "aclreqcnt_v4_tmpl"))
326*86d949f9SVitaliy Gusev return (-1);
327*86d949f9SVitaliy Gusev }
328*86d949f9SVitaliy Gusev return (0);
329*86d949f9SVitaliy Gusev }
330*86d949f9SVitaliy Gusev
331*86d949f9SVitaliy Gusev static int
nfs_clntstat(nfs_mdb_stats_t * stptr,int flags)332*86d949f9SVitaliy Gusev nfs_clntstat(nfs_mdb_stats_t *stptr, int flags)
333*86d949f9SVitaliy Gusev {
334*86d949f9SVitaliy Gusev mdb_printf("NFS Statistics\n");
335*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->clntstat, "clstat_tmpl"))
336*86d949f9SVitaliy Gusev return (-1);
337*86d949f9SVitaliy Gusev if (flags & NFS_V2_STAT) {
338*86d949f9SVitaliy Gusev mdb_printf("Version 2\n");
339*86d949f9SVitaliy Gusev if (prt_nfs_stats(
340*86d949f9SVitaliy Gusev (uintptr_t)stptr->nfsstats.nfs_stats_v2.rfsreqcnt_ptr,
341*86d949f9SVitaliy Gusev "rfsreqcnt_v2_tmpl"))
342*86d949f9SVitaliy Gusev return (-1);
343*86d949f9SVitaliy Gusev }
344*86d949f9SVitaliy Gusev if (flags & NFS_V3_STAT) {
345*86d949f9SVitaliy Gusev mdb_printf("Version 3\n");
346*86d949f9SVitaliy Gusev if (prt_nfs_stats(
347*86d949f9SVitaliy Gusev (uintptr_t)stptr->nfsstats.nfs_stats_v3.rfsreqcnt_ptr,
348*86d949f9SVitaliy Gusev "rfsreqcnt_v3_tmpl"))
349*86d949f9SVitaliy Gusev return (-1);
350*86d949f9SVitaliy Gusev }
351*86d949f9SVitaliy Gusev if (flags & NFS_V4_STAT) {
352*86d949f9SVitaliy Gusev mdb_printf("NFSv4 client\n");
353*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->clntstat, "clstat4_tmpl"))
354*86d949f9SVitaliy Gusev return (-1);
355*86d949f9SVitaliy Gusev mdb_printf("Version 4\n");
356*86d949f9SVitaliy Gusev if (prt_nfs_stats(
357*86d949f9SVitaliy Gusev (uintptr_t)stptr->nfsstats.nfs_stats_v4.rfsreqcnt_ptr,
358*86d949f9SVitaliy Gusev "rfsreqcnt_v4_tmpl"))
359*86d949f9SVitaliy Gusev return (-1);
360*86d949f9SVitaliy Gusev }
361*86d949f9SVitaliy Gusev return (0);
362*86d949f9SVitaliy Gusev }
363*86d949f9SVitaliy Gusev
364*86d949f9SVitaliy Gusev static int
nfs_clntstat_rpc(nfs_mdb_stats_t * stptr)365*86d949f9SVitaliy Gusev nfs_clntstat_rpc(nfs_mdb_stats_t *stptr)
366*86d949f9SVitaliy Gusev {
367*86d949f9SVitaliy Gusev mdb_printf("NFS RPC Statistics\n");
368*86d949f9SVitaliy Gusev mdb_printf("ConnectionLess\n");
369*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->rpcstats.rpc_clts_client,
370*86d949f9SVitaliy Gusev "clts_rcstat_tmpl"))
371*86d949f9SVitaliy Gusev return (-1);
372*86d949f9SVitaliy Gusev mdb_printf("ConnectionOriented\n");
373*86d949f9SVitaliy Gusev if (prt_nfs_stats((uintptr_t)stptr->rpcstats.rpc_cots_client,
374*86d949f9SVitaliy Gusev "cots_rcstat_tmpl"))
375*86d949f9SVitaliy Gusev return (-1);
376*86d949f9SVitaliy Gusev return (0);
377*86d949f9SVitaliy Gusev }
378*86d949f9SVitaliy Gusev
379*86d949f9SVitaliy Gusev static int
nfs_clntstat_acl(nfs_mdb_stats_t * stptr,int flags)380*86d949f9SVitaliy Gusev nfs_clntstat_acl(nfs_mdb_stats_t *stptr, int flags)
381*86d949f9SVitaliy Gusev {
382*86d949f9SVitaliy Gusev mdb_printf("ACL Statistics\n");
383*86d949f9SVitaliy Gusev if (flags & NFS_V2_STAT) {
384*86d949f9SVitaliy Gusev mdb_printf("Version 2\n");
385*86d949f9SVitaliy Gusev if (prt_nfs_stats(
386*86d949f9SVitaliy Gusev (uintptr_t)stptr->nfsstats.nfs_stats_v2.aclreqcnt_ptr,
387*86d949f9SVitaliy Gusev "aclreqcnt_v2_tmpl"))
388*86d949f9SVitaliy Gusev return (-1);
389*86d949f9SVitaliy Gusev }
390*86d949f9SVitaliy Gusev if (flags & NFS_V3_STAT) {
391*86d949f9SVitaliy Gusev mdb_printf("Version 3\n");
392*86d949f9SVitaliy Gusev if (prt_nfs_stats(
393*86d949f9SVitaliy Gusev (uintptr_t)stptr->nfsstats.nfs_stats_v3.aclreqcnt_ptr,
394*86d949f9SVitaliy Gusev "aclreqcnt_v3_tmpl"))
395*86d949f9SVitaliy Gusev return (-1);
396*86d949f9SVitaliy Gusev }
397*86d949f9SVitaliy Gusev if (flags & NFS_V4_STAT) {
398*86d949f9SVitaliy Gusev mdb_printf("Version 4\n");
399*86d949f9SVitaliy Gusev if (prt_nfs_stats(
400*86d949f9SVitaliy Gusev (uintptr_t)stptr->nfsstats.nfs_stats_v4.aclreqcnt_ptr,
401*86d949f9SVitaliy Gusev "aclreqcnt_v4_tmpl"))
402*86d949f9SVitaliy Gusev return (-1);
403*86d949f9SVitaliy Gusev }
404*86d949f9SVitaliy Gusev return (0);
405*86d949f9SVitaliy Gusev }
406*86d949f9SVitaliy Gusev
407*86d949f9SVitaliy Gusev
408*86d949f9SVitaliy Gusev /*
409*86d949f9SVitaliy Gusev * helper functions for printing out the kstat data
410*86d949f9SVitaliy Gusev */
411*86d949f9SVitaliy Gusev
412*86d949f9SVitaliy Gusev #define NFS_STAT_NUM_CLMNS 16
413*86d949f9SVitaliy Gusev
414*86d949f9SVitaliy Gusev static int
prt_nfs_stats(uintptr_t addr,char * name)415*86d949f9SVitaliy Gusev prt_nfs_stats(uintptr_t addr, char *name)
416*86d949f9SVitaliy Gusev {
417*86d949f9SVitaliy Gusev
418*86d949f9SVitaliy Gusev GElf_Sym sym;
419*86d949f9SVitaliy Gusev kstat_named_t kstats;
420*86d949f9SVitaliy Gusev char *kstat_line;
421*86d949f9SVitaliy Gusev uint64_t *value;
422*86d949f9SVitaliy Gusev uint_t count;
423*86d949f9SVitaliy Gusev int i = 0, status = 0;
424*86d949f9SVitaliy Gusev
425*86d949f9SVitaliy Gusev
426*86d949f9SVitaliy Gusev if (mdb_lookup_by_name(name, &sym) != 0) {
427*86d949f9SVitaliy Gusev mdb_warn("failed to find %s", name);
428*86d949f9SVitaliy Gusev return (1);
429*86d949f9SVitaliy Gusev }
430*86d949f9SVitaliy Gusev
431*86d949f9SVitaliy Gusev count = sym.st_size / sizeof (kstat_named_t);
432*86d949f9SVitaliy Gusev
433*86d949f9SVitaliy Gusev kstat_line = mdb_alloc(count * NFS_STAT_NUM_CLMNS, UM_SLEEP);
434*86d949f9SVitaliy Gusev value = mdb_alloc(count * sizeof (uint64_t), UM_SLEEP);
435*86d949f9SVitaliy Gusev for (i = 0; i < count; i++) {
436*86d949f9SVitaliy Gusev if (mdb_vread(&kstats, sizeof (kstat_named_t),
437*86d949f9SVitaliy Gusev addr + (i * sizeof (kstat_named_t))) < 0) {
438*86d949f9SVitaliy Gusev status = 1;
439*86d949f9SVitaliy Gusev goto done;
440*86d949f9SVitaliy Gusev }
441*86d949f9SVitaliy Gusev mdb_snprintf(&kstat_line[NFS_STAT_NUM_CLMNS * i],
442*86d949f9SVitaliy Gusev NFS_STAT_NUM_CLMNS, "%s", kstats.name);
443*86d949f9SVitaliy Gusev value[i] = kstats.value.ui64;
444*86d949f9SVitaliy Gusev }
445*86d949f9SVitaliy Gusev kstat_prtout(kstat_line, value, count);
446*86d949f9SVitaliy Gusev done:
447*86d949f9SVitaliy Gusev mdb_free(kstat_line, count * NFS_STAT_NUM_CLMNS);
448*86d949f9SVitaliy Gusev mdb_free(value, count * sizeof (uint64_t));
449*86d949f9SVitaliy Gusev return (status);
450*86d949f9SVitaliy Gusev }
451*86d949f9SVitaliy Gusev
452*86d949f9SVitaliy Gusev static void
kstat_prtout(char * ks_line,uint64_t * values,int count)453*86d949f9SVitaliy Gusev kstat_prtout(char *ks_line, uint64_t *values, int count)
454*86d949f9SVitaliy Gusev {
455*86d949f9SVitaliy Gusev char val_str[32];
456*86d949f9SVitaliy Gusev int i = 0, num = 0;
457*86d949f9SVitaliy Gusev
458*86d949f9SVitaliy Gusev while (i < count) {
459*86d949f9SVitaliy Gusev mdb_printf("%-*s", NFS_STAT_NUM_CLMNS,
460*86d949f9SVitaliy Gusev &ks_line[NFS_STAT_NUM_CLMNS * i]);
461*86d949f9SVitaliy Gusev
462*86d949f9SVitaliy Gusev num++;
463*86d949f9SVitaliy Gusev if (num == NFS_STAT_NUM_STATS / NFS_STAT_NUM_CLMNS) {
464*86d949f9SVitaliy Gusev mdb_printf("\n");
465*86d949f9SVitaliy Gusev while (num > 0) {
466*86d949f9SVitaliy Gusev mdb_snprintf(val_str, 24, "%ld ",
467*86d949f9SVitaliy Gusev values[i+1-num]);
468*86d949f9SVitaliy Gusev mdb_printf("%-*s", NFS_STAT_NUM_CLMNS, val_str);
469*86d949f9SVitaliy Gusev --num;
470*86d949f9SVitaliy Gusev }
471*86d949f9SVitaliy Gusev mdb_printf("\n");
472*86d949f9SVitaliy Gusev }
473*86d949f9SVitaliy Gusev i++;
474*86d949f9SVitaliy Gusev }
475*86d949f9SVitaliy Gusev mdb_printf("\n");
476*86d949f9SVitaliy Gusev }
477