diff options
author | jhb <jhb@FreeBSD.org> | 2009-03-11 21:48:36 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2009-03-11 21:48:36 +0000 |
commit | 2548f05c6c8be3fe53f4191e634699bb4fa4c56b (patch) | |
tree | 48083c4fab749cb8da99377a83f7d470672d4c2c /sys/kern/kern_ktrace.c | |
parent | de74558fd8fae07358ec61b9001d0a7590bb9d22 (diff) | |
download | FreeBSD-src-2548f05c6c8be3fe53f4191e634699bb4fa4c56b.zip FreeBSD-src-2548f05c6c8be3fe53f4191e634699bb4fa4c56b.tar.gz |
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
Diffstat (limited to 'sys/kern/kern_ktrace.c')
-rw-r--r-- | sys/kern/kern_ktrace.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index f4304de..6ccf2c0 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -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, struct ktr_request *req) * 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, struct ktr_request *req) 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]; |