18f0e65c9SRick Macklem /*-
2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
3d63027b6SPedro F. Giffuni *
48f0e65c9SRick Macklem * Copyright (c) 2009 Robert N. M. Watson
58f0e65c9SRick Macklem * All rights reserved.
68f0e65c9SRick Macklem *
78f0e65c9SRick Macklem * This software was developed at the University of Cambridge Computer
88f0e65c9SRick Macklem * Laboratory with support from a grant from Google, Inc.
98f0e65c9SRick Macklem *
108f0e65c9SRick Macklem * Redistribution and use in source and binary forms, with or without
118f0e65c9SRick Macklem * modification, are permitted provided that the following conditions
128f0e65c9SRick Macklem * are met:
138f0e65c9SRick Macklem * 1. Redistributions of source code must retain the above copyright
148f0e65c9SRick Macklem * notice, this list of conditions and the following disclaimer.
158f0e65c9SRick Macklem * 2. Redistributions in binary form must reproduce the above copyright
168f0e65c9SRick Macklem * notice, this list of conditions and the following disclaimer in the
178f0e65c9SRick Macklem * documentation and/or other materials provided with the distribution.
188f0e65c9SRick Macklem *
198f0e65c9SRick Macklem * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
208f0e65c9SRick Macklem * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
218f0e65c9SRick Macklem * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
228f0e65c9SRick Macklem * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
238f0e65c9SRick Macklem * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
248f0e65c9SRick Macklem * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
258f0e65c9SRick Macklem * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
268f0e65c9SRick Macklem * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
278f0e65c9SRick Macklem * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
288f0e65c9SRick Macklem * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
298f0e65c9SRick Macklem * SUCH DAMAGE.
308f0e65c9SRick Macklem */
318f0e65c9SRick Macklem
328f0e65c9SRick Macklem #include <sys/param.h>
338f0e65c9SRick Macklem #include <sys/systm.h>
348f0e65c9SRick Macklem #include <sys/conf.h>
358f0e65c9SRick Macklem #include <sys/kernel.h>
368f0e65c9SRick Macklem #include <sys/malloc.h>
378f0e65c9SRick Macklem #include <sys/module.h>
388f0e65c9SRick Macklem
398f0e65c9SRick Macklem #include <sys/dtrace.h>
408f0e65c9SRick Macklem #include <sys/dtrace_bsd.h>
418f0e65c9SRick Macklem
428f0e65c9SRick Macklem #include <fs/nfs/nfsproto.h>
438f0e65c9SRick Macklem
448f0e65c9SRick Macklem #include <fs/nfsclient/nfs_kdtrace.h>
458f0e65c9SRick Macklem
468f0e65c9SRick Macklem /*
478f0e65c9SRick Macklem * dtnfscl is a DTrace provider that tracks the intent to perform RPCs
48a96c9b30SPedro F. Giffuni * in the NFS client, as well as access to and maintenance of the access and
498f0e65c9SRick Macklem * attribute caches. This is not quite the same as RPCs, because NFS may
508f0e65c9SRick Macklem * issue multiple RPC transactions in the event that authentication fails,
518f0e65c9SRick Macklem * there's a jukebox error, or none at all if the access or attribute cache
528f0e65c9SRick Macklem * hits. However, it cleanly represents the logical layer between RPC
538f0e65c9SRick Macklem * transmission and vnode/vfs operations, providing access to state linking
548f0e65c9SRick Macklem * the two.
558f0e65c9SRick Macklem */
568f0e65c9SRick Macklem
578f0e65c9SRick Macklem static int dtnfsclient_unload(void);
588f0e65c9SRick Macklem static void dtnfsclient_getargdesc(void *, dtrace_id_t, void *,
598f0e65c9SRick Macklem dtrace_argdesc_t *);
608f0e65c9SRick Macklem static void dtnfsclient_provide(void *, dtrace_probedesc_t *);
618f0e65c9SRick Macklem static void dtnfsclient_destroy(void *, dtrace_id_t, void *);
628f0e65c9SRick Macklem static void dtnfsclient_enable(void *, dtrace_id_t, void *);
638f0e65c9SRick Macklem static void dtnfsclient_disable(void *, dtrace_id_t, void *);
648f0e65c9SRick Macklem static void dtnfsclient_load(void *);
658f0e65c9SRick Macklem
668f0e65c9SRick Macklem static dtrace_pattr_t dtnfsclient_attr = {
678f0e65c9SRick Macklem { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
688f0e65c9SRick Macklem { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
698f0e65c9SRick Macklem { DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN },
708f0e65c9SRick Macklem { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
718f0e65c9SRick Macklem { DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON },
728f0e65c9SRick Macklem };
738f0e65c9SRick Macklem
748f0e65c9SRick Macklem /*
758f0e65c9SRick Macklem * Description of NFSv4, NFSv3 and (optional) NFSv2 probes for a procedure.
768f0e65c9SRick Macklem */
778f0e65c9SRick Macklem struct dtnfsclient_rpc {
788f0e65c9SRick Macklem char *nr_v4_name;
798f0e65c9SRick Macklem char *nr_v3_name; /* Or NULL if none. */
808f0e65c9SRick Macklem char *nr_v2_name; /* Or NULL if none. */
818f0e65c9SRick Macklem
828f0e65c9SRick Macklem /*
838f0e65c9SRick Macklem * IDs for the start and done cases, for NFSv2, NFSv3 and NFSv4.
848f0e65c9SRick Macklem */
858f0e65c9SRick Macklem uint32_t nr_v2_id_start, nr_v2_id_done;
868f0e65c9SRick Macklem uint32_t nr_v3_id_start, nr_v3_id_done;
878f0e65c9SRick Macklem uint32_t nr_v4_id_start, nr_v4_id_done;
888f0e65c9SRick Macklem };
898f0e65c9SRick Macklem
908f0e65c9SRick Macklem /*
918f0e65c9SRick Macklem * This table is indexed by NFSv3 procedure number, but also used for NFSv2
928f0e65c9SRick Macklem * procedure names and NFSv4 operations.
938f0e65c9SRick Macklem */
941f60bfd8SRick Macklem static struct dtnfsclient_rpc dtnfsclient_rpcs[NFSV41_NPROCS + 1] = {
958f0e65c9SRick Macklem { "null", "null", "null" },
968f0e65c9SRick Macklem { "getattr", "getattr", "getattr" },
978f0e65c9SRick Macklem { "setattr", "setattr", "setattr" },
988f0e65c9SRick Macklem { "lookup", "lookup", "lookup" },
998f0e65c9SRick Macklem { "access", "access", "noop" },
1008f0e65c9SRick Macklem { "readlink", "readlink", "readlink" },
1018f0e65c9SRick Macklem { "read", "read", "read" },
1028f0e65c9SRick Macklem { "write", "write", "write" },
1038f0e65c9SRick Macklem { "create", "create", "create" },
1048f0e65c9SRick Macklem { "mkdir", "mkdir", "mkdir" },
1058f0e65c9SRick Macklem { "symlink", "symlink", "symlink" },
1068f0e65c9SRick Macklem { "mknod", "mknod" },
1078f0e65c9SRick Macklem { "remove", "remove", "remove" },
1088f0e65c9SRick Macklem { "rmdir", "rmdir", "rmdir" },
1098f0e65c9SRick Macklem { "rename", "rename", "rename" },
1108f0e65c9SRick Macklem { "link", "link", "link" },
1118f0e65c9SRick Macklem { "readdir", "readdir", "readdir" },
1128f0e65c9SRick Macklem { "readdirplus", "readdirplus" },
1138f0e65c9SRick Macklem { "fsstat", "fsstat", "statfs" },
1148f0e65c9SRick Macklem { "fsinfo", "fsinfo" },
1158f0e65c9SRick Macklem { "pathconf", "pathconf" },
1168f0e65c9SRick Macklem { "commit", "commit" },
1178f0e65c9SRick Macklem { "lookupp" },
1188f0e65c9SRick Macklem { "setclientid" },
1198f0e65c9SRick Macklem { "setclientidcfrm" },
1208f0e65c9SRick Macklem { "lock" },
1218f0e65c9SRick Macklem { "locku" },
1228f0e65c9SRick Macklem { "open" },
1238f0e65c9SRick Macklem { "close" },
1248f0e65c9SRick Macklem { "openconfirm" },
1258f0e65c9SRick Macklem { "lockt" },
1268f0e65c9SRick Macklem { "opendowngrade" },
1278f0e65c9SRick Macklem { "renew" },
1288f0e65c9SRick Macklem { "putrootfh" },
1298f0e65c9SRick Macklem { "releaselckown" },
1308f0e65c9SRick Macklem { "delegreturn" },
1318f0e65c9SRick Macklem { "retdelegremove" },
1328f0e65c9SRick Macklem { "retdelegrename1" },
1338f0e65c9SRick Macklem { "retdelegrename2" },
1348f0e65c9SRick Macklem { "getacl" },
1358f0e65c9SRick Macklem { "setacl" },
1368f0e65c9SRick Macklem { "noop", "noop", "noop" }
1378f0e65c9SRick Macklem };
1388f0e65c9SRick Macklem
1398f0e65c9SRick Macklem /*
1408f0e65c9SRick Macklem * Module name strings.
1418f0e65c9SRick Macklem */
1428f0e65c9SRick Macklem static char *dtnfsclient_accesscache_str = "accesscache";
1438f0e65c9SRick Macklem static char *dtnfsclient_attrcache_str = "attrcache";
1448f0e65c9SRick Macklem static char *dtnfsclient_nfs2_str = "nfs2";
1458f0e65c9SRick Macklem static char *dtnfsclient_nfs3_str = "nfs3";
1468f0e65c9SRick Macklem static char *dtnfsclient_nfs4_str = "nfs4";
1478f0e65c9SRick Macklem
1488f0e65c9SRick Macklem /*
1498f0e65c9SRick Macklem * Function name strings.
1508f0e65c9SRick Macklem */
1518f0e65c9SRick Macklem static char *dtnfsclient_flush_str = "flush";
1528f0e65c9SRick Macklem static char *dtnfsclient_load_str = "load";
1538f0e65c9SRick Macklem static char *dtnfsclient_get_str = "get";
1548f0e65c9SRick Macklem
1558f0e65c9SRick Macklem /*
1568f0e65c9SRick Macklem * Name strings.
1578f0e65c9SRick Macklem */
1588f0e65c9SRick Macklem static char *dtnfsclient_done_str = "done";
1598f0e65c9SRick Macklem static char *dtnfsclient_hit_str = "hit";
1608f0e65c9SRick Macklem static char *dtnfsclient_miss_str = "miss";
1618f0e65c9SRick Macklem static char *dtnfsclient_start_str = "start";
1628f0e65c9SRick Macklem
1638f0e65c9SRick Macklem static dtrace_pops_t dtnfsclient_pops = {
16447f11baaSMark Johnston .dtps_provide = dtnfsclient_provide,
16547f11baaSMark Johnston .dtps_provide_module = NULL,
16647f11baaSMark Johnston .dtps_enable = dtnfsclient_enable,
16747f11baaSMark Johnston .dtps_disable = dtnfsclient_disable,
16847f11baaSMark Johnston .dtps_suspend = NULL,
16947f11baaSMark Johnston .dtps_resume = NULL,
17047f11baaSMark Johnston .dtps_getargdesc = dtnfsclient_getargdesc,
17147f11baaSMark Johnston .dtps_getargval = NULL,
17247f11baaSMark Johnston .dtps_usermode = NULL,
17347f11baaSMark Johnston .dtps_destroy = dtnfsclient_destroy
1748f0e65c9SRick Macklem };
1758f0e65c9SRick Macklem
1768f0e65c9SRick Macklem static dtrace_provider_id_t dtnfsclient_id;
1778f0e65c9SRick Macklem
1788f0e65c9SRick Macklem /*
1798f0e65c9SRick Macklem * When tracing on a procedure is enabled, the DTrace ID for an RPC event is
1808f0e65c9SRick Macklem * stored in one of these two NFS client-allocated arrays; 0 indicates that
1818f0e65c9SRick Macklem * the event is not being traced so probes should not be called.
1828f0e65c9SRick Macklem *
1831f60bfd8SRick Macklem * For simplicity, we allocate both v2, v3 and v4 arrays as NFSV41_NPROCS + 1,
1841f60bfd8SRick Macklem * and the v2, v3 arrays are simply sparse.
1858f0e65c9SRick Macklem */
1861f60bfd8SRick Macklem extern uint32_t nfscl_nfs2_start_probes[NFSV41_NPROCS + 1];
1871f60bfd8SRick Macklem extern uint32_t nfscl_nfs2_done_probes[NFSV41_NPROCS + 1];
1888f0e65c9SRick Macklem
1891f60bfd8SRick Macklem extern uint32_t nfscl_nfs3_start_probes[NFSV41_NPROCS + 1];
1901f60bfd8SRick Macklem extern uint32_t nfscl_nfs3_done_probes[NFSV41_NPROCS + 1];
1918f0e65c9SRick Macklem
1921f60bfd8SRick Macklem extern uint32_t nfscl_nfs4_start_probes[NFSV41_NPROCS + 1];
1931f60bfd8SRick Macklem extern uint32_t nfscl_nfs4_done_probes[NFSV41_NPROCS + 1];
1948f0e65c9SRick Macklem
1958f0e65c9SRick Macklem /*
1968f0e65c9SRick Macklem * Look up a DTrace probe ID to see if it's associated with a "done" event --
1978f0e65c9SRick Macklem * if so, we will return a fourth argument type of "int".
1988f0e65c9SRick Macklem */
1998f0e65c9SRick Macklem static int
dtnfs234_isdoneprobe(dtrace_id_t id)2008f0e65c9SRick Macklem dtnfs234_isdoneprobe(dtrace_id_t id)
2018f0e65c9SRick Macklem {
2028f0e65c9SRick Macklem int i;
2038f0e65c9SRick Macklem
2041f60bfd8SRick Macklem for (i = 0; i < NFSV41_NPROCS + 1; i++) {
2058f0e65c9SRick Macklem if (dtnfsclient_rpcs[i].nr_v4_id_done == id ||
2068f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v3_id_done == id ||
2078f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v2_id_done == id)
2088f0e65c9SRick Macklem return (1);
2098f0e65c9SRick Macklem }
2108f0e65c9SRick Macklem return (0);
2118f0e65c9SRick Macklem }
2128f0e65c9SRick Macklem
2138f0e65c9SRick Macklem static void
dtnfsclient_getargdesc(void * arg,dtrace_id_t id,void * parg,dtrace_argdesc_t * desc)2148f0e65c9SRick Macklem dtnfsclient_getargdesc(void *arg, dtrace_id_t id, void *parg,
2158f0e65c9SRick Macklem dtrace_argdesc_t *desc)
2168f0e65c9SRick Macklem {
2178f0e65c9SRick Macklem const char *p = NULL;
2188f0e65c9SRick Macklem
2198f0e65c9SRick Macklem if (id == nfscl_accesscache_flush_done_id ||
2208f0e65c9SRick Macklem id == nfscl_attrcache_flush_done_id ||
2218f0e65c9SRick Macklem id == nfscl_attrcache_get_miss_id) {
2228f0e65c9SRick Macklem switch (desc->dtargd_ndx) {
2238f0e65c9SRick Macklem case 0:
2248f0e65c9SRick Macklem p = "struct vnode *";
2258f0e65c9SRick Macklem break;
2268f0e65c9SRick Macklem default:
2278f0e65c9SRick Macklem desc->dtargd_ndx = DTRACE_ARGNONE;
2288f0e65c9SRick Macklem break;
2298f0e65c9SRick Macklem }
2308f0e65c9SRick Macklem } else if (id == nfscl_accesscache_get_hit_id ||
2318f0e65c9SRick Macklem id == nfscl_accesscache_get_miss_id) {
2328f0e65c9SRick Macklem switch (desc->dtargd_ndx) {
2338f0e65c9SRick Macklem case 0:
2348f0e65c9SRick Macklem p = "struct vnode *";
2358f0e65c9SRick Macklem break;
2368f0e65c9SRick Macklem case 1:
2378f0e65c9SRick Macklem p = "uid_t";
2388f0e65c9SRick Macklem break;
2398f0e65c9SRick Macklem case 2:
2408f0e65c9SRick Macklem p = "uint32_t";
2418f0e65c9SRick Macklem break;
2428f0e65c9SRick Macklem default:
2438f0e65c9SRick Macklem desc->dtargd_ndx = DTRACE_ARGNONE;
2448f0e65c9SRick Macklem break;
2458f0e65c9SRick Macklem }
2468f0e65c9SRick Macklem } else if (id == nfscl_accesscache_load_done_id) {
2478f0e65c9SRick Macklem switch (desc->dtargd_ndx) {
2488f0e65c9SRick Macklem case 0:
2498f0e65c9SRick Macklem p = "struct vnode *";
2508f0e65c9SRick Macklem break;
2518f0e65c9SRick Macklem case 1:
2528f0e65c9SRick Macklem p = "uid_t";
2538f0e65c9SRick Macklem break;
2548f0e65c9SRick Macklem case 2:
2558f0e65c9SRick Macklem p = "uint32_t";
2568f0e65c9SRick Macklem break;
2578f0e65c9SRick Macklem case 3:
2588f0e65c9SRick Macklem p = "int";
2598f0e65c9SRick Macklem break;
2608f0e65c9SRick Macklem default:
2618f0e65c9SRick Macklem desc->dtargd_ndx = DTRACE_ARGNONE;
2628f0e65c9SRick Macklem break;
2638f0e65c9SRick Macklem }
2648f0e65c9SRick Macklem } else if (id == nfscl_attrcache_get_hit_id) {
2658f0e65c9SRick Macklem switch (desc->dtargd_ndx) {
2668f0e65c9SRick Macklem case 0:
2678f0e65c9SRick Macklem p = "struct vnode *";
2688f0e65c9SRick Macklem break;
2698f0e65c9SRick Macklem case 1:
2708f0e65c9SRick Macklem p = "struct vattr *";
2718f0e65c9SRick Macklem break;
2728f0e65c9SRick Macklem default:
2738f0e65c9SRick Macklem desc->dtargd_ndx = DTRACE_ARGNONE;
2748f0e65c9SRick Macklem break;
2758f0e65c9SRick Macklem }
2768f0e65c9SRick Macklem } else if (id == nfscl_attrcache_load_done_id) {
2778f0e65c9SRick Macklem switch (desc->dtargd_ndx) {
2788f0e65c9SRick Macklem case 0:
2798f0e65c9SRick Macklem p = "struct vnode *";
2808f0e65c9SRick Macklem break;
2818f0e65c9SRick Macklem case 1:
2828f0e65c9SRick Macklem p = "struct vattr *";
2838f0e65c9SRick Macklem break;
2848f0e65c9SRick Macklem case 2:
2858f0e65c9SRick Macklem p = "int";
2868f0e65c9SRick Macklem break;
2878f0e65c9SRick Macklem default:
2888f0e65c9SRick Macklem desc->dtargd_ndx = DTRACE_ARGNONE;
2898f0e65c9SRick Macklem break;
2908f0e65c9SRick Macklem }
2918f0e65c9SRick Macklem } else {
2928f0e65c9SRick Macklem switch (desc->dtargd_ndx) {
2938f0e65c9SRick Macklem case 0:
2948f0e65c9SRick Macklem p = "struct vnode *";
2958f0e65c9SRick Macklem break;
2968f0e65c9SRick Macklem case 1:
2978f0e65c9SRick Macklem p = "struct mbuf *";
2988f0e65c9SRick Macklem break;
2998f0e65c9SRick Macklem case 2:
3008f0e65c9SRick Macklem p = "struct ucred *";
3018f0e65c9SRick Macklem break;
3028f0e65c9SRick Macklem case 3:
3038f0e65c9SRick Macklem p = "int";
3048f0e65c9SRick Macklem break;
3058f0e65c9SRick Macklem case 4:
3068f0e65c9SRick Macklem if (dtnfs234_isdoneprobe(id)) {
3078f0e65c9SRick Macklem p = "int";
3088f0e65c9SRick Macklem break;
3098f0e65c9SRick Macklem }
3108f0e65c9SRick Macklem /* FALLSTHROUGH */
3118f0e65c9SRick Macklem default:
3128f0e65c9SRick Macklem desc->dtargd_ndx = DTRACE_ARGNONE;
3138f0e65c9SRick Macklem break;
3148f0e65c9SRick Macklem }
3158f0e65c9SRick Macklem }
3168f0e65c9SRick Macklem if (p != NULL)
3178f0e65c9SRick Macklem strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native));
3188f0e65c9SRick Macklem }
3198f0e65c9SRick Macklem
3208f0e65c9SRick Macklem static void
dtnfsclient_provide(void * arg,dtrace_probedesc_t * desc)3218f0e65c9SRick Macklem dtnfsclient_provide(void *arg, dtrace_probedesc_t *desc)
3228f0e65c9SRick Macklem {
3238f0e65c9SRick Macklem int i;
3248f0e65c9SRick Macklem
3258f0e65c9SRick Macklem if (desc != NULL)
3268f0e65c9SRick Macklem return;
3278f0e65c9SRick Macklem
3288f0e65c9SRick Macklem /*
3298f0e65c9SRick Macklem * Register access cache probes.
3308f0e65c9SRick Macklem */
3318f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
3328f0e65c9SRick Macklem dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
3338f0e65c9SRick Macklem nfscl_accesscache_flush_done_id = dtrace_probe_create(
3348f0e65c9SRick Macklem dtnfsclient_id, dtnfsclient_accesscache_str,
3358f0e65c9SRick Macklem dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
3368f0e65c9SRick Macklem }
3378f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
3388f0e65c9SRick Macklem dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
3398f0e65c9SRick Macklem nfscl_accesscache_get_hit_id = dtrace_probe_create(
3408f0e65c9SRick Macklem dtnfsclient_id, dtnfsclient_accesscache_str,
3418f0e65c9SRick Macklem dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
3428f0e65c9SRick Macklem }
3438f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
3448f0e65c9SRick Macklem dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
3458f0e65c9SRick Macklem nfscl_accesscache_get_miss_id = dtrace_probe_create(
3468f0e65c9SRick Macklem dtnfsclient_id, dtnfsclient_accesscache_str,
3478f0e65c9SRick Macklem dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
3488f0e65c9SRick Macklem }
3498f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str,
3508f0e65c9SRick Macklem dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
3518f0e65c9SRick Macklem nfscl_accesscache_load_done_id = dtrace_probe_create(
3528f0e65c9SRick Macklem dtnfsclient_id, dtnfsclient_accesscache_str,
3538f0e65c9SRick Macklem dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
3548f0e65c9SRick Macklem }
3558f0e65c9SRick Macklem
3568f0e65c9SRick Macklem /*
3578f0e65c9SRick Macklem * Register attribute cache probes.
3588f0e65c9SRick Macklem */
3598f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
3608f0e65c9SRick Macklem dtnfsclient_flush_str, dtnfsclient_done_str) == 0) {
3618f0e65c9SRick Macklem nfscl_attrcache_flush_done_id = dtrace_probe_create(
3628f0e65c9SRick Macklem dtnfsclient_id, dtnfsclient_attrcache_str,
3638f0e65c9SRick Macklem dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL);
3648f0e65c9SRick Macklem }
3658f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
3668f0e65c9SRick Macklem dtnfsclient_get_str, dtnfsclient_hit_str) == 0) {
3678f0e65c9SRick Macklem nfscl_attrcache_get_hit_id = dtrace_probe_create(
3688f0e65c9SRick Macklem dtnfsclient_id, dtnfsclient_attrcache_str,
3698f0e65c9SRick Macklem dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL);
3708f0e65c9SRick Macklem }
3718f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
3728f0e65c9SRick Macklem dtnfsclient_get_str, dtnfsclient_miss_str) == 0) {
3738f0e65c9SRick Macklem nfscl_attrcache_get_miss_id = dtrace_probe_create(
3748f0e65c9SRick Macklem dtnfsclient_id, dtnfsclient_attrcache_str,
3758f0e65c9SRick Macklem dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL);
3768f0e65c9SRick Macklem }
3778f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str,
3788f0e65c9SRick Macklem dtnfsclient_load_str, dtnfsclient_done_str) == 0) {
3798f0e65c9SRick Macklem nfscl_attrcache_load_done_id = dtrace_probe_create(
3808f0e65c9SRick Macklem dtnfsclient_id, dtnfsclient_attrcache_str,
3818f0e65c9SRick Macklem dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL);
3828f0e65c9SRick Macklem }
3838f0e65c9SRick Macklem
3848f0e65c9SRick Macklem /*
3858f0e65c9SRick Macklem * Register NFSv2 RPC procedures; note sparseness check for each slot
3868f0e65c9SRick Macklem * in the NFSv3, NFSv4 procnum-indexed array.
3878f0e65c9SRick Macklem */
3881f60bfd8SRick Macklem for (i = 0; i < NFSV41_NPROCS + 1; i++) {
3898f0e65c9SRick Macklem if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
3908f0e65c9SRick Macklem dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
3918f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_start_str) ==
3928f0e65c9SRick Macklem 0) {
3938f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v2_id_start =
3948f0e65c9SRick Macklem dtrace_probe_create(dtnfsclient_id,
3958f0e65c9SRick Macklem dtnfsclient_nfs2_str,
3968f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v2_name,
3978f0e65c9SRick Macklem dtnfsclient_start_str, 0,
3988f0e65c9SRick Macklem &nfscl_nfs2_start_probes[i]);
3998f0e65c9SRick Macklem }
4008f0e65c9SRick Macklem if (dtnfsclient_rpcs[i].nr_v2_name != NULL &&
4018f0e65c9SRick Macklem dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str,
4028f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_done_str) ==
4038f0e65c9SRick Macklem 0) {
4048f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v2_id_done =
4058f0e65c9SRick Macklem dtrace_probe_create(dtnfsclient_id,
4068f0e65c9SRick Macklem dtnfsclient_nfs2_str,
4078f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v2_name,
4088f0e65c9SRick Macklem dtnfsclient_done_str, 0,
4098f0e65c9SRick Macklem &nfscl_nfs2_done_probes[i]);
4108f0e65c9SRick Macklem }
4118f0e65c9SRick Macklem }
4128f0e65c9SRick Macklem
4138f0e65c9SRick Macklem /*
4148f0e65c9SRick Macklem * Register NFSv3 RPC procedures; note sparseness check for each slot
4158f0e65c9SRick Macklem * in the NFSv4 procnum-indexed array.
4168f0e65c9SRick Macklem */
4171f60bfd8SRick Macklem for (i = 0; i < NFSV41_NPROCS + 1; i++) {
4188f0e65c9SRick Macklem if (dtnfsclient_rpcs[i].nr_v3_name != NULL &&
4198f0e65c9SRick Macklem dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
4208f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_start_str) ==
4218f0e65c9SRick Macklem 0) {
4228f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v3_id_start =
4238f0e65c9SRick Macklem dtrace_probe_create(dtnfsclient_id,
4248f0e65c9SRick Macklem dtnfsclient_nfs3_str,
4258f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v3_name,
4268f0e65c9SRick Macklem dtnfsclient_start_str, 0,
4278f0e65c9SRick Macklem &nfscl_nfs3_start_probes[i]);
4288f0e65c9SRick Macklem }
4298f0e65c9SRick Macklem if (dtnfsclient_rpcs[i].nr_v3_name != NULL &&
4308f0e65c9SRick Macklem dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str,
4318f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_done_str) ==
4328f0e65c9SRick Macklem 0) {
4338f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v3_id_done =
4348f0e65c9SRick Macklem dtrace_probe_create(dtnfsclient_id,
4358f0e65c9SRick Macklem dtnfsclient_nfs3_str,
4368f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v3_name,
4378f0e65c9SRick Macklem dtnfsclient_done_str, 0,
4388f0e65c9SRick Macklem &nfscl_nfs3_done_probes[i]);
4398f0e65c9SRick Macklem }
4408f0e65c9SRick Macklem }
4418f0e65c9SRick Macklem
4428f0e65c9SRick Macklem /*
4438f0e65c9SRick Macklem * Register NFSv4 RPC procedures.
4448f0e65c9SRick Macklem */
4451f60bfd8SRick Macklem for (i = 0; i < NFSV41_NPROCS + 1; i++) {
4468f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs4_str,
4478f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v4_name, dtnfsclient_start_str) ==
4488f0e65c9SRick Macklem 0) {
4498f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v4_id_start =
4508f0e65c9SRick Macklem dtrace_probe_create(dtnfsclient_id,
4518f0e65c9SRick Macklem dtnfsclient_nfs4_str,
4528f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v4_name,
4538f0e65c9SRick Macklem dtnfsclient_start_str, 0,
4548f0e65c9SRick Macklem &nfscl_nfs4_start_probes[i]);
4558f0e65c9SRick Macklem }
4568f0e65c9SRick Macklem if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs4_str,
4578f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v4_name, dtnfsclient_done_str) ==
4588f0e65c9SRick Macklem 0) {
4598f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v4_id_done =
4608f0e65c9SRick Macklem dtrace_probe_create(dtnfsclient_id,
4618f0e65c9SRick Macklem dtnfsclient_nfs4_str,
4628f0e65c9SRick Macklem dtnfsclient_rpcs[i].nr_v4_name,
4638f0e65c9SRick Macklem dtnfsclient_done_str, 0,
4648f0e65c9SRick Macklem &nfscl_nfs4_done_probes[i]);
4658f0e65c9SRick Macklem }
4668f0e65c9SRick Macklem }
4678f0e65c9SRick Macklem }
4688f0e65c9SRick Macklem
4698f0e65c9SRick Macklem static void
dtnfsclient_destroy(void * arg,dtrace_id_t id,void * parg)4708f0e65c9SRick Macklem dtnfsclient_destroy(void *arg, dtrace_id_t id, void *parg)
4718f0e65c9SRick Macklem {
4728f0e65c9SRick Macklem }
4738f0e65c9SRick Macklem
4748f0e65c9SRick Macklem static void
dtnfsclient_enable(void * arg,dtrace_id_t id,void * parg)4758f0e65c9SRick Macklem dtnfsclient_enable(void *arg, dtrace_id_t id, void *parg)
4768f0e65c9SRick Macklem {
4778f0e65c9SRick Macklem uint32_t *p = parg;
4788f0e65c9SRick Macklem void *f = dtrace_probe;
4798f0e65c9SRick Macklem
4808f0e65c9SRick Macklem if (id == nfscl_accesscache_flush_done_id)
4818f0e65c9SRick Macklem dtrace_nfscl_accesscache_flush_done_probe = f;
4828f0e65c9SRick Macklem else if (id == nfscl_accesscache_get_hit_id)
4838f0e65c9SRick Macklem dtrace_nfscl_accesscache_get_hit_probe = f;
4848f0e65c9SRick Macklem else if (id == nfscl_accesscache_get_miss_id)
4858f0e65c9SRick Macklem dtrace_nfscl_accesscache_get_miss_probe = f;
4868f0e65c9SRick Macklem else if (id == nfscl_accesscache_load_done_id)
4878f0e65c9SRick Macklem dtrace_nfscl_accesscache_load_done_probe = f;
4888f0e65c9SRick Macklem else if (id == nfscl_attrcache_flush_done_id)
4898f0e65c9SRick Macklem dtrace_nfscl_attrcache_flush_done_probe = f;
4908f0e65c9SRick Macklem else if (id == nfscl_attrcache_get_hit_id)
4918f0e65c9SRick Macklem dtrace_nfscl_attrcache_get_hit_probe = f;
4928f0e65c9SRick Macklem else if (id == nfscl_attrcache_get_miss_id)
4938f0e65c9SRick Macklem dtrace_nfscl_attrcache_get_miss_probe = f;
4948f0e65c9SRick Macklem else if (id == nfscl_attrcache_load_done_id)
4958f0e65c9SRick Macklem dtrace_nfscl_attrcache_load_done_probe = f;
4968f0e65c9SRick Macklem else
4978f0e65c9SRick Macklem *p = id;
4988f0e65c9SRick Macklem }
4998f0e65c9SRick Macklem
5008f0e65c9SRick Macklem static void
dtnfsclient_disable(void * arg,dtrace_id_t id,void * parg)5018f0e65c9SRick Macklem dtnfsclient_disable(void *arg, dtrace_id_t id, void *parg)
5028f0e65c9SRick Macklem {
5038f0e65c9SRick Macklem uint32_t *p = parg;
5048f0e65c9SRick Macklem
5058f0e65c9SRick Macklem if (id == nfscl_accesscache_flush_done_id)
5068f0e65c9SRick Macklem dtrace_nfscl_accesscache_flush_done_probe = NULL;
5078f0e65c9SRick Macklem else if (id == nfscl_accesscache_get_hit_id)
5088f0e65c9SRick Macklem dtrace_nfscl_accesscache_get_hit_probe = NULL;
5098f0e65c9SRick Macklem else if (id == nfscl_accesscache_get_miss_id)
5108f0e65c9SRick Macklem dtrace_nfscl_accesscache_get_miss_probe = NULL;
5118f0e65c9SRick Macklem else if (id == nfscl_accesscache_load_done_id)
5128f0e65c9SRick Macklem dtrace_nfscl_accesscache_load_done_probe = NULL;
5138f0e65c9SRick Macklem else if (id == nfscl_attrcache_flush_done_id)
5148f0e65c9SRick Macklem dtrace_nfscl_attrcache_flush_done_probe = NULL;
5158f0e65c9SRick Macklem else if (id == nfscl_attrcache_get_hit_id)
5168f0e65c9SRick Macklem dtrace_nfscl_attrcache_get_hit_probe = NULL;
5178f0e65c9SRick Macklem else if (id == nfscl_attrcache_get_miss_id)
5188f0e65c9SRick Macklem dtrace_nfscl_attrcache_get_miss_probe = NULL;
5198f0e65c9SRick Macklem else if (id == nfscl_attrcache_load_done_id)
5208f0e65c9SRick Macklem dtrace_nfscl_attrcache_load_done_probe = NULL;
5218f0e65c9SRick Macklem else
5228f0e65c9SRick Macklem *p = 0;
5238f0e65c9SRick Macklem }
5248f0e65c9SRick Macklem
5258f0e65c9SRick Macklem static void
dtnfsclient_load(void * dummy)5268f0e65c9SRick Macklem dtnfsclient_load(void *dummy)
5278f0e65c9SRick Macklem {
5288f0e65c9SRick Macklem
5298f0e65c9SRick Macklem if (dtrace_register("nfscl", &dtnfsclient_attr,
5308f0e65c9SRick Macklem DTRACE_PRIV_USER, NULL, &dtnfsclient_pops, NULL,
5318f0e65c9SRick Macklem &dtnfsclient_id) != 0)
5328f0e65c9SRick Macklem return;
5338f0e65c9SRick Macklem
5348f0e65c9SRick Macklem dtrace_nfscl_nfs234_start_probe =
5358f0e65c9SRick Macklem (dtrace_nfsclient_nfs23_start_probe_func_t)dtrace_probe;
5368f0e65c9SRick Macklem dtrace_nfscl_nfs234_done_probe =
5378f0e65c9SRick Macklem (dtrace_nfsclient_nfs23_done_probe_func_t)dtrace_probe;
5388f0e65c9SRick Macklem }
5398f0e65c9SRick Macklem
5408f0e65c9SRick Macklem static int
dtnfsclient_unload(void)54127609943SDimitry Andric dtnfsclient_unload(void)
5428f0e65c9SRick Macklem {
5438f0e65c9SRick Macklem
5448f0e65c9SRick Macklem dtrace_nfscl_nfs234_start_probe = NULL;
5458f0e65c9SRick Macklem dtrace_nfscl_nfs234_done_probe = NULL;
5468f0e65c9SRick Macklem
5478f0e65c9SRick Macklem return (dtrace_unregister(dtnfsclient_id));
5488f0e65c9SRick Macklem }
5498f0e65c9SRick Macklem
5508f0e65c9SRick Macklem static int
dtnfsclient_modevent(module_t mod __unused,int type,void * data __unused)5518f0e65c9SRick Macklem dtnfsclient_modevent(module_t mod __unused, int type, void *data __unused)
5528f0e65c9SRick Macklem {
5538f0e65c9SRick Macklem int error = 0;
5548f0e65c9SRick Macklem
5558f0e65c9SRick Macklem switch (type) {
5568f0e65c9SRick Macklem case MOD_LOAD:
5578f0e65c9SRick Macklem break;
5588f0e65c9SRick Macklem
5598f0e65c9SRick Macklem case MOD_UNLOAD:
5608f0e65c9SRick Macklem break;
5618f0e65c9SRick Macklem
5628f0e65c9SRick Macklem case MOD_SHUTDOWN:
5638f0e65c9SRick Macklem break;
5648f0e65c9SRick Macklem
5658f0e65c9SRick Macklem default:
5668f0e65c9SRick Macklem error = EOPNOTSUPP;
5678f0e65c9SRick Macklem break;
5688f0e65c9SRick Macklem }
5698f0e65c9SRick Macklem
5708f0e65c9SRick Macklem return (error);
5718f0e65c9SRick Macklem }
5728f0e65c9SRick Macklem
5738f0e65c9SRick Macklem SYSINIT(dtnfsclient_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
5748f0e65c9SRick Macklem dtnfsclient_load, NULL);
5758f0e65c9SRick Macklem SYSUNINIT(dtnfsclient_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY,
5768f0e65c9SRick Macklem dtnfsclient_unload, NULL);
5778f0e65c9SRick Macklem
5788f0e65c9SRick Macklem DEV_MODULE(dtnfscl, dtnfsclient_modevent, NULL);
5798f0e65c9SRick Macklem MODULE_VERSION(dtnfscl, 1);
5808f0e65c9SRick Macklem MODULE_DEPEND(dtnfscl, dtrace, 1, 1, 1);
5818f0e65c9SRick Macklem MODULE_DEPEND(dtnfscl, opensolaris, 1, 1, 1);
5828f0e65c9SRick Macklem MODULE_DEPEND(dtnfscl, nfscl, 1, 1, 1);
5838f0e65c9SRick Macklem MODULE_DEPEND(dtnfscl, nfscommon, 1, 1, 1);
584