xref: /onnv-gate/usr/src/cmd/mdb/common/modules/smbfs/smbfs.c (revision 11332:ed3411181494)
16007Sthurlow /*
26007Sthurlow  * CDDL HEADER START
36007Sthurlow  *
46007Sthurlow  * The contents of this file are subject to the terms of the
56007Sthurlow  * Common Development and Distribution License (the "License").
66007Sthurlow  * You may not use this file except in compliance with the License.
76007Sthurlow  *
86007Sthurlow  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96007Sthurlow  * or http://www.opensolaris.org/os/licensing.
106007Sthurlow  * See the License for the specific language governing permissions
116007Sthurlow  * and limitations under the License.
126007Sthurlow  *
136007Sthurlow  * When distributing Covered Code, include this CDDL HEADER in each
146007Sthurlow  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156007Sthurlow  * If applicable, add the following below this CDDL HEADER, with the
166007Sthurlow  * fields enclosed by brackets "[]" replaced with your own identifying
176007Sthurlow  * information: Portions Copyright [yyyy] [name of copyright owner]
186007Sthurlow  *
196007Sthurlow  * CDDL HEADER END
206007Sthurlow  */
216007Sthurlow 
226007Sthurlow /*
23*11332SGordon.Ross@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
246007Sthurlow  * Use is subject to license terms.
256007Sthurlow  */
266007Sthurlow 
276007Sthurlow #include <sys/mdb_modapi.h>
286007Sthurlow #include <sys/types.h>
296007Sthurlow #include <sys/refstr_impl.h>
306007Sthurlow #include <sys/vnode.h>
316007Sthurlow #include <sys/vfs.h>
326007Sthurlow 
336007Sthurlow #include "smbfs.h"
346007Sthurlow #include "smbfs_node.h"
356007Sthurlow 
366007Sthurlow #define	OPT_VERBOSE	0x0001	/* Be [-v]erbose in dcmd's */
376007Sthurlow 
386007Sthurlow /*
396007Sthurlow  * This macro lets us easily use both sizeof (typename)
406007Sthurlow  * and the string-ified typename for the error message.
416007Sthurlow  */
426007Sthurlow #define	SMBFS_OBJ_FETCH(obj_addr, obj_type, dest, err) \
436007Sthurlow 	if (mdb_vread(dest, sizeof (obj_type), ((uintptr_t)obj_addr)) \
446007Sthurlow 	!= sizeof (obj_type)) { \
456007Sthurlow 		mdb_warn("error reading "#obj_type" at %p", obj_addr); \
466007Sthurlow 		return (err); \
476007Sthurlow 	}
486007Sthurlow 
496007Sthurlow /*
506007Sthurlow  * We need to read in a private copy
516007Sthurlow  * of every string we want to print out.
526007Sthurlow  */
536007Sthurlow void
print_str(uintptr_t addr)546007Sthurlow print_str(uintptr_t addr)
556007Sthurlow {
566007Sthurlow 	char buf[64];
576007Sthurlow 	int len, mx = sizeof (buf) - 4;
586007Sthurlow 
596007Sthurlow 	if ((len = mdb_readstr(buf, sizeof (buf), addr)) <= 0) {
606007Sthurlow 		mdb_printf(" (%p)", addr);
616007Sthurlow 	} else {
626007Sthurlow 		if (len > mx)
636007Sthurlow 			strcpy(&buf[mx], "...");
646007Sthurlow 		mdb_printf(" %s", buf);
656007Sthurlow 	}
666007Sthurlow }
676007Sthurlow 
686007Sthurlow /*
696007Sthurlow  * Dcmd (and callback function) to print a summary of
706007Sthurlow  * all "smbfs" entries in the VFS list.
716007Sthurlow  */
726007Sthurlow 
736007Sthurlow typedef struct smbfs_vfs_cbdata {
746007Sthurlow 	int flags;
756007Sthurlow 	int printed_header;
766007Sthurlow 	uintptr_t vfsops;	/* filter by vfs ops pointer */
776007Sthurlow 	smbmntinfo_t smi;	/* scratch space for smbfs_vfs_cb */
786007Sthurlow } smbfs_vfs_cbdata_t;
796007Sthurlow 
806007Sthurlow int
smbfs_vfs_cb(uintptr_t addr,const void * data,void * arg)816007Sthurlow smbfs_vfs_cb(uintptr_t addr, const void *data, void *arg)
826007Sthurlow {
836007Sthurlow 	const vfs_t *vfs = data;
846007Sthurlow 	smbfs_vfs_cbdata_t *cbd = arg;
856007Sthurlow 	uintptr_t ta;
866007Sthurlow 
876007Sthurlow 	/* Filter by matching smbfs ops vector. */
886007Sthurlow 	if (cbd->vfsops && cbd->vfsops != (uintptr_t)vfs->vfs_op) {
896007Sthurlow 		return (WALK_NEXT);
906007Sthurlow 	}
916007Sthurlow 
926007Sthurlow 	if (cbd->printed_header == 0) {
936007Sthurlow 		cbd->printed_header = 1;
946007Sthurlow 		mdb_printf("// vfs_t smbmntinfo_t mnt_path\n");
956007Sthurlow 	}
966007Sthurlow 
976007Sthurlow 	mdb_printf(" %-p", addr);	/* vfs_t */
986007Sthurlow 	mdb_printf(" %-p", (uintptr_t)vfs->vfs_data);
996007Sthurlow 	/*
1006007Sthurlow 	 * Note: vfs_mntpt is a refstr_t.
1016007Sthurlow 	 * Advance to string member.
1026007Sthurlow 	 */
1036007Sthurlow 	ta = (uintptr_t)vfs->vfs_mntpt;
1046007Sthurlow 	ta += OFFSETOF(struct refstr, rs_string);
1056007Sthurlow 	print_str(ta);
1066007Sthurlow 	mdb_printf("\n");
1076007Sthurlow 
1086007Sthurlow 	if (cbd->flags & OPT_VERBOSE) {
1096007Sthurlow 		mdb_inc_indent(2);
1106007Sthurlow 		/* Don't fail the walk if this fails. */
1116007Sthurlow 		if (mdb_vread(&cbd->smi, sizeof (cbd->smi),
1126007Sthurlow 		    (uintptr_t)vfs->vfs_data) == -1) {
1136007Sthurlow 			mdb_warn("error reading smbmntinfo_t at %p",
1146007Sthurlow 			    (uintptr_t)vfs->vfs_data);
1156007Sthurlow 		} else {
1166007Sthurlow 			/* Interesting parts of smbmntinfo_t */
1176007Sthurlow 			mdb_printf("smi_share: %p, smi_root: %p\n",
1186007Sthurlow 			    cbd->smi.smi_share, cbd->smi.smi_root);
1196007Sthurlow 		}
1206007Sthurlow 		mdb_dec_indent(2);
1216007Sthurlow 	}
1226007Sthurlow 
1236007Sthurlow 	return (WALK_NEXT);
1246007Sthurlow }
1256007Sthurlow 
1266007Sthurlow int
smbfs_vfs_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1276007Sthurlow smbfs_vfs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1286007Sthurlow {
1296007Sthurlow 	smbfs_vfs_cbdata_t *cbd;
1306007Sthurlow 	vfs_t *vfs;
1316007Sthurlow 
1326007Sthurlow 	cbd = mdb_zalloc(sizeof (*cbd),  UM_SLEEP | UM_GC);
1336007Sthurlow 
1346007Sthurlow 	/*
1356007Sthurlow 	 * Get the ops address here, so things work
1366007Sthurlow 	 * even if the smbfs module is loaded later
1376007Sthurlow 	 * than this mdb module.
1386007Sthurlow 	 */
1396007Sthurlow 	if (mdb_readvar(&cbd->vfsops, "smbfs_vfsops") == -1) {
1406007Sthurlow 		mdb_warn("failed to find 'smbfs_vfsops'\n");
1416007Sthurlow 		return (DCMD_ERR);
1426007Sthurlow 	}
1436007Sthurlow 
1446007Sthurlow 	if (mdb_getopts(argc, argv,
1456007Sthurlow 	    'v', MDB_OPT_SETBITS, OPT_VERBOSE, &cbd->flags,
1466007Sthurlow 	    NULL) != argc) {
1476007Sthurlow 		return (DCMD_USAGE);
1486007Sthurlow 	}
1496007Sthurlow 
1506007Sthurlow 	if (!(flags & DCMD_ADDRSPEC)) {
1516007Sthurlow 		if (mdb_walk("genunix`vfs", smbfs_vfs_cb, cbd)
1526007Sthurlow 		    == -1) {
1536007Sthurlow 			mdb_warn("can't walk smbfs vfs");
1546007Sthurlow 			return (DCMD_ERR);
1556007Sthurlow 		}
1566007Sthurlow 		return (DCMD_OK);
1576007Sthurlow 	}
1586007Sthurlow 
1596007Sthurlow 	vfs = mdb_alloc(sizeof (*vfs),  UM_SLEEP | UM_GC);
1606007Sthurlow 	SMBFS_OBJ_FETCH(addr, vfs_t, vfs, DCMD_ERR);
1616007Sthurlow 	smbfs_vfs_cb(addr, vfs, cbd);
1626007Sthurlow 	return (DCMD_OK);
1636007Sthurlow }
1646007Sthurlow 
1656007Sthurlow void
smbfs_vfs_help(void)1666007Sthurlow smbfs_vfs_help(void)
1676007Sthurlow {
1686007Sthurlow 	mdb_printf(
1696007Sthurlow 	    "Display addresses of the mounted smbfs structures\n"
1706007Sthurlow 	    "and the pathname of the mountpoint\n"
1716007Sthurlow 	    "\nOptions:\n"
1726007Sthurlow 	    "  -v    display details of the smbmntinfo\n");
1736007Sthurlow }
1746007Sthurlow 
1756007Sthurlow /*
176*11332SGordon.Ross@Sun.COM  * Dcmd (and callback function) to print a summary of
177*11332SGordon.Ross@Sun.COM  * all smbnodes in the node "hash" (cache) AVL tree.
1786007Sthurlow  */
1796007Sthurlow 
180*11332SGordon.Ross@Sun.COM typedef struct smbfs_node_cbdata {
181*11332SGordon.Ross@Sun.COM 	int flags;
182*11332SGordon.Ross@Sun.COM 	int printed_header;
183*11332SGordon.Ross@Sun.COM 	vnode_t vn;
184*11332SGordon.Ross@Sun.COM } smbfs_node_cbdata_t;
1856007Sthurlow 
1866007Sthurlow int
smbfs_node_cb(uintptr_t addr,const void * data,void * arg)187*11332SGordon.Ross@Sun.COM smbfs_node_cb(uintptr_t addr, const void *data, void *arg)
1886007Sthurlow {
1896007Sthurlow 	const smbnode_t *np = data;
190*11332SGordon.Ross@Sun.COM 	smbfs_node_cbdata_t *cbd = arg;
1916007Sthurlow 
1926007Sthurlow 	if (cbd->printed_header == 0) {
1936007Sthurlow 		cbd->printed_header = 1;
194*11332SGordon.Ross@Sun.COM 		mdb_printf("// vnode smbnode rpath\n");
1956007Sthurlow 	}
1966007Sthurlow 
197*11332SGordon.Ross@Sun.COM 	mdb_printf(" %-p", (uintptr_t)np->r_vnode);
1986007Sthurlow 	mdb_printf(" %-p", addr);	/* smbnode */
1996007Sthurlow 	print_str((uintptr_t)np->n_rpath);
2006007Sthurlow 	mdb_printf("\n");
2016007Sthurlow 
2026007Sthurlow 	if (cbd->flags & OPT_VERBOSE) {
2036007Sthurlow 		mdb_inc_indent(2);
2046007Sthurlow 		/* Don't fail the walk if this fails. */
2056007Sthurlow 		if (mdb_vread(&cbd->vn, sizeof (cbd->vn),
2066007Sthurlow 		    (uintptr_t)np->r_vnode) == -1) {
2076007Sthurlow 			mdb_warn("error reading vnode_t at %p",
2086007Sthurlow 			    (uintptr_t)np->r_vnode);
2096007Sthurlow 		} else {
2106007Sthurlow 			/* Interesting parts of vnode_t */
211*11332SGordon.Ross@Sun.COM 			mdb_printf("v_type=%d v_count=%d",
212*11332SGordon.Ross@Sun.COM 			    cbd->vn.v_type, cbd->vn.v_count);
2136007Sthurlow 			mdb_printf("\n");
2146007Sthurlow 		}
2156007Sthurlow 		mdb_dec_indent(2);
2166007Sthurlow 	}
2176007Sthurlow 
2186007Sthurlow 	return (WALK_NEXT);
2196007Sthurlow }
2206007Sthurlow 
2216007Sthurlow int
smbfs_node_dcmd(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)222*11332SGordon.Ross@Sun.COM smbfs_node_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2236007Sthurlow {
224*11332SGordon.Ross@Sun.COM 	smbfs_node_cbdata_t *cbd;
2256007Sthurlow 
2266007Sthurlow 	cbd = mdb_zalloc(sizeof (*cbd), UM_SLEEP | UM_GC);
2276007Sthurlow 
2286007Sthurlow 	if (mdb_getopts(argc, argv,
2296007Sthurlow 	    'v', MDB_OPT_SETBITS, OPT_VERBOSE, &cbd->flags,
230*11332SGordon.Ross@Sun.COM 	    NULL) != argc) {
2316007Sthurlow 		return (DCMD_USAGE);
2326007Sthurlow 	}
2336007Sthurlow 
2346007Sthurlow 	if (!(flags & DCMD_ADDRSPEC)) {
235*11332SGordon.Ross@Sun.COM 		mdb_warn("expect an smbmntinfo_t addr");
236*11332SGordon.Ross@Sun.COM 		return (DCMD_USAGE);
2376007Sthurlow 	}
238*11332SGordon.Ross@Sun.COM 	addr += OFFSETOF(smbmntinfo_t, smi_hash_avl);
2396007Sthurlow 
240*11332SGordon.Ross@Sun.COM 	if (mdb_pwalk("genunix`avl", smbfs_node_cb, cbd, addr) == -1) {
241*11332SGordon.Ross@Sun.COM 		mdb_warn("cannot walk smbfs nodes");
242*11332SGordon.Ross@Sun.COM 		return (DCMD_ERR);
243*11332SGordon.Ross@Sun.COM 	}
2446007Sthurlow 
2456007Sthurlow 	return (DCMD_OK);
2466007Sthurlow }
2476007Sthurlow 
2486007Sthurlow void
smbfs_node_help(void)249*11332SGordon.Ross@Sun.COM smbfs_node_help(void)
2506007Sthurlow {
2516007Sthurlow 	mdb_printf("Options:\n"
2526007Sthurlow 	    "  -v           be verbose when displaying smbnodes\n");
2536007Sthurlow }
2546007Sthurlow 
2556007Sthurlow static const mdb_dcmd_t dcmds[] = {
256*11332SGordon.Ross@Sun.COM 	{
257*11332SGordon.Ross@Sun.COM 		"smbfs_vfs", "?[-v]",
2586007Sthurlow 		"show smbfs-mounted vfs structs",
259*11332SGordon.Ross@Sun.COM 		smbfs_vfs_dcmd, smbfs_vfs_help
260*11332SGordon.Ross@Sun.COM 	},
261*11332SGordon.Ross@Sun.COM 	{
262*11332SGordon.Ross@Sun.COM 		"smbfs_node", "?[-v]",
263*11332SGordon.Ross@Sun.COM 		"given an smbmntinfo_t, list smbnodes",
264*11332SGordon.Ross@Sun.COM 		smbfs_node_dcmd, smbfs_node_help
265*11332SGordon.Ross@Sun.COM 	},
2666007Sthurlow 	{NULL}
2676007Sthurlow };
2686007Sthurlow 
2696007Sthurlow static const mdb_walker_t walkers[] = {
2706007Sthurlow 	{NULL}
2716007Sthurlow };
2726007Sthurlow 
2736007Sthurlow static const mdb_modinfo_t modinfo = {
2746007Sthurlow 	MDB_API_VERSION,
2756007Sthurlow 	dcmds,
2766007Sthurlow 	walkers
2776007Sthurlow };
2786007Sthurlow 
2796007Sthurlow const mdb_modinfo_t *
_mdb_init(void)2806007Sthurlow _mdb_init(void)
2816007Sthurlow {
2826007Sthurlow 	return (&modinfo);
2836007Sthurlow }
284