From c0055de89181126603fb1cf69920319d621e0222 Mon Sep 17 00:00:00 2001 From: rwatson Date: Sun, 22 Mar 2009 22:07:52 +0000 Subject: Add dtnfsclient, a first cut at an NFSv2/v3 client reuest DTrace provider. The NFS client exposes 'start' and 'done' probes for NFSv2 and NFSv3 RPCs when using the new RPC implementation, passing in the vnode, mbuf chain, credential, and NFSv2 or NFSv3 procedure number. For 'done' probes, the error number is also available. Probes are named in the following way: ... nfsclient:nfs2:write:start nfsclient:nfs2:write:done ... nfsclient:nfs3:access:start nfsclient:nfs3:access:done ... Access to the unmarshalled arguments is not easily available at this point in the stack, but the passed probe arguments are sufficient to to a lot of interesting things in practice. Technically, these probes may cover multiple RPC retransmits, and even transactions if the transaction ID change as a result of authentication failure or a jukebox error from the server, but usefully capture the intent of a single NFS request, such as access, getattr, write, etc. Typical use might involve profiling RPC latency by system call, number of RPCs, how often a getattr leads to a call to access, when failed access control checks occur, etc. More detailed RPC information might best be provided by adding a krpc provider. It would also be useful to add NFS client probes for events such as the access cache or attribute cache satisfying requests without an RPC. Sponsored by: Google, Inc. MFC after: 1 month --- sys/nfsclient/nfs_krpc.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) (limited to 'sys/nfsclient') diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c index ce6a87b..8f3f124 100644 --- a/sys/nfsclient/nfs_krpc.c +++ b/sys/nfsclient/nfs_krpc.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); */ #include "opt_inet6.h" +#include "opt_kdtrace.h" #include "opt_kgssapi.h" #include @@ -73,6 +74,25 @@ __FBSDID("$FreeBSD$"); #ifndef NFS_LEGACYRPC +#ifdef KDTRACE_HOOKS +#include + +dtrace_nfsclient_nfs23_start_probe_func_t + dtrace_nfsclient_nfs23_start_probe; + +dtrace_nfsclient_nfs23_done_probe_func_t + dtrace_nfsclient_nfs23_done_probe; + +/* + * Registered probes by RPC type. + */ +uint32_t nfsclient_nfs2_start_probes[NFS_NPROCS]; +uint32_t nfsclient_nfs2_done_probes[NFS_NPROCS]; + +uint32_t nfsclient_nfs3_start_probes[NFS_NPROCS]; +uint32_t nfsclient_nfs3_done_probes[NFS_NPROCS]; +#endif + static int nfs_realign_test; static int nfs_realign_count; static int nfs_bufpackets = 4; @@ -468,6 +488,25 @@ nfs_request(struct vnode *vp, struct mbuf *mreq, int procnum, ext.rc_timers = NULL; } +#ifdef KDTRACE_HOOKS + if (dtrace_nfsclient_nfs23_start_probe != NULL) { + uint32_t probe_id; + int probe_procnum; + + if (nmp->nm_flag & NFSMNT_NFSV3) { + probe_id = nfsclient_nfs3_start_probes[procnum]; + probe_procnum = procnum; + } else { + probe_id = nfsclient_nfs2_start_probes[procnum]; + probe_procnum = (nmp->nm_flag & NFSMNT_NFSV3) ? + procnum : nfsv2_procid[procnum]; + } + if (probe_id != 0) + (dtrace_nfsclient_nfs23_start_probe)(probe_id, vp, + mreq, cred, probe_procnum); + } +#endif + nfsstats.rpcrequests++; tryagain: timo.tv_sec = nmp->nm_timeo / NFS_HZ; @@ -535,6 +574,24 @@ tryagain: goto nfsmout; } +#ifdef KDTRACE_HOOKS + if (dtrace_nfsclient_nfs23_done_probe != NULL) { + uint32_t probe_id; + int probe_procnum; + + if (nmp->nm_flag & NFSMNT_NFSV3) { + probe_id = nfsclient_nfs3_done_probes[procnum]; + probe_procnum = procnum; + } else { + probe_id = nfsclient_nfs2_done_probes[procnum]; + probe_procnum = (nmp->nm_flag & NFSMNT_NFSV3) ? + procnum : nfsv2_procid[procnum]; + } + if (probe_id != 0) + (dtrace_nfsclient_nfs23_done_probe)(probe_id, vp, + mreq, cred, probe_procnum, 0); + } +#endif m_freem(mreq); *mrp = mrep; *mdp = md; @@ -543,6 +600,24 @@ tryagain: return (0); nfsmout: +#ifdef KDTRACE_HOOKS + if (dtrace_nfsclient_nfs23_done_probe != NULL) { + uint32_t probe_id; + int probe_procnum; + + if (nmp->nm_flag & NFSMNT_NFSV3) { + probe_id = nfsclient_nfs3_done_probes[procnum]; + probe_procnum = procnum; + } else { + probe_id = nfsclient_nfs2_done_probes[procnum]; + probe_procnum = (nmp->nm_flag & NFSMNT_NFSV3) ? + procnum : nfsv2_procid[procnum]; + } + if (probe_id != 0) + (dtrace_nfsclient_nfs23_done_probe)(probe_id, vp, + mreq, cred, probe_procnum, error); + } +#endif m_freem(mreq); if (auth) AUTH_DESTROY(auth); -- cgit v1.1