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