Date: Wed, 11 Mar 2009 21:48:36 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r189707 - in head: sys/kern sys/sys usr.bin/kdump usr.bin/ktrace Message-ID: <200903112148.n2BLmaQJ007484@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Wed Mar 11 21:48:36 2009 New Revision: 189707 URL: http://svn.freebsd.org/changeset/base/189707 Log: Add a new type of KTRACE record for sysctl(3) invocations. It uses the internal sysctl_sysctl_name() handler to map the MIB array to a string name and logs this name in the trace log. This can be useful to see exactly which sysctls a thread is invoking. MFC after: 1 month Modified: head/sys/kern/kern_ktrace.c head/sys/kern/kern_sysctl.c head/sys/sys/ktrace.h head/usr.bin/kdump/kdump.1 head/usr.bin/kdump/kdump.c head/usr.bin/ktrace/ktrace.1 head/usr.bin/ktrace/ktrace.h head/usr.bin/ktrace/subr.c Modified: head/sys/kern/kern_ktrace.c ============================================================================== --- head/sys/kern/kern_ktrace.c Wed Mar 11 19:45:52 2009 (r189706) +++ head/sys/kern/kern_ktrace.c Wed Mar 11 21:48:36 2009 (r189707) @@ -111,6 +111,7 @@ static int data_lengths[] = { sizeof(struct ktr_csw), /* KTR_CSW */ 0, /* KTR_USER */ 0, /* KTR_STRUCT */ + 0, /* KTR_SYSCTL */ }; static STAILQ_HEAD(, ktr_request) ktr_free; @@ -319,7 +320,7 @@ ktr_enqueuerequest(struct thread *td, st * is used both internally before committing other records, and also on * system call return. We drain all the ones we can find at the time when * drain is requested, but don't keep draining after that as those events - * may me approximately "after" the current event. + * may be approximately "after" the current event. */ static void ktr_drain(struct thread *td) @@ -481,6 +482,40 @@ ktrnamei(path) } void +ktrsysctl(name, namelen) + int *name; + u_int namelen; +{ + struct ktr_request *req; + u_int mib[CTL_MAXNAME + 2]; + char *mibname; + size_t mibnamelen; + int error; + + /* Lookup name of mib. */ + KASSERT(namelen <= CTL_MAXNAME, ("sysctl MIB too long")); + mib[0] = 0; + mib[1] = 1; + bcopy(name, mib + 2, namelen * sizeof(*name)); + mibnamelen = 128; + mibname = malloc(mibnamelen, M_KTRACE, M_WAITOK); + error = kernel_sysctl(curthread, mib, namelen + 2, mibname, &mibnamelen, + NULL, 0, &mibnamelen, 0); + if (error) { + free(mibname, M_KTRACE); + return; + } + req = ktr_getrequest(KTR_SYSCTL); + if (req == NULL) { + free(mibname, M_KTRACE); + return; + } + req->ktr_header.ktr_len = mibnamelen; + req->ktr_buffer = mibname; + ktr_submitrequest(curthread, req); +} + +void ktrgenio(fd, rw, uio, error) int fd; enum uio_rw rw; @@ -925,6 +960,9 @@ ktr_writerequest(struct thread *td, stru mtx_unlock(&ktrace_mtx); kth = &req->ktr_header; + KASSERT(((u_short)kth->ktr_type & ~KTR_DROP) < + sizeof(data_lengths) / sizeof(data_lengths[0]), + ("data_lengths array overflow")); datalen = data_lengths[(u_short)kth->ktr_type & ~KTR_DROP]; buflen = kth->ktr_len; auio.uio_iov = &aiov[0]; Modified: head/sys/kern/kern_sysctl.c ============================================================================== --- head/sys/kern/kern_sysctl.c Wed Mar 11 19:45:52 2009 (r189706) +++ head/sys/kern/kern_sysctl.c Wed Mar 11 21:48:36 2009 (r189707) @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include "opt_compat.h" +#include "opt_ktrace.h" #include "opt_mac.h" #include <sys/param.h> @@ -54,6 +55,9 @@ __FBSDID("$FreeBSD$"); #include <sys/sysproto.h> #include <sys/uio.h> #include <sys/vimage.h> +#ifdef KTRACE +#include <sys/ktrace.h> +#endif #include <security/mac/mac_framework.h> @@ -758,7 +762,7 @@ sysctl_sysctl_next(SYSCTL_HANDLER_ARGS) static SYSCTL_NODE(_sysctl, 2, next, CTLFLAG_RD, sysctl_sysctl_next, ""); static int -name2oid (char *name, int *oid, int *len, struct sysctl_oid **oidpp) +name2oid(char *name, int *oid, int *len, struct sysctl_oid **oidpp) { int i; struct sysctl_oid *oidp; @@ -1499,6 +1503,11 @@ userland_sysctl(struct thread *td, int * req.newfunc = sysctl_new_user; req.lock = REQ_LOCKED; +#ifdef KTRACE + if (KTRPOINT(curthread, KTR_SYSCTL)) + ktrsysctl(name, namelen); +#endif + SYSCTL_XLOCK(); CURVNET_SET(TD_TO_VNET(curthread)); Modified: head/sys/sys/ktrace.h ============================================================================== --- head/sys/sys/ktrace.h Wed Mar 11 19:45:52 2009 (r189706) +++ head/sys/sys/ktrace.h Wed Mar 11 21:48:36 2009 (r189707) @@ -158,6 +158,12 @@ struct sockaddr; struct stat; /* + * KTR_SYSCTL - name of a sysctl MIB + */ +#define KTR_SYSCTL 9 + /* record contains null-terminated MIB name */ + +/* * KTR_DROP - If this bit is set in ktr_type, then at least one event * between the previous record and this record was dropped. */ @@ -175,6 +181,8 @@ struct stat; #define KTRFAC_CSW (1<<KTR_CSW) #define KTRFAC_USER (1<<KTR_USER) #define KTRFAC_STRUCT (1<<KTR_STRUCT) +#define KTRFAC_SYSCTL (1<<KTR_SYSCTL) + /* * trace flags (also in p_traceflags) */ @@ -190,6 +198,7 @@ void ktrcsw(int, int); void ktrpsig(int, sig_t, sigset_t *, int); void ktrgenio(int, enum uio_rw, struct uio *, int); void ktrsyscall(int, int narg, register_t args[]); +void ktrsysctl(int *name, u_int namelen); void ktrsysret(int, int, register_t); void ktrprocexit(struct thread *); void ktruserret(struct thread *); Modified: head/usr.bin/kdump/kdump.1 ============================================================================== --- head/usr.bin/kdump/kdump.1 Wed Mar 11 19:45:52 2009 (r189706) +++ head/usr.bin/kdump/kdump.1 Wed Mar 11 21:48:36 2009 (r189707) @@ -172,6 +172,7 @@ The possible operations are: .It Li CSW Ta context switch Ta stop/resume user/kernel .It Li USER Ta data from user process Ta the data .It Li STRU Ta various syscalls Ta structure +.It Li SCTL Ta Xr sysctl 3 requests Ta MIB name .El .Sh SEE ALSO .Xr ktrace 1 Modified: head/usr.bin/kdump/kdump.c ============================================================================== --- head/usr.bin/kdump/kdump.c Wed Mar 11 19:45:52 2009 (r189706) +++ head/usr.bin/kdump/kdump.c Wed Mar 11 21:48:36 2009 (r189707) @@ -217,6 +217,7 @@ main(int argc, char *argv[]) ktrsysret((struct ktr_sysret *)m); break; case KTR_NAMEI: + case KTR_SYSCTL: ktrnamei(m, ktrlen); break; case KTR_GENIO: @@ -288,6 +289,9 @@ dumpheader(struct ktr_header *kth) case KTR_STRUCT: type = "STRU"; break; + case KTR_SYSCTL: + type = "SCTL"; + break; default: (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); type = unknown; Modified: head/usr.bin/ktrace/ktrace.1 ============================================================================== --- head/usr.bin/ktrace/ktrace.1 Wed Mar 11 19:45:52 2009 (r189706) +++ head/usr.bin/ktrace/ktrace.1 Wed Mar 11 21:48:36 2009 (r189707) @@ -125,6 +125,10 @@ trace various structures userland traces .It Cm w context switches +.It Cm y +trace +.Xr sysctl 3 +requests .It Cm + trace the default set of trace points - .Cm c , n , i , s , t , u Modified: head/usr.bin/ktrace/ktrace.h ============================================================================== --- head/usr.bin/ktrace/ktrace.h Wed Mar 11 19:45:52 2009 (r189706) +++ head/usr.bin/ktrace/ktrace.h Wed Mar 11 21:48:36 2009 (r189707) @@ -35,7 +35,8 @@ */ #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \ - KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER | KTRFAC_STRUCT) + KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER | \ + KTRFAC_STRUCT | KTRFAC_SYSCTL) #define ALL_POINTS (DEF_POINTS | KTRFAC_CSW) Modified: head/usr.bin/ktrace/subr.c ============================================================================== --- head/usr.bin/ktrace/subr.c Wed Mar 11 19:45:52 2009 (r189706) +++ head/usr.bin/ktrace/subr.c Wed Mar 11 21:48:36 2009 (r189707) @@ -83,6 +83,9 @@ getpoints(char *s) case 'w': facs |= KTRFAC_CSW; break; + case 'y': + facs |= KTRFAC_SYSCTL; + break; case '+': facs |= DEF_POINTS; break;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200903112148.n2BLmaQJ007484>