xref: /illumos-gate/usr/src/cmd/mdb/common/modules/nfs/svc.c (revision 86d949f9)
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 <mdb/mdb_ctf.h>
17*86d949f9SVitaliy Gusev #include <sys/types.h>
18*86d949f9SVitaliy Gusev #include <sys/zone.h>
19*86d949f9SVitaliy Gusev #include <rpc/svc.h>
20*86d949f9SVitaliy Gusev 
21*86d949f9SVitaliy Gusev #include "common.h"
22*86d949f9SVitaliy Gusev #include "svc.h"
23*86d949f9SVitaliy Gusev 
24*86d949f9SVitaliy Gusev /*
25*86d949f9SVitaliy Gusev  * svc_pool dcmd implementation
26*86d949f9SVitaliy Gusev  */
27*86d949f9SVitaliy Gusev 
28*86d949f9SVitaliy Gusev static const char *
svc_idname(uint_t id)29*86d949f9SVitaliy Gusev svc_idname(uint_t id)
30*86d949f9SVitaliy Gusev {
31*86d949f9SVitaliy Gusev 	switch (id) {
32*86d949f9SVitaliy Gusev 	case NFS_SVCPOOL_ID:
33*86d949f9SVitaliy Gusev 		return ("NFS");
34*86d949f9SVitaliy Gusev 	case NLM_SVCPOOL_ID:
35*86d949f9SVitaliy Gusev 		return ("NLM");
36*86d949f9SVitaliy Gusev 	case NFS_CB_SVCPOOL_ID:
37*86d949f9SVitaliy Gusev 		return ("NFS_CB");
38*86d949f9SVitaliy Gusev 	default:
39*86d949f9SVitaliy Gusev 		return ("");
40*86d949f9SVitaliy Gusev 	}
41*86d949f9SVitaliy Gusev }
42*86d949f9SVitaliy Gusev 
43*86d949f9SVitaliy Gusev static void
svc_print_pool(SVCPOOL * pool,uintptr_t addr)44*86d949f9SVitaliy Gusev svc_print_pool(SVCPOOL *pool, uintptr_t addr)
45*86d949f9SVitaliy Gusev {
46*86d949f9SVitaliy Gusev 	mdb_printf("SVCPOOL = %p -> POOL ID = %s(%d)\n", addr,
47*86d949f9SVitaliy Gusev 	    svc_idname(pool->p_id), pool->p_id);
48*86d949f9SVitaliy Gusev 	mdb_printf("Non detached threads    = %d\n", pool->p_threads);
49*86d949f9SVitaliy Gusev 	mdb_printf("Detached threads        = %d\n", pool->p_detached_threads);
50*86d949f9SVitaliy Gusev 	mdb_printf("Max threads             = %d\n", pool->p_maxthreads);
51*86d949f9SVitaliy Gusev 	mdb_printf("`redline'               = %d\n", pool->p_redline);
52*86d949f9SVitaliy Gusev 	mdb_printf("Reserved threads        = %d\n", pool->p_reserved_threads);
53*86d949f9SVitaliy Gusev 	mdb_printf("Thread lock             = %s\n",
54*86d949f9SVitaliy Gusev 	    common_mutex(&pool->p_thread_lock));
55*86d949f9SVitaliy Gusev 
56*86d949f9SVitaliy Gusev 	mdb_printf("Asleep threads          = %d\n", pool->p_asleep);
57*86d949f9SVitaliy Gusev 	mdb_printf("Request lock            = %s\n",
58*86d949f9SVitaliy Gusev 	    common_mutex(&pool->p_req_lock));
59*86d949f9SVitaliy Gusev 
60*86d949f9SVitaliy Gusev 	mdb_printf("Pending requests        = %d\n", pool->p_reqs);
61*86d949f9SVitaliy Gusev 	mdb_printf("Walking threads         = %d\n", pool->p_walkers);
62*86d949f9SVitaliy Gusev 	mdb_printf("Max requests from xprt  = %d\n", pool->p_max_same_xprt);
63*86d949f9SVitaliy Gusev 	mdb_printf("Stack size for svc_run  = %d\n", pool->p_stksize);
64*86d949f9SVitaliy Gusev 	mdb_printf("Creator lock            = %s\n",
65*86d949f9SVitaliy Gusev 	    common_mutex(&pool->p_creator_lock));
66*86d949f9SVitaliy Gusev 
67*86d949f9SVitaliy Gusev 	mdb_printf("No of Master xprt's     = %d\n", pool->p_lcount);
68*86d949f9SVitaliy Gusev 	mdb_printf("rwlock for mxprtlist    = %s\n",
69*86d949f9SVitaliy Gusev 	    common_rwlock(&pool->p_lrwlock));
70*86d949f9SVitaliy Gusev 	mdb_printf("master xprt list ptr    = %p\n\n", pool->p_lhead);
71*86d949f9SVitaliy Gusev }
72*86d949f9SVitaliy Gusev 
73*86d949f9SVitaliy Gusev int
svc_pool_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)74*86d949f9SVitaliy Gusev svc_pool_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
75*86d949f9SVitaliy Gusev {
76*86d949f9SVitaliy Gusev 	SVCPOOL svcpool;
77*86d949f9SVitaliy Gusev 	uint_t opt_v = FALSE;
78*86d949f9SVitaliy Gusev 	int *pools;
79*86d949f9SVitaliy Gusev 	int count, i;
80*86d949f9SVitaliy Gusev 
81*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
82*86d949f9SVitaliy Gusev 		/* Walk through all svcpools in the global zone */
83*86d949f9SVitaliy Gusev 		if (mdb_walk_dcmd("svc_pool", "svc_pool", argc, argv) == -1) {
84*86d949f9SVitaliy Gusev 			mdb_warn("failed to walk svcpools");
85*86d949f9SVitaliy Gusev 			return (DCMD_ERR);
86*86d949f9SVitaliy Gusev 		}
87*86d949f9SVitaliy Gusev 		return (DCMD_OK);
88*86d949f9SVitaliy Gusev 	}
89*86d949f9SVitaliy Gusev 
90*86d949f9SVitaliy Gusev 	count = mdb_getopts(argc, argv,
91*86d949f9SVitaliy Gusev 	    'v', MDB_OPT_SETBITS, TRUE, &opt_v, NULL);
92*86d949f9SVitaliy Gusev 	argc -= count;
93*86d949f9SVitaliy Gusev 	argv += count;
94*86d949f9SVitaliy Gusev 
95*86d949f9SVitaliy Gusev 	pools = mdb_alloc(argc * sizeof (*pools), UM_SLEEP | UM_GC);
96*86d949f9SVitaliy Gusev 	for (i = 0; i < argc; i++) {
97*86d949f9SVitaliy Gusev 		const char *s;
98*86d949f9SVitaliy Gusev 
99*86d949f9SVitaliy Gusev 		switch (argv[i].a_type) {
100*86d949f9SVitaliy Gusev 		case MDB_TYPE_STRING:
101*86d949f9SVitaliy Gusev 			s = argv[i].a_un.a_str;
102*86d949f9SVitaliy Gusev 
103*86d949f9SVitaliy Gusev 			if (strcmp(s, "nfs") == 0)
104*86d949f9SVitaliy Gusev 				pools[i] = NFS_SVCPOOL_ID;
105*86d949f9SVitaliy Gusev 			else if (strcmp(s, "nlm") == 0)
106*86d949f9SVitaliy Gusev 				pools[i] = NLM_SVCPOOL_ID;
107*86d949f9SVitaliy Gusev 			else if (strcmp(s, "nfs_cb") == 0)
108*86d949f9SVitaliy Gusev 				pools[i] = NFS_CB_SVCPOOL_ID;
109*86d949f9SVitaliy Gusev 			else
110*86d949f9SVitaliy Gusev 				return (DCMD_USAGE);
111*86d949f9SVitaliy Gusev 
112*86d949f9SVitaliy Gusev 			break;
113*86d949f9SVitaliy Gusev 
114*86d949f9SVitaliy Gusev 		case MDB_TYPE_IMMEDIATE:
115*86d949f9SVitaliy Gusev 			pools[i] = (int)argv[i].a_un.a_val;
116*86d949f9SVitaliy Gusev 			break;
117*86d949f9SVitaliy Gusev 
118*86d949f9SVitaliy Gusev 		default:
119*86d949f9SVitaliy Gusev 			return (DCMD_USAGE);
120*86d949f9SVitaliy Gusev 		}
121*86d949f9SVitaliy Gusev 	}
122*86d949f9SVitaliy Gusev 
123*86d949f9SVitaliy Gusev 	if (mdb_vread(&svcpool, sizeof (svcpool), addr) == -1) {
124*86d949f9SVitaliy Gusev 		mdb_warn("failed to read svcpool");
125*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
126*86d949f9SVitaliy Gusev 	}
127*86d949f9SVitaliy Gusev 
128*86d949f9SVitaliy Gusev 	/*
129*86d949f9SVitaliy Gusev 	 * Make sure the svcpool is on the list (or the list is empty).
130*86d949f9SVitaliy Gusev 	 * If not, just return with DCMD_OK.
131*86d949f9SVitaliy Gusev 	 */
132*86d949f9SVitaliy Gusev 	for (i = 0; i < argc; i++) {
133*86d949f9SVitaliy Gusev 		if (svcpool.p_id == pools[i]) {
134*86d949f9SVitaliy Gusev 			argc = 0;
135*86d949f9SVitaliy Gusev 			break;
136*86d949f9SVitaliy Gusev 		}
137*86d949f9SVitaliy Gusev 	}
138*86d949f9SVitaliy Gusev 	if (argc != 0)
139*86d949f9SVitaliy Gusev 		return (DCMD_OK);
140*86d949f9SVitaliy Gusev 
141*86d949f9SVitaliy Gusev 	/* Print the svcpool */
142*86d949f9SVitaliy Gusev 	svc_print_pool(&svcpool, addr);
143*86d949f9SVitaliy Gusev 	if (opt_v && svcpool.p_lhead && (mdb_pwalk_dcmd("svc_mxprt",
144*86d949f9SVitaliy Gusev 	    "svc_mxprt", 0, NULL, (uintptr_t)svcpool.p_lhead) == -1))
145*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
146*86d949f9SVitaliy Gusev 
147*86d949f9SVitaliy Gusev 	return (DCMD_OK);
148*86d949f9SVitaliy Gusev }
149*86d949f9SVitaliy Gusev 
150*86d949f9SVitaliy Gusev void
svc_pool_help(void)151*86d949f9SVitaliy Gusev svc_pool_help(void)
152*86d949f9SVitaliy Gusev {
153*86d949f9SVitaliy Gusev 	mdb_printf(
154*86d949f9SVitaliy Gusev 	    "-v       display also the master xprts for the svcpools\n"
155*86d949f9SVitaliy Gusev 	    "poolid   either $[numeric] or verbose: nfs or nlm or nfs_cb\n"
156*86d949f9SVitaliy Gusev 	    "\n"
157*86d949f9SVitaliy Gusev 	    "If the poolid list is specified, only those svcpools are dumped\n"
158*86d949f9SVitaliy Gusev 	    "whose poolid is in the list.\n");
159*86d949f9SVitaliy Gusev }
160*86d949f9SVitaliy Gusev 
161*86d949f9SVitaliy Gusev /*
162*86d949f9SVitaliy Gusev  * svc_mxprt dcmd implementation
163*86d949f9SVitaliy Gusev  */
164*86d949f9SVitaliy Gusev 
165*86d949f9SVitaliy Gusev static void
svc_print_masterxprt(SVCMASTERXPRT * xprt)166*86d949f9SVitaliy Gusev svc_print_masterxprt(SVCMASTERXPRT *xprt)
167*86d949f9SVitaliy Gusev {
168*86d949f9SVitaliy Gusev 	mdb_printf("svcxprt_common structure:\n");
169*86d949f9SVitaliy Gusev 	mdb_printf("queue ptr               = %p\n", xprt->xp_wq);
170*86d949f9SVitaliy Gusev 	mdb_printf("cached cred for server  = %d\n", xprt->xp_cred);
171*86d949f9SVitaliy Gusev 	mdb_printf("transport type          = %d\n", xprt->xp_type);
172*86d949f9SVitaliy Gusev 	mdb_printf("TSDU or TIDU size       = %d\n", xprt->xp_msg_size);
173*86d949f9SVitaliy Gusev 
174*86d949f9SVitaliy Gusev 	mdb_printf("address                 = %s\n",
175*86d949f9SVitaliy Gusev 	    common_netbuf_str(&xprt->xp_rtaddr));
176*86d949f9SVitaliy Gusev 	mdb_printf("Request queue head      = %p\n", xprt->xp_req_head);
177*86d949f9SVitaliy Gusev 	mdb_printf("Request queue tail      = %p\n", xprt->xp_req_tail);
178*86d949f9SVitaliy Gusev 	mdb_printf("Request lock address    = %s\n",
179*86d949f9SVitaliy Gusev 	    common_mutex(&xprt->xp_req_lock));
180*86d949f9SVitaliy Gusev 
181*86d949f9SVitaliy Gusev 	mdb_printf("Current no of attached threads  = %d\n",
182*86d949f9SVitaliy Gusev 	    xprt->xp_threads);
183*86d949f9SVitaliy Gusev 	mdb_printf("Current no of detached threads  = %d\n",
184*86d949f9SVitaliy Gusev 	    xprt->xp_detached_threads);
185*86d949f9SVitaliy Gusev 	mdb_printf("Thread count lock address       = %s\n\n",
186*86d949f9SVitaliy Gusev 	    common_mutex(&xprt->xp_thread_lock));
187*86d949f9SVitaliy Gusev }
188*86d949f9SVitaliy Gusev 
189*86d949f9SVitaliy Gusev int
svc_mxprt_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)190*86d949f9SVitaliy Gusev svc_mxprt_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
191*86d949f9SVitaliy Gusev {
192*86d949f9SVitaliy Gusev 	SVCMASTERXPRT xprt;
193*86d949f9SVitaliy Gusev 	uint_t opt_w = FALSE;
194*86d949f9SVitaliy Gusev 
195*86d949f9SVitaliy Gusev 	if (mdb_getopts(argc, argv,
196*86d949f9SVitaliy Gusev 	    'w', MDB_OPT_SETBITS, TRUE, &opt_w, NULL) != argc)
197*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
198*86d949f9SVitaliy Gusev 
199*86d949f9SVitaliy Gusev 	if ((flags & DCMD_ADDRSPEC) == 0) {
200*86d949f9SVitaliy Gusev 		mdb_printf("requires address of SVCMASTERXPRT\n");
201*86d949f9SVitaliy Gusev 		return (DCMD_USAGE);
202*86d949f9SVitaliy Gusev 	}
203*86d949f9SVitaliy Gusev 
204*86d949f9SVitaliy Gusev 	if (opt_w) {
205*86d949f9SVitaliy Gusev 		/* Walk through all xprts */
206*86d949f9SVitaliy Gusev 		if (mdb_pwalk_dcmd("svc_mxprt", "svc_mxprt", 0, NULL,
207*86d949f9SVitaliy Gusev 		    addr) == -1) {
208*86d949f9SVitaliy Gusev 			mdb_warn("failed to walk svc_mxprt");
209*86d949f9SVitaliy Gusev 			return (DCMD_ERR);
210*86d949f9SVitaliy Gusev 		}
211*86d949f9SVitaliy Gusev 		return (DCMD_OK);
212*86d949f9SVitaliy Gusev 	}
213*86d949f9SVitaliy Gusev 
214*86d949f9SVitaliy Gusev 	if (mdb_vread(&xprt, sizeof (xprt), addr) == -1) {
215*86d949f9SVitaliy Gusev 		mdb_warn("failed to read xprt");
216*86d949f9SVitaliy Gusev 		return (DCMD_ERR);
217*86d949f9SVitaliy Gusev 	}
218*86d949f9SVitaliy Gusev 
219*86d949f9SVitaliy Gusev 	svc_print_masterxprt(&xprt);
220*86d949f9SVitaliy Gusev 
221*86d949f9SVitaliy Gusev 	return (DCMD_OK);
222*86d949f9SVitaliy Gusev }
223*86d949f9SVitaliy Gusev 
224*86d949f9SVitaliy Gusev void
svc_mxprt_help(void)225*86d949f9SVitaliy Gusev svc_mxprt_help(void)
226*86d949f9SVitaliy Gusev {
227*86d949f9SVitaliy Gusev 	mdb_printf(
228*86d949f9SVitaliy Gusev 	    "-w       walks along all master xprts in the list\n"
229*86d949f9SVitaliy Gusev 	    "\n"
230*86d949f9SVitaliy Gusev 	    "The following two commands are equivalent:\n"
231*86d949f9SVitaliy Gusev 	    "  ::svc_mxprt -w\n"
232*86d949f9SVitaliy Gusev 	    "  ::walk svc_mxprt|::svc_mxprt\n");
233*86d949f9SVitaliy Gusev }
234*86d949f9SVitaliy Gusev 
235*86d949f9SVitaliy Gusev /*
236*86d949f9SVitaliy Gusev  * svc_pool walker implementation
237*86d949f9SVitaliy Gusev  */
238*86d949f9SVitaliy Gusev 
239*86d949f9SVitaliy Gusev static int
svc_get_pool(uintptr_t zone_addr,uintptr_t * svc_addr)240*86d949f9SVitaliy Gusev svc_get_pool(uintptr_t zone_addr, uintptr_t *svc_addr)
241*86d949f9SVitaliy Gusev {
242*86d949f9SVitaliy Gusev 	mdb_ctf_id_t id;
243*86d949f9SVitaliy Gusev 	ulong_t offset;
244*86d949f9SVitaliy Gusev 	uintptr_t glob_addr;
245*86d949f9SVitaliy Gusev 
246*86d949f9SVitaliy Gusev 	if (zoned_get_zsd(zone_addr, "svc_zone_key", &glob_addr) != DCMD_OK) {
247*86d949f9SVitaliy Gusev 		mdb_warn("failed to get zoned svc");
248*86d949f9SVitaliy Gusev 		return (WALK_ERR);
249*86d949f9SVitaliy Gusev 	}
250*86d949f9SVitaliy Gusev 
251*86d949f9SVitaliy Gusev 	if (mdb_ctf_lookup_by_name("struct svc_globals", &id)) {
252*86d949f9SVitaliy Gusev 		mdb_warn("failed to look up type %s", "struct svc_globals");
253*86d949f9SVitaliy Gusev 		return (WALK_ERR);
254*86d949f9SVitaliy Gusev 	}
255*86d949f9SVitaliy Gusev 
256*86d949f9SVitaliy Gusev 	if (mdb_ctf_offsetof(id, "svc_pools", &offset)) {
257*86d949f9SVitaliy Gusev 		mdb_warn("failed to get %s offset", "svc_pools");
258*86d949f9SVitaliy Gusev 		return (WALK_ERR);
259*86d949f9SVitaliy Gusev 	}
260*86d949f9SVitaliy Gusev 
261*86d949f9SVitaliy Gusev 	offset /= NBBY;
262*86d949f9SVitaliy Gusev 	if (mdb_vread(svc_addr, sizeof (*svc_addr), glob_addr + offset) == -1) {
263*86d949f9SVitaliy Gusev 		mdb_warn("failed to read svc_pools address");
264*86d949f9SVitaliy Gusev 		return (WALK_ERR);
265*86d949f9SVitaliy Gusev 	}
266*86d949f9SVitaliy Gusev 
267*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
268*86d949f9SVitaliy Gusev }
269*86d949f9SVitaliy Gusev 
270*86d949f9SVitaliy Gusev int
svc_pool_walk_init(mdb_walk_state_t * wsp)271*86d949f9SVitaliy Gusev svc_pool_walk_init(mdb_walk_state_t *wsp)
272*86d949f9SVitaliy Gusev {
273*86d949f9SVitaliy Gusev 	/* Use global zone by default */
274*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
275*86d949f9SVitaliy Gusev 		/* wsp->walk_addr = global_zone */
276*86d949f9SVitaliy Gusev 		if (mdb_readvar(&wsp->walk_addr, "global_zone") == -1) {
277*86d949f9SVitaliy Gusev 			mdb_warn("failed to locate global_zone");
278*86d949f9SVitaliy Gusev 			return (WALK_ERR);
279*86d949f9SVitaliy Gusev 		}
280*86d949f9SVitaliy Gusev 	}
281*86d949f9SVitaliy Gusev 
282*86d949f9SVitaliy Gusev 	/* put svcpool address of the zone into wsp->walk_addr */
283*86d949f9SVitaliy Gusev 	return (svc_get_pool(wsp->walk_addr, &wsp->walk_addr));
284*86d949f9SVitaliy Gusev }
285*86d949f9SVitaliy Gusev 
286*86d949f9SVitaliy Gusev int
svc_pool_walk_step(mdb_walk_state_t * wsp)287*86d949f9SVitaliy Gusev svc_pool_walk_step(mdb_walk_state_t *wsp)
288*86d949f9SVitaliy Gusev {
289*86d949f9SVitaliy Gusev 	SVCPOOL pool;
290*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
291*86d949f9SVitaliy Gusev 
292*86d949f9SVitaliy Gusev 	if (addr == 0)
293*86d949f9SVitaliy Gusev 		return (WALK_DONE);
294*86d949f9SVitaliy Gusev 
295*86d949f9SVitaliy Gusev 	if (mdb_vread(&pool, sizeof (pool), addr) == -1) {
296*86d949f9SVitaliy Gusev 		mdb_warn("failed to read SVCPOOL");
297*86d949f9SVitaliy Gusev 		return (WALK_ERR);
298*86d949f9SVitaliy Gusev 	}
299*86d949f9SVitaliy Gusev 
300*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)pool.p_next;
301*86d949f9SVitaliy Gusev 	return (wsp->walk_callback(addr, &pool, wsp->walk_cbdata));
302*86d949f9SVitaliy Gusev }
303*86d949f9SVitaliy Gusev 
304*86d949f9SVitaliy Gusev /*
305*86d949f9SVitaliy Gusev  * svc_mxprt walker implementation
306*86d949f9SVitaliy Gusev  */
307*86d949f9SVitaliy Gusev 
308*86d949f9SVitaliy Gusev int
svc_mxprt_walk_init(mdb_walk_state_t * wsp)309*86d949f9SVitaliy Gusev svc_mxprt_walk_init(mdb_walk_state_t *wsp)
310*86d949f9SVitaliy Gusev {
311*86d949f9SVitaliy Gusev 	if (wsp->walk_addr == 0) {
312*86d949f9SVitaliy Gusev 		mdb_warn("global walk not supported");
313*86d949f9SVitaliy Gusev 		return (WALK_ERR);
314*86d949f9SVitaliy Gusev 	}
315*86d949f9SVitaliy Gusev 
316*86d949f9SVitaliy Gusev 	wsp->walk_data = (void *)wsp->walk_addr;
317*86d949f9SVitaliy Gusev 
318*86d949f9SVitaliy Gusev 	return (WALK_NEXT);
319*86d949f9SVitaliy Gusev }
320*86d949f9SVitaliy Gusev 
321*86d949f9SVitaliy Gusev int
svc_mxprt_walk_step(mdb_walk_state_t * wsp)322*86d949f9SVitaliy Gusev svc_mxprt_walk_step(mdb_walk_state_t *wsp)
323*86d949f9SVitaliy Gusev {
324*86d949f9SVitaliy Gusev 	SVCMASTERXPRT xprt;
325*86d949f9SVitaliy Gusev 	uintptr_t addr = wsp->walk_addr;
326*86d949f9SVitaliy Gusev 	int status;
327*86d949f9SVitaliy Gusev 
328*86d949f9SVitaliy Gusev 	if (mdb_vread(&xprt, sizeof (xprt), addr) == -1) {
329*86d949f9SVitaliy Gusev 		mdb_warn("can't read SVCMASTERXPRT");
330*86d949f9SVitaliy Gusev 		return (WALK_ERR);
331*86d949f9SVitaliy Gusev 	}
332*86d949f9SVitaliy Gusev 
333*86d949f9SVitaliy Gusev 	wsp->walk_addr = (uintptr_t)xprt.xp_next;
334*86d949f9SVitaliy Gusev 
335*86d949f9SVitaliy Gusev 	status = wsp->walk_callback(addr, &xprt, wsp->walk_cbdata);
336*86d949f9SVitaliy Gusev 	if (status != WALK_NEXT)
337*86d949f9SVitaliy Gusev 		return (status);
338*86d949f9SVitaliy Gusev 
339*86d949f9SVitaliy Gusev 	return (((void *)wsp->walk_addr == wsp->walk_data) ? WALK_DONE
340*86d949f9SVitaliy Gusev 	    : WALK_NEXT);
341*86d949f9SVitaliy Gusev }
342