4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 #include <sys/mdb_modapi.h>
29 #include <sys/types.h>
30 #include <sys/refstr_impl.h>
31 #include <sys/vnode.h>
34 #include <smbfs/smbfs.h>
35 #include <smbfs/smbfs_node.h>
37 #define OPT_VERBOSE 0x0001 /* Be [-v]erbose in dcmd's */
40 * This macro lets us easily use both sizeof (typename)
41 * and the string-ified typename for the error message.
43 #define SMBFS_OBJ_FETCH(obj_addr, obj_type, dest, err) \
44 if (mdb_vread(dest, sizeof (obj_type), ((uintptr_t)obj_addr)) \
45 != sizeof (obj_type)) { \
46 mdb_warn("error reading "#obj_type" at %p", obj_addr); \
51 * We need to read in a private copy
52 * of every string we want to print out.
55 print_str(uintptr_t addr
)
58 int len
, mx
= sizeof (buf
) - 4;
60 if ((len
= mdb_readstr(buf
, sizeof (buf
), addr
)) <= 0) {
61 mdb_printf(" (%p)", addr
);
64 strcpy(&buf
[mx
], "...");
65 mdb_printf(" %s", buf
);
70 * Dcmd (and callback function) to print a summary of
71 * all "smbfs" entries in the VFS list.
74 typedef struct smbfs_vfs_cbdata
{
77 uintptr_t vfsops
; /* filter by vfs ops pointer */
78 smbmntinfo_t smi
; /* scratch space for smbfs_vfs_cb */
82 smbfs_vfs_cb(uintptr_t addr
, const void *data
, void *arg
)
84 const vfs_t
*vfs
= data
;
85 smbfs_vfs_cbdata_t
*cbd
= arg
;
88 /* Filter by matching smbfs ops vector. */
89 if (cbd
->vfsops
&& cbd
->vfsops
!= (uintptr_t)vfs
->vfs_op
) {
93 if (cbd
->printed_header
== 0) {
94 cbd
->printed_header
= 1;
95 mdb_printf("// vfs_t smbmntinfo_t mnt_path\n");
98 mdb_printf(" %-p", addr
); /* vfs_t */
99 mdb_printf(" %-p", (uintptr_t)vfs
->vfs_data
);
101 * Note: vfs_mntpt is a refstr_t.
102 * Advance to string member.
104 ta
= (uintptr_t)vfs
->vfs_mntpt
;
105 ta
+= OFFSETOF(struct refstr
, rs_string
);
109 if (cbd
->flags
& OPT_VERBOSE
) {
111 /* Don't fail the walk if this fails. */
112 if (mdb_vread(&cbd
->smi
, sizeof (cbd
->smi
),
113 (uintptr_t)vfs
->vfs_data
) == -1) {
114 mdb_warn("error reading smbmntinfo_t at %p",
115 (uintptr_t)vfs
->vfs_data
);
117 /* Interesting parts of smbmntinfo_t */
118 mdb_printf("smi_share: %p, smi_root: %p\n",
119 cbd
->smi
.smi_share
, cbd
->smi
.smi_root
);
128 smbfs_vfs_dcmd(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
130 smbfs_vfs_cbdata_t
*cbd
;
134 cbd
= mdb_zalloc(sizeof (*cbd
), UM_SLEEP
| UM_GC
);
137 * Get the ops address here, so things work
138 * even if the smbfs module is loaded later
139 * than this mdb module.
141 if (mdb_lookup_by_name("smbfs_vfsops", &sym
) != 0) {
142 mdb_warn("failed to find 'smbfs_vfsops'\n");
146 cbd
->vfsops
= sym
.st_value
;
148 if (mdb_getopts(argc
, argv
,
149 'v', MDB_OPT_SETBITS
, OPT_VERBOSE
, &cbd
->flags
,
154 if (!(flags
& DCMD_ADDRSPEC
)) {
155 if (mdb_walk("genunix`vfs", smbfs_vfs_cb
, cbd
)
157 mdb_warn("can't walk smbfs vfs");
163 vfs
= mdb_alloc(sizeof (*vfs
), UM_SLEEP
| UM_GC
);
164 SMBFS_OBJ_FETCH(addr
, vfs_t
, vfs
, DCMD_ERR
);
165 smbfs_vfs_cb(addr
, vfs
, cbd
);
173 "Display addresses of the mounted smbfs structures\n"
174 "and the pathname of the mountpoint\n"
176 " -v display details of the smbmntinfo\n");
180 * Dcmd (and callback function) to print a summary of
181 * all smbnodes in the node "hash" (cache) AVL tree.
184 typedef struct smbfs_node_cbdata
{
188 } smbfs_node_cbdata_t
;
191 smbfs_node_cb(uintptr_t addr
, const void *data
, void *arg
)
193 const smbnode_t
*np
= data
;
194 smbfs_node_cbdata_t
*cbd
= arg
;
196 if (cbd
->printed_header
== 0) {
197 cbd
->printed_header
= 1;
198 mdb_printf("// vnode smbnode rpath\n");
201 mdb_printf(" %-p", (uintptr_t)np
->r_vnode
);
202 mdb_printf(" %-p", addr
); /* smbnode */
203 print_str((uintptr_t)np
->n_rpath
);
206 if (cbd
->flags
& OPT_VERBOSE
) {
208 /* Don't fail the walk if this fails. */
209 if (mdb_vread(&cbd
->vn
, sizeof (cbd
->vn
),
210 (uintptr_t)np
->r_vnode
) == -1) {
211 mdb_warn("error reading vnode_t at %p",
212 (uintptr_t)np
->r_vnode
);
214 /* Interesting parts of vnode_t */
215 mdb_printf("v_type=%d v_count=%d",
216 cbd
->vn
.v_type
, cbd
->vn
.v_count
);
226 smbfs_node_dcmd(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
228 smbfs_node_cbdata_t
*cbd
;
230 cbd
= mdb_zalloc(sizeof (*cbd
), UM_SLEEP
| UM_GC
);
232 if (mdb_getopts(argc
, argv
,
233 'v', MDB_OPT_SETBITS
, OPT_VERBOSE
, &cbd
->flags
,
238 if (!(flags
& DCMD_ADDRSPEC
)) {
239 mdb_warn("expect an smbmntinfo_t addr");
242 addr
+= OFFSETOF(smbmntinfo_t
, smi_hash_avl
);
244 if (mdb_pwalk("genunix`avl", smbfs_node_cb
, cbd
, addr
) == -1) {
245 mdb_warn("cannot walk smbfs nodes");
253 smbfs_node_help(void)
255 mdb_printf("Options:\n"
256 " -v be verbose when displaying smbnodes\n");
259 static const mdb_dcmd_t dcmds
[] = {
261 "smbfs_vfs", "?[-v]",
262 "show smbfs-mounted vfs structs",
263 smbfs_vfs_dcmd
, smbfs_vfs_help
266 "smbfs_node", "?[-v]",
267 "given an smbmntinfo_t, list smbnodes",
268 smbfs_node_dcmd
, smbfs_node_help
273 static const mdb_walker_t walkers
[] = {
277 static const mdb_modinfo_t modinfo
= {
283 const mdb_modinfo_t
*