diff options
Diffstat (limited to 'sys/nfsclient/nfs_kdtrace.c')
-rw-r--r-- | sys/nfsclient/nfs_kdtrace.c | 542 |
1 files changed, 0 insertions, 542 deletions
diff --git a/sys/nfsclient/nfs_kdtrace.c b/sys/nfsclient/nfs_kdtrace.c deleted file mode 100644 index 429dbc3..0000000 --- a/sys/nfsclient/nfs_kdtrace.c +++ /dev/null @@ -1,542 +0,0 @@ -/*- - * Copyright (c) 2009 Robert N. M. Watson - * All rights reserved. - * - * This software was developed at the University of Cambridge Computer - * Laboratory with support from a grant from Google, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/conf.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/module.h> - -#include <sys/dtrace.h> -#include <sys/dtrace_bsd.h> - -#include <nfs/nfsproto.h> - -/* - * dtnfsclient is a DTrace provider that tracks the intent to perform RPCs - * in the NFS client, as well as acess to and maintenance of the access and - * attribute caches. This is not quite the same as RPCs, because NFS may - * issue multiple RPC transactions in the event that authentication fails, - * there's a jukebox error, or none at all if the access or attribute cache - * hits. However, it cleanly represents the logical layer between RPC - * transmission and vnode/vfs operations, providing access to state linking - * the two. - */ - -static int dtnfsclient_unload(void); -static void dtnfsclient_getargdesc(void *, dtrace_id_t, void *, - dtrace_argdesc_t *); -static void dtnfsclient_provide(void *, dtrace_probedesc_t *); -static void dtnfsclient_destroy(void *, dtrace_id_t, void *); -static void dtnfsclient_enable(void *, dtrace_id_t, void *); -static void dtnfsclient_disable(void *, dtrace_id_t, void *); -static void dtnfsclient_load(void *); - -static dtrace_pattr_t dtnfsclient_attr = { -{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }, -{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, -{ DTRACE_STABILITY_PRIVATE, DTRACE_STABILITY_PRIVATE, DTRACE_CLASS_UNKNOWN }, -{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }, -{ DTRACE_STABILITY_STABLE, DTRACE_STABILITY_STABLE, DTRACE_CLASS_COMMON }, -}; - -/* - * Description of NFSv3 and (optional) NFSv2 probes for a procedure. - */ -struct dtnfsclient_rpc { - char *nr_v3_name; - char *nr_v2_name; /* Or NULL if none. */ - - /* - * IDs for the start and done cases, for both NFSv2 and NFSv3. - */ - uint32_t nr_v2_id_start, nr_v2_id_done; - uint32_t nr_v3_id_start, nr_v3_id_done; -}; - -/* - * This table is indexed by NFSv3 procedure number, but also used for NFSv2 - * procedure names. - */ -static struct dtnfsclient_rpc dtnfsclient_rpcs[NFS_NPROCS] = { - { "null", "null" }, - { "getattr", "getattr" }, - { "setattr", "setattr" }, - { "lookup", "lookup" }, - { "access" }, - { "readlink", "readlink" }, - { "read", "read" }, - { "write", "write" }, - { "create", "create" }, - { "mkdir", "mkdir" }, - { "symlink", "symlink" }, - { "mknod" }, - { "remove", "remove" }, - { "rmdir", "rmdir" }, - { "rename", "rename" }, - { "link", "link" }, - { "readdir", "readdir" }, - { "readdirplus" }, - { "fsstat", "statfs" }, - { "fsinfo" }, - { "pathconf" }, - { "commit" }, - { "noop" }, -}; - -/* - * Module name strings. - */ -static char *dtnfsclient_accesscache_str = "accesscache"; -static char *dtnfsclient_attrcache_str = "attrcache"; -static char *dtnfsclient_nfs2_str = "nfs2"; -static char *dtnfsclient_nfs3_str = "nfs3"; - -/* - * Function name strings. - */ -static char *dtnfsclient_flush_str = "flush"; -static char *dtnfsclient_load_str = "load"; -static char *dtnfsclient_get_str = "get"; - -/* - * Name strings. - */ -static char *dtnfsclient_done_str = "done"; -static char *dtnfsclient_hit_str = "hit"; -static char *dtnfsclient_miss_str = "miss"; -static char *dtnfsclient_start_str = "start"; - -static dtrace_pops_t dtnfsclient_pops = { - dtnfsclient_provide, - NULL, - dtnfsclient_enable, - dtnfsclient_disable, - NULL, - NULL, - dtnfsclient_getargdesc, - NULL, - NULL, - dtnfsclient_destroy -}; - -static dtrace_provider_id_t dtnfsclient_id; - -/* - * Most probes are generated from the above RPC table, but for access and - * attribute caches, we have specific IDs we recognize and handle specially - * in various spots. - */ -extern uint32_t nfsclient_accesscache_flush_done_id; -extern uint32_t nfsclient_accesscache_get_hit_id; -extern uint32_t nfsclient_accesscache_get_miss_id; -extern uint32_t nfsclient_accesscache_load_done_id; - -extern uint32_t nfsclient_attrcache_flush_done_id; -extern uint32_t nfsclient_attrcache_get_hit_id; -extern uint32_t nfsclient_attrcache_get_miss_id; -extern uint32_t nfsclient_attrcache_load_done_id; - -/* - * When tracing on a procedure is enabled, the DTrace ID for an RPC event is - * stored in one of these two NFS client-allocated arrays; 0 indicates that - * the event is not being traced so probes should not be called. - * - * For simplicity, we allocate both v2 and v3 arrays as NFS_NPROCS, and the - * v2 array is simply sparse. - */ -extern uint32_t nfsclient_nfs2_start_probes[NFS_NPROCS]; -extern uint32_t nfsclient_nfs2_done_probes[NFS_NPROCS]; - -extern uint32_t nfsclient_nfs3_start_probes[NFS_NPROCS]; -extern uint32_t nfsclient_nfs3_done_probes[NFS_NPROCS]; - -/* - * Look up a DTrace probe ID to see if it's associated with a "done" event -- - * if so, we will return a fourth argument type of "int". - */ -static int -dtnfs23_isdoneprobe(dtrace_id_t id) -{ - int i; - - for (i = 0; i < NFS_NPROCS; i++) { - if (dtnfsclient_rpcs[i].nr_v3_id_done == id || - dtnfsclient_rpcs[i].nr_v2_id_done == id) - return (1); - } - return (0); -} - -static void -dtnfsclient_getargdesc(void *arg, dtrace_id_t id, void *parg, - dtrace_argdesc_t *desc) -{ - const char *p = NULL; - - if (id == nfsclient_accesscache_flush_done_id || - id == nfsclient_attrcache_flush_done_id || - id == nfsclient_attrcache_get_miss_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else if (id == nfsclient_accesscache_get_hit_id || - id == nfsclient_accesscache_get_miss_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "uid_t"; - break; - case 2: - p = "uint32_t"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else if (id == nfsclient_accesscache_load_done_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "uid_t"; - break; - case 2: - p = "uint32_t"; - break; - case 3: - p = "int"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else if (id == nfsclient_attrcache_get_hit_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "struct vattr *"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else if (id == nfsclient_attrcache_load_done_id) { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "struct vattr *"; - break; - case 2: - p = "int"; - break; - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } else { - switch (desc->dtargd_ndx) { - case 0: - p = "struct vnode *"; - break; - case 1: - p = "struct mbuf *"; - break; - case 2: - p = "struct ucred *"; - break; - case 3: - p = "int"; - break; - case 4: - if (dtnfs23_isdoneprobe(id)) { - p = "int"; - break; - } - /* FALLSTHROUGH */ - default: - desc->dtargd_ndx = DTRACE_ARGNONE; - break; - } - } - if (p != NULL) - strlcpy(desc->dtargd_native, p, sizeof(desc->dtargd_native)); -} - -static void -dtnfsclient_provide(void *arg, dtrace_probedesc_t *desc) -{ - int i; - - if (desc != NULL) - return; - - /* - * Register access cache probes. - */ - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_flush_str, dtnfsclient_done_str) == 0) { - nfsclient_accesscache_flush_done_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_get_str, dtnfsclient_hit_str) == 0) { - nfsclient_accesscache_get_hit_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_get_str, dtnfsclient_miss_str) == 0) { - nfsclient_accesscache_get_miss_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_load_str, dtnfsclient_done_str) == 0) { - nfsclient_accesscache_load_done_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_accesscache_str, - dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL); - } - - /* - * Register attribute cache probes. - */ - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_flush_str, dtnfsclient_done_str) == 0) { - nfsclient_attrcache_flush_done_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_flush_str, dtnfsclient_done_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_get_str, dtnfsclient_hit_str) == 0) { - nfsclient_attrcache_get_hit_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_get_str, dtnfsclient_hit_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_get_str, dtnfsclient_miss_str) == 0) { - nfsclient_attrcache_get_miss_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_get_str, dtnfsclient_miss_str, 0, NULL); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_load_str, dtnfsclient_done_str) == 0) { - nfsclient_attrcache_load_done_id = dtrace_probe_create( - dtnfsclient_id, dtnfsclient_attrcache_str, - dtnfsclient_load_str, dtnfsclient_done_str, 0, NULL); - } - - /* - * Register NFSv2 RPC procedures; note sparseness check for each slot - * in the NFSv3 procnum-indexed array. - */ - for (i = 0; i < NFS_NPROCS; i++) { - if (dtnfsclient_rpcs[i].nr_v2_name != NULL && - dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str, - dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_start_str) == - 0) { - dtnfsclient_rpcs[i].nr_v2_id_start = - dtrace_probe_create(dtnfsclient_id, - dtnfsclient_nfs2_str, - dtnfsclient_rpcs[i].nr_v2_name, - dtnfsclient_start_str, 0, - &nfsclient_nfs2_start_probes[i]); - } - if (dtnfsclient_rpcs[i].nr_v2_name != NULL && - dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs2_str, - dtnfsclient_rpcs[i].nr_v2_name, dtnfsclient_done_str) == - 0) { - dtnfsclient_rpcs[i].nr_v2_id_done = - dtrace_probe_create(dtnfsclient_id, - dtnfsclient_nfs2_str, - dtnfsclient_rpcs[i].nr_v2_name, - dtnfsclient_done_str, 0, - &nfsclient_nfs2_done_probes[i]); - } - } - - /* - * Register NFSv3 RPC procedures. - */ - for (i = 0; i < NFS_NPROCS; i++) { - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str, - dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_start_str) == - 0) { - dtnfsclient_rpcs[i].nr_v3_id_start = - dtrace_probe_create(dtnfsclient_id, - dtnfsclient_nfs3_str, - dtnfsclient_rpcs[i].nr_v3_name, - dtnfsclient_start_str, 0, - &nfsclient_nfs3_start_probes[i]); - } - if (dtrace_probe_lookup(dtnfsclient_id, dtnfsclient_nfs3_str, - dtnfsclient_rpcs[i].nr_v3_name, dtnfsclient_done_str) == - 0) { - dtnfsclient_rpcs[i].nr_v3_id_done = - dtrace_probe_create(dtnfsclient_id, - dtnfsclient_nfs3_str, - dtnfsclient_rpcs[i].nr_v3_name, - dtnfsclient_done_str, 0, - &nfsclient_nfs3_done_probes[i]); - } - } -} - -static void -dtnfsclient_destroy(void *arg, dtrace_id_t id, void *parg) -{ -} - -static void -dtnfsclient_enable(void *arg, dtrace_id_t id, void *parg) -{ - uint32_t *p = parg; - void *f = dtrace_probe; - - if (id == nfsclient_accesscache_flush_done_id) - dtrace_nfsclient_accesscache_flush_done_probe = f; - else if (id == nfsclient_accesscache_get_hit_id) - dtrace_nfsclient_accesscache_get_hit_probe = f; - else if (id == nfsclient_accesscache_get_miss_id) - dtrace_nfsclient_accesscache_get_miss_probe = f; - else if (id == nfsclient_accesscache_load_done_id) - dtrace_nfsclient_accesscache_load_done_probe = f; - else if (id == nfsclient_attrcache_flush_done_id) - dtrace_nfsclient_attrcache_flush_done_probe = f; - else if (id == nfsclient_attrcache_get_hit_id) - dtrace_nfsclient_attrcache_get_hit_probe = f; - else if (id == nfsclient_attrcache_get_miss_id) - dtrace_nfsclient_attrcache_get_miss_probe = f; - else if (id == nfsclient_attrcache_load_done_id) - dtrace_nfsclient_attrcache_load_done_probe = f; - else - *p = id; -} - -static void -dtnfsclient_disable(void *arg, dtrace_id_t id, void *parg) -{ - uint32_t *p = parg; - - if (id == nfsclient_accesscache_flush_done_id) - dtrace_nfsclient_accesscache_flush_done_probe = NULL; - else if (id == nfsclient_accesscache_get_hit_id) - dtrace_nfsclient_accesscache_get_hit_probe = NULL; - else if (id == nfsclient_accesscache_get_miss_id) - dtrace_nfsclient_accesscache_get_miss_probe = NULL; - else if (id == nfsclient_accesscache_load_done_id) - dtrace_nfsclient_accesscache_load_done_probe = NULL; - else if (id == nfsclient_attrcache_flush_done_id) - dtrace_nfsclient_attrcache_flush_done_probe = NULL; - else if (id == nfsclient_attrcache_get_hit_id) - dtrace_nfsclient_attrcache_get_hit_probe = NULL; - else if (id == nfsclient_attrcache_get_miss_id) - dtrace_nfsclient_attrcache_get_miss_probe = NULL; - else if (id == nfsclient_attrcache_load_done_id) - dtrace_nfsclient_attrcache_load_done_probe = NULL; - else - *p = 0; -} - -static void -dtnfsclient_load(void *dummy) -{ - - if (dtrace_register("nfsclient", &dtnfsclient_attr, - DTRACE_PRIV_USER, NULL, &dtnfsclient_pops, NULL, - &dtnfsclient_id) != 0) - return; - - dtrace_nfsclient_nfs23_start_probe = - (dtrace_nfsclient_nfs23_start_probe_func_t)dtrace_probe; - dtrace_nfsclient_nfs23_done_probe = - (dtrace_nfsclient_nfs23_done_probe_func_t)dtrace_probe; -} - - -static int -dtnfsclient_unload() -{ - - dtrace_nfsclient_nfs23_start_probe = NULL; - dtrace_nfsclient_nfs23_done_probe = NULL; - - return (dtrace_unregister(dtnfsclient_id)); -} - -static int -dtnfsclient_modevent(module_t mod __unused, int type, void *data __unused) -{ - int error = 0; - - switch (type) { - case MOD_LOAD: - break; - - case MOD_UNLOAD: - break; - - case MOD_SHUTDOWN: - break; - - default: - error = EOPNOTSUPP; - break; - } - - return (error); -} - -SYSINIT(dtnfsclient_load, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, - dtnfsclient_load, NULL); -SYSUNINIT(dtnfsclient_unload, SI_SUB_DTRACE_PROVIDER, SI_ORDER_ANY, - dtnfsclient_unload, NULL); - -DEV_MODULE(dtnfsclient, dtnfsclient_modevent, NULL); -MODULE_VERSION(dtnfsclient, 1); -MODULE_DEPEND(dtnfsclient, dtrace, 1, 1, 1); -MODULE_DEPEND(dtnfsclient, opensolaris, 1, 1, 1); -MODULE_DEPEND(dtnfsclient, oldnfs, 1, 1, 1); |