summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_ktrace.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2009-03-11 21:48:36 +0000
committerjhb <jhb@FreeBSD.org>2009-03-11 21:48:36 +0000
commit2548f05c6c8be3fe53f4191e634699bb4fa4c56b (patch)
tree48083c4fab749cb8da99377a83f7d470672d4c2c /sys/kern/kern_ktrace.c
parentde74558fd8fae07358ec61b9001d0a7590bb9d22 (diff)
downloadFreeBSD-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.c40
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];
OpenPOWER on IntegriCloud