nfs_clkdtrace.c revision 1.2.4.2 1 1.2.4.2 pgoyette /* $NetBSD: nfs_clkdtrace.c,v 1.2.4.2 2017/01/07 08:56:48 pgoyette Exp $ */
2 1.2.4.2 pgoyette /*-
3 1.2.4.2 pgoyette * Copyright (c) 2009 Robert N. M. Watson
4 1.2.4.2 pgoyette * All rights reserved.
5 1.2.4.2 pgoyette *
6 1.2.4.2 pgoyette * This software was developed at the University of Cambridge Computer
7 1.2.4.2 pgoyette * Laboratory with support from a grant from Google, Inc.
8 1.2.4.2 pgoyette *
9 1.2.4.2 pgoyette * Redistribution and use in source and binary forms, with or without
10 1.2.4.2 pgoyette * modification, are permitted provided that the following conditions
11 1.2.4.2 pgoyette * are met:
12 1.2.4.2 pgoyette * 1. Redistributions of source code must retain the above copyright
13 1.2.4.2 pgoyette * notice, this list of conditions and the following disclaimer.
14 1.2.4.2 pgoyette * 2. Redistributions in binary form must reproduce the above copyright
15 1.2.4.2 pgoyette * notice, this list of conditions and the following disclaimer in the
16 1.2.4.2 pgoyette * documentation and/or other materials provided with the distribution.
17 1.2.4.2 pgoyette *
18 1.2.4.2 pgoyette * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 1.2.4.2 pgoyette * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 1.2.4.2 pgoyette * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 1.2.4.2 pgoyette * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 1.2.4.2 pgoyette * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 1.2.4.2 pgoyette * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 1.2.4.2 pgoyette * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 1.2.4.2 pgoyette * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 1.2.4.2 pgoyette * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 1.2.4.2 pgoyette * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 1.2.4.2 pgoyette * SUCH DAMAGE.
29 1.2.4.2 pgoyette */
30 1.2.4.2 pgoyette
31 1.2.4.2 pgoyette #include <sys/cdefs.h>
32 1.2.4.2 pgoyette /* __FBSDID("FreeBSD: head/sys/fs/nfsclient/nfs_clkdtrace.c 298788 2016-04-29 16:07:25Z pfg "); */
33 1.2.4.2 pgoyette __RCSID("$NetBSD: nfs_clkdtrace.c,v 1.2.4.2 2017/01/07 08:56:48 pgoyette Exp $");
34 1.2.4.2 pgoyette
35 1.2.4.2 pgoyette #include <sys/param.h>
36 1.2.4.2 pgoyette #include <sys/systm.h>
37 1.2.4.2 pgoyette #include <sys/conf.h>
38 1.2.4.2 pgoyette #include <sys/kernel.h>
39 1.2.4.2 pgoyette #include <sys/malloc.h>
40 1.2.4.2 pgoyette #include <sys/module.h>
41 1.2.4.2 pgoyette
42 1.2.4.2 pgoyette #if 0
43 1.2.4.2 pgoyette #include <sys/dtrace.h>
44 1.2.4.2 pgoyette #endif
45 1.2.4.2 pgoyette
46 1.2.4.2 pgoyette #include <sys/dtrace_bsd.h>
47 1.2.4.2 pgoyette
48 1.2.4.2 pgoyette #include <fs/nfs/common/nfsproto.h>
49 1.2.4.2 pgoyette
50 1.2.4.2 pgoyette #include <fs/nfs/client/nfs_kdtrace.h>
51 1.2.4.2 pgoyette
52 1.2.4.2 pgoyette /*
53 1.2.4.2 pgoyette * dtnfscl is a DTrace provider that tracks the intent to perform RPCs
54 1.2.4.2 pgoyette * in the NFS client, as well as access to and maintenance of the access and
55 1.2.4.2 pgoyette * attribute caches. This is not quite the same as RPCs, because NFS may
56 1.2.4.2 pgoyette * issue multiple RPC transactions in the event that authentication fails,
57 1.2.4.2 pgoyette * there's a jukebox error, or none at all if the access or attribute cache
58 1.2.4.2 pgoyette * hits. However, it cleanly represents the logical layer between RPC
59 1.2.4.2 pgoyette * transmission and vnode/vfs operations, providing access to state linking
60 1.2.4.2 pgoyette * the two.
61 1.2.4.2 pgoyette */
62 1.2.4.2 pgoyette
63 1.2.4.2 pgoyette static int dtnfsclient_unload(void);
64 1.2.4.2 pgoyette static void dtnfsclient_getargdesc(void *, dtrace_id_t, void *,
65 1.2.4.2 pgoyette dtrace_argdesc_t *);
66 1.2.4.2 pgoyette static void dtnfsclient_provide(void *, dtrace_probedesc_t *);
67 1.2.4.2 pgoyette static void dtnfsclient_destroy(void *, dtrace_id_t, void *);
68 1.2.4.2 pgoyette static void dtnfsclient_enable(void *, dtrace_id_t, void *);
69 1.2.4.2 pgoyette static void dtnfsclient_disable(void *, dtrace_id_t, void *);
70 1.2.4.2 pgoyette static void dtnfsclient_load(void *);
71 1.2.4.2 pgoyette
72 1.2.4.2 pgoyette static dtrace_pattr_t dtnfsclient_attr = {
73 1.2.4.2 pgoyette { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
74 1.2.4.2 pgoyette { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
75 1.2.4.2 pgoyette { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
76 1.2.4.2 pgoyette { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
77 1.2.4.2 pgoyette { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
78 1.2.4.2 pgoyette };
79 1.2.4.2 pgoyette
80 1.2.4.2 pgoyette /*
81 1.2.4.2 pgoyette * Description of NFSv4, NFSv3 and (optional) NFSv2 probes for a procedure.
82 1.2.4.2 pgoyette */
83 1.2.4.2 pgoyette struct dtnfsclient_rpc {
84 1.2.4.2 pgoyette char *nr_v4_name;
85 1.2.4.2 pgoyette char *nr_v3_name; /* Or NULL if none. */
86 1.2.4.2 pgoyette char *nr_v2_name; /* Or NULL if none. */
87 1.2.4.2 pgoyette
88 1.2.4.2 pgoyette /*
89 1.2.4.2 pgoyette * IDs for the start and done cases, for NFSv2, NFSv3 and NFSv4.
90 1.2.4.2 pgoyette */
91 1.2.4.2 pgoyette uint32_t nr_v2_id_start, nr_v2_id_done;
92 1.2.4.2 pgoyette uint32_t nr_v3_id_start, nr_v3_id_done;
93 1.2.4.2 pgoyette uint32_t nr_v4_id_start, nr_v4_id_done;
94 1.2.4.2 pgoyette };
95 1.2.4.2 pgoyette
96 1.2.4.2 pgoyette /*
97 1.2.4.2 pgoyette * This table is indexed by NFSv3 procedure number, but also used for NFSv2
98 1.2.4.2 pgoyette * procedure names and NFSv4 operations.
99 1.2.4.2 pgoyette */
100 1.2.4.2 pgoyette static struct dtnfsclient_rpc dtnfsclient_rpcs[NFSV41_NPROCS + 1] = {
101 1.2.4.2 pgoyette { "null", "null", "null" },
102 1.2.4.2 pgoyette { "getattr", "getattr", "getattr" },
103 1.2.4.2 pgoyette { "setattr", "setattr", "setattr" },
104 1.2.4.2 pgoyette { "lookup", "lookup", "lookup" },
105 1.2.4.2 pgoyette { "access", "access", "noop" },
106 1.2.4.2 pgoyette { "readlink", "readlink", "readlink" },
107 1.2.4.2 pgoyette { "read", "read", "read" },
108 1.2.4.2 pgoyette { "write", "write", "write" },
109 1.2.4.2 pgoyette { "create", "create", "create" },
110 1.2.4.2 pgoyette { "mkdir", "mkdir", "mkdir" },
111 1.2.4.2 pgoyette { "symlink", "symlink", "symlink" },
112 1.2.4.2 pgoyette { "mknod", "mknod" },
113 1.2.4.2 pgoyette { "remove", "remove", "remove" },
114 1.2.4.2 pgoyette { "rmdir", "rmdir", "rmdir" },
115 1.2.4.2 pgoyette { "rename", "rename", "rename" },
116 1.2.4.2 pgoyette { "link", "link", "link" },
117 1.2.4.2 pgoyette { "readdir", "readdir", "readdir" },
118 1.2.4.2 pgoyette { "readdirplus", "readdirplus" },
119 1.2.4.2 pgoyette { "fsstat", "fsstat", "statfs" },
120 1.2.4.2 pgoyette { "fsinfo", "fsinfo" },
121 1.2.4.2 pgoyette { "pathconf", "pathconf" },
122 1.2.4.2 pgoyette { "commit", "commit" },
123 1.2.4.2 pgoyette { "lookupp" },
124 1.2.4.2 pgoyette { "setclientid" },
125 1.2.4.2 pgoyette { "setclientidcfrm" },
126 1.2.4.2 pgoyette { "lock" },
127 1.2.4.2 pgoyette { "locku" },
128 1.2.4.2 pgoyette { "open" },
129 1.2.4.2 pgoyette { "close" },
130 1.2.4.2 pgoyette { "openconfirm" },
131 1.2.4.2 pgoyette { "lockt" },
132 1.2.4.2 pgoyette { "opendowngrade" },
133 1.2.4.2 pgoyette { "renew" },
134 1.2.4.2 pgoyette { "putrootfh" },
135 1.2.4.2 pgoyette { "releaselckown" },
136 1.2.4.2 pgoyette { "delegreturn" },
137 1.2.4.2 pgoyette { "retdelegremove" },
138 1.2.4.2 pgoyette { "retdelegrename1" },
139 1.2.4.2 pgoyette { "retdelegrename2" },
140 1.2.4.2 pgoyette { "getacl" },
141 1.2.4.2 pgoyette { "setacl" },
142 1.2.4.2 pgoyette { "noop", "noop", "noop" }
143 1.2.4.2 pgoyette };
144 1.2.4.2 pgoyette
145 1.2.4.2 pgoyette /*
146 1.2.4.2 pgoyette * Module name strings.
147 1.2.4.2 pgoyette */
148 1.2.4.2 pgoyette static char *dtnfsclient_accesscache_str = "accesscache";
149 1.2.4.2 pgoyette static char *dtnfsclient_attrcache_str = "attrcache";
150 1.2.4.2 pgoyette static char *dtnfsclient_nfs2_str = "nfs2";
151 1.2.4.2 pgoyette static char *dtnfsclient_nfs3_str = "nfs3";
152 1.2.4.2 pgoyette static char *dtnfsclient_nfs4_str = "nfs4";
153 1.2.4.2 pgoyette
154 1.2.4.2 pgoyette /*
155 1.2.4.2 pgoyette * Function name strings.
156 1.2.4.2 pgoyette */
157 1.2.4.2 pgoyette static char *dtnfsclient_flush_str = "flush";
158 1.2.4.2 pgoyette static char *dtnfsclient_load_str = "load";
159 1.2.4.2 pgoyette static char *dtnfsclient_get_str = "get";
160 1.2.4.2 pgoyette
161 1.2.4.2 pgoyette /*
162 1.2.4.2 pgoyette * Name strings.
163 1.2.4.2 pgoyette */
164 1.2.4.2 pgoyette static char *dtnfsclient_done_str = "done";
165 1.2.4.2 pgoyette static char *dtnfsclient_hit_str = "hit";
166 1.2.4.2 pgoyette static char *dtnfsclient_miss_str = "miss";
167 1.2.4.2 pgoyette static char *dtnfsclient_start_str = "start";
168 1.2.4.2 pgoyette
169 1.2.4.2 pgoyette static dtrace_pops_t dtnfsclient_pops = {
170 1.2.4.2 pgoyette dtnfsclient_provide,
171 1.2.4.2 pgoyette NULL,
172 1.2.4.2 pgoyette dtnfsclient_enable,
173 1.2.4.2 pgoyette dtnfsclient_disable,
174 1.2.4.2 pgoyette NULL,
175 1.2.4.2 pgoyette NULL,
176 1.2.4.2 pgoyette dtnfsclient_getargdesc,
177 1.2.4.2 pgoyette NULL,
178 1.2.4.2 pgoyette NULL,
179 1.2.4.2 pgoyette dtnfsclient_destroy
180 1.2.4.2 pgoyette };
181 1.2.4.2 pgoyette
182 1.2.4.2 pgoyette static dtrace_provider_id_t dtnfsclient_id;
183 1.2.4.2 pgoyette
184 1.2.4.2 pgoyette /*
185 1.2.4.2 pgoyette * When tracing on a procedure is enabled, the DTrace ID for an RPC event is
186 1.2.4.2 pgoyette * stored in one of these two NFS client-allocated arrays; 0 indicates that
187 1.2.4.2 pgoyette * the event is not being traced so probes should not be called.
188 1.2.4.2 pgoyette *
189 1.2.4.2 pgoyette * For simplicity, we allocate both v2, v3 and v4 arrays as NFSV41_NPROCS + 1,
190 1.2.4.2 pgoyette * and the v2, v3 arrays are simply sparse.
191 1.2.4.2 pgoyette */
192 1.2.4.2 pgoyette extern uint32_t nfscl_nfs2_start_probes[NFSV41_NPROCS + 1];
193 1.2.4.2 pgoyette extern uint32_t nfscl_nfs2_done_probes[NFSV41_NPROCS + 1];
194 1.2.4.2 pgoyette
195 1.2.4.2 pgoyette extern uint32_t nfscl_nfs3_start_probes[NFSV41_NPROCS + 1];
196 1.2.4.2 pgoyette extern uint32_t nfscl_nfs3_done_probes[NFSV41_NPROCS + 1];
197 1.2.4.2 pgoyette
198 1.2.4.2 pgoyette extern uint32_t nfscl_nfs4_start_probes[NFSV41_NPROCS + 1];
199 1.2.4.2 pgoyette extern uint32_t nfscl_nfs4_done_probes[NFSV41_NPROCS + 1];
200 1.2.4.2 pgoyette
201 1.2.4.2 pgoyette /*
202 1.2.4.2 pgoyette * Look up a DTrace probe ID to see if it's associated with a "done" event --
203 1.2.4.2 pgoyette * if so, we will return a fourth argument type of "int".
204 1.2.4.2 pgoyette */
205 1.2.4.2 pgoyette static int
206 1.2.4.2 pgoyette dtnfs234_isdoneprobe(dtrace_id_t id)
207 1.2.4.2 pgoyette {
208 1.2.4.2 pgoyette int i;
209 1.2.4.2 pgoyette
210 1.2.4.2 pgoyette for (i = 0; i < NFSV41_NPROCS + 1; i++) {
211 1.2.4.2 pgoyette if (dtnfsclient_rpcs[i].nr_v4_id_done == id ||
212 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v3_id_done == id ||
213 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v2_id_done == id)
214 1.2.4.2 pgoyette return (1);
215 1.2.4.2 pgoyette }
216 1.2.4.2 pgoyette return (0);
217 1.2.4.2 pgoyette }
218 1.2.4.2 pgoyette
219 1.2.4.2 pgoyette static void
220 1.2.4.2 pgoyette dtnfsclient_getargdesc(void *arg, dtrace_id_t id, void *parg,
221 1.2.4.2 pgoyette dtrace_argdesc_t *desc)
222 1.2.4.2 pgoyette {
223 1.2.4.2 pgoyette const char *p = NULL;
224 1.2.4.2 pgoyette
225 1.2.4.2 pgoyette if (id == nfscl_accesscache_flush_done_id ||
226 1.2.4.2 pgoyette id == nfscl_attrcache_flush_done_id ||
227 1.2.4.2 pgoyette id == nfscl_attrcache_get_miss_id) {
228 1.2.4.2 pgoyette switch (desc->dtargd_ndx) {
229 1.2.4.2 pgoyette case 0:
230 1.2.4.2 pgoyette p = "struct vnode *";
231 1.2.4.2 pgoyette break;
232 1.2.4.2 pgoyette default:
233 1.2.4.2 pgoyette desc->dtargd_ndx = DTRACE_ARGNONE;
234 1.2.4.2 pgoyette break;
235 1.2.4.2 pgoyette }
236 1.2.4.2 pgoyette } else if (id == nfscl_accesscache_get_hit_id ||
237 1.2.4.2 pgoyette id == nfscl_accesscache_get_miss_id) {
238 1.2.4.2 pgoyette switch (desc->dtargd_ndx) {
239 1.2.4.2 pgoyette case 0:
240 1.2.4.2 pgoyette p = "struct vnode *";
241 1.2.4.2 pgoyette break;
242 1.2.4.2 pgoyette case 1:
243 1.2.4.2 pgoyette p = "uid_t";
244 1.2.4.2 pgoyette break;
245 1.2.4.2 pgoyette case 2:
246 1.2.4.2 pgoyette p = "uint32_t";
247 1.2.4.2 pgoyette break;
248 1.2.4.2 pgoyette default:
249 1.2.4.2 pgoyette desc->dtargd_ndx = DTRACE_ARGNONE;
250 1.2.4.2 pgoyette break;
251 1.2.4.2 pgoyette }
252 1.2.4.2 pgoyette } else if (id == nfscl_accesscache_load_done_id) {
253 1.2.4.2 pgoyette switch (desc->dtargd_ndx) {
254 1.2.4.2 pgoyette case 0:
255 1.2.4.2 pgoyette p = "struct vnode *";
256 1.2.4.2 pgoyette break;
257 1.2.4.2 pgoyette case 1:
258 1.2.4.2 pgoyette p = "uid_t";
259 1.2.4.2 pgoyette break;
260 1.2.4.2 pgoyette case 2:
261 1.2.4.2 pgoyette p = "uint32_t";
262 1.2.4.2 pgoyette break;
263 1.2.4.2 pgoyette case 3:
264 1.2.4.2 pgoyette p = "int";
265 1.2.4.2 pgoyette break;
266 1.2.4.2 pgoyette default:
267 1.2.4.2 pgoyette desc->dtargd_ndx = DTRACE_ARGNONE;
268 1.2.4.2 pgoyette break;
269 1.2.4.2 pgoyette }
270 1.2.4.2 pgoyette } else if (id == nfscl_attrcache_get_hit_id) {
271 1.2.4.2 pgoyette switch (desc->dtargd_ndx) {
272 1.2.4.2 pgoyette case 0:
273 1.2.4.2 pgoyette p = "struct vnode *";
274 1.2.4.2 pgoyette break;
275 1.2.4.2 pgoyette case 1:
276 1.2.4.2 pgoyette p = "struct vattr *";
277 1.2.4.2 pgoyette break;
278 1.2.4.2 pgoyette default:
279 1.2.4.2 pgoyette desc->dtargd_ndx = DTRACE_ARGNONE;
280 1.2.4.2 pgoyette break;
281 1.2.4.2 pgoyette }
282 1.2.4.2 pgoyette } else if (id == nfscl_attrcache_load_done_id) {
283 1.2.4.2 pgoyette switch (desc->dtargd_ndx) {
284 1.2.4.2 pgoyette case 0:
285 1.2.4.2 pgoyette p = "struct vnode *";
286 1.2.4.2 pgoyette break;
287 1.2.4.2 pgoyette case 1:
288 1.2.4.2 pgoyette p = "struct vattr *";
289 1.2.4.2 pgoyette break;
290 1.2.4.2 pgoyette case 2:
291 1.2.4.2 pgoyette p = "int";
292 1.2.4.2 pgoyette break;
293 1.2.4.2 pgoyette default:
294 1.2.4.2 pgoyette desc->dtargd_ndx = DTRACE_ARGNONE;
295 1.2.4.2 pgoyette break;
296 1.2.4.2 pgoyette }
297 1.2.4.2 pgoyette } else {
298 1.2.4.2 pgoyette switch (desc->dtargd_ndx) {
299 1.2.4.2 pgoyette case 0:
300 1.2.4.2 pgoyette p = "struct vnode *";
301 1.2.4.2 pgoyette break;
302 1.2.4.2 pgoyette case 1:
303 1.2.4.2 pgoyette p = "struct mbuf *";
304 1.2.4.2 pgoyette break;
305 1.2.4.2 pgoyette case 2:
306 1.2.4.2 pgoyette p = "struct ucred *";
307 1.2.4.2 pgoyette break;
308 1.2.4.2 pgoyette case 3:
309 1.2.4.2 pgoyette p = "int";
310 1.2.4.2 pgoyette break;
311 1.2.4.2 pgoyette case 4:
312 1.2.4.2 pgoyette if (dtnfs234_isdoneprobe(id)) {
313 1.2.4.2 pgoyette p = "int";
314 1.2.4.2 pgoyette break;
315 1.2.4.2 pgoyette }
316 1.2.4.2 pgoyette /* FALLSTHROUGH */
317 1.2.4.2 pgoyette default:
318 1.2.4.2 pgoyette desc->dtargd_ndx = DTRACE_ARGNONE;
319 1.2.4.2 pgoyette break;
320 1.2.4.2 pgoyette }
321 1.2.4.2 pgoyette }
322 1.2.4.2 pgoyette if (p != NULL)
323 1.2.4.2 pgoyette strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native));
324 1.2.4.2 pgoyette }
325 1.2.4.2 pgoyette
326 1.2.4.2 pgoyette static void
327 1.2.4.2 pgoyette dtnfsclient_provide(void *arg, dtrace_probedesc_t *desc)
328 1.2.4.2 pgoyette {
329 1.2.4.2 pgoyette int i;
330 1.2.4.2 pgoyette
331 1.2.4.2 pgoyette if (desc != NULL)
332 1.2.4.2 pgoyette return;
333 1.2.4.2 pgoyette
334 1.2.4.2 pgoyette /*
335 1.2.4.2 pgoyette * Register access cache probes.
336 1.2.4.2 pgoyette */
337 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
338 1.2.4.2 pgoyette dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
339 1.2.4.2 pgoyette nfscl_accesscache_flush_done_id = dtrace_probe_create(
340 1.2.4.2 pgoyette dtnfsclient_id, dtnfsclient_accesscache_str,
341 1.2.4.2 pgoyette dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
342 1.2.4.2 pgoyette }
343 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
344 1.2.4.2 pgoyette dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
345 1.2.4.2 pgoyette nfscl_accesscache_get_hit_id = dtrace_probe_create(
346 1.2.4.2 pgoyette dtnfsclient_id, dtnfsclient_accesscache_str,
347 1.2.4.2 pgoyette dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
348 1.2.4.2 pgoyette }
349 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
350 1.2.4.2 pgoyette dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
351 1.2.4.2 pgoyette nfscl_accesscache_get_miss_id = dtrace_probe_create(
352 1.2.4.2 pgoyette dtnfsclient_id, dtnfsclient_accesscache_str,
353 1.2.4.2 pgoyette dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
354 1.2.4.2 pgoyette }
355 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
356 1.2.4.2 pgoyette dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
357 1.2.4.2 pgoyette nfscl_accesscache_load_done_id = dtrace_probe_create(
358 1.2.4.2 pgoyette dtnfsclient_id, dtnfsclient_accesscache_str,
359 1.2.4.2 pgoyette dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
360 1.2.4.2 pgoyette }
361 1.2.4.2 pgoyette
362 1.2.4.2 pgoyette /*
363 1.2.4.2 pgoyette * Register attribute cache probes.
364 1.2.4.2 pgoyette */
365 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
366 1.2.4.2 pgoyette dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
367 1.2.4.2 pgoyette nfscl_attrcache_flush_done_id = dtrace_probe_create(
368 1.2.4.2 pgoyette dtnfsclient_id, dtnfsclient_attrcache_str,
369 1.2.4.2 pgoyette dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
370 1.2.4.2 pgoyette }
371 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
372 1.2.4.2 pgoyette dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
373 1.2.4.2 pgoyette nfscl_attrcache_get_hit_id = dtrace_probe_create(
374 1.2.4.2 pgoyette dtnfsclient_id, dtnfsclient_attrcache_str,
375 1.2.4.2 pgoyette dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
376 1.2.4.2 pgoyette }
377 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
378 1.2.4.2 pgoyette dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
379 1.2.4.2 pgoyette nfscl_attrcache_get_miss_id = dtrace_probe_create(
380 1.2.4.2 pgoyette dtnfsclient_id, dtnfsclient_attrcache_str,
381 1.2.4.2 pgoyette dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
382 1.2.4.2 pgoyette }
383 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
384 1.2.4.2 pgoyette dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
385 1.2.4.2 pgoyette nfscl_attrcache_load_done_id = dtrace_probe_create(
386 1.2.4.2 pgoyette dtnfsclient_id, dtnfsclient_attrcache_str,
387 1.2.4.2 pgoyette dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
388 1.2.4.2 pgoyette }
389 1.2.4.2 pgoyette
390 1.2.4.2 pgoyette /*
391 1.2.4.2 pgoyette * Register NFSv2 RPC procedures; note sparseness check for each slot
392 1.2.4.2 pgoyette * in the NFSv3, NFSv4 procnum-indexed array.
393 1.2.4.2 pgoyette */
394 1.2.4.2 pgoyette for (i = 0; i < NFSV41_NPROCS + 1; i++) {
395 1.2.4.2 pgoyette if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
396 1.2.4.2 pgoyette dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
397 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_start_str) ==
398 1.2.4.2 pgoyette 0) {
399 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v2_id_start =
400 1.2.4.2 pgoyette dtrace_probe_create(dtnfsclient_id,
401 1.2.4.2 pgoyette dtnfsclient_nfs2_str,
402 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v2_name,
403 1.2.4.2 pgoyette dtnfsclient_start_str, 0,
404 1.2.4.2 pgoyette &nfscl_nfs2_start_probes[i]);
405 1.2.4.2 pgoyette }
406 1.2.4.2 pgoyette if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
407 1.2.4.2 pgoyette dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
408 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_done_str) ==
409 1.2.4.2 pgoyette 0) {
410 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v2_id_done =
411 1.2.4.2 pgoyette dtrace_probe_create(dtnfsclient_id,
412 1.2.4.2 pgoyette dtnfsclient_nfs2_str,
413 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v2_name,
414 1.2.4.2 pgoyette dtnfsclient_done_str, 0,
415 1.2.4.2 pgoyette &nfscl_nfs2_done_probes[i]);
416 1.2.4.2 pgoyette }
417 1.2.4.2 pgoyette }
418 1.2.4.2 pgoyette
419 1.2.4.2 pgoyette /*
420 1.2.4.2 pgoyette * Register NFSv3 RPC procedures; note sparseness check for each slot
421 1.2.4.2 pgoyette * in the NFSv4 procnum-indexed array.
422 1.2.4.2 pgoyette */
423 1.2.4.2 pgoyette for (i = 0; i < NFSV41_NPROCS + 1; i++) {
424 1.2.4.2 pgoyette if (dtnfsclient_rpcs[i].nr_v3_name != NULL &&
425 1.2.4.2 pgoyette dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
426 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_start_str) ==
427 1.2.4.2 pgoyette 0) {
428 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v3_id_start =
429 1.2.4.2 pgoyette dtrace_probe_create(dtnfsclient_id,
430 1.2.4.2 pgoyette dtnfsclient_nfs3_str,
431 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v3_name,
432 1.2.4.2 pgoyette dtnfsclient_start_str, 0,
433 1.2.4.2 pgoyette &nfscl_nfs3_start_probes[i]);
434 1.2.4.2 pgoyette }
435 1.2.4.2 pgoyette if (dtnfsclient_rpcs[i].nr_v3_name != NULL &&
436 1.2.4.2 pgoyette dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
437 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_done_str) ==
438 1.2.4.2 pgoyette 0) {
439 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v3_id_done =
440 1.2.4.2 pgoyette dtrace_probe_create(dtnfsclient_id,
441 1.2.4.2 pgoyette dtnfsclient_nfs3_str,
442 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v3_name,
443 1.2.4.2 pgoyette dtnfsclient_done_str, 0,
444 1.2.4.2 pgoyette &nfscl_nfs3_done_probes[i]);
445 1.2.4.2 pgoyette }
446 1.2.4.2 pgoyette }
447 1.2.4.2 pgoyette
448 1.2.4.2 pgoyette /*
449 1.2.4.2 pgoyette * Register NFSv4 RPC procedures.
450 1.2.4.2 pgoyette */
451 1.2.4.2 pgoyette for (i = 0; i < NFSV41_NPROCS + 1; i++) {
452 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs4_str,
453 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v4_name, dtnfsclient_start_str) ==
454 1.2.4.2 pgoyette 0) {
455 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v4_id_start =
456 1.2.4.2 pgoyette dtrace_probe_create(dtnfsclient_id,
457 1.2.4.2 pgoyette dtnfsclient_nfs4_str,
458 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v4_name,
459 1.2.4.2 pgoyette dtnfsclient_start_str, 0,
460 1.2.4.2 pgoyette &nfscl_nfs4_start_probes[i]);
461 1.2.4.2 pgoyette }
462 1.2.4.2 pgoyette if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs4_str,
463 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v4_name, dtnfsclient_done_str) ==
464 1.2.4.2 pgoyette 0) {
465 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v4_id_done =
466 1.2.4.2 pgoyette dtrace_probe_create(dtnfsclient_id,
467 1.2.4.2 pgoyette dtnfsclient_nfs4_str,
468 1.2.4.2 pgoyette dtnfsclient_rpcs[i].nr_v4_name,
469 1.2.4.2 pgoyette dtnfsclient_done_str, 0,
470 1.2.4.2 pgoyette &nfscl_nfs4_done_probes[i]);
471 1.2.4.2 pgoyette }
472 1.2.4.2 pgoyette }
473 1.2.4.2 pgoyette }
474 1.2.4.2 pgoyette
475 1.2.4.2 pgoyette static void
476 1.2.4.2 pgoyette dtnfsclient_destroy(void *arg, dtrace_id_t id, void *parg)
477 1.2.4.2 pgoyette {
478 1.2.4.2 pgoyette }
479 1.2.4.2 pgoyette
480 1.2.4.2 pgoyette static void
481 1.2.4.2 pgoyette dtnfsclient_enable(void *arg, dtrace_id_t id, void *parg)
482 1.2.4.2 pgoyette {
483 1.2.4.2 pgoyette uint32_t *p = parg;
484 1.2.4.2 pgoyette void *f = dtrace_probe;
485 1.2.4.2 pgoyette
486 1.2.4.2 pgoyette if (id == nfscl_accesscache_flush_done_id)
487 1.2.4.2 pgoyette dtrace_nfscl_accesscache_flush_done_probe = f;
488 1.2.4.2 pgoyette else if (id == nfscl_accesscache_get_hit_id)
489 1.2.4.2 pgoyette dtrace_nfscl_accesscache_get_hit_probe = f;
490 1.2.4.2 pgoyette else if (id == nfscl_accesscache_get_miss_id)
491 1.2.4.2 pgoyette dtrace_nfscl_accesscache_get_miss_probe = f;
492 1.2.4.2 pgoyette else if (id == nfscl_accesscache_load_done_id)
493 1.2.4.2 pgoyette dtrace_nfscl_accesscache_load_done_probe = f;
494 1.2.4.2 pgoyette else if (id == nfscl_attrcache_flush_done_id)
495 1.2.4.2 pgoyette dtrace_nfscl_attrcache_flush_done_probe = f;
496 1.2.4.2 pgoyette else if (id == nfscl_attrcache_get_hit_id)
497 1.2.4.2 pgoyette dtrace_nfscl_attrcache_get_hit_probe = f;
498 1.2.4.2 pgoyette else if (id == nfscl_attrcache_get_miss_id)
499 1.2.4.2 pgoyette dtrace_nfscl_attrcache_get_miss_probe = f;
500 1.2.4.2 pgoyette else if (id == nfscl_attrcache_load_done_id)
501 1.2.4.2 pgoyette dtrace_nfscl_attrcache_load_done_probe = f;
502 1.2.4.2 pgoyette else
503 1.2.4.2 pgoyette *p = id;
504 1.2.4.2 pgoyette }
505 1.2.4.2 pgoyette
506 1.2.4.2 pgoyette static void
507 1.2.4.2 pgoyette dtnfsclient_disable(void *arg, dtrace_id_t id, void *parg)
508 1.2.4.2 pgoyette {
509 1.2.4.2 pgoyette uint32_t *p = parg;
510 1.2.4.2 pgoyette
511 1.2.4.2 pgoyette if (id == nfscl_accesscache_flush_done_id)
512 1.2.4.2 pgoyette dtrace_nfscl_accesscache_flush_done_probe = NULL;
513 1.2.4.2 pgoyette else if (id == nfscl_accesscache_get_hit_id)
514 1.2.4.2 pgoyette dtrace_nfscl_accesscache_get_hit_probe = NULL;
515 1.2.4.2 pgoyette else if (id == nfscl_accesscache_get_miss_id)
516 1.2.4.2 pgoyette dtrace_nfscl_accesscache_get_miss_probe = NULL;
517 1.2.4.2 pgoyette else if (id == nfscl_accesscache_load_done_id)
518 1.2.4.2 pgoyette dtrace_nfscl_accesscache_load_done_probe = NULL;
519 1.2.4.2 pgoyette else if (id == nfscl_attrcache_flush_done_id)
520 1.2.4.2 pgoyette dtrace_nfscl_attrcache_flush_done_probe = NULL;
521 1.2.4.2 pgoyette else if (id == nfscl_attrcache_get_hit_id)
522 1.2.4.2 pgoyette dtrace_nfscl_attrcache_get_hit_probe = NULL;
523 1.2.4.2 pgoyette else if (id == nfscl_attrcache_get_miss_id)
524 1.2.4.2 pgoyette dtrace_nfscl_attrcache_get_miss_probe = NULL;
525 1.2.4.2 pgoyette else if (id == nfscl_attrcache_load_done_id)
526 1.2.4.2 pgoyette dtrace_nfscl_attrcache_load_done_probe = NULL;
527 1.2.4.2 pgoyette else
528 1.2.4.2 pgoyette *p = 0;
529 1.2.4.2 pgoyette }
530 1.2.4.2 pgoyette
531 1.2.4.2 pgoyette static void
532 1.2.4.2 pgoyette dtnfsclient_load(void *dummy)
533 1.2.4.2 pgoyette {
534 1.2.4.2 pgoyette
535 1.2.4.2 pgoyette if (dtrace_register("nfscl", &dtnfsclient_attr,
536 1.2.4.2 pgoyette DTRACE_PRIV_USER, NULL, &dtnfsclient_pops, NULL,
537 1.2.4.2 pgoyette &dtnfsclient_id) != 0)
538 1.2.4.2 pgoyette return;
539 1.2.4.2 pgoyette
540 1.2.4.2 pgoyette dtrace_nfscl_nfs234_start_probe =
541 1.2.4.2 pgoyette (dtrace_nfsclient_nfs23_start_probe_func_t)dtrace_probe;
542 1.2.4.2 pgoyette dtrace_nfscl_nfs234_done_probe =
543 1.2.4.2 pgoyette (dtrace_nfsclient_nfs23_done_probe_func_t)dtrace_probe;
544 1.2.4.2 pgoyette }
545 1.2.4.2 pgoyette
546 1.2.4.2 pgoyette
547 1.2.4.2 pgoyette static int
548 1.2.4.2 pgoyette dtnfsclient_unload()
549 1.2.4.2 pgoyette {
550 1.2.4.2 pgoyette
551 1.2.4.2 pgoyette dtrace_nfscl_nfs234_start_probe = NULL;
552 1.2.4.2 pgoyette dtrace_nfscl_nfs234_done_probe = NULL;
553 1.2.4.2 pgoyette
554 1.2.4.2 pgoyette return (dtrace_unregister(dtnfsclient_id));
555 1.2.4.2 pgoyette }
556 1.2.4.2 pgoyette
557 1.2.4.2 pgoyette static int
558 1.2.4.2 pgoyette dtnfsclient_modevent(module_t mod __unused, int type, void *data __unused)
559 1.2.4.2 pgoyette {
560 1.2.4.2 pgoyette int error = 0;
561 1.2.4.2 pgoyette
562 1.2.4.2 pgoyette switch (type) {
563 1.2.4.2 pgoyette case MOD_LOAD:
564 1.2.4.2 pgoyette break;
565 1.2.4.2 pgoyette
566 1.2.4.2 pgoyette case MOD_UNLOAD:
567 1.2.4.2 pgoyette break;
568 1.2.4.2 pgoyette
569 1.2.4.2 pgoyette case MOD_SHUTDOWN:
570 1.2.4.2 pgoyette break;
571 1.2.4.2 pgoyette
572 1.2.4.2 pgoyette default:
573 1.2.4.2 pgoyette error = EOPNOTSUPP;
574 1.2.4.2 pgoyette break;
575 1.2.4.2 pgoyette }
576 1.2.4.2 pgoyette
577 1.2.4.2 pgoyette return (error);
578 1.2.4.2 pgoyette }
579 1.2.4.2 pgoyette
580 1.2.4.2 pgoyette SYSINIT(dtnfsclient_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
581 1.2.4.2 pgoyette dtnfsclient_load, NULL);
582 1.2.4.2 pgoyette SYSUNINIT(dtnfsclient_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
583 1.2.4.2 pgoyette dtnfsclient_unload, NULL);
584 1.2.4.2 pgoyette
585 1.2.4.2 pgoyette DEV_MODULE(dtnfscl, dtnfsclient_modevent, NULL);
586 1.2.4.2 pgoyette MODULE_VERSION(dtnfscl, 1);
587 1.2.4.2 pgoyette MODULE_DEPEND(dtnfscl, dtrace, 1, 1, 1);
588 1.2.4.2 pgoyette MODULE_DEPEND(dtnfscl, opensolaris, 1, 1, 1);
589 1.2.4.2 pgoyette MODULE_DEPEND(dtnfscl, nfscl, 1, 1, 1);
590 1.2.4.2 pgoyette MODULE_DEPEND(dtnfscl, nfscommon, 1, 1, 1);
591