xref: /illumos-gate/usr/src/cmd/mdb/common/modules/nfs/nfs_clnt.c (revision 86d949f9497332fe19be6b5d711d265eb957439f)
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/mdb_modapi.h>
16*86d949f9SVitaliy Gusev #include <sys/list.h>
17*86d949f9SVitaliy Gusev #include <nfs/rnode.h>
18*86d949f9SVitaliy Gusev #include <nfs/rnode4.h>
19*86d949f9SVitaliy Gusev #include <nfs/nfs_clnt.h>
20*86d949f9SVitaliy Gusev #include <nfs/nfs4_clnt.h>
21*86d949f9SVitaliy Gusev #include <mdb/mdb_ks.h>
22*86d949f9SVitaliy Gusev #include <mdb/mdb_ctf.h>
23*86d949f9SVitaliy Gusev 
24*86d949f9SVitaliy Gusev #include "nfs_clnt.h"
25*86d949f9SVitaliy Gusev #include "common.h"
26*86d949f9SVitaliy Gusev 
27*86d949f9SVitaliy Gusev /*
28*86d949f9SVitaliy Gusev  * Common functions
29*86d949f9SVitaliy Gusev  */
30*86d949f9SVitaliy Gusev 
31*86d949f9SVitaliy Gusev static void
nfs_print_io_stat(uintptr_t kstat_addr)32*86d949f9SVitaliy Gusev nfs_print_io_stat(uintptr_t kstat_addr)
33*86d949f9SVitaliy Gusev {
34*86d949f9SVitaliy Gusev 	kstat_t kstat;
35*86d949f9SVitaliy Gusev 	kstat_io_t kstat_io;
36*86d949f9SVitaliy Gusev 
37*86d949f9SVitaliy Gusev 	mdb_printf("IO statistics for this mount:\n");
38*86d949f9SVitaliy Gusev 	mdb_inc_indent(2);
39*86d949f9SVitaliy Gusev 
40*86d949f9SVitaliy Gusev 	if (mdb_vread(&kstat, sizeof (kstat), kstat_addr) == -1 ||
41*86d949f9SVitaliy Gusev 	    mdb_vread(&kstat_io, sizeof (kstat_io),
42*86d949f9SVitaliy Gusev 	    (uintptr_t)KSTAT_IO_PTR(&kstat)) == -1) {
43*86d949f9SVitaliy Gusev 		mdb_printf("No. of bytes read:       %9s\n", "??");
44*86d949f9SVitaliy Gusev 		mdb_printf("No. of read operations:  %9s\n", "??");
45*86d949f9SVitaliy Gusev 		mdb_printf("No. of bytes written:    %9s\n", "??");
46*86d949f9SVitaliy Gusev 		mdb_printf("No. of write operations: %9s\n", "??");
47*86d949f9SVitaliy Gusev 	} else {
48*86d949f9SVitaliy Gusev 		mdb_printf("No. of bytes read:       %9llu\n", kstat_io.nread);
49*86d949f9SVitaliy Gusev 		mdb_printf("No. of read operations:  %9lu\n", kstat_io.reads);
50*86d949f9SVitaliy Gusev 		mdb_printf("No. of bytes written:    %9llu\n",
51*86d949f9SVitaliy Gusev 		    kstat_io.nwritten);
52*86d949f9SVitaliy Gusev 		mdb_printf("No. of write operations: %9lu\n", kstat_io.writes);
53*86d949f9SVitaliy Gusev 	}
54*86d949f9SVitaliy Gusev 
55*86d949f9SVitaliy Gusev 	mdb_dec_indent(2);
56*86d949f9SVitaliy Gusev }
57*86d949f9SVitaliy Gusev 
58*86d949f9SVitaliy Gusev static int
walk_count_cb(uintptr_t addr,const void * data,void * cb_data)59*86d949f9SVitaliy Gusev walk_count_cb(uintptr_t addr, const void *data, void *cb_data)
60*86d949f9SVitaliy Gusev {
61*86d949f9SVitaliy Gusev 	(*(size_t *)cb_data)++;
62*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
63*86d949f9SVitaliy Gusev }
64*86d949f9SVitaliy Gusev 
65*86d949f9SVitaliy Gusev #define	TBL_ENTRY(e)	{#e, e}
66*86d949f9SVitaliy Gusev 
67*86d949f9SVitaliy Gusev static const struct {
68*86d949f9SVitaliy Gusev 	const char *str;
69*86d949f9SVitaliy Gusev 	nfs_opnum4 op;
70*86d949f9SVitaliy Gusev } nfs4_op_tbl[] = {
71*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_ACCESS),
72*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_CLOSE),
73*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_COMMIT),
74*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_CREATE),
75*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_DELEGPURGE),
76*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_DELEGRETURN),
77*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_GETATTR),
78*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_GETFH),
79*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_LINK),
80*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_LOCK),
81*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_LOCKT),
82*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_LOCKU),
83*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_LOOKUP),
84*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_LOOKUPP),
85*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_NVERIFY),
86*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_OPEN),
87*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_OPENATTR),
88*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_OPEN_CONFIRM),
89*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_OPEN_DOWNGRADE),
90*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_PUTFH),
91*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_PUTPUBFH),
92*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_PUTROOTFH),
93*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_READ),
94*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_READDIR),
95*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_READLINK),
96*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_REMOVE),
97*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_RENAME),
98*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_RENEW),
99*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_RESTOREFH),
100*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_SAVEFH),
101*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_SECINFO),
102*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_SETATTR),
103*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_SETCLIENTID),
104*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_SETCLIENTID_CONFIRM),
105*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_VERIFY),
106*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_WRITE),
107*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_RELEASE_LOCKOWNER),
108*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_ILLEGAL),
109*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_CCREATE),
110*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_CLINK),
111*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_CLOOKUP),
112*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_COPEN),
113*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_CPUTFH),
114*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_CREMOVE),
115*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_CRENAME),
116*86d949f9SVitaliy Gusev 	TBL_ENTRY(OP_CSECINFO),
117*86d949f9SVitaliy Gusev 	{NULL}
118*86d949f9SVitaliy Gusev };
119*86d949f9SVitaliy Gusev 
120*86d949f9SVitaliy Gusev static const char *
nfs4_op_str(nfs_opnum4 op)121*86d949f9SVitaliy Gusev nfs4_op_str(nfs_opnum4 op)
122*86d949f9SVitaliy Gusev {
123*86d949f9SVitaliy Gusev 	int i;
124*86d949f9SVitaliy Gusev 
125*86d949f9SVitaliy Gusev 	for (i = 0; nfs4_op_tbl[i].str != NULL; i++)
126*86d949f9SVitaliy Gusev 		if (nfs4_op_tbl[i].op == op)
127*86d949f9SVitaliy Gusev 			return (nfs4_op_tbl[i].str);
128*86d949f9SVitaliy Gusev 
129*86d949f9SVitaliy Gusev 	return ("??");
130*86d949f9SVitaliy Gusev }
131*86d949f9SVitaliy Gusev 
132*86d949f9SVitaliy Gusev static const struct {
133*86d949f9SVitaliy Gusev 	const char *str;
134*86d949f9SVitaliy Gusev 	nfs4_recov_t action;
135*86d949f9SVitaliy Gusev } nfs4_recov_tbl[] = {
136*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_UNUSED),
137*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_CLIENTID),
138*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_OPENFILES),
139*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_FHEXPIRED),
140*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_FAILOVER),
141*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_WRONGSEC),
142*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_EXPIRED),
143*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_BAD_STATEID),
144*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_BADHANDLE),
145*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_BAD_SEQID),
146*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_OLDSTATEID),
147*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_GRACE),
148*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_DELAY),
149*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_LOST_LOCK),
150*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_LOST_STATE_RQST),
151*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_STALE),
152*86d949f9SVitaliy Gusev 	TBL_ENTRY(NR_MOVED),
153*86d949f9SVitaliy Gusev 	{NULL}
154*86d949f9SVitaliy Gusev };
155*86d949f9SVitaliy Gusev 
156*86d949f9SVitaliy Gusev static const char *
nfs4_recov_str(nfs4_recov_t action)157*86d949f9SVitaliy Gusev nfs4_recov_str(nfs4_recov_t action)
158*86d949f9SVitaliy Gusev {
159*86d949f9SVitaliy Gusev 	int i;
160*86d949f9SVitaliy Gusev 
161*86d949f9SVitaliy Gusev 	for (i = 0; nfs4_recov_tbl[i].str != NULL; i++)
162*86d949f9SVitaliy Gusev 		if (nfs4_recov_tbl[i].action == action)
163*86d949f9SVitaliy Gusev 			return (nfs4_recov_tbl[i].str);
164*86d949f9SVitaliy Gusev 
165*86d949f9SVitaliy Gusev 	return ("??");
166*86d949f9SVitaliy Gusev }
167*86d949f9SVitaliy Gusev 
168*86d949f9SVitaliy Gusev static const struct {
169*86d949f9SVitaliy Gusev 	const char *str;
170*86d949f9SVitaliy Gusev 	nfsstat4 stat;
171*86d949f9SVitaliy Gusev } nfs4_stat_tbl[] = {
172*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4_OK),
173*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_PERM),
174*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NOENT),
175*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_IO),
176*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NXIO),
177*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_ACCESS),
178*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_EXIST),
179*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_XDEV),
180*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NOTDIR),
181*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_ISDIR),
182*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_INVAL),
183*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_FBIG),
184*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NOSPC),
185*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_ROFS),
186*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_MLINK),
187*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NAMETOOLONG),
188*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NOTEMPTY),
189*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_DQUOT),
190*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_STALE),
191*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BADHANDLE),
192*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BAD_COOKIE),
193*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NOTSUPP),
194*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_TOOSMALL),
195*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_SERVERFAULT),
196*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BADTYPE),
197*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_DELAY),
198*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_SAME),
199*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_DENIED),
200*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_EXPIRED),
201*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_LOCKED),
202*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_GRACE),
203*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_FHEXPIRED),
204*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_SHARE_DENIED),
205*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_WRONGSEC),
206*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_CLID_INUSE),
207*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_RESOURCE),
208*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_MOVED),
209*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NOFILEHANDLE),
210*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_MINOR_VERS_MISMATCH),
211*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_STALE_CLIENTID),
212*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_STALE_STATEID),
213*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_OLD_STATEID),
214*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BAD_STATEID),
215*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BAD_SEQID),
216*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NOT_SAME),
217*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_LOCK_RANGE),
218*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_SYMLINK),
219*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_RESTOREFH),
220*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_LEASE_MOVED),
221*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_ATTRNOTSUPP),
222*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_NO_GRACE),
223*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_RECLAIM_BAD),
224*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_RECLAIM_CONFLICT),
225*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BADXDR),
226*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_LOCKS_HELD),
227*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_OPENMODE),
228*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BADOWNER),
229*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BADCHAR),
230*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BADNAME),
231*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_BAD_RANGE),
232*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_LOCK_NOTSUPP),
233*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_OP_ILLEGAL),
234*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_DEADLOCK),
235*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_FILE_OPEN),
236*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_ADMIN_REVOKED),
237*86d949f9SVitaliy Gusev 	TBL_ENTRY(NFS4ERR_CB_PATH_DOWN),
238*86d949f9SVitaliy Gusev 	{NULL}
239*86d949f9SVitaliy Gusev };
240*86d949f9SVitaliy Gusev 
241*86d949f9SVitaliy Gusev static const char *
nfs4_stat_str(nfsstat4 stat)242*86d949f9SVitaliy Gusev nfs4_stat_str(nfsstat4 stat)
243*86d949f9SVitaliy Gusev {
244*86d949f9SVitaliy Gusev 	int i;
245*86d949f9SVitaliy Gusev 
246*86d949f9SVitaliy Gusev 	for (i = 0; nfs4_stat_tbl[i].str != NULL; i++)
247*86d949f9SVitaliy Gusev 		if (nfs4_stat_tbl[i].stat == stat)
248*86d949f9SVitaliy Gusev 			return (nfs4_stat_tbl[i].str);
249*86d949f9SVitaliy Gusev 
250*86d949f9SVitaliy Gusev 	return ("??");
251*86d949f9SVitaliy Gusev }
252*86d949f9SVitaliy Gusev 
253*86d949f9SVitaliy Gusev static const struct {
254*86d949f9SVitaliy Gusev 	const char *str;
255*86d949f9SVitaliy Gusev 	nfs4_tag_type_t tt;
256*86d949f9SVitaliy Gusev } nfs4_tag_tbl[] = {
257*86d949f9SVitaliy Gusev 	{"", TAG_NONE},
258*86d949f9SVitaliy Gusev 	{"access", TAG_ACCESS},
259*86d949f9SVitaliy Gusev 	{"close", TAG_CLOSE},
260*86d949f9SVitaliy Gusev 	{"lost close", TAG_CLOSE_LOST},
261*86d949f9SVitaliy Gusev 	{"undo close", TAG_CLOSE_UNDO},
262*86d949f9SVitaliy Gusev 	{"commit", TAG_COMMIT},
263*86d949f9SVitaliy Gusev 	{"delegreturn", TAG_DELEGRETURN},
264*86d949f9SVitaliy Gusev 	{"fsinfo", TAG_FSINFO},
265*86d949f9SVitaliy Gusev 	{"get symlink text", TAG_GET_SYMLINK},
266*86d949f9SVitaliy Gusev 	{"getattr", TAG_GETATTR},
267*86d949f9SVitaliy Gusev 	{"getattr fslocation", TAG_GETATTR_FSLOCATION},
268*86d949f9SVitaliy Gusev 	{"inactive", TAG_INACTIVE},
269*86d949f9SVitaliy Gusev 	{"link", TAG_LINK},
270*86d949f9SVitaliy Gusev 	{"lock", TAG_LOCK},
271*86d949f9SVitaliy Gusev 	{"reclaim lock", TAG_LOCK_RECLAIM},
272*86d949f9SVitaliy Gusev 	{"resend lock", TAG_LOCK_RESEND},
273*86d949f9SVitaliy Gusev 	{"reinstate lock", TAG_LOCK_REINSTATE},
274*86d949f9SVitaliy Gusev 	{"unknown lock", TAG_LOCK_UNKNOWN},
275*86d949f9SVitaliy Gusev 	{"lock test", TAG_LOCKT},
276*86d949f9SVitaliy Gusev 	{"unlock", TAG_LOCKU},
277*86d949f9SVitaliy Gusev 	{"resend locku", TAG_LOCKU_RESEND},
278*86d949f9SVitaliy Gusev 	{"reinstate unlock", TAG_LOCKU_REINSTATE},
279*86d949f9SVitaliy Gusev 	{"lookup", TAG_LOOKUP},
280*86d949f9SVitaliy Gusev 	{"lookup parent", TAG_LOOKUP_PARENT},
281*86d949f9SVitaliy Gusev 	{"lookup valid", TAG_LOOKUP_VALID},
282*86d949f9SVitaliy Gusev 	{"lookup valid parent", TAG_LOOKUP_VPARENT},
283*86d949f9SVitaliy Gusev 	{"mkdir", TAG_MKDIR},
284*86d949f9SVitaliy Gusev 	{"mknod", TAG_MKNOD},
285*86d949f9SVitaliy Gusev 	{"mount", TAG_MOUNT},
286*86d949f9SVitaliy Gusev 	{"open", TAG_OPEN},
287*86d949f9SVitaliy Gusev 	{"open confirm", TAG_OPEN_CONFIRM},
288*86d949f9SVitaliy Gusev 	{"lost open confirm", TAG_OPEN_CONFIRM_LOST},
289*86d949f9SVitaliy Gusev 	{"open downgrade", TAG_OPEN_DG},
290*86d949f9SVitaliy Gusev 	{"lost open downgrade", TAG_OPEN_DG_LOST},
291*86d949f9SVitaliy Gusev 	{"lost open", TAG_OPEN_LOST},
292*86d949f9SVitaliy Gusev 	{"openattr", TAG_OPENATTR},
293*86d949f9SVitaliy Gusev 	{"pathconf", TAG_PATHCONF},
294*86d949f9SVitaliy Gusev 	{"putrootfh", TAG_PUTROOTFH},
295*86d949f9SVitaliy Gusev 	{"read", TAG_READ},
296*86d949f9SVitaliy Gusev 	{"readahead", TAG_READAHEAD},
297*86d949f9SVitaliy Gusev 	{"readdir", TAG_READDIR},
298*86d949f9SVitaliy Gusev 	{"readlink", TAG_READLINK},
299*86d949f9SVitaliy Gusev 	{"relock", TAG_RELOCK},
300*86d949f9SVitaliy Gusev 	{"remap lookup", TAG_REMAP_LOOKUP},
301*86d949f9SVitaliy Gusev 	{"remap lookup attr dir", TAG_REMAP_LOOKUP_AD},
302*86d949f9SVitaliy Gusev 	{"remap lookup named attrs", TAG_REMAP_LOOKUP_NA},
303*86d949f9SVitaliy Gusev 	{"remap mount", TAG_REMAP_MOUNT},
304*86d949f9SVitaliy Gusev 	{"rmdir", TAG_RMDIR},
305*86d949f9SVitaliy Gusev 	{"remove", TAG_REMOVE},
306*86d949f9SVitaliy Gusev 	{"rename", TAG_RENAME},
307*86d949f9SVitaliy Gusev 	{"rename volatile fh", TAG_RENAME_VFH},
308*86d949f9SVitaliy Gusev 	{"renew", TAG_RENEW},
309*86d949f9SVitaliy Gusev 	{"reopen", TAG_REOPEN},
310*86d949f9SVitaliy Gusev 	{"lost reopen", TAG_REOPEN_LOST},
311*86d949f9SVitaliy Gusev 	{"secinfo", TAG_SECINFO},
312*86d949f9SVitaliy Gusev 	{"setattr", TAG_SETATTR},
313*86d949f9SVitaliy Gusev 	{"setclientid", TAG_SETCLIENTID},
314*86d949f9SVitaliy Gusev 	{"setclientid_confirm", TAG_SETCLIENTID_CF},
315*86d949f9SVitaliy Gusev 	{"symlink", TAG_SYMLINK},
316*86d949f9SVitaliy Gusev 	{"write", TAG_WRITE},
317*86d949f9SVitaliy Gusev 	{NULL, 0}
318*86d949f9SVitaliy Gusev };
319*86d949f9SVitaliy Gusev 
320*86d949f9SVitaliy Gusev static const char *
nfs4_tag_str(nfs4_tag_type_t tt)321*86d949f9SVitaliy Gusev nfs4_tag_str(nfs4_tag_type_t tt)
322*86d949f9SVitaliy Gusev {
323*86d949f9SVitaliy Gusev 	int i;
324*86d949f9SVitaliy Gusev 
325*86d949f9SVitaliy Gusev 	for (i = 0; nfs4_tag_tbl[i].str != NULL; i++)
326*86d949f9SVitaliy Gusev 		if (nfs4_tag_tbl[i].tt == tt)
327*86d949f9SVitaliy Gusev 			return (nfs4_tag_tbl[i].str);
328*86d949f9SVitaliy Gusev 
329*86d949f9SVitaliy Gusev 	return ("??");
330*86d949f9SVitaliy Gusev }
331*86d949f9SVitaliy Gusev 
332*86d949f9SVitaliy Gusev /*
333*86d949f9SVitaliy Gusev  * nfs_mntinfo dcmd implementation
334*86d949f9SVitaliy Gusev  */
335*86d949f9SVitaliy Gusev 
336*86d949f9SVitaliy Gusev static const mdb_bitmask_t nfs_mi_flags[] = {
337*86d949f9SVitaliy Gusev 	{"MI_HARD", MI_HARD, MI_HARD},
338*86d949f9SVitaliy Gusev 	{"MI_PRINTED", MI_PRINTED, MI_PRINTED},
339*86d949f9SVitaliy Gusev 	{"MI_INT", MI_INT, MI_INT},
340*86d949f9SVitaliy Gusev 	{"MI_DOWN", MI_DOWN, MI_DOWN},
341*86d949f9SVitaliy Gusev 	{"MI_NOAC", MI_NOAC, MI_NOAC},
342*86d949f9SVitaliy Gusev 	{"MI_NOCTO", MI_NOCTO, MI_NOCTO},
343*86d949f9SVitaliy Gusev 	{"MI_DYNAMIC", MI_DYNAMIC, MI_DYNAMIC},
344*86d949f9SVitaliy Gusev 	{"MI_LLOCK", MI_LLOCK, MI_LLOCK},
345*86d949f9SVitaliy Gusev 	{"MI_GRPID", MI_GRPID, MI_GRPID},
346*86d949f9SVitaliy Gusev 	{"MI_RPCTIMESYNC", MI_RPCTIMESYNC, MI_RPCTIMESYNC},
347*86d949f9SVitaliy Gusev 	{"MI_LINK", MI_LINK, MI_LINK},
348*86d949f9SVitaliy Gusev 	{"MI_SYMLINK", MI_SYMLINK, MI_SYMLINK},
349*86d949f9SVitaliy Gusev 	{"MI_READDIRONLY", MI_READDIRONLY, MI_READDIRONLY},
350*86d949f9SVitaliy Gusev 	{"MI_ACL", MI_ACL, MI_ACL},
351*86d949f9SVitaliy Gusev 	{"MI_BINDINPROG", MI_BINDINPROG, MI_BINDINPROG},
352*86d949f9SVitaliy Gusev 	{"MI_LOOPBACK", MI_LOOPBACK, MI_LOOPBACK},
353*86d949f9SVitaliy Gusev 	{"MI_SEMISOFT", MI_SEMISOFT, MI_SEMISOFT},
354*86d949f9SVitaliy Gusev 	{"MI_NOPRINT", MI_NOPRINT, MI_NOPRINT},
355*86d949f9SVitaliy Gusev 	{"MI_DIRECTIO", MI_DIRECTIO, MI_DIRECTIO},
356*86d949f9SVitaliy Gusev 	{"MI_EXTATTR", MI_EXTATTR, MI_EXTATTR},
357*86d949f9SVitaliy Gusev 	{"MI_ASYNC_MGR_STOP", MI_ASYNC_MGR_STOP, MI_ASYNC_MGR_STOP},
358*86d949f9SVitaliy Gusev 	{"MI_DEAD", MI_DEAD, MI_DEAD},
359*86d949f9SVitaliy Gusev 	{NULL, 0, 0}
360*86d949f9SVitaliy Gusev };
361*86d949f9SVitaliy Gusev 
362*86d949f9SVitaliy Gusev static int
nfs_print_mntinfo_cb(uintptr_t addr,const void * data,void * cb_data)363*86d949f9SVitaliy Gusev nfs_print_mntinfo_cb(uintptr_t addr, const void *data, void *cb_data)
364*86d949f9SVitaliy Gusev {
365*86d949f9SVitaliy Gusev 	const mntinfo_t *mi = data;
366*86d949f9SVitaliy Gusev 	uintptr_t nfs3_ops;
367*86d949f9SVitaliy Gusev 	vfs_t vfs;
368*86d949f9SVitaliy Gusev 	char buf[MAXPATHLEN];
369*86d949f9SVitaliy Gusev 	uint_t opt_v = *(uint_t *)cb_data;
370*86d949f9SVitaliy Gusev 	int i;
371*86d949f9SVitaliy Gusev 
372*86d949f9SVitaliy Gusev 	if (mdb_readvar(&nfs3_ops, "nfs3_vfsops") == -1) {
373*86d949f9SVitaliy Gusev 		mdb_warn("failed to read %s", "nfs3_vfsops");
374*86d949f9SVitaliy Gusev 		return (WALK_ERR);
375*86d949f9SVitaliy Gusev 	}
376*86d949f9SVitaliy Gusev 
377*86d949f9SVitaliy Gusev 	if (mdb_vread(&vfs, sizeof (vfs), (uintptr_t)mi->mi_vfsp) == -1) {
378*86d949f9SVitaliy Gusev 		mdb_warn("failed to read vfs_t at %p", mi->mi_vfsp);
379*86d949f9SVitaliy Gusev 		return (WALK_ERR);
380*86d949f9SVitaliy Gusev 	}
381*86d949f9SVitaliy Gusev 
382*86d949f9SVitaliy Gusev 	mdb_printf("NFS Version: %d\n",
383*86d949f9SVitaliy Gusev 	    nfs3_ops == (uintptr_t)vfs.vfs_op ? 3 : 2);
384*86d949f9SVitaliy Gusev 	mdb_inc_indent(2);
385*86d949f9SVitaliy Gusev 
386*86d949f9SVitaliy Gusev 	mdb_printf("mi_flags:    %b\n", mi->mi_flags, nfs_mi_flags);
387*86d949f9SVitaliy Gusev 	if (mdb_read_refstr((uintptr_t)vfs.vfs_mntpt, buf,
388*86d949f9SVitaliy Gusev 	    sizeof (buf)) == -1)
389*86d949f9SVitaliy Gusev 		strcpy(buf, "??");
390*86d949f9SVitaliy Gusev 	mdb_printf("mount point: %s\n", buf);
391*86d949f9SVitaliy Gusev 	if (mdb_read_refstr((uintptr_t)vfs.vfs_resource, buf,
392*86d949f9SVitaliy Gusev 	    sizeof (buf)) == -1)
393*86d949f9SVitaliy Gusev 		strcpy(buf, "??");
394*86d949f9SVitaliy Gusev 	mdb_printf("mount from:  %s\n", buf);
395*86d949f9SVitaliy Gusev 
396*86d949f9SVitaliy Gusev 	mdb_dec_indent(2);
397*86d949f9SVitaliy Gusev 	mdb_printf("\n");
398*86d949f9SVitaliy Gusev 
399*86d949f9SVitaliy Gusev 	if (!opt_v)
400*86d949f9SVitaliy Gusev 		return (WALK_NEXT);
401*86d949f9SVitaliy Gusev 
402*86d949f9SVitaliy Gusev 	mdb_inc_indent(2);
403*86d949f9SVitaliy Gusev 
404*86d949f9SVitaliy Gusev 	mdb_printf("mi_zone = %p\n", mi->mi_zone);
405*86d949f9SVitaliy Gusev 	mdb_printf("mi_curread = %i, mi_curwrite = %i, mi_retrans = %i, "
406*86d949f9SVitaliy Gusev 	    "mi_timeo = %i\n", mi->mi_curread, mi->mi_curwrite, mi->mi_retrans,
407*86d949f9SVitaliy Gusev 	    mi->mi_timeo);
408*86d949f9SVitaliy Gusev 	mdb_printf("mi_acregmin = %lu, mi_acregmax = %lu, mi_acdirmin = %lu, "
409*86d949f9SVitaliy Gusev 	    "mi_acdirmax = %lu\n", mi->mi_acregmin, mi->mi_acregmax,
410*86d949f9SVitaliy Gusev 	    mi->mi_acdirmin, mi->mi_acdirmax);
411*86d949f9SVitaliy Gusev 
412*86d949f9SVitaliy Gusev 	mdb_printf("\nServer list: %p\n", mi->mi_servers);
413*86d949f9SVitaliy Gusev 	mdb_inc_indent(2);
414*86d949f9SVitaliy Gusev 	if (mdb_pwalk_dcmd("nfs_serv", "nfs_servinfo", 0, NULL,
415*86d949f9SVitaliy Gusev 	    (uintptr_t)mi->mi_servers) == -1)
416*86d949f9SVitaliy Gusev 		mdb_printf("??\n");
417*86d949f9SVitaliy Gusev 	mdb_dec_indent(2);
418*86d949f9SVitaliy Gusev 
419*86d949f9SVitaliy Gusev 	mdb_printf("Current Server: %p ", mi->mi_curr_serv);
420*86d949f9SVitaliy Gusev 	if (mdb_call_dcmd("nfs_servinfo", (uintptr_t)mi->mi_curr_serv,
421*86d949f9SVitaliy Gusev 	    DCMD_ADDRSPEC, 0, NULL) == -1)
422*86d949f9SVitaliy Gusev 		mdb_printf("??\n");
423*86d949f9SVitaliy Gusev 
424*86d949f9SVitaliy Gusev 	mdb_printf(
425*86d949f9SVitaliy Gusev 	    "\nTotal: Server Non-responses = %u, Server Failovers = %u\n",
426*86d949f9SVitaliy Gusev 	    mi->mi_noresponse, mi->mi_failover);
427*86d949f9SVitaliy Gusev 
428*86d949f9SVitaliy Gusev 	if (mi->mi_io_kstats != NULL)
429*86d949f9SVitaliy Gusev 		nfs_print_io_stat((uintptr_t)mi->mi_io_kstats);
430*86d949f9SVitaliy Gusev 
431*86d949f9SVitaliy Gusev 	mdb_printf("\nAsync Request queue:\n");
432*86d949f9SVitaliy Gusev 	mdb_inc_indent(2);
433*86d949f9SVitaliy Gusev 	mdb_printf("max threads = %u, active threads = %u\n",
434*86d949f9SVitaliy Gusev 	    mi->mi_max_threads, mi->mi_threads[NFS_ASYNC_QUEUE]);
435*86d949f9SVitaliy Gusev 	mdb_printf("Async reserved page operation only active threads = %u\n",
436*86d949f9SVitaliy Gusev 	    mi->mi_threads[NFS_ASYNC_PGOPS_QUEUE]);
437*86d949f9SVitaliy Gusev 	mdb_printf("number requests queued:\n");
438*86d949f9SVitaliy Gusev 	for (i = 0; i < NFS_ASYNC_TYPES; i++) {
439*86d949f9SVitaliy Gusev 		const char *opname;
440*86d949f9SVitaliy Gusev 		size_t count = 0;
441*86d949f9SVitaliy Gusev 
442*86d949f9SVitaliy Gusev 		switch (i) {
443*86d949f9SVitaliy Gusev 		case NFS_PUTAPAGE:
444*86d949f9SVitaliy Gusev 			opname = "PUTAPAGE";
445*86d949f9SVitaliy Gusev 			break;
446*86d949f9SVitaliy Gusev 		case NFS_PAGEIO:
447*86d949f9SVitaliy Gusev 			opname = "PAGEIO";
448*86d949f9SVitaliy Gusev 			break;
449*86d949f9SVitaliy Gusev 		case NFS_COMMIT:
450*86d949f9SVitaliy Gusev 			opname = "COMMIT";
451*86d949f9SVitaliy Gusev 			break;
452*86d949f9SVitaliy Gusev 		case NFS_READ_AHEAD:
453*86d949f9SVitaliy Gusev 			opname = "READ_AHEAD";
454*86d949f9SVitaliy Gusev 			break;
455*86d949f9SVitaliy Gusev 		case NFS_READDIR:
456*86d949f9SVitaliy Gusev 			opname = "READDIR";
457*86d949f9SVitaliy Gusev 			break;
458*86d949f9SVitaliy Gusev 		case NFS_INACTIVE:
459*86d949f9SVitaliy Gusev 			opname = "INACTIVE";
460*86d949f9SVitaliy Gusev 			break;
461*86d949f9SVitaliy Gusev 		default:
462*86d949f9SVitaliy Gusev 			opname = "??";
463*86d949f9SVitaliy Gusev 			break;
464*86d949f9SVitaliy Gusev 		}
465*86d949f9SVitaliy Gusev 
466*86d949f9SVitaliy Gusev 		if (mi->mi_async_reqs[i] == NULL || mdb_pwalk("nfs_async",
467*86d949f9SVitaliy Gusev 		    walk_count_cb, &count, (uintptr_t)mi->mi_async_reqs[i])
468*86d949f9SVitaliy Gusev 		    == -1)
469*86d949f9SVitaliy Gusev 			mdb_printf("\t%s = ??", opname);
470*86d949f9SVitaliy Gusev 		else
471*86d949f9SVitaliy Gusev 			mdb_printf("\t%s = %llu", opname, count);
472*86d949f9SVitaliy Gusev 	}
473*86d949f9SVitaliy Gusev 	mdb_printf("\n");
474*86d949f9SVitaliy Gusev 	mdb_dec_indent(2);
475*86d949f9SVitaliy Gusev 
476*86d949f9SVitaliy Gusev 	if (mi->mi_printftime)
477*86d949f9SVitaliy Gusev 		mdb_printf("\nLast error report time = %Y\n",
478*86d949f9SVitaliy Gusev 		    mi->mi_printftime);
479*86d949f9SVitaliy Gusev 
480*86d949f9SVitaliy Gusev 	mdb_dec_indent(2);
481*86d949f9SVitaliy Gusev 	mdb_printf("\n");
482*86d949f9SVitaliy Gusev 
483*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
484*86d949f9SVitaliy Gusev }
485*86d949f9SVitaliy Gusev 
486*86d949f9SVitaliy Gusev int
nfs_mntinfo_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)487*86d949f9SVitaliy Gusev nfs_mntinfo_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
488*86d949f9SVitaliy Gusev {
489*86d949f9SVitaliy Gusev 	mntinfo_t mi;
490*86d949f9SVitaliy Gusev 	uint_t opt_v = FALSE;
491*86d949f9SVitaliy Gusev 
492*86d949f9SVitaliy Gusev 	if (mdb_getopts(argc, argv,
493*86d949f9SVitaliy Gusev 	    'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL) != argc)
494*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
495*86d949f9SVitaliy Gusev 
496*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
497*86d949f9SVitaliy Gusev 		if (mdb_walk("nfs_mnt", nfs_print_mntinfo_cb, &opt_v) == -1) {
498*86d949f9SVitaliy Gusev 			mdb_warn("failed to walk nfs_mnt");
499*86d949f9SVitaliy Gusev 			return (DCMD_ERR);
500*86d949f9SVitaliy Gusev 		}
501*86d949f9SVitaliy Gusev 		return (DCMD_OK);
502*86d949f9SVitaliy Gusev 	}
503*86d949f9SVitaliy Gusev 
504*86d949f9SVitaliy Gusev 	if (mdb_vread(&mi, sizeof (mi), addr) == -1) {
505*86d949f9SVitaliy Gusev 		mdb_warn("failed to read mntinfo_t");
506*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
507*86d949f9SVitaliy Gusev 	}
508*86d949f9SVitaliy Gusev 
509*86d949f9SVitaliy Gusev 	return (nfs_print_mntinfo_cb(addr, &mi, &opt_v) == WALK_ERR ? DCMD_ERR
510*86d949f9SVitaliy Gusev 	    : DCMD_OK);
511*86d949f9SVitaliy Gusev }
512*86d949f9SVitaliy Gusev 
513*86d949f9SVitaliy Gusev void
nfs_mntinfo_help(void)514*86d949f9SVitaliy Gusev nfs_mntinfo_help(void)
515*86d949f9SVitaliy Gusev {
516*86d949f9SVitaliy Gusev 	mdb_printf("-v       verbose information\n");
517*86d949f9SVitaliy Gusev }
518*86d949f9SVitaliy Gusev 
519*86d949f9SVitaliy Gusev /*
520*86d949f9SVitaliy Gusev  * nfs_servinfo dcmd implementation
521*86d949f9SVitaliy Gusev  */
522*86d949f9SVitaliy Gusev 
523*86d949f9SVitaliy Gusev int
nfs_servinfo_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)524*86d949f9SVitaliy Gusev nfs_servinfo_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
525*86d949f9SVitaliy Gusev {
526*86d949f9SVitaliy Gusev 	servinfo_t si;
527*86d949f9SVitaliy Gusev 	uint_t opt_v = FALSE;
528*86d949f9SVitaliy Gusev 	const char *addr_str;
529*86d949f9SVitaliy Gusev 	struct knetconfig knconf;
530*86d949f9SVitaliy Gusev 	char *hostname;
531*86d949f9SVitaliy Gusev 	int i;
532*86d949f9SVitaliy Gusev 
533*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
534*86d949f9SVitaliy Gusev 		mdb_printf("requires address of servinfo_t\n");
535*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
536*86d949f9SVitaliy Gusev 	}
537*86d949f9SVitaliy Gusev 
538*86d949f9SVitaliy Gusev 	if (mdb_getopts(argc, argv,
539*86d949f9SVitaliy Gusev 	    'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL) != argc)
540*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
541*86d949f9SVitaliy Gusev 
542*86d949f9SVitaliy Gusev 	if (mdb_vread(&si, sizeof (si), addr) == -1) {
543*86d949f9SVitaliy Gusev 		mdb_warn("can't read servinfo_t");
544*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
545*86d949f9SVitaliy Gusev 	}
546*86d949f9SVitaliy Gusev 
547*86d949f9SVitaliy Gusev 	addr_str = common_netbuf_str(&si.sv_addr);
548*86d949f9SVitaliy Gusev 
549*86d949f9SVitaliy Gusev 	if (!opt_v) {
550*86d949f9SVitaliy Gusev 		mdb_printf("%s\n", addr_str);
551*86d949f9SVitaliy Gusev 		return (DCMD_OK);
552*86d949f9SVitaliy Gusev 	}
553*86d949f9SVitaliy Gusev 
554*86d949f9SVitaliy Gusev 	mdb_printf("secdata ptr = %p\n", si.sv_secdata);
555*86d949f9SVitaliy Gusev 
556*86d949f9SVitaliy Gusev 	mdb_printf("address = ");
557*86d949f9SVitaliy Gusev 	if (mdb_vread(&knconf, sizeof (knconf),
558*86d949f9SVitaliy Gusev 	    (uintptr_t)si.sv_knconf) == -1) {
559*86d949f9SVitaliy Gusev 		mdb_printf("?\?/?\?/??");
560*86d949f9SVitaliy Gusev 	} else {
561*86d949f9SVitaliy Gusev 		char knc_str[KNC_STRSIZE];
562*86d949f9SVitaliy Gusev 
563*86d949f9SVitaliy Gusev 		mdb_printf("%u", knconf.knc_semantics);
564*86d949f9SVitaliy Gusev 
565*86d949f9SVitaliy Gusev 		if (mdb_readstr(knc_str, sizeof (knc_str),
566*86d949f9SVitaliy Gusev 		    (uintptr_t)knconf.knc_protofmly) == -1)
567*86d949f9SVitaliy Gusev 			mdb_printf("/??");
568*86d949f9SVitaliy Gusev 		else
569*86d949f9SVitaliy Gusev 			mdb_printf("/%s", knc_str);
570*86d949f9SVitaliy Gusev 
571*86d949f9SVitaliy Gusev 		if (mdb_readstr(knc_str, sizeof (knc_str),
572*86d949f9SVitaliy Gusev 		    (uintptr_t)knconf.knc_proto) == -1)
573*86d949f9SVitaliy Gusev 			mdb_printf("/??");
574*86d949f9SVitaliy Gusev 		else
575*86d949f9SVitaliy Gusev 			mdb_printf("/%s", knc_str);
576*86d949f9SVitaliy Gusev 	}
577*86d949f9SVitaliy Gusev 	mdb_printf("/%s\n", addr_str);
578*86d949f9SVitaliy Gusev 
579*86d949f9SVitaliy Gusev 	if (si.sv_hostnamelen <= 0 || (hostname = mdb_alloc(si.sv_hostnamelen,
580*86d949f9SVitaliy Gusev 	    UM_NOSLEEP | UM_GC)) == NULL || mdb_readstr(hostname,
581*86d949f9SVitaliy Gusev 	    si.sv_hostnamelen, (uintptr_t)si.sv_hostname) == -1)
582*86d949f9SVitaliy Gusev 		mdb_printf("hostname = ??\n");
583*86d949f9SVitaliy Gusev 	else
584*86d949f9SVitaliy Gusev 		mdb_printf("hostname = %s\n", hostname);
585*86d949f9SVitaliy Gusev 
586*86d949f9SVitaliy Gusev 	mdb_printf("filehandle = ");
587*86d949f9SVitaliy Gusev 	if (si.sv_fhandle.fh_len >= 0 &&
588*86d949f9SVitaliy Gusev 	    si.sv_fhandle.fh_len <= NFS_FHANDLE_LEN)
589*86d949f9SVitaliy Gusev 		for (i = 0; i < si.sv_fhandle.fh_len; i++)
590*86d949f9SVitaliy Gusev 			mdb_printf("%02x",
591*86d949f9SVitaliy Gusev 			    (unsigned char)si.sv_fhandle.fh_buf[i]);
592*86d949f9SVitaliy Gusev 	else
593*86d949f9SVitaliy Gusev 		mdb_printf("??");
594*86d949f9SVitaliy Gusev 	mdb_printf("\n\n");
595*86d949f9SVitaliy Gusev 
596*86d949f9SVitaliy Gusev 	return (DCMD_OK);
597*86d949f9SVitaliy Gusev }
598*86d949f9SVitaliy Gusev 
599*86d949f9SVitaliy Gusev void
nfs_servinfo_help(void)600*86d949f9SVitaliy Gusev nfs_servinfo_help(void)
601*86d949f9SVitaliy Gusev {
602*86d949f9SVitaliy Gusev 	mdb_printf("-v       verbose information\n");
603*86d949f9SVitaliy Gusev }
604*86d949f9SVitaliy Gusev 
605*86d949f9SVitaliy Gusev /*
606*86d949f9SVitaliy Gusev  * nfs4_mntinfo dcmd implementation
607*86d949f9SVitaliy Gusev  */
608*86d949f9SVitaliy Gusev 
609*86d949f9SVitaliy Gusev static const mdb_bitmask_t nfs_mi4_flags[] = {
610*86d949f9SVitaliy Gusev 	{"MI4_HARD", MI4_HARD, MI4_HARD},
611*86d949f9SVitaliy Gusev 	{"MI4_PRINTED", MI4_PRINTED, MI4_PRINTED},
612*86d949f9SVitaliy Gusev 	{"MI4_INT", MI4_INT, MI4_INT},
613*86d949f9SVitaliy Gusev 	{"MI4_DOWN", MI4_DOWN, MI4_DOWN},
614*86d949f9SVitaliy Gusev 	{"MI4_NOAC", MI4_NOAC, MI4_NOAC},
615*86d949f9SVitaliy Gusev 	{"MI4_NOCTO", MI4_NOCTO, MI4_NOCTO},
616*86d949f9SVitaliy Gusev 	{"MI4_LLOCK", MI4_LLOCK, MI4_LLOCK},
617*86d949f9SVitaliy Gusev 	{"MI4_GRPID", MI4_GRPID, MI4_GRPID},
618*86d949f9SVitaliy Gusev 	{"MI4_SHUTDOWN", MI4_SHUTDOWN, MI4_SHUTDOWN},
619*86d949f9SVitaliy Gusev 	{"MI4_LINK", MI4_LINK, MI4_LINK},
620*86d949f9SVitaliy Gusev 	{"MI4_SYMLINK", MI4_SYMLINK, MI4_SYMLINK},
621*86d949f9SVitaliy Gusev 	{"MI4_EPHEMERAL_RECURSED", MI4_EPHEMERAL_RECURSED,
622*86d949f9SVitaliy Gusev 		MI4_EPHEMERAL_RECURSED},
623*86d949f9SVitaliy Gusev 	{"MI4_ACL", MI4_ACL, MI4_ACL},
624*86d949f9SVitaliy Gusev 	{"MI4_MIRRORMOUNT", MI4_MIRRORMOUNT, MI4_MIRRORMOUNT},
625*86d949f9SVitaliy Gusev 	{"MI4_REFERRAL", MI4_REFERRAL, MI4_REFERRAL},
626*86d949f9SVitaliy Gusev 	{"MI4_EPHEMERAL", MI4_EPHEMERAL, MI4_EPHEMERAL},
627*86d949f9SVitaliy Gusev 	{"MI4_NOPRINT", MI4_NOPRINT, MI4_NOPRINT},
628*86d949f9SVitaliy Gusev 	{"MI4_DIRECTIO", MI4_DIRECTIO, MI4_DIRECTIO},
629*86d949f9SVitaliy Gusev 	{"MI4_RECOV_ACTIV", MI4_RECOV_ACTIV, MI4_RECOV_ACTIV},
630*86d949f9SVitaliy Gusev 	{"MI4_REMOVE_ON_LAST_CLOSE", MI4_REMOVE_ON_LAST_CLOSE,
631*86d949f9SVitaliy Gusev 		MI4_REMOVE_ON_LAST_CLOSE},
632*86d949f9SVitaliy Gusev 	{"MI4_RECOV_FAIL", MI4_RECOV_FAIL, MI4_RECOV_FAIL},
633*86d949f9SVitaliy Gusev 	{"MI4_PUBLIC", MI4_PUBLIC, MI4_PUBLIC},
634*86d949f9SVitaliy Gusev 	{"MI4_MOUNTING", MI4_MOUNTING, MI4_MOUNTING},
635*86d949f9SVitaliy Gusev 	{"MI4_POSIX_LOCK", MI4_POSIX_LOCK, MI4_POSIX_LOCK},
636*86d949f9SVitaliy Gusev 	{"MI4_LOCK_DEBUG", MI4_LOCK_DEBUG, MI4_LOCK_DEBUG},
637*86d949f9SVitaliy Gusev 	{"MI4_DEAD", MI4_DEAD, MI4_DEAD},
638*86d949f9SVitaliy Gusev 	{"MI4_INACTIVE_IDLE", MI4_INACTIVE_IDLE, MI4_INACTIVE_IDLE},
639*86d949f9SVitaliy Gusev 	{"MI4_BADOWNER_DEBUG", MI4_BADOWNER_DEBUG, MI4_BADOWNER_DEBUG},
640*86d949f9SVitaliy Gusev 	{"MI4_ASYNC_MGR_STOP", MI4_ASYNC_MGR_STOP, MI4_ASYNC_MGR_STOP},
641*86d949f9SVitaliy Gusev 	{"MI4_TIMEDOUT", MI4_TIMEDOUT, MI4_TIMEDOUT},
642*86d949f9SVitaliy Gusev 	{NULL, 0, 0}
643*86d949f9SVitaliy Gusev };
644*86d949f9SVitaliy Gusev 
645*86d949f9SVitaliy Gusev static const mdb_bitmask_t nfs_mi4_recovflags[] = {
646*86d949f9SVitaliy Gusev 	{"MI4R_NEED_CLIENTID", MI4R_NEED_CLIENTID, MI4R_NEED_CLIENTID},
647*86d949f9SVitaliy Gusev 	{"MI4R_REOPEN_FILES", MI4R_REOPEN_FILES, MI4R_REOPEN_FILES},
648*86d949f9SVitaliy Gusev 	{"MI4R_NEED_SECINFO", MI4R_NEED_SECINFO, MI4R_NEED_SECINFO},
649*86d949f9SVitaliy Gusev 	{"MI4R_NEED_NEW_SERVER", MI4R_NEED_NEW_SERVER, MI4R_NEED_NEW_SERVER},
650*86d949f9SVitaliy Gusev 	{"MI4R_REMAP_FILES", MI4R_REMAP_FILES, MI4R_REMAP_FILES},
651*86d949f9SVitaliy Gusev 	{"MI4R_SRV_REBOOT", MI4R_SRV_REBOOT, MI4R_SRV_REBOOT},
652*86d949f9SVitaliy Gusev 	{"MI4R_LOST_STATE", MI4R_LOST_STATE, MI4R_LOST_STATE},
653*86d949f9SVitaliy Gusev 	{"MI4R_BAD_SEQID", MI4R_BAD_SEQID, MI4R_BAD_SEQID},
654*86d949f9SVitaliy Gusev 	{"MI4R_MOVED", MI4R_MOVED, MI4R_MOVED},
655*86d949f9SVitaliy Gusev 	{NULL, 0, 0}
656*86d949f9SVitaliy Gusev };
657*86d949f9SVitaliy Gusev 
658*86d949f9SVitaliy Gusev int
nfs4_mntinfo_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)659*86d949f9SVitaliy Gusev nfs4_mntinfo_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
660*86d949f9SVitaliy Gusev {
661*86d949f9SVitaliy Gusev 	mntinfo4_t mi;
662*86d949f9SVitaliy Gusev 	vfs_t vfs;
663*86d949f9SVitaliy Gusev 	char buf[MAXPATHLEN];
664*86d949f9SVitaliy Gusev 	uint_t opt_m = FALSE;
665*86d949f9SVitaliy Gusev 	uint_t opt_v = FALSE;
666*86d949f9SVitaliy Gusev 
667*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
668*86d949f9SVitaliy Gusev 		if (mdb_walk_dcmd("nfs4_mnt", "nfs4_mntinfo", argc,
669*86d949f9SVitaliy Gusev 		    argv) == -1) {
670*86d949f9SVitaliy Gusev 			mdb_warn("failed to walk nfs4_mnt");
671*86d949f9SVitaliy Gusev 			return (DCMD_ERR);
672*86d949f9SVitaliy Gusev 		}
673*86d949f9SVitaliy Gusev 		return (DCMD_OK);
674*86d949f9SVitaliy Gusev 	}
675*86d949f9SVitaliy Gusev 
676*86d949f9SVitaliy Gusev 	if (mdb_getopts(argc, argv,
677*86d949f9SVitaliy Gusev 	    'm', MDB_OPT_SETBITS, TRUE, &opt_m,
678*86d949f9SVitaliy Gusev 	    'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL) != argc)
679*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
680*86d949f9SVitaliy Gusev 
681*86d949f9SVitaliy Gusev 	if (mdb_vread(&mi, sizeof (mi), addr) == -1) {
682*86d949f9SVitaliy Gusev 		mdb_warn("failed to read mntinfo4_t at %p", addr);
683*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
684*86d949f9SVitaliy Gusev 	}
685*86d949f9SVitaliy Gusev 
686*86d949f9SVitaliy Gusev 	if (mdb_vread(&vfs, sizeof (vfs), (uintptr_t)mi.mi_vfsp) == -1) {
687*86d949f9SVitaliy Gusev 		mdb_warn("failed to read vfs_t at %p", mi.mi_vfsp);
688*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
689*86d949f9SVitaliy Gusev 	}
690*86d949f9SVitaliy Gusev 
691*86d949f9SVitaliy Gusev 	mdb_printf("+--------------------------------------+\n");
692*86d949f9SVitaliy Gusev 	mdb_printf("    mntinfo4_t: 0x%p\n", addr);
693*86d949f9SVitaliy Gusev 	mdb_printf("   NFS Version: 4\n");
694*86d949f9SVitaliy Gusev 	mdb_printf("      mi_flags: %b\n", mi.mi_flags, nfs_mi4_flags);
695*86d949f9SVitaliy Gusev 	mdb_printf("      mi_error: %u\n", mi.mi_error);
696*86d949f9SVitaliy Gusev 	mdb_printf(" mi_open_files: %i\n", mi.mi_open_files);
697*86d949f9SVitaliy Gusev 	mdb_printf("  mi_msg_count: %i\n", mi.mi_msg_count);
698*86d949f9SVitaliy Gusev 	mdb_printf(" mi_recovflags: %b\n", mi.mi_recovflags,
699*86d949f9SVitaliy Gusev 	    nfs_mi4_recovflags);
700*86d949f9SVitaliy Gusev 	mdb_printf("mi_recovthread: 0x%p\n", mi.mi_recovthread);
701*86d949f9SVitaliy Gusev 	mdb_printf("mi_in_recovery: %i\n", mi.mi_in_recovery);
702*86d949f9SVitaliy Gusev 
703*86d949f9SVitaliy Gusev 	if (mdb_read_refstr((uintptr_t)vfs.vfs_mntpt, buf,
704*86d949f9SVitaliy Gusev 	    sizeof (buf)) == -1)
705*86d949f9SVitaliy Gusev 		strcpy(buf, "??");
706*86d949f9SVitaliy Gusev 	mdb_printf("   mount point: %s\n", buf);
707*86d949f9SVitaliy Gusev 	if (mdb_read_refstr((uintptr_t)vfs.vfs_resource, buf,
708*86d949f9SVitaliy Gusev 	    sizeof (buf)) == -1)
709*86d949f9SVitaliy Gusev 		strcpy(buf, "??");
710*86d949f9SVitaliy Gusev 	mdb_printf("    mount from: %s\n", buf);
711*86d949f9SVitaliy Gusev 
712*86d949f9SVitaliy Gusev 	if (opt_v) {
713*86d949f9SVitaliy Gusev 		int i;
714*86d949f9SVitaliy Gusev 
715*86d949f9SVitaliy Gusev 		mdb_printf("\n");
716*86d949f9SVitaliy Gusev 		mdb_inc_indent(2);
717*86d949f9SVitaliy Gusev 
718*86d949f9SVitaliy Gusev 		mdb_printf("mi_zone = %p\n", mi.mi_zone);
719*86d949f9SVitaliy Gusev 		mdb_printf("mi_curread = %i, mi_curwrite = %i, "
720*86d949f9SVitaliy Gusev 		    "mi_retrans = %i, mi_timeo = %i\n", mi.mi_curread,
721*86d949f9SVitaliy Gusev 		    mi.mi_curwrite, mi.mi_retrans, mi.mi_timeo);
722*86d949f9SVitaliy Gusev 		mdb_printf("mi_acregmin = %lu, mi_acregmax = %lu, "
723*86d949f9SVitaliy Gusev 		    "mi_acdirmin = %lu, mi_acdirmax = %lu\n", mi.mi_acregmin,
724*86d949f9SVitaliy Gusev 		    mi.mi_acregmax, mi.mi_acdirmin, mi.mi_acdirmax);
725*86d949f9SVitaliy Gusev 
726*86d949f9SVitaliy Gusev 		mdb_printf("\nServer list: %p\n", mi.mi_servers);
727*86d949f9SVitaliy Gusev 		mdb_inc_indent(2);
728*86d949f9SVitaliy Gusev 		if (mdb_pwalk_dcmd("nfs4_serv", "nfs4_servinfo", 0, NULL,
729*86d949f9SVitaliy Gusev 		    (uintptr_t)mi.mi_servers) == -1)
730*86d949f9SVitaliy Gusev 			mdb_printf("??\n");
731*86d949f9SVitaliy Gusev 		mdb_dec_indent(2);
732*86d949f9SVitaliy Gusev 
733*86d949f9SVitaliy Gusev 		mdb_printf("Current Server: %p ", mi.mi_curr_serv);
734*86d949f9SVitaliy Gusev 		if (mdb_call_dcmd("nfs4_servinfo", (uintptr_t)mi.mi_curr_serv,
735*86d949f9SVitaliy Gusev 		    DCMD_ADDRSPEC, 0, NULL) == -1)
736*86d949f9SVitaliy Gusev 			mdb_printf("??\n");
737*86d949f9SVitaliy Gusev 
738*86d949f9SVitaliy Gusev 		mdb_printf("\nTotal: Server Non-responses = %u, "
739*86d949f9SVitaliy Gusev 		    "Server Failovers = %u\n", mi.mi_noresponse,
740*86d949f9SVitaliy Gusev 		    mi.mi_failover);
741*86d949f9SVitaliy Gusev 
742*86d949f9SVitaliy Gusev 		if (mi.mi_io_kstats != NULL)
743*86d949f9SVitaliy Gusev 			nfs_print_io_stat((uintptr_t)mi.mi_io_kstats);
744*86d949f9SVitaliy Gusev 
745*86d949f9SVitaliy Gusev 		mdb_printf("\nAsync Request queue:\n");
746*86d949f9SVitaliy Gusev 		mdb_inc_indent(2);
747*86d949f9SVitaliy Gusev 		mdb_printf("max threads = %u, active threads = %u\n",
748*86d949f9SVitaliy Gusev 		    mi.mi_max_threads, mi.mi_threads[NFS4_ASYNC_QUEUE]);
749*86d949f9SVitaliy Gusev 		mdb_printf("Async reserved page operation only active "
750*86d949f9SVitaliy Gusev 		    "threads = %u\n", mi.mi_threads[NFS4_ASYNC_PGOPS_QUEUE]);
751*86d949f9SVitaliy Gusev 		mdb_printf("number requests queued:\n");
752*86d949f9SVitaliy Gusev 		for (i = 0; i < NFS4_ASYNC_TYPES; i++) {
753*86d949f9SVitaliy Gusev 			const char *opname;
754*86d949f9SVitaliy Gusev 			size_t count = 0;
755*86d949f9SVitaliy Gusev 
756*86d949f9SVitaliy Gusev 			switch (i) {
757*86d949f9SVitaliy Gusev 			case NFS4_PUTAPAGE:
758*86d949f9SVitaliy Gusev 				opname = "PUTAPAGE";
759*86d949f9SVitaliy Gusev 				break;
760*86d949f9SVitaliy Gusev 			case NFS4_PAGEIO:
761*86d949f9SVitaliy Gusev 				opname = "PAGEIO";
762*86d949f9SVitaliy Gusev 				break;
763*86d949f9SVitaliy Gusev 			case NFS4_COMMIT:
764*86d949f9SVitaliy Gusev 				opname = "COMMIT";
765*86d949f9SVitaliy Gusev 				break;
766*86d949f9SVitaliy Gusev 			case NFS4_READ_AHEAD:
767*86d949f9SVitaliy Gusev 				opname = "READ_AHEAD";
768*86d949f9SVitaliy Gusev 				break;
769*86d949f9SVitaliy Gusev 			case NFS4_READDIR:
770*86d949f9SVitaliy Gusev 				opname = "READDIR";
771*86d949f9SVitaliy Gusev 				break;
772*86d949f9SVitaliy Gusev 			case NFS4_INACTIVE:
773*86d949f9SVitaliy Gusev 				opname = "INACTIVE";
774*86d949f9SVitaliy Gusev 				break;
775*86d949f9SVitaliy Gusev 			default:
776*86d949f9SVitaliy Gusev 				opname = "??";
777*86d949f9SVitaliy Gusev 				break;
778*86d949f9SVitaliy Gusev 			}
779*86d949f9SVitaliy Gusev 
780*86d949f9SVitaliy Gusev 			if (mi.mi_async_reqs[i] != NULL &&
781*86d949f9SVitaliy Gusev 			    mdb_pwalk("nfs4_async", walk_count_cb, &count,
782*86d949f9SVitaliy Gusev 			    (uintptr_t)mi.mi_async_reqs[i]) == -1)
783*86d949f9SVitaliy Gusev 				mdb_printf("\t%s = ??", opname);
784*86d949f9SVitaliy Gusev 			else
785*86d949f9SVitaliy Gusev 				mdb_printf("\t%s = %llu", opname, count);
786*86d949f9SVitaliy Gusev 		}
787*86d949f9SVitaliy Gusev 		mdb_printf("\n");
788*86d949f9SVitaliy Gusev 		mdb_dec_indent(2);
789*86d949f9SVitaliy Gusev 
790*86d949f9SVitaliy Gusev 		mdb_dec_indent(2);
791*86d949f9SVitaliy Gusev 	}
792*86d949f9SVitaliy Gusev 
793*86d949f9SVitaliy Gusev 	return (DCMD_OK);
794*86d949f9SVitaliy Gusev }
795*86d949f9SVitaliy Gusev 
796*86d949f9SVitaliy Gusev void
nfs4_mntinfo_help(void)797*86d949f9SVitaliy Gusev nfs4_mntinfo_help(void)
798*86d949f9SVitaliy Gusev {
799*86d949f9SVitaliy Gusev 	mdb_printf("<mntinfo4>::nfs4_mntinfo  -> gives mntinfo4_t information\n"
800*86d949f9SVitaliy Gusev 	    "          ::nfs4_mntinfo  -> walks thru all NFSv4 mntinfo4_t\n"
801*86d949f9SVitaliy Gusev 	    "Each of these formats also takes the following argument\n"
802*86d949f9SVitaliy Gusev 	    "        -v      -> Verbose output\n");
803*86d949f9SVitaliy Gusev }
804*86d949f9SVitaliy Gusev 
805*86d949f9SVitaliy Gusev /*
806*86d949f9SVitaliy Gusev  * nfs4_servinfo dcmd implementation
807*86d949f9SVitaliy Gusev  */
808*86d949f9SVitaliy Gusev 
809*86d949f9SVitaliy Gusev int
nfs4_servinfo_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)810*86d949f9SVitaliy Gusev nfs4_servinfo_dcmd(uintptr_t addr, uint_t flags, int argc,
811*86d949f9SVitaliy Gusev     const mdb_arg_t *argv)
812*86d949f9SVitaliy Gusev {
813*86d949f9SVitaliy Gusev 	servinfo4_t si;
814*86d949f9SVitaliy Gusev 	uint_t opt_v = FALSE;
815*86d949f9SVitaliy Gusev 	const char *addr_str;
816*86d949f9SVitaliy Gusev 	struct knetconfig knconf;
817*86d949f9SVitaliy Gusev 	char *hostname;
818*86d949f9SVitaliy Gusev 	int i;
819*86d949f9SVitaliy Gusev 
820*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
821*86d949f9SVitaliy Gusev 		mdb_printf("requires address of servinfo4_t\n");
822*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
823*86d949f9SVitaliy Gusev 	}
824*86d949f9SVitaliy Gusev 
825*86d949f9SVitaliy Gusev 	if (mdb_getopts(argc, argv,
826*86d949f9SVitaliy Gusev 	    'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL) != argc)
827*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
828*86d949f9SVitaliy Gusev 
829*86d949f9SVitaliy Gusev 	if (mdb_vread(&si, sizeof (si), addr) == -1) {
830*86d949f9SVitaliy Gusev 		mdb_warn("can't read servinfo_t");
831*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
832*86d949f9SVitaliy Gusev 	}
833*86d949f9SVitaliy Gusev 
834*86d949f9SVitaliy Gusev 	addr_str = common_netbuf_str(&si.sv_addr);
835*86d949f9SVitaliy Gusev 
836*86d949f9SVitaliy Gusev 	if (!opt_v) {
837*86d949f9SVitaliy Gusev 		mdb_printf("%s\n", addr_str);
838*86d949f9SVitaliy Gusev 		return (DCMD_OK);
839*86d949f9SVitaliy Gusev 	}
840*86d949f9SVitaliy Gusev 
841*86d949f9SVitaliy Gusev 	mdb_printf("secdata ptr = %p\n", si.sv_secdata);
842*86d949f9SVitaliy Gusev 
843*86d949f9SVitaliy Gusev 	mdb_printf("address = ");
844*86d949f9SVitaliy Gusev 	if (mdb_vread(&knconf, sizeof (knconf),
845*86d949f9SVitaliy Gusev 	    (uintptr_t)si.sv_knconf) == -1) {
846*86d949f9SVitaliy Gusev 		mdb_printf("?\?/?\?/??");
847*86d949f9SVitaliy Gusev 	} else {
848*86d949f9SVitaliy Gusev 		char knc_str[KNC_STRSIZE];
849*86d949f9SVitaliy Gusev 
850*86d949f9SVitaliy Gusev 		mdb_printf("%u", knconf.knc_semantics);
851*86d949f9SVitaliy Gusev 
852*86d949f9SVitaliy Gusev 		if (mdb_readstr(knc_str, sizeof (knc_str),
853*86d949f9SVitaliy Gusev 		    (uintptr_t)knconf.knc_protofmly) == -1)
854*86d949f9SVitaliy Gusev 			mdb_printf("/??");
855*86d949f9SVitaliy Gusev 		else
856*86d949f9SVitaliy Gusev 			mdb_printf("/%s", knc_str);
857*86d949f9SVitaliy Gusev 
858*86d949f9SVitaliy Gusev 		if (mdb_readstr(knc_str, sizeof (knc_str),
859*86d949f9SVitaliy Gusev 		    (uintptr_t)knconf.knc_proto) == -1)
860*86d949f9SVitaliy Gusev 			mdb_printf("/??");
861*86d949f9SVitaliy Gusev 		else
862*86d949f9SVitaliy Gusev 			mdb_printf("/%s", knc_str);
863*86d949f9SVitaliy Gusev 	}
864*86d949f9SVitaliy Gusev 	mdb_printf("/%s\n", addr_str);
865*86d949f9SVitaliy Gusev 
866*86d949f9SVitaliy Gusev 	if (si.sv_hostnamelen <= 0 || (hostname = mdb_alloc(si.sv_hostnamelen,
867*86d949f9SVitaliy Gusev 	    UM_NOSLEEP | UM_GC)) == NULL || mdb_readstr(hostname,
868*86d949f9SVitaliy Gusev 	    si.sv_hostnamelen, (uintptr_t)si.sv_hostname) == -1)
869*86d949f9SVitaliy Gusev 		mdb_printf("hostname = ??\n");
870*86d949f9SVitaliy Gusev 	else
871*86d949f9SVitaliy Gusev 		mdb_printf("hostname = %s\n", hostname);
872*86d949f9SVitaliy Gusev 
873*86d949f9SVitaliy Gusev 	mdb_printf("server filehandle = ");
874*86d949f9SVitaliy Gusev 	if (si.sv_fhandle.fh_len >= 0 && si.sv_fhandle.fh_len <= NFS4_FHSIZE)
875*86d949f9SVitaliy Gusev 		for (i = 0; i < si.sv_fhandle.fh_len; i++)
876*86d949f9SVitaliy Gusev 			mdb_printf("%02x",
877*86d949f9SVitaliy Gusev 			    (unsigned char)si.sv_fhandle.fh_buf[i]);
878*86d949f9SVitaliy Gusev 	else
879*86d949f9SVitaliy Gusev 		mdb_printf("??");
880*86d949f9SVitaliy Gusev 
881*86d949f9SVitaliy Gusev 	mdb_printf("\nparent dir filehandle = ");
882*86d949f9SVitaliy Gusev 	if (si.sv_pfhandle.fh_len >= 0 && si.sv_pfhandle.fh_len <= NFS4_FHSIZE)
883*86d949f9SVitaliy Gusev 		for (i = 0; i < si.sv_pfhandle.fh_len; i++)
884*86d949f9SVitaliy Gusev 			mdb_printf("%02x",
885*86d949f9SVitaliy Gusev 			    (unsigned char)si.sv_pfhandle.fh_buf[i]);
886*86d949f9SVitaliy Gusev 	else
887*86d949f9SVitaliy Gusev 		mdb_printf("??");
888*86d949f9SVitaliy Gusev 	mdb_printf("\n\n");
889*86d949f9SVitaliy Gusev 
890*86d949f9SVitaliy Gusev 	return (DCMD_OK);
891*86d949f9SVitaliy Gusev }
892*86d949f9SVitaliy Gusev 
893*86d949f9SVitaliy Gusev void
nfs4_servinfo_help(void)894*86d949f9SVitaliy Gusev nfs4_servinfo_help(void)
895*86d949f9SVitaliy Gusev {
896*86d949f9SVitaliy Gusev 	mdb_printf("-v       verbose information\n");
897*86d949f9SVitaliy Gusev }
898*86d949f9SVitaliy Gusev 
899*86d949f9SVitaliy Gusev /*
900*86d949f9SVitaliy Gusev  * nfs4_server_info dcmd implementation
901*86d949f9SVitaliy Gusev  */
902*86d949f9SVitaliy Gusev 
903*86d949f9SVitaliy Gusev static const mdb_bitmask_t nfs4_si_flags[] = {
904*86d949f9SVitaliy Gusev 	{"N4S_CLIENTID_SET", N4S_CLIENTID_SET, N4S_CLIENTID_SET},
905*86d949f9SVitaliy Gusev 	{"N4S_CLIENTID_PEND", N4S_CLIENTID_PEND, N4S_CLIENTID_PEND},
906*86d949f9SVitaliy Gusev 	{"N4S_CB_PINGED", N4S_CB_PINGED, N4S_CB_PINGED},
907*86d949f9SVitaliy Gusev 	{"N4S_CB_WAITER", N4S_CB_WAITER, N4S_CB_WAITER},
908*86d949f9SVitaliy Gusev 	{"N4S_INSERTED", N4S_INSERTED, N4S_INSERTED},
909*86d949f9SVitaliy Gusev 	{"N4S_BADOWNER_DEBUG", N4S_BADOWNER_DEBUG, N4S_BADOWNER_DEBUG},
910*86d949f9SVitaliy Gusev 	{NULL, 0, 0}
911*86d949f9SVitaliy Gusev };
912*86d949f9SVitaliy Gusev 
913*86d949f9SVitaliy Gusev int
nfs4_server_info_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)914*86d949f9SVitaliy Gusev nfs4_server_info_dcmd(uintptr_t addr, uint_t flags, int argc,
915*86d949f9SVitaliy Gusev     const mdb_arg_t *argv)
916*86d949f9SVitaliy Gusev {
917*86d949f9SVitaliy Gusev 	nfs4_server_t srv;
918*86d949f9SVitaliy Gusev 	char *id_val;
919*86d949f9SVitaliy Gusev 	uint_t opt_c = FALSE;
920*86d949f9SVitaliy Gusev 	uint_t opt_s = FALSE;
921*86d949f9SVitaliy Gusev 
922*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
923*86d949f9SVitaliy Gusev 		if (mdb_walk_dcmd("nfs4_server", "nfs4_server_info", argc, argv)
924*86d949f9SVitaliy Gusev 		    == -1) {
925*86d949f9SVitaliy Gusev 			mdb_warn("nfs4_server walker failed");
926*86d949f9SVitaliy Gusev 			return (DCMD_ERR);
927*86d949f9SVitaliy Gusev 		}
928*86d949f9SVitaliy Gusev 		return (DCMD_OK);
929*86d949f9SVitaliy Gusev 	}
930*86d949f9SVitaliy Gusev 
931*86d949f9SVitaliy Gusev 	if (mdb_getopts(argc, argv,
932*86d949f9SVitaliy Gusev 	    'c', MDB_OPT_SETBITS, TRUE, &opt_c,
933*86d949f9SVitaliy Gusev 	    's', MDB_OPT_SETBITS, TRUE, &opt_s, NULL) != argc)
934*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
935*86d949f9SVitaliy Gusev 
936*86d949f9SVitaliy Gusev 	if (mdb_vread(&srv, sizeof (srv), addr) == -1) {
937*86d949f9SVitaliy Gusev 		mdb_warn("failed to read nfs4_server_t at %p", addr);
938*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
939*86d949f9SVitaliy Gusev 	}
940*86d949f9SVitaliy Gusev 
941*86d949f9SVitaliy Gusev 	if (srv.saddr.len == 0)
942*86d949f9SVitaliy Gusev 		return (DCMD_OK);
943*86d949f9SVitaliy Gusev 
944*86d949f9SVitaliy Gusev 	mdb_printf("Address: %p Zone: %i Server: %s\n", addr, srv.zoneid,
945*86d949f9SVitaliy Gusev 	    common_netbuf_str(&srv.saddr));
946*86d949f9SVitaliy Gusev 	mdb_printf("Program: %x Flags: %b\n", srv.s_program, srv.s_flags,
947*86d949f9SVitaliy Gusev 	    nfs4_si_flags);
948*86d949f9SVitaliy Gusev 	mdb_printf("Client ID: %#llx", srv.clientid);
949*86d949f9SVitaliy Gusev 	if (opt_s) {
950*86d949f9SVitaliy Gusev 		struct {
951*86d949f9SVitaliy Gusev 			uint32_t start_time;
952*86d949f9SVitaliy Gusev 			uint32_t c_id;
953*86d949f9SVitaliy Gusev 		} *impl_id = (void *)&srv.clientid;
954*86d949f9SVitaliy Gusev 		mdb_printf(" (srvrboot: %Y, c_id: %u)", impl_id->start_time,
955*86d949f9SVitaliy Gusev 		    impl_id->c_id);
956*86d949f9SVitaliy Gusev 	}
957*86d949f9SVitaliy Gusev 
958*86d949f9SVitaliy Gusev 	mdb_printf("\nCLIDtoSend: [verifier: %llx", srv.clidtosend.verifier);
959*86d949f9SVitaliy Gusev 	if (opt_c) {
960*86d949f9SVitaliy Gusev 		struct {
961*86d949f9SVitaliy Gusev 			uint32_t sec;
962*86d949f9SVitaliy Gusev 			uint32_t subsec;
963*86d949f9SVitaliy Gusev 		} *curtime = (void *)&srv.clidtosend.verifier;
964*86d949f9SVitaliy Gusev 		mdb_printf(" (%Y + %u nsec)", curtime->sec, curtime->subsec);
965*86d949f9SVitaliy Gusev 	}
966*86d949f9SVitaliy Gusev 
967*86d949f9SVitaliy Gusev 	mdb_printf(", client identifier: ");
968*86d949f9SVitaliy Gusev 	id_val = mdb_alloc(srv.clidtosend.id_len, UM_NOSLEEP | UM_GC);
969*86d949f9SVitaliy Gusev 	if (id_val != NULL && mdb_vread(id_val, srv.clidtosend.id_len,
970*86d949f9SVitaliy Gusev 	    (uintptr_t)srv.clidtosend.id_val) == srv.clidtosend.id_len) {
971*86d949f9SVitaliy Gusev 		uint_t i;
972*86d949f9SVitaliy Gusev 
973*86d949f9SVitaliy Gusev 		if (opt_c) {
974*86d949f9SVitaliy Gusev 			size_t l;
975*86d949f9SVitaliy Gusev 			struct netbuf nb;
976*86d949f9SVitaliy Gusev 
977*86d949f9SVitaliy Gusev 			l = strlen(id_val) + 1;
978*86d949f9SVitaliy Gusev 			nb.len = nb.maxlen = srv.clidtosend.id_len - l;
979*86d949f9SVitaliy Gusev 			nb.buf = srv.clidtosend.id_val + l;
980*86d949f9SVitaliy Gusev 			mdb_printf("(%s/%s) ", id_val, common_netbuf_str(&nb));
981*86d949f9SVitaliy Gusev 		}
982*86d949f9SVitaliy Gusev 
983*86d949f9SVitaliy Gusev 		for (i = 0; i < srv.clidtosend.id_len; i++)
984*86d949f9SVitaliy Gusev 			mdb_printf("%02x", (unsigned char)id_val[i]);
985*86d949f9SVitaliy Gusev 	} else {
986*86d949f9SVitaliy Gusev 		mdb_printf("??");
987*86d949f9SVitaliy Gusev 	}
988*86d949f9SVitaliy Gusev 	mdb_printf(" ]\n");
989*86d949f9SVitaliy Gusev 
990*86d949f9SVitaliy Gusev 	mdb_printf("mntinfo4 list: %p\n", srv.mntinfo4_list);
991*86d949f9SVitaliy Gusev 	mdb_printf("Deleg list: %p ::walk list\n", addr +
992*86d949f9SVitaliy Gusev 	    OFFSETOF(nfs4_server_t, s_deleg_list));
993*86d949f9SVitaliy Gusev 	mdb_printf("Lease Valid: ");
994*86d949f9SVitaliy Gusev 	switch (srv.lease_valid) {
995*86d949f9SVitaliy Gusev 	case NFS4_LEASE_INVALID:
996*86d949f9SVitaliy Gusev 		mdb_printf("INVALID\n");
997*86d949f9SVitaliy Gusev 		break;
998*86d949f9SVitaliy Gusev 	case NFS4_LEASE_VALID:
999*86d949f9SVitaliy Gusev 		mdb_printf("VALID\n");
1000*86d949f9SVitaliy Gusev 		break;
1001*86d949f9SVitaliy Gusev 	case NFS4_LEASE_UNINITIALIZED:
1002*86d949f9SVitaliy Gusev 		mdb_printf("UNINIT\n");
1003*86d949f9SVitaliy Gusev 		break;
1004*86d949f9SVitaliy Gusev 	case NFS4_LEASE_NOT_STARTED:
1005*86d949f9SVitaliy Gusev 		mdb_printf("NOT_STARTED\n");
1006*86d949f9SVitaliy Gusev 		break;
1007*86d949f9SVitaliy Gusev 	default:
1008*86d949f9SVitaliy Gusev 		mdb_printf("??\n");
1009*86d949f9SVitaliy Gusev 		break;
1010*86d949f9SVitaliy Gusev 	}
1011*86d949f9SVitaliy Gusev 
1012*86d949f9SVitaliy Gusev 	mdb_printf("Lease Time: %i sec\n", srv.s_lease_time);
1013*86d949f9SVitaliy Gusev 	mdb_printf("Last renewal: %Y\n", srv.last_renewal_time);
1014*86d949f9SVitaliy Gusev 	mdb_printf("Propgn Delay: %li sec : %li nsec\n",
1015*86d949f9SVitaliy Gusev 	    srv.propagation_delay.tv_sec, srv.propagation_delay.tv_nsec);
1016*86d949f9SVitaliy Gusev 	mdb_printf("Credential: %p\n\n", srv.s_cred);
1017*86d949f9SVitaliy Gusev 
1018*86d949f9SVitaliy Gusev 	return (DCMD_OK);
1019*86d949f9SVitaliy Gusev }
1020*86d949f9SVitaliy Gusev 
1021*86d949f9SVitaliy Gusev void
nfs4_server_info_help(void)1022*86d949f9SVitaliy Gusev nfs4_server_info_help(void)
1023*86d949f9SVitaliy Gusev {
1024*86d949f9SVitaliy Gusev 	mdb_printf(
1025*86d949f9SVitaliy Gusev 	    "-c       assumes client is an illumos NFSv4 Client\n"
1026*86d949f9SVitaliy Gusev 	    "-s       assumes server is an illumos NFSv4 Server\n"
1027*86d949f9SVitaliy Gusev 	    "\n"
1028*86d949f9SVitaliy Gusev 	    "The -c option enables the dcmd to decode the client generated\n"
1029*86d949f9SVitaliy Gusev 	    "structure CLIDtoSend that is normally opaque to the server.\n"
1030*86d949f9SVitaliy Gusev 	    "The -s option enables the dcmd to decode the server generated\n"
1031*86d949f9SVitaliy Gusev 	    "structure Client ID that is normally opaque to the client.\n");
1032*86d949f9SVitaliy Gusev }
1033*86d949f9SVitaliy Gusev 
1034*86d949f9SVitaliy Gusev /*
1035*86d949f9SVitaliy Gusev  * nfs4_mimsg dcmd implementation
1036*86d949f9SVitaliy Gusev  */
1037*86d949f9SVitaliy Gusev 
1038*86d949f9SVitaliy Gusev static const struct {
1039*86d949f9SVitaliy Gusev 	const char *str;
1040*86d949f9SVitaliy Gusev 	nfs4_event_type_t et;
1041*86d949f9SVitaliy Gusev } nfs4_event_type_tbl[] = {
1042*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_BAD_SEQID),
1043*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_BADHANDLE),
1044*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_CLIENTID),
1045*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_DEAD_FILE),
1046*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_END),
1047*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_FAIL_RELOCK),
1048*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_FAIL_REMAP_LEN),
1049*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_FAIL_REMAP_OP),
1050*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_FAILOVER),
1051*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_FILE_DIFF),
1052*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_LOST_STATE),
1053*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_OPENS_CHANGED),
1054*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_SIGLOST),
1055*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_SIGLOST_NO_DUMP),
1056*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_START),
1057*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_UNEXPECTED_ACTION),
1058*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_UNEXPECTED_ERRNO),
1059*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_UNEXPECTED_STATUS),
1060*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_WRONGSEC),
1061*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_LOST_STATE_BAD_OP),
1062*86d949f9SVitaliy Gusev 	TBL_ENTRY(RE_REFERRAL),
1063*86d949f9SVitaliy Gusev 	{NULL}
1064*86d949f9SVitaliy Gusev };
1065*86d949f9SVitaliy Gusev 
1066*86d949f9SVitaliy Gusev static const struct {
1067*86d949f9SVitaliy Gusev 	const char *str;
1068*86d949f9SVitaliy Gusev 	nfs4_fact_type_t ft;
1069*86d949f9SVitaliy Gusev } nfs4_fact_type_tbl[] = {
1070*86d949f9SVitaliy Gusev 	TBL_ENTRY(RF_BADOWNER),
1071*86d949f9SVitaliy Gusev 	TBL_ENTRY(RF_ERR),
1072*86d949f9SVitaliy Gusev 	TBL_ENTRY(RF_RENEW_EXPIRED),
1073*86d949f9SVitaliy Gusev 	TBL_ENTRY(RF_SRV_NOT_RESPOND),
1074*86d949f9SVitaliy Gusev 	TBL_ENTRY(RF_SRV_OK),
1075*86d949f9SVitaliy Gusev 	TBL_ENTRY(RF_SRVS_NOT_RESPOND),
1076*86d949f9SVitaliy Gusev 	TBL_ENTRY(RF_SRVS_OK),
1077*86d949f9SVitaliy Gusev 	TBL_ENTRY(RF_DELMAP_CB_ERR),
1078*86d949f9SVitaliy Gusev 	TBL_ENTRY(RF_SENDQ_FULL),
1079*86d949f9SVitaliy Gusev 	{NULL}
1080*86d949f9SVitaliy Gusev };
1081*86d949f9SVitaliy Gusev 
1082*86d949f9SVitaliy Gusev static void
mimsg_print_event(const nfs4_debug_msg_t * msg)1083*86d949f9SVitaliy Gusev mimsg_print_event(const nfs4_debug_msg_t *msg)
1084*86d949f9SVitaliy Gusev {
1085*86d949f9SVitaliy Gusev 	const nfs4_revent_t *ep = &msg->rmsg_u.msg_event;
1086*86d949f9SVitaliy Gusev 	char msg_srv[MAXPATHLEN];
1087*86d949f9SVitaliy Gusev 	char msg_mntpt[MAXPATHLEN];
1088*86d949f9SVitaliy Gusev 	char char1[MAXPATHLEN];
1089*86d949f9SVitaliy Gusev 	char *char1p = char1;
1090*86d949f9SVitaliy Gusev 	char char2[MAXPATHLEN];
1091*86d949f9SVitaliy Gusev 	char *char2p = char2;
1092*86d949f9SVitaliy Gusev 
1093*86d949f9SVitaliy Gusev 	if (mdb_readstr(msg_srv, sizeof (msg_srv),
1094*86d949f9SVitaliy Gusev 	    (uintptr_t)msg->msg_srv) == -1)
1095*86d949f9SVitaliy Gusev 		strcpy(msg_srv, "??");
1096*86d949f9SVitaliy Gusev 
1097*86d949f9SVitaliy Gusev 	if (mdb_readstr(msg_mntpt, sizeof (msg_mntpt),
1098*86d949f9SVitaliy Gusev 	    (uintptr_t)msg->msg_mntpt) == -1)
1099*86d949f9SVitaliy Gusev 		strcpy(msg_mntpt, "??");
1100*86d949f9SVitaliy Gusev 
1101*86d949f9SVitaliy Gusev 	if (ep->re_char1 != NULL) {
1102*86d949f9SVitaliy Gusev 		if (mdb_readstr(char1, sizeof (char1),
1103*86d949f9SVitaliy Gusev 		    (uintptr_t)ep->re_char1) == -1)
1104*86d949f9SVitaliy Gusev 			strcpy(char1, "??");
1105*86d949f9SVitaliy Gusev 	} else {
1106*86d949f9SVitaliy Gusev 		char1[0] = '\0';
1107*86d949f9SVitaliy Gusev 		char1p = NULL;
1108*86d949f9SVitaliy Gusev 	}
1109*86d949f9SVitaliy Gusev 
1110*86d949f9SVitaliy Gusev 	if (ep->re_char2 != NULL) {
1111*86d949f9SVitaliy Gusev 		if (mdb_readstr(char2, sizeof (char2),
1112*86d949f9SVitaliy Gusev 		    (uintptr_t)ep->re_char2) == -1)
1113*86d949f9SVitaliy Gusev 			strcpy(char2, "??");
1114*86d949f9SVitaliy Gusev 	} else {
1115*86d949f9SVitaliy Gusev 		char2[0] = '\0';
1116*86d949f9SVitaliy Gusev 		char2p = NULL;
1117*86d949f9SVitaliy Gusev 	}
1118*86d949f9SVitaliy Gusev 
1119*86d949f9SVitaliy Gusev 	switch (ep->re_type) {
1120*86d949f9SVitaliy Gusev 	case RE_BAD_SEQID:
1121*86d949f9SVitaliy Gusev 		mdb_printf("Operation %s for file %s (rnode_pt 0x%p), pid %d "
1122*86d949f9SVitaliy Gusev 		    "using seqid %u got %s on server %s.  Last good seqid was "
1123*86d949f9SVitaliy Gusev 		    "%u for operation %s.", nfs4_tag_str(ep->re_tag1), char1p,
1124*86d949f9SVitaliy Gusev 		    ep->re_rp1, ep->re_pid, ep->re_seqid1,
1125*86d949f9SVitaliy Gusev 		    nfs4_stat_str(ep->re_stat4), msg_srv, ep->re_seqid2,
1126*86d949f9SVitaliy Gusev 		    nfs4_tag_str(ep->re_tag2));
1127*86d949f9SVitaliy Gusev 		break;
1128*86d949f9SVitaliy Gusev 	case RE_BADHANDLE:
1129*86d949f9SVitaliy Gusev 		if (ep->re_char1 != NULL) {
1130*86d949f9SVitaliy Gusev 			mdb_printf("server %s said filehandle was invalid for "
1131*86d949f9SVitaliy Gusev 			    "file: %s (rnode_pt %p) on mount %s", msg_srv,
1132*86d949f9SVitaliy Gusev 			    char1, ep->re_rp1, msg_mntpt);
1133*86d949f9SVitaliy Gusev 		} else {
1134*86d949f9SVitaliy Gusev 			mdb_printf("server %s said filehandle was invalid for "
1135*86d949f9SVitaliy Gusev 			    "file: (rnode_pt %p) on mount %s", msg_srv,
1136*86d949f9SVitaliy Gusev 			    ep->re_rp1, msg_mntpt);
1137*86d949f9SVitaliy Gusev 		}
1138*86d949f9SVitaliy Gusev 		break;
1139*86d949f9SVitaliy Gusev 	case RE_CLIENTID:
1140*86d949f9SVitaliy Gusev 		mdb_printf("Can't recover clientid on mi 0x%p due to error %u "
1141*86d949f9SVitaliy Gusev 		    "(%s), for server %s.  Marking file system as unusable.",
1142*86d949f9SVitaliy Gusev 		    ep->re_mi, ep->re_uint, nfs4_stat_str(ep->re_stat4),
1143*86d949f9SVitaliy Gusev 		    msg_srv);
1144*86d949f9SVitaliy Gusev 		break;
1145*86d949f9SVitaliy Gusev 	case RE_DEAD_FILE:
1146*86d949f9SVitaliy Gusev 		mdb_printf("File %s (rnode_pt %p) on server %s could not be "
1147*86d949f9SVitaliy Gusev 		    "recovered and was closed.  %s %s.", char1p, ep->re_rp1,
1148*86d949f9SVitaliy Gusev 		    msg_srv, char2,
1149*86d949f9SVitaliy Gusev 		    ep->re_stat4 ? nfs4_stat_str(ep->re_stat4) : "");
1150*86d949f9SVitaliy Gusev 		break;
1151*86d949f9SVitaliy Gusev 	case RE_END:
1152*86d949f9SVitaliy Gusev 		mdb_printf("Recovery done for mount %s (0x%p) on server %s, "
1153*86d949f9SVitaliy Gusev 		    "rnode_pt1 %s (0x%p), rnode_pt2 %s (0x%p)", msg_mntpt,
1154*86d949f9SVitaliy Gusev 		    ep->re_mi, msg_srv, char1p, ep->re_rp1, char2p, ep->re_rp2);
1155*86d949f9SVitaliy Gusev 		break;
1156*86d949f9SVitaliy Gusev 	case RE_FAIL_RELOCK:
1157*86d949f9SVitaliy Gusev 		mdb_printf("Couldn't reclaim lock for pid %d for file %s "
1158*86d949f9SVitaliy Gusev 		    "(rnode_pt %p) on (server %s): error %u", ep->re_pid,
1159*86d949f9SVitaliy Gusev 		    char1p, ep->re_rp1, msg_srv,
1160*86d949f9SVitaliy Gusev 		    ep->re_uint ? ep->re_uint : ep->re_stat4);
1161*86d949f9SVitaliy Gusev 		break;
1162*86d949f9SVitaliy Gusev 	case RE_FAIL_REMAP_LEN:
1163*86d949f9SVitaliy Gusev 		mdb_printf("remap_lookup: server %s returned bad fhandle "
1164*86d949f9SVitaliy Gusev 		    "length (%u)", msg_srv, ep->re_uint);
1165*86d949f9SVitaliy Gusev 		break;
1166*86d949f9SVitaliy Gusev 	case RE_FAIL_REMAP_OP:
1167*86d949f9SVitaliy Gusev 		mdb_printf("remap_lookup: didn't get expected OP_GETFH for "
1168*86d949f9SVitaliy Gusev 		    "server %s", msg_srv);
1169*86d949f9SVitaliy Gusev 		break;
1170*86d949f9SVitaliy Gusev 	case RE_FAILOVER:
1171*86d949f9SVitaliy Gusev 		if (ep->re_char1)
1172*86d949f9SVitaliy Gusev 			mdb_printf("Failing over from %s to %s", msg_srv,
1173*86d949f9SVitaliy Gusev 			    char1p);
1174*86d949f9SVitaliy Gusev 		else
1175*86d949f9SVitaliy Gusev 			mdb_printf("Failing over: selecting original server %s",
1176*86d949f9SVitaliy Gusev 			    msg_srv);
1177*86d949f9SVitaliy Gusev 		break;
1178*86d949f9SVitaliy Gusev 	case RE_FILE_DIFF:
1179*86d949f9SVitaliy Gusev 		mdb_printf("Replicas %s and %s: file %s(%p) not same",
1180*86d949f9SVitaliy Gusev 		    msg_srv, msg_mntpt, ep->re_char1, (void *)ep->re_rp1);
1181*86d949f9SVitaliy Gusev 		break;
1182*86d949f9SVitaliy Gusev 	case RE_LOST_STATE:
1183*86d949f9SVitaliy Gusev 		/*
1184*86d949f9SVitaliy Gusev 		 * if char1 is null you should use ::nfs4_fname for re_rp1
1185*86d949f9SVitaliy Gusev 		 */
1186*86d949f9SVitaliy Gusev 		mdb_printf("client has a lost %s request for rnode_pt1 %s "
1187*86d949f9SVitaliy Gusev 		    "(0x%p), rnode_pt2 %s (0x%p) on fs %s, server %s.",
1188*86d949f9SVitaliy Gusev 		    nfs4_op_str(ep->re_uint), char1p, ep->re_rp1, char2p,
1189*86d949f9SVitaliy Gusev 		    ep->re_rp2, msg_mntpt, msg_srv);
1190*86d949f9SVitaliy Gusev 		break;
1191*86d949f9SVitaliy Gusev 	case RE_OPENS_CHANGED:
1192*86d949f9SVitaliy Gusev 		mdb_printf("Recovery: number of open files changed "
1193*86d949f9SVitaliy Gusev 		    "for mount %s (0x%p) (old %d, new %d) on server %s\n",
1194*86d949f9SVitaliy Gusev 		    msg_mntpt, (void *)ep->re_mi, ep->re_uint, ep->re_pid,
1195*86d949f9SVitaliy Gusev 		    msg_srv);
1196*86d949f9SVitaliy Gusev 		break;
1197*86d949f9SVitaliy Gusev 	case RE_SIGLOST:
1198*86d949f9SVitaliy Gusev 	case RE_SIGLOST_NO_DUMP:
1199*86d949f9SVitaliy Gusev 		mdb_printf("Process %d lost its locks on file %s (rnode_pt %p) "
1200*86d949f9SVitaliy Gusev 		    "due to a NFS error (%u) on server %s", ep->re_pid, char1p,
1201*86d949f9SVitaliy Gusev 		    ep->re_rp1, ep->re_uint ? ep->re_uint : ep->re_stat4,
1202*86d949f9SVitaliy Gusev 		    msg_srv);
1203*86d949f9SVitaliy Gusev 		break;
1204*86d949f9SVitaliy Gusev 	case RE_START:
1205*86d949f9SVitaliy Gusev 		mdb_printf("Starting recovery for mount %s (0x%p, flags %#x) "
1206*86d949f9SVitaliy Gusev 		    "on server %s, rnode_pt1 %s (0x%p), rnode_pt2 %s (0x%p)",
1207*86d949f9SVitaliy Gusev 		    msg_mntpt, ep->re_mi, ep->re_uint, msg_srv, char1p,
1208*86d949f9SVitaliy Gusev 		    ep->re_rp1, char2p, ep->re_rp2);
1209*86d949f9SVitaliy Gusev 		break;
1210*86d949f9SVitaliy Gusev 	case RE_UNEXPECTED_ACTION:
1211*86d949f9SVitaliy Gusev 		mdb_printf("Recovery, unexpected action (%d) on server %s\n",
1212*86d949f9SVitaliy Gusev 		    ep->re_uint, msg_srv);
1213*86d949f9SVitaliy Gusev 		break;
1214*86d949f9SVitaliy Gusev 	case RE_UNEXPECTED_ERRNO:
1215*86d949f9SVitaliy Gusev 		mdb_printf("Recovery, unexpected errno (%d) on server %s\n",
1216*86d949f9SVitaliy Gusev 		    ep->re_uint, msg_srv);
1217*86d949f9SVitaliy Gusev 		break;
1218*86d949f9SVitaliy Gusev 	case RE_UNEXPECTED_STATUS:
1219*86d949f9SVitaliy Gusev 		mdb_printf("Recovery, unexpected NFS status code (%s) "
1220*86d949f9SVitaliy Gusev 		    "on server %s\n",
1221*86d949f9SVitaliy Gusev 		    nfs4_stat_str(ep->re_stat4), msg_srv);
1222*86d949f9SVitaliy Gusev 		break;
1223*86d949f9SVitaliy Gusev 	case RE_WRONGSEC:
1224*86d949f9SVitaliy Gusev 		mdb_printf("Recovery, can't recover from NFS4ERR_WRONGSEC."
1225*86d949f9SVitaliy Gusev 		    " error %d for mount %s server %s: rnode_pt1 %s (0x%p)"
1226*86d949f9SVitaliy Gusev 		    " rnode_pt2 %s (0x%p)", ep->re_uint, msg_mntpt, msg_srv,
1227*86d949f9SVitaliy Gusev 		    ep->re_char1, (void *)ep->re_rp1, ep->re_char2,
1228*86d949f9SVitaliy Gusev 		    (void *)ep->re_rp2);
1229*86d949f9SVitaliy Gusev 		break;
1230*86d949f9SVitaliy Gusev 	case RE_LOST_STATE_BAD_OP:
1231*86d949f9SVitaliy Gusev 		mdb_printf("NFS lost state with unrecognized op (%d)."
1232*86d949f9SVitaliy Gusev 		    " fs %s, server %s, pid %d, file %s (rnode_pt: 0x%p), "
1233*86d949f9SVitaliy Gusev 		    "dir %s (0x%p)", ep->re_uint, msg_mntpt, msg_srv,
1234*86d949f9SVitaliy Gusev 		    ep->re_pid, ep->re_char1, (void *)ep->re_rp1,
1235*86d949f9SVitaliy Gusev 		    ep->re_char2, (void *)ep->re_rp2);
1236*86d949f9SVitaliy Gusev 		break;
1237*86d949f9SVitaliy Gusev 	case RE_REFERRAL:
1238*86d949f9SVitaliy Gusev 		if (ep->re_char1)
1239*86d949f9SVitaliy Gusev 			mdb_printf("Referal, Server: %s on Mntpt: %s"
1240*86d949f9SVitaliy Gusev 			    "being referred from %s to %s", msg_srv,
1241*86d949f9SVitaliy Gusev 			    msg_mntpt, msg_srv, ep->re_char1);
1242*86d949f9SVitaliy Gusev 		else
1243*86d949f9SVitaliy Gusev 			mdb_printf("Referal, Server: %s on Mntpt: %s"
1244*86d949f9SVitaliy Gusev 			    "NFS4: being referred from %s to unknown server",
1245*86d949f9SVitaliy Gusev 			    msg_srv, msg_mntpt, msg->msg_srv);
1246*86d949f9SVitaliy Gusev 		break;
1247*86d949f9SVitaliy Gusev 	default:
1248*86d949f9SVitaliy Gusev 		mdb_printf("illegal event %d", ep->re_type);
1249*86d949f9SVitaliy Gusev 		break;
1250*86d949f9SVitaliy Gusev 	}
1251*86d949f9SVitaliy Gusev }
1252*86d949f9SVitaliy Gusev 
1253*86d949f9SVitaliy Gusev static void
mimsg_print_fact(const nfs4_debug_msg_t * msg)1254*86d949f9SVitaliy Gusev mimsg_print_fact(const nfs4_debug_msg_t *msg)
1255*86d949f9SVitaliy Gusev {
1256*86d949f9SVitaliy Gusev 	const nfs4_rfact_t *fp = &msg->rmsg_u.msg_fact;
1257*86d949f9SVitaliy Gusev 	char msg_srv[MAXPATHLEN];
1258*86d949f9SVitaliy Gusev 	char file[MAXPATHLEN];
1259*86d949f9SVitaliy Gusev 
1260*86d949f9SVitaliy Gusev 	if (mdb_readstr(msg_srv, sizeof (msg_srv),
1261*86d949f9SVitaliy Gusev 	    (uintptr_t)msg->msg_srv) == -1)
1262*86d949f9SVitaliy Gusev 		strcpy(msg_srv, "??");
1263*86d949f9SVitaliy Gusev 
1264*86d949f9SVitaliy Gusev 	switch (fp->rf_type) {
1265*86d949f9SVitaliy Gusev 	case RF_BADOWNER:
1266*86d949f9SVitaliy Gusev 		mdb_printf("NFSMAPID_DOMAIN does not match server: %s's "
1267*86d949f9SVitaliy Gusev 		    "domain.", msg_srv);
1268*86d949f9SVitaliy Gusev 		break;
1269*86d949f9SVitaliy Gusev 	case RF_ERR:
1270*86d949f9SVitaliy Gusev 		mdb_printf("Op %s got error ", nfs4_op_str(fp->rf_op));
1271*86d949f9SVitaliy Gusev 		if (fp->rf_error)
1272*86d949f9SVitaliy Gusev 			mdb_printf("%d", fp->rf_error);
1273*86d949f9SVitaliy Gusev 		else
1274*86d949f9SVitaliy Gusev 			mdb_printf("%s", nfs4_stat_str(fp->rf_stat4));
1275*86d949f9SVitaliy Gusev 		mdb_printf(" causing recovery action %s.",
1276*86d949f9SVitaliy Gusev 		    nfs4_recov_str(fp->rf_action));
1277*86d949f9SVitaliy Gusev 		if (fp->rf_reboot)
1278*86d949f9SVitaliy Gusev 			mdb_printf("  Client also suspects server rebooted");
1279*86d949f9SVitaliy Gusev 		break;
1280*86d949f9SVitaliy Gusev 	case RF_RENEW_EXPIRED:
1281*86d949f9SVitaliy Gusev 		mdb_printf("Client's lease expired on server %s.", msg_srv);
1282*86d949f9SVitaliy Gusev 		break;
1283*86d949f9SVitaliy Gusev 	case RF_SRV_NOT_RESPOND:
1284*86d949f9SVitaliy Gusev 		mdb_printf("Server %s not responding, still trying", msg_srv);
1285*86d949f9SVitaliy Gusev 		break;
1286*86d949f9SVitaliy Gusev 	case RF_SRV_OK:
1287*86d949f9SVitaliy Gusev 		mdb_printf("Server %s ok", msg_srv);
1288*86d949f9SVitaliy Gusev 		break;
1289*86d949f9SVitaliy Gusev 	case RF_SRVS_NOT_RESPOND:
1290*86d949f9SVitaliy Gusev 		mdb_printf("Servers %s not responding, still trying", msg_srv);
1291*86d949f9SVitaliy Gusev 		break;
1292*86d949f9SVitaliy Gusev 	case RF_SRVS_OK:
1293*86d949f9SVitaliy Gusev 		mdb_printf("Servers %s ok", msg_srv);
1294*86d949f9SVitaliy Gusev 		break;
1295*86d949f9SVitaliy Gusev 	case RF_DELMAP_CB_ERR:
1296*86d949f9SVitaliy Gusev 		if (mdb_readstr(file, sizeof (file),
1297*86d949f9SVitaliy Gusev 		    (uintptr_t)fp->rf_char1) == -1)
1298*86d949f9SVitaliy Gusev 			strcpy(file, "??");
1299*86d949f9SVitaliy Gusev 		mdb_printf("Op %s got error %s when executing delmap on file "
1300*86d949f9SVitaliy Gusev 		    "%s (rnode_pt 0x%p).", nfs4_op_str(fp->rf_op),
1301*86d949f9SVitaliy Gusev 		    nfs4_stat_str(fp->rf_stat4), file, fp->rf_rp1);
1302*86d949f9SVitaliy Gusev 		break;
1303*86d949f9SVitaliy Gusev 	case RF_SENDQ_FULL:
1304*86d949f9SVitaliy Gusev 		mdb_printf("Send queue to NFS server %s is full; still trying",
1305*86d949f9SVitaliy Gusev 		    msg_srv);
1306*86d949f9SVitaliy Gusev 		break;
1307*86d949f9SVitaliy Gusev 	default:
1308*86d949f9SVitaliy Gusev 		mdb_printf("??");
1309*86d949f9SVitaliy Gusev 		break;
1310*86d949f9SVitaliy Gusev 	}
1311*86d949f9SVitaliy Gusev }
1312*86d949f9SVitaliy Gusev 
1313*86d949f9SVitaliy Gusev static int
print_mimsg_cb(uintptr_t addr,const void * data,void * cb_data)1314*86d949f9SVitaliy Gusev print_mimsg_cb(uintptr_t addr, const void *data, void *cb_data)
1315*86d949f9SVitaliy Gusev {
1316*86d949f9SVitaliy Gusev 	nfs4_debug_msg_t msg;
1317*86d949f9SVitaliy Gusev 	uint_t opt_s = *(uint_t *)cb_data;
1318*86d949f9SVitaliy Gusev 
1319*86d949f9SVitaliy Gusev 	if (mdb_vread(&msg, sizeof (msg), addr) == -1) {
1320*86d949f9SVitaliy Gusev 		mdb_warn("failed to read nfs4_debug_msg_t at %p", addr);
1321*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1322*86d949f9SVitaliy Gusev 	}
1323*86d949f9SVitaliy Gusev 
1324*86d949f9SVitaliy Gusev 	if (opt_s) {
1325*86d949f9SVitaliy Gusev 		const char *msg_type = "??";
1326*86d949f9SVitaliy Gusev 		const char *ef_type = "??";
1327*86d949f9SVitaliy Gusev 		int i;
1328*86d949f9SVitaliy Gusev 
1329*86d949f9SVitaliy Gusev 		switch (msg.msg_type) {
1330*86d949f9SVitaliy Gusev 		case RM_EVENT:
1331*86d949f9SVitaliy Gusev 			msg_type = "event";
1332*86d949f9SVitaliy Gusev 			for (i = 0; nfs4_event_type_tbl[i].str != NULL; i++)
1333*86d949f9SVitaliy Gusev 				if (nfs4_event_type_tbl[i].et ==
1334*86d949f9SVitaliy Gusev 				    msg.rmsg_u.msg_event.re_type) {
1335*86d949f9SVitaliy Gusev 					ef_type = nfs4_event_type_tbl[i].str;
1336*86d949f9SVitaliy Gusev 					break;
1337*86d949f9SVitaliy Gusev 				}
1338*86d949f9SVitaliy Gusev 			break;
1339*86d949f9SVitaliy Gusev 		case RM_FACT:
1340*86d949f9SVitaliy Gusev 			msg_type = "fact";
1341*86d949f9SVitaliy Gusev 			for (i = 0; nfs4_fact_type_tbl[i].str != NULL; i++)
1342*86d949f9SVitaliy Gusev 				if (nfs4_fact_type_tbl[i].ft ==
1343*86d949f9SVitaliy Gusev 				    msg.rmsg_u.msg_fact.rf_type) {
1344*86d949f9SVitaliy Gusev 					ef_type = nfs4_fact_type_tbl[i].str;
1345*86d949f9SVitaliy Gusev 					break;
1346*86d949f9SVitaliy Gusev 				}
1347*86d949f9SVitaliy Gusev 			break;
1348*86d949f9SVitaliy Gusev 		}
1349*86d949f9SVitaliy Gusev 
1350*86d949f9SVitaliy Gusev 		mdb_printf("%Y: %s %s\n", msg.msg_time.tv_sec, msg_type,
1351*86d949f9SVitaliy Gusev 		    ef_type);
1352*86d949f9SVitaliy Gusev 
1353*86d949f9SVitaliy Gusev 		return (WALK_NEXT);
1354*86d949f9SVitaliy Gusev 	}
1355*86d949f9SVitaliy Gusev 
1356*86d949f9SVitaliy Gusev 	mdb_printf("[NFS4]%Y: ", msg.msg_time.tv_sec);
1357*86d949f9SVitaliy Gusev 	switch (msg.msg_type) {
1358*86d949f9SVitaliy Gusev 	case RM_EVENT:
1359*86d949f9SVitaliy Gusev 		mimsg_print_event(&msg);
1360*86d949f9SVitaliy Gusev 		break;
1361*86d949f9SVitaliy Gusev 	case RM_FACT:
1362*86d949f9SVitaliy Gusev 		mimsg_print_fact(&msg);
1363*86d949f9SVitaliy Gusev 		break;
1364*86d949f9SVitaliy Gusev 	default:
1365*86d949f9SVitaliy Gusev 		mdb_printf("??");
1366*86d949f9SVitaliy Gusev 		break;
1367*86d949f9SVitaliy Gusev 	}
1368*86d949f9SVitaliy Gusev 	mdb_printf("\n");
1369*86d949f9SVitaliy Gusev 
1370*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
1371*86d949f9SVitaliy Gusev }
1372*86d949f9SVitaliy Gusev 
1373*86d949f9SVitaliy Gusev int
nfs4_mimsg_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1374*86d949f9SVitaliy Gusev nfs4_mimsg_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1375*86d949f9SVitaliy Gusev {
1376*86d949f9SVitaliy Gusev 	uint_t opt_s = FALSE;
1377*86d949f9SVitaliy Gusev 
1378*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
1379*86d949f9SVitaliy Gusev 		mdb_printf("requires address of mi_msg_list\n");
1380*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1381*86d949f9SVitaliy Gusev 	}
1382*86d949f9SVitaliy Gusev 
1383*86d949f9SVitaliy Gusev 	if (mdb_getopts(argc, argv,
1384*86d949f9SVitaliy Gusev 	    's', MDB_OPT_SETBITS, TRUE, &opt_s, NULL) != argc)
1385*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1386*86d949f9SVitaliy Gusev 
1387*86d949f9SVitaliy Gusev 	if (mdb_pwalk("list", print_mimsg_cb, &opt_s, addr) == -1) {
1388*86d949f9SVitaliy Gusev 		mdb_warn("failed to walk mi_msg_list list");
1389*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
1390*86d949f9SVitaliy Gusev 	}
1391*86d949f9SVitaliy Gusev 
1392*86d949f9SVitaliy Gusev 	return (DCMD_OK);
1393*86d949f9SVitaliy Gusev }
1394*86d949f9SVitaliy Gusev 
1395*86d949f9SVitaliy Gusev void
nfs4_mimsg_help(void)1396*86d949f9SVitaliy Gusev nfs4_mimsg_help(void)
1397*86d949f9SVitaliy Gusev {
1398*86d949f9SVitaliy Gusev 	mdb_printf(
1399*86d949f9SVitaliy Gusev 	    "-c       assumes client is an illumos NFSv4 Client\n"
1400*86d949f9SVitaliy Gusev 	    "-s       assumes server is an illumos NFSv4 Server\n"
1401*86d949f9SVitaliy Gusev 	    "\n"
1402*86d949f9SVitaliy Gusev 	    "The -c option enables the dcmd to decode the client generated\n"
1403*86d949f9SVitaliy Gusev 	    "structure CLIDtoSend that is normally opaque to the server.\n"
1404*86d949f9SVitaliy Gusev 	    "The -s option enables the dcmd to decode the server generated\n"
1405*86d949f9SVitaliy Gusev 	    "structure Client ID that is normally opaque to the client.\n");
1406*86d949f9SVitaliy Gusev }
1407*86d949f9SVitaliy Gusev 
1408*86d949f9SVitaliy Gusev /*
1409*86d949f9SVitaliy Gusev  * nfs4_fname dcmd implementation
1410*86d949f9SVitaliy Gusev  */
1411*86d949f9SVitaliy Gusev 
1412*86d949f9SVitaliy Gusev static void
print_nfs4_fname(uintptr_t addr)1413*86d949f9SVitaliy Gusev print_nfs4_fname(uintptr_t addr)
1414*86d949f9SVitaliy Gusev {
1415*86d949f9SVitaliy Gusev 	char path[MAXPATHLEN];
1416*86d949f9SVitaliy Gusev 	char *p = path + sizeof (path) - 1;
1417*86d949f9SVitaliy Gusev 
1418*86d949f9SVitaliy Gusev 	*p = '\0';
1419*86d949f9SVitaliy Gusev 	while (addr != 0) {
1420*86d949f9SVitaliy Gusev 		nfs4_fname_t fn;
1421*86d949f9SVitaliy Gusev 		char name[MAXNAMELEN];
1422*86d949f9SVitaliy Gusev 
1423*86d949f9SVitaliy Gusev 		if (mdb_vread(&fn, sizeof (fn), addr) == -1 ||
1424*86d949f9SVitaliy Gusev 		    fn.fn_len >= sizeof (name) || fn.fn_len < 0 ||
1425*86d949f9SVitaliy Gusev 		    p - fn.fn_len - 1 < path || mdb_readstr(name, sizeof (name),
1426*86d949f9SVitaliy Gusev 		    (uintptr_t)fn.fn_name) != fn.fn_len) {
1427*86d949f9SVitaliy Gusev 			mdb_printf("??");
1428*86d949f9SVitaliy Gusev 			break;
1429*86d949f9SVitaliy Gusev 		}
1430*86d949f9SVitaliy Gusev 
1431*86d949f9SVitaliy Gusev 		bcopy(name, p -= fn.fn_len, fn.fn_len);
1432*86d949f9SVitaliy Gusev 
1433*86d949f9SVitaliy Gusev 		if ((addr = (uintptr_t)fn.fn_parent) != 0)
1434*86d949f9SVitaliy Gusev 			*--p = '/';
1435*86d949f9SVitaliy Gusev 	}
1436*86d949f9SVitaliy Gusev 	mdb_printf("%s", p);
1437*86d949f9SVitaliy Gusev }
1438*86d949f9SVitaliy Gusev 
1439*86d949f9SVitaliy Gusev int
nfs4_fname_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1440*86d949f9SVitaliy Gusev nfs4_fname_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1441*86d949f9SVitaliy Gusev {
1442*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
1443*86d949f9SVitaliy Gusev 		mdb_printf("requires address of nfs4_fname_t \n");
1444*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1445*86d949f9SVitaliy Gusev 	}
1446*86d949f9SVitaliy Gusev 
1447*86d949f9SVitaliy Gusev 	if (argc != 0)
1448*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1449*86d949f9SVitaliy Gusev 
1450*86d949f9SVitaliy Gusev 	print_nfs4_fname(addr);
1451*86d949f9SVitaliy Gusev 	mdb_printf("\n");
1452*86d949f9SVitaliy Gusev 
1453*86d949f9SVitaliy Gusev 	return (DCMD_OK);
1454*86d949f9SVitaliy Gusev }
1455*86d949f9SVitaliy Gusev 
1456*86d949f9SVitaliy Gusev /*
1457*86d949f9SVitaliy Gusev  * Open Owner commands and walkers
1458*86d949f9SVitaliy Gusev  */
1459*86d949f9SVitaliy Gusev int
nfs4_oo_cb(uintptr_t addr,const void * data,void * varg)1460*86d949f9SVitaliy Gusev nfs4_oo_cb(uintptr_t addr, const void *data, void *varg)
1461*86d949f9SVitaliy Gusev {
1462*86d949f9SVitaliy Gusev 	nfs4_open_owner_t	oop;
1463*86d949f9SVitaliy Gusev 
1464*86d949f9SVitaliy Gusev 	if (mdb_vread(&oop, sizeof (nfs4_open_owner_t), addr) == -1) {
1465*86d949f9SVitaliy Gusev 		mdb_warn("failed to read nfs4_open_onwer at %p", addr);
1466*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1467*86d949f9SVitaliy Gusev 	}
1468*86d949f9SVitaliy Gusev 	mdb_printf("%p %p %d %d %s %s\n", addr, oop.oo_cred,
1469*86d949f9SVitaliy Gusev 	    oop.oo_ref_count, oop.oo_seqid,
1470*86d949f9SVitaliy Gusev 	    oop.oo_just_created ? "True" : "False",
1471*86d949f9SVitaliy Gusev 	    oop.oo_seqid_inuse  ? "True" : "False");
1472*86d949f9SVitaliy Gusev 
1473*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
1474*86d949f9SVitaliy Gusev }
1475*86d949f9SVitaliy Gusev 
1476*86d949f9SVitaliy Gusev /*
1477*86d949f9SVitaliy Gusev  * nfs4_foo dcmd implementation
1478*86d949f9SVitaliy Gusev  */
1479*86d949f9SVitaliy Gusev int
nfs4_foo_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1480*86d949f9SVitaliy Gusev nfs4_foo_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1481*86d949f9SVitaliy Gusev {
1482*86d949f9SVitaliy Gusev 	int			foo_off;
1483*86d949f9SVitaliy Gusev 	uintptr_t		list_addr;
1484*86d949f9SVitaliy Gusev 
1485*86d949f9SVitaliy Gusev 	mntinfo4_t		mi;
1486*86d949f9SVitaliy Gusev 	foo_off = offsetof(mntinfo4_t, mi_foo_list);
1487*86d949f9SVitaliy Gusev 
1488*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
1489*86d949f9SVitaliy Gusev 		mdb_printf("requires address of mntinfo4_t\n");
1490*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1491*86d949f9SVitaliy Gusev 	}
1492*86d949f9SVitaliy Gusev 
1493*86d949f9SVitaliy Gusev 	if (argc != 0)
1494*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1495*86d949f9SVitaliy Gusev 
1496*86d949f9SVitaliy Gusev 	if (mdb_vread(&mi, sizeof (mntinfo4_t), addr) == -1) {
1497*86d949f9SVitaliy Gusev 		mdb_warn("Failed to read mntinfo at %p", addr);
1498*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
1499*86d949f9SVitaliy Gusev 	}
1500*86d949f9SVitaliy Gusev 
1501*86d949f9SVitaliy Gusev 	list_addr =  addr + foo_off;
1502*86d949f9SVitaliy Gusev 
1503*86d949f9SVitaliy Gusev 	mdb_printf("mntinfo4: %p, mi_foo_num=%d, mi_foo_max=%d \n",
1504*86d949f9SVitaliy Gusev 	    addr, mi.mi_foo_num, mi.mi_foo_max);
1505*86d949f9SVitaliy Gusev 	mdb_printf("Address       Cred             RefCnt   SeqID    ");
1506*86d949f9SVitaliy Gusev 	mdb_printf("JustCre SeqInUse BadSeqid\n");
1507*86d949f9SVitaliy Gusev 
1508*86d949f9SVitaliy Gusev 	if (mdb_pwalk("list", nfs4_oo_cb, NULL, list_addr) == -1) {
1509*86d949f9SVitaliy Gusev 		mdb_warn("failed to walk 'nfs4_foo'");
1510*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
1511*86d949f9SVitaliy Gusev 	}
1512*86d949f9SVitaliy Gusev 	return (DCMD_OK);
1513*86d949f9SVitaliy Gusev }
1514*86d949f9SVitaliy Gusev 
1515*86d949f9SVitaliy Gusev /*
1516*86d949f9SVitaliy Gusev  * nfs4_oob_dcmd dcmd
1517*86d949f9SVitaliy Gusev  */
1518*86d949f9SVitaliy Gusev int
nfs4_oob_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1519*86d949f9SVitaliy Gusev nfs4_oob_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1520*86d949f9SVitaliy Gusev {
1521*86d949f9SVitaliy Gusev 	int			oo_off;
1522*86d949f9SVitaliy Gusev 	uintptr_t		list_addr;
1523*86d949f9SVitaliy Gusev 	uintptr_t		list_inst;
1524*86d949f9SVitaliy Gusev 	int			i;
1525*86d949f9SVitaliy Gusev 
1526*86d949f9SVitaliy Gusev 
1527*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
1528*86d949f9SVitaliy Gusev 		mdb_printf("requires address of mntinfo4_t\n");
1529*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1530*86d949f9SVitaliy Gusev 	}
1531*86d949f9SVitaliy Gusev 
1532*86d949f9SVitaliy Gusev 	if (argc != 0)
1533*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1534*86d949f9SVitaliy Gusev 
1535*86d949f9SVitaliy Gusev 	oo_off = offsetof(mntinfo4_t, mi_oo_list);
1536*86d949f9SVitaliy Gusev 	list_addr =  addr + oo_off;
1537*86d949f9SVitaliy Gusev 
1538*86d949f9SVitaliy Gusev 	mdb_printf("Address       Cred             RefCnt   SeqID    ");
1539*86d949f9SVitaliy Gusev 	mdb_printf("JustCre SeqInUse BadSeqid\n");
1540*86d949f9SVitaliy Gusev 
1541*86d949f9SVitaliy Gusev 	for (i = 0; i < NFS4_NUM_OO_BUCKETS; i++) {
1542*86d949f9SVitaliy Gusev 		list_inst = list_addr + (sizeof (nfs4_oo_hash_bucket_t) * i);
1543*86d949f9SVitaliy Gusev 
1544*86d949f9SVitaliy Gusev 		if (mdb_pwalk("list", nfs4_oo_cb, NULL, list_inst) == -1) {
1545*86d949f9SVitaliy Gusev 			mdb_warn("failed to walk 'nfs4_oob'");
1546*86d949f9SVitaliy Gusev 			return (DCMD_ERR);
1547*86d949f9SVitaliy Gusev 		}
1548*86d949f9SVitaliy Gusev 	}
1549*86d949f9SVitaliy Gusev 
1550*86d949f9SVitaliy Gusev 	return (DCMD_OK);
1551*86d949f9SVitaliy Gusev }
1552*86d949f9SVitaliy Gusev 
1553*86d949f9SVitaliy Gusev /*
1554*86d949f9SVitaliy Gusev  * print out open stream entry
1555*86d949f9SVitaliy Gusev  */
1556*86d949f9SVitaliy Gusev int
nfs4_openstream_print(uintptr_t addr,void * buf,int * opts)1557*86d949f9SVitaliy Gusev nfs4_openstream_print(uintptr_t addr, void *buf, int *opts)
1558*86d949f9SVitaliy Gusev {
1559*86d949f9SVitaliy Gusev 	nfs4_open_stream_t	os;
1560*86d949f9SVitaliy Gusev 
1561*86d949f9SVitaliy Gusev 	if (mdb_vread(&os, sizeof (nfs4_open_stream_t), addr) == -1) {
1562*86d949f9SVitaliy Gusev 		mdb_warn("Failed to read open stream at %p", addr);
1563*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
1564*86d949f9SVitaliy Gusev 	}
1565*86d949f9SVitaliy Gusev 
1566*86d949f9SVitaliy Gusev 	mdb_printf("%p\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t"
1567*86d949f9SVitaliy Gusev 	    "%d\t%d\t%d\n", addr, os.os_ref_count, os.os_share_acc_read,
1568*86d949f9SVitaliy Gusev 	    os.os_share_acc_write, os.os_mmap_read, os.os_mmap_write,
1569*86d949f9SVitaliy Gusev 	    os.os_share_deny_none, os.os_share_deny_read,
1570*86d949f9SVitaliy Gusev 	    os.os_share_deny_write, os.os_open_ref_count, os.os_dc_openacc,
1571*86d949f9SVitaliy Gusev 	    os.os_mapcnt);
1572*86d949f9SVitaliy Gusev 
1573*86d949f9SVitaliy Gusev 	if (opts && *opts & TRUE) {
1574*86d949f9SVitaliy Gusev 		mdb_printf("  ");
1575*86d949f9SVitaliy Gusev 		if (os.os_valid)
1576*86d949f9SVitaliy Gusev 			mdb_printf("os_valid ");
1577*86d949f9SVitaliy Gusev 		if (os.os_delegation)
1578*86d949f9SVitaliy Gusev 			mdb_printf("os_delegation ");
1579*86d949f9SVitaliy Gusev 		if (os.os_final_close)
1580*86d949f9SVitaliy Gusev 			mdb_printf("os_final_close ");
1581*86d949f9SVitaliy Gusev 		if (os.os_pending_close)
1582*86d949f9SVitaliy Gusev 			mdb_printf("os_pending_close ");
1583*86d949f9SVitaliy Gusev 		if (os.os_failed_reopen)
1584*86d949f9SVitaliy Gusev 			mdb_printf("os_failed_reopen ");
1585*86d949f9SVitaliy Gusev 		if (os.os_force_close)
1586*86d949f9SVitaliy Gusev 			mdb_printf("os_force_close ");
1587*86d949f9SVitaliy Gusev 		mdb_printf("os_orig_oo_name: %s\n",
1588*86d949f9SVitaliy Gusev 		    (uchar_t *)&os.os_orig_oo_name);
1589*86d949f9SVitaliy Gusev 	}
1590*86d949f9SVitaliy Gusev 	return (DCMD_OK);
1591*86d949f9SVitaliy Gusev }
1592*86d949f9SVitaliy Gusev 
1593*86d949f9SVitaliy Gusev /*
1594*86d949f9SVitaliy Gusev  * nfs4_svnode dcmd implementation
1595*86d949f9SVitaliy Gusev  */
1596*86d949f9SVitaliy Gusev int
nfs4_openstreams_cb(uintptr_t addr,void * private,int * opts)1597*86d949f9SVitaliy Gusev nfs4_openstreams_cb(uintptr_t addr, void *private, int *opts)
1598*86d949f9SVitaliy Gusev {
1599*86d949f9SVitaliy Gusev 	mdb_ctf_id_t ctfid;
1600*86d949f9SVitaliy Gusev 	ulong_t offset;
1601*86d949f9SVitaliy Gusev 	uintptr_t os_list_ptr;
1602*86d949f9SVitaliy Gusev 
1603*86d949f9SVitaliy Gusev 	/*
1604*86d949f9SVitaliy Gusev 	 * Walk the rnode4 ptr's r_open_streams list.
1605*86d949f9SVitaliy Gusev 	 */
1606*86d949f9SVitaliy Gusev 	if ((mdb_ctf_lookup_by_name("rnode4_t", &ctfid) == 0) &&
1607*86d949f9SVitaliy Gusev 	    (mdb_ctf_offsetof(ctfid, "r_open_streams", &offset) == 0) &&
1608*86d949f9SVitaliy Gusev 	    (offset % (sizeof (uintptr_t) * NBBY) == 0)) {
1609*86d949f9SVitaliy Gusev 		offset /= NBBY;
1610*86d949f9SVitaliy Gusev 	} else {
1611*86d949f9SVitaliy Gusev 		offset = offsetof(rnode4_t, r_open_streams);
1612*86d949f9SVitaliy Gusev 	}
1613*86d949f9SVitaliy Gusev 
1614*86d949f9SVitaliy Gusev 	os_list_ptr = addr + offset;
1615*86d949f9SVitaliy Gusev 
1616*86d949f9SVitaliy Gusev 	if (mdb_pwalk("list", (mdb_walk_cb_t)nfs4_openstream_print, opts,
1617*86d949f9SVitaliy Gusev 	    os_list_ptr) == -1) {
1618*86d949f9SVitaliy Gusev 		mdb_warn("Failed to walk r_open_streams");
1619*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
1620*86d949f9SVitaliy Gusev 	}
1621*86d949f9SVitaliy Gusev 	return (DCMD_OK);
1622*86d949f9SVitaliy Gusev }
1623*86d949f9SVitaliy Gusev 
1624*86d949f9SVitaliy Gusev /*
1625*86d949f9SVitaliy Gusev  * nfs4_os_dcmd list open streams
1626*86d949f9SVitaliy Gusev  */
1627*86d949f9SVitaliy Gusev int
nfs4_os_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1628*86d949f9SVitaliy Gusev nfs4_os_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1629*86d949f9SVitaliy Gusev {
1630*86d949f9SVitaliy Gusev 	int opts = 0;
1631*86d949f9SVitaliy Gusev 
1632*86d949f9SVitaliy Gusev 	if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &opts,
1633*86d949f9SVitaliy Gusev 	    NULL) != argc) {
1634*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1635*86d949f9SVitaliy Gusev 	}
1636*86d949f9SVitaliy Gusev 
1637*86d949f9SVitaliy Gusev 	mdb_printf("    ref\t|    os_share   |    os_mmap   |       "
1638*86d949f9SVitaliy Gusev 	    "os_share_deny       |    open    |    deleg    |\t|\n");
1639*86d949f9SVitaliy Gusev 
1640*86d949f9SVitaliy Gusev 	mdb_printf("%<u>%-?s %-s|%s %s|%s  %s|%s %s %s|"
1641*86d949f9SVitaliy Gusev 	    "%s |%s |%s |%</u>\n", "Address", "count", "acc_read",
1642*86d949f9SVitaliy Gusev 	    "acc_write", "read", "write", "none", "read", "write", "count",
1643*86d949f9SVitaliy Gusev 	    "access", "mapcnt");
1644*86d949f9SVitaliy Gusev 
1645*86d949f9SVitaliy Gusev 	/*
1646*86d949f9SVitaliy Gusev 	 * Walk the rnode4 cache if no address is specified
1647*86d949f9SVitaliy Gusev 	 */
1648*86d949f9SVitaliy Gusev 	if (!(flags & DCMD_ADDRSPEC)) {
1649*86d949f9SVitaliy Gusev 		if (mdb_walk("nfs_rtable4", (mdb_walk_cb_t)nfs4_openstreams_cb,
1650*86d949f9SVitaliy Gusev 		    &opts) == -1) {
1651*86d949f9SVitaliy Gusev 			mdb_warn("unable to walk nfs_rtable4");
1652*86d949f9SVitaliy Gusev 			return (DCMD_ERR);
1653*86d949f9SVitaliy Gusev 		}
1654*86d949f9SVitaliy Gusev 		return (DCMD_OK);
1655*86d949f9SVitaliy Gusev 	}
1656*86d949f9SVitaliy Gusev 	return (nfs4_openstreams_cb(addr, NULL, &opts));
1657*86d949f9SVitaliy Gusev }
1658*86d949f9SVitaliy Gusev 
1659*86d949f9SVitaliy Gusev 
1660*86d949f9SVitaliy Gusev int
nfs4_svnode_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1661*86d949f9SVitaliy Gusev nfs4_svnode_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1662*86d949f9SVitaliy Gusev {
1663*86d949f9SVitaliy Gusev 	svnode_t sn;
1664*86d949f9SVitaliy Gusev 
1665*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
1666*86d949f9SVitaliy Gusev 		mdb_printf("requires address of svnode_t\n");
1667*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1668*86d949f9SVitaliy Gusev 	}
1669*86d949f9SVitaliy Gusev 
1670*86d949f9SVitaliy Gusev 	if (argc != 0)
1671*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
1672*86d949f9SVitaliy Gusev 
1673*86d949f9SVitaliy Gusev 	if (mdb_vread(&sn, sizeof (sn), addr) == -1) {
1674*86d949f9SVitaliy Gusev 		mdb_warn("can't read svnode_t at %p", addr);
1675*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
1676*86d949f9SVitaliy Gusev 	}
1677*86d949f9SVitaliy Gusev 
1678*86d949f9SVitaliy Gusev 	if (DCMD_HDRSPEC(flags))
1679*86d949f9SVitaliy Gusev 		mdb_printf("%<b>%<u>%-?s %-?s %-20s%</u>%</b>\n", "SVNODE",
1680*86d949f9SVitaliy Gusev 		    "VNODE", "PATH");
1681*86d949f9SVitaliy Gusev 
1682*86d949f9SVitaliy Gusev 	mdb_printf("%-?p %-?p ", addr, sn.sv_r_vnode);
1683*86d949f9SVitaliy Gusev 	print_nfs4_fname((uintptr_t)sn.sv_name);
1684*86d949f9SVitaliy Gusev 	mdb_printf("\n");
1685*86d949f9SVitaliy Gusev 
1686*86d949f9SVitaliy Gusev 	return (DCMD_OK);
1687*86d949f9SVitaliy Gusev }
1688*86d949f9SVitaliy Gusev 
1689*86d949f9SVitaliy Gusev /*
1690*86d949f9SVitaliy Gusev  * nfs_rtable walker implementation
1691*86d949f9SVitaliy Gusev  */
1692*86d949f9SVitaliy Gusev 
1693*86d949f9SVitaliy Gusev hash_table_walk_arg_t nfs_rtable_arg = {
1694*86d949f9SVitaliy Gusev 	0,		/* will be set in the init */
1695*86d949f9SVitaliy Gusev 	0,		/* will be set in the init */
1696*86d949f9SVitaliy Gusev 	sizeof (rhashq_t),
1697*86d949f9SVitaliy Gusev 	"r_hashf",
1698*86d949f9SVitaliy Gusev 	OFFSETOF(rhashq_t, r_hashf),
1699*86d949f9SVitaliy Gusev 	"rnode_t",
1700*86d949f9SVitaliy Gusev 	sizeof (rnode_t),
1701*86d949f9SVitaliy Gusev 	OFFSETOF(struct rnode, r_hashf)
1702*86d949f9SVitaliy Gusev };
1703*86d949f9SVitaliy Gusev 
1704*86d949f9SVitaliy Gusev static int
nfs_rtable_common_init(mdb_walk_state_t * wsp,const char * tabname,const char * sizename)1705*86d949f9SVitaliy Gusev nfs_rtable_common_init(mdb_walk_state_t *wsp, const char *tabname,
1706*86d949f9SVitaliy Gusev     const char *sizename)
1707*86d949f9SVitaliy Gusev {
1708*86d949f9SVitaliy Gusev 	hash_table_walk_arg_t *arg = wsp->walk_arg;
1709*86d949f9SVitaliy Gusev 	int rtsize;
1710*86d949f9SVitaliy Gusev 	uintptr_t rtaddr;
1711*86d949f9SVitaliy Gusev 
1712*86d949f9SVitaliy Gusev 	if (mdb_readsym(&rtsize, sizeof (rtsize), sizename) == -1) {
1713*86d949f9SVitaliy Gusev 		mdb_warn("failed to get %s", sizename);
1714*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1715*86d949f9SVitaliy Gusev 	}
1716*86d949f9SVitaliy Gusev 
1717*86d949f9SVitaliy Gusev 	if (rtsize < 0) {
1718*86d949f9SVitaliy Gusev 		mdb_warn("%s is negative: %d", sizename, rtsize);
1719*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1720*86d949f9SVitaliy Gusev 	}
1721*86d949f9SVitaliy Gusev 
1722*86d949f9SVitaliy Gusev 	if (mdb_readsym(&rtaddr, sizeof (rtaddr), tabname) == -1) {
1723*86d949f9SVitaliy Gusev 		mdb_warn("failed to get %s", tabname);
1724*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1725*86d949f9SVitaliy Gusev 	}
1726*86d949f9SVitaliy Gusev 
1727*86d949f9SVitaliy Gusev 	arg->array_addr = rtaddr;
1728*86d949f9SVitaliy Gusev 	arg->array_len = rtsize;
1729*86d949f9SVitaliy Gusev 
1730*86d949f9SVitaliy Gusev 	return (hash_table_walk_init(wsp));
1731*86d949f9SVitaliy Gusev }
1732*86d949f9SVitaliy Gusev 
1733*86d949f9SVitaliy Gusev int
nfs_rtable_walk_init(mdb_walk_state_t * wsp)1734*86d949f9SVitaliy Gusev nfs_rtable_walk_init(mdb_walk_state_t *wsp)
1735*86d949f9SVitaliy Gusev {
1736*86d949f9SVitaliy Gusev 	if (wsp->walk_addr != 0) {
1737*86d949f9SVitaliy Gusev 		mdb_warn("nfs_rtable supports only global walks");
1738*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1739*86d949f9SVitaliy Gusev 	}
1740*86d949f9SVitaliy Gusev 
1741*86d949f9SVitaliy Gusev 	return (nfs_rtable_common_init(wsp, "rtable", "rtablesize"));
1742*86d949f9SVitaliy Gusev }
1743*86d949f9SVitaliy Gusev 
1744*86d949f9SVitaliy Gusev /*
1745*86d949f9SVitaliy Gusev  * nfs_rtable4 walker implementation
1746*86d949f9SVitaliy Gusev  */
1747*86d949f9SVitaliy Gusev 
1748*86d949f9SVitaliy Gusev hash_table_walk_arg_t nfs_rtable4_arg = {
1749*86d949f9SVitaliy Gusev 	0,		/* will be set in the init */
1750*86d949f9SVitaliy Gusev 	0,		/* will be set in the init */
1751*86d949f9SVitaliy Gusev 	sizeof (r4hashq_t),
1752*86d949f9SVitaliy Gusev 	"r_hashf",
1753*86d949f9SVitaliy Gusev 	OFFSETOF(r4hashq_t, r_hashf),
1754*86d949f9SVitaliy Gusev 	"rnode4_t",
1755*86d949f9SVitaliy Gusev 	sizeof (rnode4_t),
1756*86d949f9SVitaliy Gusev 	OFFSETOF(struct rnode4, r_hashf)
1757*86d949f9SVitaliy Gusev };
1758*86d949f9SVitaliy Gusev 
1759*86d949f9SVitaliy Gusev int
nfs_rtable4_walk_init(mdb_walk_state_t * wsp)1760*86d949f9SVitaliy Gusev nfs_rtable4_walk_init(mdb_walk_state_t *wsp)
1761*86d949f9SVitaliy Gusev {
1762*86d949f9SVitaliy Gusev 	if (wsp->walk_addr != 0) {
1763*86d949f9SVitaliy Gusev 		mdb_warn("nfs_rtable4 supports only global walks");
1764*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1765*86d949f9SVitaliy Gusev 	}
1766*86d949f9SVitaliy Gusev 
1767*86d949f9SVitaliy Gusev 	return (nfs_rtable_common_init(wsp, "rtable4", "rtable4size"));
1768*86d949f9SVitaliy Gusev }
1769*86d949f9SVitaliy Gusev 
1770*86d949f9SVitaliy Gusev /*
1771*86d949f9SVitaliy Gusev  * nfs_vfs walker implementation
1772*86d949f9SVitaliy Gusev  */
1773*86d949f9SVitaliy Gusev 
1774*86d949f9SVitaliy Gusev typedef struct nfs_vfs_walk {
1775*86d949f9SVitaliy Gusev 	uintptr_t nfs2_ops;
1776*86d949f9SVitaliy Gusev 	uintptr_t nfs3_ops;
1777*86d949f9SVitaliy Gusev 	uintptr_t nfs4_ops;
1778*86d949f9SVitaliy Gusev 	void *data;		/* walker specific data */
1779*86d949f9SVitaliy Gusev } nfs_vfs_walk_t;
1780*86d949f9SVitaliy Gusev 
1781*86d949f9SVitaliy Gusev int
nfs_vfs_walk_init(mdb_walk_state_t * wsp)1782*86d949f9SVitaliy Gusev nfs_vfs_walk_init(mdb_walk_state_t *wsp)
1783*86d949f9SVitaliy Gusev {
1784*86d949f9SVitaliy Gusev 	nfs_vfs_walk_t data;
1785*86d949f9SVitaliy Gusev 	nfs_vfs_walk_t *datap;
1786*86d949f9SVitaliy Gusev 
1787*86d949f9SVitaliy Gusev 	if (mdb_readvar(&data.nfs2_ops, "nfs_vfsops") == -1) {
1788*86d949f9SVitaliy Gusev 		mdb_warn("failed to read %s", "nfs_vfsops");
1789*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1790*86d949f9SVitaliy Gusev 	}
1791*86d949f9SVitaliy Gusev 
1792*86d949f9SVitaliy Gusev 	if (mdb_readvar(&data.nfs3_ops, "nfs3_vfsops") == -1) {
1793*86d949f9SVitaliy Gusev 		mdb_warn("failed to read %s", "nfs3_vfsops");
1794*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1795*86d949f9SVitaliy Gusev 	}
1796*86d949f9SVitaliy Gusev 
1797*86d949f9SVitaliy Gusev 	if (mdb_readvar(&data.nfs4_ops, "nfs4_vfsops") == -1) {
1798*86d949f9SVitaliy Gusev 		mdb_warn("failed to read %s", "nfs4_vfsops");
1799*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1800*86d949f9SVitaliy Gusev 	}
1801*86d949f9SVitaliy Gusev 
1802*86d949f9SVitaliy Gusev 	if (mdb_layered_walk("genunix`vfs", wsp) == -1) {
1803*86d949f9SVitaliy Gusev 		mdb_warn("failed to walk vfs");
1804*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1805*86d949f9SVitaliy Gusev 	}
1806*86d949f9SVitaliy Gusev 
1807*86d949f9SVitaliy Gusev 	datap = mdb_alloc(sizeof (data), UM_SLEEP);
1808*86d949f9SVitaliy Gusev 	*datap = data;
1809*86d949f9SVitaliy Gusev 	wsp->walk_data = datap;
1810*86d949f9SVitaliy Gusev 
1811*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
1812*86d949f9SVitaliy Gusev }
1813*86d949f9SVitaliy Gusev 
1814*86d949f9SVitaliy Gusev int
nfs_vfs_walk_step(mdb_walk_state_t * wsp)1815*86d949f9SVitaliy Gusev nfs_vfs_walk_step(mdb_walk_state_t *wsp)
1816*86d949f9SVitaliy Gusev {
1817*86d949f9SVitaliy Gusev 	nfs_vfs_walk_t *data = (nfs_vfs_walk_t *)wsp->walk_data;
1818*86d949f9SVitaliy Gusev 	vfs_t *vfs = (vfs_t *)wsp->walk_layer;
1819*86d949f9SVitaliy Gusev 
1820*86d949f9SVitaliy Gusev 	if (data->nfs2_ops != (uintptr_t)vfs->vfs_op &&
1821*86d949f9SVitaliy Gusev 	    data->nfs3_ops != (uintptr_t)vfs->vfs_op &&
1822*86d949f9SVitaliy Gusev 	    data->nfs4_ops != (uintptr_t)vfs->vfs_op)
1823*86d949f9SVitaliy Gusev 		return (WALK_NEXT);
1824*86d949f9SVitaliy Gusev 
1825*86d949f9SVitaliy Gusev 	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
1826*86d949f9SVitaliy Gusev 	    wsp->walk_cbdata));
1827*86d949f9SVitaliy Gusev }
1828*86d949f9SVitaliy Gusev 
1829*86d949f9SVitaliy Gusev void
nfs_vfs_walk_fini(mdb_walk_state_t * wsp)1830*86d949f9SVitaliy Gusev nfs_vfs_walk_fini(mdb_walk_state_t *wsp)
1831*86d949f9SVitaliy Gusev {
1832*86d949f9SVitaliy Gusev 	mdb_free(wsp->walk_data, sizeof (nfs_vfs_walk_t));
1833*86d949f9SVitaliy Gusev }
1834*86d949f9SVitaliy Gusev 
1835*86d949f9SVitaliy Gusev /*
1836*86d949f9SVitaliy Gusev  * nfs_mnt walker implementation
1837*86d949f9SVitaliy Gusev  */
1838*86d949f9SVitaliy Gusev 
1839*86d949f9SVitaliy Gusev int
nfs_mnt_walk_init(mdb_walk_state_t * wsp)1840*86d949f9SVitaliy Gusev nfs_mnt_walk_init(mdb_walk_state_t *wsp)
1841*86d949f9SVitaliy Gusev {
1842*86d949f9SVitaliy Gusev 	int status;
1843*86d949f9SVitaliy Gusev 	nfs_vfs_walk_t *data;
1844*86d949f9SVitaliy Gusev 
1845*86d949f9SVitaliy Gusev 	status = nfs_vfs_walk_init(wsp);
1846*86d949f9SVitaliy Gusev 	if (status != WALK_NEXT)
1847*86d949f9SVitaliy Gusev 		return (status);
1848*86d949f9SVitaliy Gusev 
1849*86d949f9SVitaliy Gusev 	data = wsp->walk_data;
1850*86d949f9SVitaliy Gusev 	data->data = mdb_alloc(sizeof (mntinfo_t), UM_SLEEP);
1851*86d949f9SVitaliy Gusev 
1852*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
1853*86d949f9SVitaliy Gusev }
1854*86d949f9SVitaliy Gusev 
1855*86d949f9SVitaliy Gusev int
nfs_mnt_walk_step(mdb_walk_state_t * wsp)1856*86d949f9SVitaliy Gusev nfs_mnt_walk_step(mdb_walk_state_t *wsp)
1857*86d949f9SVitaliy Gusev {
1858*86d949f9SVitaliy Gusev 	nfs_vfs_walk_t *data = (nfs_vfs_walk_t *)wsp->walk_data;
1859*86d949f9SVitaliy Gusev 	vfs_t *vfs = (vfs_t *)wsp->walk_layer;
1860*86d949f9SVitaliy Gusev 
1861*86d949f9SVitaliy Gusev 	if (data->nfs2_ops != (uintptr_t)vfs->vfs_op &&
1862*86d949f9SVitaliy Gusev 	    data->nfs3_ops != (uintptr_t)vfs->vfs_op)
1863*86d949f9SVitaliy Gusev 		return (WALK_NEXT);
1864*86d949f9SVitaliy Gusev 
1865*86d949f9SVitaliy Gusev 	if (mdb_vread(data->data, sizeof (mntinfo_t), (uintptr_t)VFTOMI(vfs))
1866*86d949f9SVitaliy Gusev 	    == -1) {
1867*86d949f9SVitaliy Gusev 		mdb_warn("can't read mntinfo");
1868*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1869*86d949f9SVitaliy Gusev 	}
1870*86d949f9SVitaliy Gusev 
1871*86d949f9SVitaliy Gusev 	return (wsp->walk_callback((uintptr_t)VFTOMI(vfs), data->data,
1872*86d949f9SVitaliy Gusev 	    wsp->walk_cbdata));
1873*86d949f9SVitaliy Gusev }
1874*86d949f9SVitaliy Gusev 
1875*86d949f9SVitaliy Gusev void
nfs_mnt_walk_fini(mdb_walk_state_t * wsp)1876*86d949f9SVitaliy Gusev nfs_mnt_walk_fini(mdb_walk_state_t *wsp)
1877*86d949f9SVitaliy Gusev {
1878*86d949f9SVitaliy Gusev 	nfs_vfs_walk_t *data = (nfs_vfs_walk_t *)wsp->walk_data;
1879*86d949f9SVitaliy Gusev 
1880*86d949f9SVitaliy Gusev 	mdb_free(data->data, sizeof (mntinfo_t));
1881*86d949f9SVitaliy Gusev 	nfs_vfs_walk_fini(wsp);
1882*86d949f9SVitaliy Gusev }
1883*86d949f9SVitaliy Gusev 
1884*86d949f9SVitaliy Gusev /*
1885*86d949f9SVitaliy Gusev  * nfs4_mnt walker implementation
1886*86d949f9SVitaliy Gusev  */
1887*86d949f9SVitaliy Gusev 
1888*86d949f9SVitaliy Gusev int
nfs4_mnt_walk_init(mdb_walk_state_t * wsp)1889*86d949f9SVitaliy Gusev nfs4_mnt_walk_init(mdb_walk_state_t *wsp)
1890*86d949f9SVitaliy Gusev {
1891*86d949f9SVitaliy Gusev 	int status;
1892*86d949f9SVitaliy Gusev 	nfs_vfs_walk_t *data;
1893*86d949f9SVitaliy Gusev 
1894*86d949f9SVitaliy Gusev 	status = nfs_vfs_walk_init(wsp);
1895*86d949f9SVitaliy Gusev 	if (status != WALK_NEXT)
1896*86d949f9SVitaliy Gusev 		return (status);
1897*86d949f9SVitaliy Gusev 
1898*86d949f9SVitaliy Gusev 	data = wsp->walk_data;
1899*86d949f9SVitaliy Gusev 	data->data = mdb_alloc(sizeof (mntinfo4_t), UM_SLEEP);
1900*86d949f9SVitaliy Gusev 
1901*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
1902*86d949f9SVitaliy Gusev }
1903*86d949f9SVitaliy Gusev 
1904*86d949f9SVitaliy Gusev int
nfs4_mnt_walk_step(mdb_walk_state_t * wsp)1905*86d949f9SVitaliy Gusev nfs4_mnt_walk_step(mdb_walk_state_t *wsp)
1906*86d949f9SVitaliy Gusev {
1907*86d949f9SVitaliy Gusev 	nfs_vfs_walk_t *data = (nfs_vfs_walk_t *)wsp->walk_data;
1908*86d949f9SVitaliy Gusev 	vfs_t *vfs = (vfs_t *)wsp->walk_layer;
1909*86d949f9SVitaliy Gusev 
1910*86d949f9SVitaliy Gusev 	if (data->nfs4_ops != (uintptr_t)vfs->vfs_op)
1911*86d949f9SVitaliy Gusev 		return (WALK_NEXT);
1912*86d949f9SVitaliy Gusev 
1913*86d949f9SVitaliy Gusev 	if (mdb_vread(data->data, sizeof (mntinfo4_t), (uintptr_t)VFTOMI4(vfs))
1914*86d949f9SVitaliy Gusev 	    == -1) {
1915*86d949f9SVitaliy Gusev 		mdb_warn("can't read mntinfo4");
1916*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1917*86d949f9SVitaliy Gusev 	}
1918*86d949f9SVitaliy Gusev 
1919*86d949f9SVitaliy Gusev 	return (wsp->walk_callback((uintptr_t)VFTOMI4(vfs), data->data,
1920*86d949f9SVitaliy Gusev 	    wsp->walk_cbdata));
1921*86d949f9SVitaliy Gusev }
1922*86d949f9SVitaliy Gusev 
1923*86d949f9SVitaliy Gusev void
nfs4_mnt_walk_fini(mdb_walk_state_t * wsp)1924*86d949f9SVitaliy Gusev nfs4_mnt_walk_fini(mdb_walk_state_t *wsp)
1925*86d949f9SVitaliy Gusev {
1926*86d949f9SVitaliy Gusev 	nfs_vfs_walk_t *data = (nfs_vfs_walk_t *)wsp->walk_data;
1927*86d949f9SVitaliy Gusev 
1928*86d949f9SVitaliy Gusev 	mdb_free(data->data, sizeof (mntinfo4_t));
1929*86d949f9SVitaliy Gusev 	nfs_vfs_walk_fini(wsp);
1930*86d949f9SVitaliy Gusev }
1931*86d949f9SVitaliy Gusev 
1932*86d949f9SVitaliy Gusev /*
1933*86d949f9SVitaliy Gusev  * nfs_serv walker implementation
1934*86d949f9SVitaliy Gusev  */
1935*86d949f9SVitaliy Gusev 
1936*86d949f9SVitaliy Gusev int
nfs_serv_walk_init(mdb_walk_state_t * wsp)1937*86d949f9SVitaliy Gusev nfs_serv_walk_init(mdb_walk_state_t *wsp)
1938*86d949f9SVitaliy Gusev {
1939*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
1940*86d949f9SVitaliy Gusev 		mdb_warn("global walk not supported");
1941*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1942*86d949f9SVitaliy Gusev 	}
1943*86d949f9SVitaliy Gusev 
1944*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
1945*86d949f9SVitaliy Gusev }
1946*86d949f9SVitaliy Gusev 
1947*86d949f9SVitaliy Gusev int
nfs_serv_walk_step(mdb_walk_state_t * wsp)1948*86d949f9SVitaliy Gusev nfs_serv_walk_step(mdb_walk_state_t *wsp)
1949*86d949f9SVitaliy Gusev {
1950*86d949f9SVitaliy Gusev 	servinfo_t si;
1951*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
1952*86d949f9SVitaliy Gusev 
1953*86d949f9SVitaliy Gusev 	if (addr == 0)
1954*86d949f9SVitaliy Gusev 		return (WALK_DONE);
1955*86d949f9SVitaliy Gusev 
1956*86d949f9SVitaliy Gusev 	if (mdb_vread(&si, sizeof (si), addr) == -1) {
1957*86d949f9SVitaliy Gusev 		mdb_warn("can't read servinfo_t");
1958*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1959*86d949f9SVitaliy Gusev 	}
1960*86d949f9SVitaliy Gusev 
1961*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)si.sv_next;
1962*86d949f9SVitaliy Gusev 	return (wsp->walk_callback(addr, &si, wsp->walk_cbdata));
1963*86d949f9SVitaliy Gusev }
1964*86d949f9SVitaliy Gusev 
1965*86d949f9SVitaliy Gusev /*
1966*86d949f9SVitaliy Gusev  * nfs4_serv walker implementation
1967*86d949f9SVitaliy Gusev  */
1968*86d949f9SVitaliy Gusev 
1969*86d949f9SVitaliy Gusev int
nfs4_serv_walk_init(mdb_walk_state_t * wsp)1970*86d949f9SVitaliy Gusev nfs4_serv_walk_init(mdb_walk_state_t *wsp)
1971*86d949f9SVitaliy Gusev {
1972*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
1973*86d949f9SVitaliy Gusev 		mdb_warn("global walk not supported");
1974*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1975*86d949f9SVitaliy Gusev 	}
1976*86d949f9SVitaliy Gusev 
1977*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
1978*86d949f9SVitaliy Gusev }
1979*86d949f9SVitaliy Gusev 
1980*86d949f9SVitaliy Gusev int
nfs4_serv_walk_step(mdb_walk_state_t * wsp)1981*86d949f9SVitaliy Gusev nfs4_serv_walk_step(mdb_walk_state_t *wsp)
1982*86d949f9SVitaliy Gusev {
1983*86d949f9SVitaliy Gusev 	servinfo4_t si;
1984*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
1985*86d949f9SVitaliy Gusev 
1986*86d949f9SVitaliy Gusev 	if (addr == 0)
1987*86d949f9SVitaliy Gusev 		return (WALK_DONE);
1988*86d949f9SVitaliy Gusev 
1989*86d949f9SVitaliy Gusev 	if (mdb_vread(&si, sizeof (si), addr) == -1) {
1990*86d949f9SVitaliy Gusev 		mdb_warn("can't read servinfo4_t");
1991*86d949f9SVitaliy Gusev 		return (WALK_ERR);
1992*86d949f9SVitaliy Gusev 	}
1993*86d949f9SVitaliy Gusev 
1994*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)si.sv_next;
1995*86d949f9SVitaliy Gusev 	return (wsp->walk_callback(addr, &si, wsp->walk_cbdata));
1996*86d949f9SVitaliy Gusev }
1997*86d949f9SVitaliy Gusev 
1998*86d949f9SVitaliy Gusev /*
1999*86d949f9SVitaliy Gusev  * nfs4_svnode walker implementation
2000*86d949f9SVitaliy Gusev  */
2001*86d949f9SVitaliy Gusev 
2002*86d949f9SVitaliy Gusev int
nfs4_svnode_walk_init(mdb_walk_state_t * wsp)2003*86d949f9SVitaliy Gusev nfs4_svnode_walk_init(mdb_walk_state_t *wsp)
2004*86d949f9SVitaliy Gusev {
2005*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
2006*86d949f9SVitaliy Gusev 		mdb_warn("global walk not supported");
2007*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2008*86d949f9SVitaliy Gusev 	}
2009*86d949f9SVitaliy Gusev 
2010*86d949f9SVitaliy Gusev 	wsp->walk_data = (void *)wsp->walk_addr;
2011*86d949f9SVitaliy Gusev 
2012*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
2013*86d949f9SVitaliy Gusev }
2014*86d949f9SVitaliy Gusev 
2015*86d949f9SVitaliy Gusev int
nfs4_svnode_walk_step(mdb_walk_state_t * wsp)2016*86d949f9SVitaliy Gusev nfs4_svnode_walk_step(mdb_walk_state_t *wsp)
2017*86d949f9SVitaliy Gusev {
2018*86d949f9SVitaliy Gusev 	svnode_t sn;
2019*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
2020*86d949f9SVitaliy Gusev 	int status;
2021*86d949f9SVitaliy Gusev 
2022*86d949f9SVitaliy Gusev 	if (mdb_vread(&sn, sizeof (sn), addr) == -1) {
2023*86d949f9SVitaliy Gusev 		mdb_warn("can't read svnode_t");
2024*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2025*86d949f9SVitaliy Gusev 	}
2026*86d949f9SVitaliy Gusev 
2027*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)sn.sv_forw;
2028*86d949f9SVitaliy Gusev 
2029*86d949f9SVitaliy Gusev 	status = wsp->walk_callback(addr, &sn, wsp->walk_cbdata);
2030*86d949f9SVitaliy Gusev 	if (status != WALK_NEXT)
2031*86d949f9SVitaliy Gusev 		return (status);
2032*86d949f9SVitaliy Gusev 
2033*86d949f9SVitaliy Gusev 	return (((void *)wsp->walk_addr == wsp->walk_data) ? WALK_DONE
2034*86d949f9SVitaliy Gusev 	    : WALK_NEXT);
2035*86d949f9SVitaliy Gusev }
2036*86d949f9SVitaliy Gusev 
2037*86d949f9SVitaliy Gusev /*
2038*86d949f9SVitaliy Gusev  * nfs4_server walker implementation
2039*86d949f9SVitaliy Gusev  */
2040*86d949f9SVitaliy Gusev 
2041*86d949f9SVitaliy Gusev int
nfs4_server_walk_init(mdb_walk_state_t * wsp)2042*86d949f9SVitaliy Gusev nfs4_server_walk_init(mdb_walk_state_t *wsp)
2043*86d949f9SVitaliy Gusev {
2044*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
2045*86d949f9SVitaliy Gusev 		GElf_Sym sym;
2046*86d949f9SVitaliy Gusev 
2047*86d949f9SVitaliy Gusev 		if (mdb_lookup_by_name("nfs4_server_lst", &sym) == -1) {
2048*86d949f9SVitaliy Gusev 			mdb_warn("failed to find 'nfs4_server_lst'");
2049*86d949f9SVitaliy Gusev 			return (WALK_ERR);
2050*86d949f9SVitaliy Gusev 		}
2051*86d949f9SVitaliy Gusev 
2052*86d949f9SVitaliy Gusev 		wsp->walk_addr = sym.st_value;
2053*86d949f9SVitaliy Gusev 	}
2054*86d949f9SVitaliy Gusev 
2055*86d949f9SVitaliy Gusev 	wsp->walk_data = (void *)wsp->walk_addr;
2056*86d949f9SVitaliy Gusev 
2057*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
2058*86d949f9SVitaliy Gusev }
2059*86d949f9SVitaliy Gusev 
2060*86d949f9SVitaliy Gusev int
nfs4_server_walk_step(mdb_walk_state_t * wsp)2061*86d949f9SVitaliy Gusev nfs4_server_walk_step(mdb_walk_state_t *wsp)
2062*86d949f9SVitaliy Gusev {
2063*86d949f9SVitaliy Gusev 	nfs4_server_t srv;
2064*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
2065*86d949f9SVitaliy Gusev 	int status;
2066*86d949f9SVitaliy Gusev 
2067*86d949f9SVitaliy Gusev 	if (mdb_vread(&srv, sizeof (srv), addr) == -1) {
2068*86d949f9SVitaliy Gusev 		mdb_warn("can't read nfs4_server_t");
2069*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2070*86d949f9SVitaliy Gusev 	}
2071*86d949f9SVitaliy Gusev 
2072*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)srv.forw;
2073*86d949f9SVitaliy Gusev 
2074*86d949f9SVitaliy Gusev 	status = wsp->walk_callback(addr, &srv, wsp->walk_cbdata);
2075*86d949f9SVitaliy Gusev 	if (status != WALK_NEXT)
2076*86d949f9SVitaliy Gusev 		return (status);
2077*86d949f9SVitaliy Gusev 
2078*86d949f9SVitaliy Gusev 	return (((void *)wsp->walk_addr == wsp->walk_data) ? WALK_DONE
2079*86d949f9SVitaliy Gusev 	    : WALK_NEXT);
2080*86d949f9SVitaliy Gusev }
2081*86d949f9SVitaliy Gusev 
2082*86d949f9SVitaliy Gusev /*
2083*86d949f9SVitaliy Gusev  * nfs_async walker implementation
2084*86d949f9SVitaliy Gusev  */
2085*86d949f9SVitaliy Gusev 
2086*86d949f9SVitaliy Gusev int
nfs_async_walk_init(mdb_walk_state_t * wsp)2087*86d949f9SVitaliy Gusev nfs_async_walk_init(mdb_walk_state_t *wsp)
2088*86d949f9SVitaliy Gusev {
2089*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
2090*86d949f9SVitaliy Gusev 		mdb_warn("global walk not supported");
2091*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2092*86d949f9SVitaliy Gusev 	}
2093*86d949f9SVitaliy Gusev 
2094*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
2095*86d949f9SVitaliy Gusev }
2096*86d949f9SVitaliy Gusev 
2097*86d949f9SVitaliy Gusev int
nfs_async_walk_step(mdb_walk_state_t * wsp)2098*86d949f9SVitaliy Gusev nfs_async_walk_step(mdb_walk_state_t *wsp)
2099*86d949f9SVitaliy Gusev {
2100*86d949f9SVitaliy Gusev 	struct nfs_async_reqs areq;
2101*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
2102*86d949f9SVitaliy Gusev 
2103*86d949f9SVitaliy Gusev 	if (addr == 0)
2104*86d949f9SVitaliy Gusev 		return (WALK_DONE);
2105*86d949f9SVitaliy Gusev 
2106*86d949f9SVitaliy Gusev 	if (mdb_vread(&areq, sizeof (areq), addr) == -1) {
2107*86d949f9SVitaliy Gusev 		mdb_warn("can't read struct nfs_async_reqs");
2108*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2109*86d949f9SVitaliy Gusev 	}
2110*86d949f9SVitaliy Gusev 
2111*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)areq.a_next;
2112*86d949f9SVitaliy Gusev 
2113*86d949f9SVitaliy Gusev 	return (wsp->walk_callback(addr, &areq, wsp->walk_cbdata));
2114*86d949f9SVitaliy Gusev }
2115*86d949f9SVitaliy Gusev 
2116*86d949f9SVitaliy Gusev /*
2117*86d949f9SVitaliy Gusev  * nfs4_async walker implementation
2118*86d949f9SVitaliy Gusev  */
2119*86d949f9SVitaliy Gusev 
2120*86d949f9SVitaliy Gusev int
nfs4_async_walk_init(mdb_walk_state_t * wsp)2121*86d949f9SVitaliy Gusev nfs4_async_walk_init(mdb_walk_state_t *wsp)
2122*86d949f9SVitaliy Gusev {
2123*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
2124*86d949f9SVitaliy Gusev 		mdb_warn("global walk not supported");
2125*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2126*86d949f9SVitaliy Gusev 	}
2127*86d949f9SVitaliy Gusev 
2128*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
2129*86d949f9SVitaliy Gusev }
2130*86d949f9SVitaliy Gusev 
2131*86d949f9SVitaliy Gusev int
nfs4_async_walk_step(mdb_walk_state_t * wsp)2132*86d949f9SVitaliy Gusev nfs4_async_walk_step(mdb_walk_state_t *wsp)
2133*86d949f9SVitaliy Gusev {
2134*86d949f9SVitaliy Gusev 	struct nfs4_async_reqs areq;
2135*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
2136*86d949f9SVitaliy Gusev 
2137*86d949f9SVitaliy Gusev 	if (addr == 0)
2138*86d949f9SVitaliy Gusev 		return (WALK_DONE);
2139*86d949f9SVitaliy Gusev 
2140*86d949f9SVitaliy Gusev 	if (mdb_vread(&areq, sizeof (areq), addr) == -1) {
2141*86d949f9SVitaliy Gusev 		mdb_warn("can't read struct nfs4_async_reqs");
2142*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2143*86d949f9SVitaliy Gusev 	}
2144*86d949f9SVitaliy Gusev 
2145*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)areq.a_next;
2146*86d949f9SVitaliy Gusev 
2147*86d949f9SVitaliy Gusev 	return (wsp->walk_callback(addr, &areq, wsp->walk_cbdata));
2148*86d949f9SVitaliy Gusev }
2149*86d949f9SVitaliy Gusev 
2150*86d949f9SVitaliy Gusev /*
2151*86d949f9SVitaliy Gusev  * nfs_acache_rnode walker implementation
2152*86d949f9SVitaliy Gusev  */
2153*86d949f9SVitaliy Gusev 
2154*86d949f9SVitaliy Gusev int
nfs_acache_rnode_walk_init(mdb_walk_state_t * wsp)2155*86d949f9SVitaliy Gusev nfs_acache_rnode_walk_init(mdb_walk_state_t *wsp)
2156*86d949f9SVitaliy Gusev {
2157*86d949f9SVitaliy Gusev 	rnode_t rn;
2158*86d949f9SVitaliy Gusev 
2159*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
2160*86d949f9SVitaliy Gusev 		mdb_warn("global walk not supported");
2161*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2162*86d949f9SVitaliy Gusev 	}
2163*86d949f9SVitaliy Gusev 
2164*86d949f9SVitaliy Gusev 	if (mdb_vread(&rn, sizeof (rn), wsp->walk_addr) == -1) {
2165*86d949f9SVitaliy Gusev 		mdb_warn("can't read rnode_t at %p", wsp->walk_addr);
2166*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2167*86d949f9SVitaliy Gusev 	}
2168*86d949f9SVitaliy Gusev 
2169*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)rn.r_acache;
2170*86d949f9SVitaliy Gusev 
2171*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
2172*86d949f9SVitaliy Gusev }
2173*86d949f9SVitaliy Gusev 
2174*86d949f9SVitaliy Gusev int
nfs_acache_rnode_walk_step(mdb_walk_state_t * wsp)2175*86d949f9SVitaliy Gusev nfs_acache_rnode_walk_step(mdb_walk_state_t *wsp)
2176*86d949f9SVitaliy Gusev {
2177*86d949f9SVitaliy Gusev 	acache_t ac;
2178*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
2179*86d949f9SVitaliy Gusev 
2180*86d949f9SVitaliy Gusev 	if (addr == 0)
2181*86d949f9SVitaliy Gusev 		return (WALK_DONE);
2182*86d949f9SVitaliy Gusev 
2183*86d949f9SVitaliy Gusev 	if (mdb_vread(&ac, sizeof (ac), addr) == -1) {
2184*86d949f9SVitaliy Gusev 		mdb_warn("can't read acache_t at %p", addr);
2185*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2186*86d949f9SVitaliy Gusev 	}
2187*86d949f9SVitaliy Gusev 
2188*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)ac.list;
2189*86d949f9SVitaliy Gusev 
2190*86d949f9SVitaliy Gusev 	return (wsp->walk_callback(addr, &ac, wsp->walk_cbdata));
2191*86d949f9SVitaliy Gusev }
2192*86d949f9SVitaliy Gusev 
2193*86d949f9SVitaliy Gusev /*
2194*86d949f9SVitaliy Gusev  * nfs_acache walker implementation
2195*86d949f9SVitaliy Gusev  */
2196*86d949f9SVitaliy Gusev 
2197*86d949f9SVitaliy Gusev static const hash_table_walk_arg_t nfs_acache_arg = {
2198*86d949f9SVitaliy Gusev 	0,		/* placeholder */
2199*86d949f9SVitaliy Gusev 	0,		/* placeholder */
2200*86d949f9SVitaliy Gusev 	sizeof (acache_hash_t),
2201*86d949f9SVitaliy Gusev 	"next",
2202*86d949f9SVitaliy Gusev 	OFFSETOF(acache_hash_t, next),
2203*86d949f9SVitaliy Gusev 	"acache_t",
2204*86d949f9SVitaliy Gusev 	sizeof (acache_t),
2205*86d949f9SVitaliy Gusev 	OFFSETOF(acache_t, next)
2206*86d949f9SVitaliy Gusev };
2207*86d949f9SVitaliy Gusev 
2208*86d949f9SVitaliy Gusev int
nfs_acache_walk_init(mdb_walk_state_t * wsp)2209*86d949f9SVitaliy Gusev nfs_acache_walk_init(mdb_walk_state_t *wsp)
2210*86d949f9SVitaliy Gusev {
2211*86d949f9SVitaliy Gusev 	hash_table_walk_arg_t *arg;
2212*86d949f9SVitaliy Gusev 	int size;
2213*86d949f9SVitaliy Gusev 	uintptr_t addr;
2214*86d949f9SVitaliy Gusev 	int status;
2215*86d949f9SVitaliy Gusev 
2216*86d949f9SVitaliy Gusev 	if (wsp->walk_addr != 0) {
2217*86d949f9SVitaliy Gusev 		mdb_warn("local walk not supported");
2218*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2219*86d949f9SVitaliy Gusev 	}
2220*86d949f9SVitaliy Gusev 
2221*86d949f9SVitaliy Gusev 	if (mdb_readsym(&size, sizeof (size), "acachesize") == -1) {
2222*86d949f9SVitaliy Gusev 		mdb_warn("failed to get %s", "acachesize");
2223*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2224*86d949f9SVitaliy Gusev 	}
2225*86d949f9SVitaliy Gusev 
2226*86d949f9SVitaliy Gusev 	if (size < 0) {
2227*86d949f9SVitaliy Gusev 		mdb_warn("%s is negative: %d", "acachesize", size);
2228*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2229*86d949f9SVitaliy Gusev 	}
2230*86d949f9SVitaliy Gusev 
2231*86d949f9SVitaliy Gusev 	if (mdb_readsym(&addr, sizeof (addr), "acache") == -1) {
2232*86d949f9SVitaliy Gusev 		mdb_warn("failed to get %s", "acache");
2233*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2234*86d949f9SVitaliy Gusev 	}
2235*86d949f9SVitaliy Gusev 
2236*86d949f9SVitaliy Gusev 	arg = mdb_alloc(sizeof (*arg), UM_SLEEP);
2237*86d949f9SVitaliy Gusev 	bcopy(&nfs_acache_arg, arg, sizeof (*arg));
2238*86d949f9SVitaliy Gusev 
2239*86d949f9SVitaliy Gusev 	arg->array_addr = addr;
2240*86d949f9SVitaliy Gusev 	arg->array_len = size;
2241*86d949f9SVitaliy Gusev 
2242*86d949f9SVitaliy Gusev 	wsp->walk_arg = arg;
2243*86d949f9SVitaliy Gusev 
2244*86d949f9SVitaliy Gusev 	status = hash_table_walk_init(wsp);
2245*86d949f9SVitaliy Gusev 	if (status != WALK_NEXT)
2246*86d949f9SVitaliy Gusev 		mdb_free(wsp->walk_arg, sizeof (hash_table_walk_arg_t));
2247*86d949f9SVitaliy Gusev 	return (status);
2248*86d949f9SVitaliy Gusev }
2249*86d949f9SVitaliy Gusev 
2250*86d949f9SVitaliy Gusev void
nfs_acache_walk_fini(mdb_walk_state_t * wsp)2251*86d949f9SVitaliy Gusev nfs_acache_walk_fini(mdb_walk_state_t *wsp)
2252*86d949f9SVitaliy Gusev {
2253*86d949f9SVitaliy Gusev 	hash_table_walk_fini(wsp);
2254*86d949f9SVitaliy Gusev 	mdb_free(wsp->walk_arg, sizeof (hash_table_walk_arg_t));
2255*86d949f9SVitaliy Gusev }
2256*86d949f9SVitaliy Gusev 
2257*86d949f9SVitaliy Gusev /*
2258*86d949f9SVitaliy Gusev  * nfs_acache4_rnode walker implementation
2259*86d949f9SVitaliy Gusev  */
2260*86d949f9SVitaliy Gusev 
2261*86d949f9SVitaliy Gusev int
nfs_acache4_rnode_walk_init(mdb_walk_state_t * wsp)2262*86d949f9SVitaliy Gusev nfs_acache4_rnode_walk_init(mdb_walk_state_t *wsp)
2263*86d949f9SVitaliy Gusev {
2264*86d949f9SVitaliy Gusev 	rnode4_t rn;
2265*86d949f9SVitaliy Gusev 
2266*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
2267*86d949f9SVitaliy Gusev 		mdb_warn("global walk not supported");
2268*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2269*86d949f9SVitaliy Gusev 	}
2270*86d949f9SVitaliy Gusev 
2271*86d949f9SVitaliy Gusev 	if (mdb_vread(&rn, sizeof (rn), wsp->walk_addr) == -1) {
2272*86d949f9SVitaliy Gusev 		mdb_warn("can't read rnode4_t at %p", wsp->walk_addr);
2273*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2274*86d949f9SVitaliy Gusev 	}
2275*86d949f9SVitaliy Gusev 
2276*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)rn.r_acache;
2277*86d949f9SVitaliy Gusev 
2278*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
2279*86d949f9SVitaliy Gusev }
2280*86d949f9SVitaliy Gusev 
2281*86d949f9SVitaliy Gusev int
nfs_acache4_rnode_walk_step(mdb_walk_state_t * wsp)2282*86d949f9SVitaliy Gusev nfs_acache4_rnode_walk_step(mdb_walk_state_t *wsp)
2283*86d949f9SVitaliy Gusev {
2284*86d949f9SVitaliy Gusev 	acache4_t ac;
2285*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
2286*86d949f9SVitaliy Gusev 
2287*86d949f9SVitaliy Gusev 	if (addr == 0)
2288*86d949f9SVitaliy Gusev 		return (WALK_DONE);
2289*86d949f9SVitaliy Gusev 
2290*86d949f9SVitaliy Gusev 	if (mdb_vread(&ac, sizeof (ac), addr) == -1) {
2291*86d949f9SVitaliy Gusev 		mdb_warn("can't read acache4_t at %p", addr);
2292*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2293*86d949f9SVitaliy Gusev 	}
2294*86d949f9SVitaliy Gusev 
2295*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)ac.list;
2296*86d949f9SVitaliy Gusev 
2297*86d949f9SVitaliy Gusev 	return (wsp->walk_callback(addr, &ac, wsp->walk_cbdata));
2298*86d949f9SVitaliy Gusev }
2299*86d949f9SVitaliy Gusev 
2300*86d949f9SVitaliy Gusev /*
2301*86d949f9SVitaliy Gusev  * nfs_acache4 walker implementation
2302*86d949f9SVitaliy Gusev  */
2303*86d949f9SVitaliy Gusev 
2304*86d949f9SVitaliy Gusev static const hash_table_walk_arg_t nfs_acache4_arg = {
2305*86d949f9SVitaliy Gusev 	0,		/* placeholder */
2306*86d949f9SVitaliy Gusev 	0,		/* placeholder */
2307*86d949f9SVitaliy Gusev 	sizeof (acache4_hash_t),
2308*86d949f9SVitaliy Gusev 	"next",
2309*86d949f9SVitaliy Gusev 	OFFSETOF(acache4_hash_t, next),
2310*86d949f9SVitaliy Gusev 	"acache4_t",
2311*86d949f9SVitaliy Gusev 	sizeof (acache4_t),
2312*86d949f9SVitaliy Gusev 	OFFSETOF(acache4_t, next)
2313*86d949f9SVitaliy Gusev };
2314*86d949f9SVitaliy Gusev 
2315*86d949f9SVitaliy Gusev int
nfs_acache4_walk_init(mdb_walk_state_t * wsp)2316*86d949f9SVitaliy Gusev nfs_acache4_walk_init(mdb_walk_state_t *wsp)
2317*86d949f9SVitaliy Gusev {
2318*86d949f9SVitaliy Gusev 	hash_table_walk_arg_t *arg;
2319*86d949f9SVitaliy Gusev 	int size;
2320*86d949f9SVitaliy Gusev 	uintptr_t addr;
2321*86d949f9SVitaliy Gusev 	int status;
2322*86d949f9SVitaliy Gusev 
2323*86d949f9SVitaliy Gusev 	if (wsp->walk_addr != 0) {
2324*86d949f9SVitaliy Gusev 		mdb_warn("local walk not supported");
2325*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2326*86d949f9SVitaliy Gusev 	}
2327*86d949f9SVitaliy Gusev 
2328*86d949f9SVitaliy Gusev 	if (mdb_readsym(&size, sizeof (size), "acache4size") == -1) {
2329*86d949f9SVitaliy Gusev 		mdb_warn("failed to get %s", "acache4size");
2330*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2331*86d949f9SVitaliy Gusev 	}
2332*86d949f9SVitaliy Gusev 
2333*86d949f9SVitaliy Gusev 	if (size < 0) {
2334*86d949f9SVitaliy Gusev 		mdb_warn("%s is negative: %d\n", "acache4size", size);
2335*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2336*86d949f9SVitaliy Gusev 	}
2337*86d949f9SVitaliy Gusev 
2338*86d949f9SVitaliy Gusev 	if (mdb_readsym(&addr, sizeof (addr), "acache4") == -1) {
2339*86d949f9SVitaliy Gusev 		mdb_warn("failed to get %s", "acache4");
2340*86d949f9SVitaliy Gusev 		return (WALK_ERR);
2341*86d949f9SVitaliy Gusev 	}
2342*86d949f9SVitaliy Gusev 
2343*86d949f9SVitaliy Gusev 	arg = mdb_alloc(sizeof (*arg), UM_SLEEP);
2344*86d949f9SVitaliy Gusev 	bcopy(&nfs_acache4_arg, arg, sizeof (*arg));
2345*86d949f9SVitaliy Gusev 
2346*86d949f9SVitaliy Gusev 	arg->array_addr = addr;
2347*86d949f9SVitaliy Gusev 	arg->array_len = size;
2348*86d949f9SVitaliy Gusev 
2349*86d949f9SVitaliy Gusev 	wsp->walk_arg = arg;
2350*86d949f9SVitaliy Gusev 
2351*86d949f9SVitaliy Gusev 	status = hash_table_walk_init(wsp);
2352*86d949f9SVitaliy Gusev 	if (status != WALK_NEXT)
2353*86d949f9SVitaliy Gusev 		mdb_free(wsp->walk_arg, sizeof (hash_table_walk_arg_t));
2354*86d949f9SVitaliy Gusev 	return (status);
2355*86d949f9SVitaliy Gusev }
2356*86d949f9SVitaliy Gusev 
2357*86d949f9SVitaliy Gusev void
nfs_acache4_walk_fini(mdb_walk_state_t * wsp)2358*86d949f9SVitaliy Gusev nfs_acache4_walk_fini(mdb_walk_state_t *wsp)
2359*86d949f9SVitaliy Gusev {
2360*86d949f9SVitaliy Gusev 	hash_table_walk_fini(wsp);
2361*86d949f9SVitaliy Gusev 	mdb_free(wsp->walk_arg, sizeof (hash_table_walk_arg_t));
2362*86d949f9SVitaliy Gusev }
2363