summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2008-02-23 01:01:49 +0000
committerdes <des@FreeBSD.org>2008-02-23 01:01:49 +0000
commitdf26e399aa077b14fb965be866012bccf2847bae (patch)
treef964310d3ee2e43cfebd6c2b2628bc7056a3aa02 /sys
parent78a1e4fcc29bdf9689366a67205160335e7897bd (diff)
downloadFreeBSD-src-df26e399aa077b14fb965be866012bccf2847bae.zip
FreeBSD-src-df26e399aa077b14fb965be866012bccf2847bae.tar.gz
This patch adds a new ktrace(2) record type, KTR_STRUCT, whose payload
consists of the null-terminated name and the contents of any structure you wish to record. A new ktrstruct() function constructs and emits a KTR_STRUCT record. It is accompanied by convenience macros for struct stat and struct sockaddr. In kdump(1), KTR_STRUCT records are handled by a dispatcher function that runs stringent sanity checks on its contents before handing it over to individual decoding funtions for each type of structure. Currently supported structures are struct stat and struct sockaddr for the AF_INET, AF_INET6 and AF_UNIX families; support for AF_APPLETALK and AF_IPX is present but disabled, as I am unable to test it properly. Since 's' was already taken, the letter 't' is used by ktrace(1) to enable KTR_STRUCT trace points, and in kdump(1) to enable their decoding. Derived from patches by Andrew Li <andrew2.li@citi.com>. PR: kern/117836 MFC after: 3 weeks
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_descrip.c8
-rw-r--r--sys/kern/kern_ktrace.c32
-rw-r--r--sys/kern/uipc_syscalls.c36
-rw-r--r--sys/kern/vfs_syscalls.c12
-rw-r--r--sys/sys/ktrace.h13
5 files changed, 100 insertions, 1 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 27a5289..7025587 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include "opt_compat.h"
#include "opt_ddb.h"
+#include "opt_ktrace.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -72,6 +73,9 @@ __FBSDID("$FreeBSD$");
#include <sys/unistd.h>
#include <sys/user.h>
#include <sys/vnode.h>
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
#include <security/audit/audit.h>
@@ -1126,6 +1130,10 @@ kern_fstat(struct thread *td, int fd, struct stat *sbp)
error = fo_stat(fp, sbp, td->td_ucred, td);
fdrop(fp, td);
+#ifdef KTRACE
+ if (error == 0 && KTRPOINT(td, KTR_STRUCT))
+ ktrstat(sbp);
+#endif
return (error);
}
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index f5385ea..c8e4451 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -51,6 +51,8 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
#include <sys/ktrace.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
@@ -107,7 +109,8 @@ static int data_lengths[] = {
sizeof(struct ktr_genio), /* KTR_GENIO */
sizeof(struct ktr_psig), /* KTR_PSIG */
sizeof(struct ktr_csw), /* KTR_CSW */
- 0 /* KTR_USER */
+ 0, /* KTR_USER */
+ 0, /* KTR_STRUCT */
};
static STAILQ_HEAD(, ktr_request) ktr_free;
@@ -552,6 +555,33 @@ ktrcsw(out, user)
kc->user = user;
ktr_enqueuerequest(curthread, req);
}
+
+void
+ktrstruct(name, namelen, data, datalen)
+ const char *name;
+ size_t namelen;
+ void *data;
+ size_t datalen;
+{
+ struct ktr_request *req;
+ char *buf = NULL;
+ size_t buflen;
+
+ if (!data)
+ datalen = 0;
+ buflen = namelen + 1 + datalen;
+ buf = malloc(buflen, M_KTRACE, M_WAITOK);
+ bcopy(name, buf, namelen);
+ buf[namelen] = '\0';
+ bcopy(data, buf + namelen + 1, datalen);
+ if ((req = ktr_getrequest(KTR_STRUCT)) == NULL) {
+ free(buf, M_KTRACE);
+ return;
+ }
+ req->ktr_buffer = buf;
+ req->ktr_header.ktr_len = buflen;
+ ktr_submitrequest(curthread, req);
+}
#endif /* KTRACE */
/* Interface and common routines */
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 9709376..48e3bec 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -222,6 +222,10 @@ kern_bind(td, fd, sa)
if (error)
return (error);
so = fp->f_data;
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrsockaddr(sa);
+#endif
#ifdef MAC
SOCK_LOCK(so);
error = mac_socket_check_bind(td->td_ucred, so, sa);
@@ -444,6 +448,10 @@ kern_accept(struct thread *td, int s, struct sockaddr **name,
/* check sa_len before it is destroyed */
if (*namelen > sa->sa_len)
*namelen = sa->sa_len;
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrsockaddr(sa);
+#endif
*name = sa;
sa = NULL;
}
@@ -538,6 +546,10 @@ kern_connect(td, fd, sa)
error = EALREADY;
goto done1;
}
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrsockaddr(sa);
+#endif
#ifdef MAC
SOCK_LOCK(so);
error = mac_socket_check_connect(td->td_ucred, so, sa);
@@ -1052,6 +1064,10 @@ kern_recvit(td, s, mp, fromseg, controlp)
}
out:
fdrop(fp, td);
+#ifdef KTRACE
+ if (fromsa && KTRPOINT(td, KTR_STRUCT))
+ ktrsockaddr(fromsa);
+#endif
if (fromsa)
FREE(fromsa, M_SONAME);
@@ -1456,6 +1472,10 @@ kern_getsockname(struct thread *td, int fd, struct sockaddr **sa,
else
len = MIN(*alen, (*sa)->sa_len);
*alen = len;
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrsockaddr(*sa);
+#endif
bad:
fdrop(fp, td);
if (error && *sa) {
@@ -1553,6 +1573,10 @@ kern_getpeername(struct thread *td, int fd, struct sockaddr **sa,
else
len = MIN(*alen, (*sa)->sa_len);
*alen = len;
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrsockaddr(*sa);
+#endif
bad:
if (error && *sa) {
free(*sa, M_SONAME);
@@ -2373,6 +2397,10 @@ sctp_generic_sendmsg (td, uap)
error = getsock(td->td_proc->p_fd, uap->sd, &fp, NULL);
if (error)
goto sctp_bad;
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrsockaddr(to);
+#endif
iov[0].iov_base = uap->msg;
iov[0].iov_len = uap->mlen;
@@ -2476,6 +2504,10 @@ sctp_generic_sendmsg_iov(td, uap)
error = copyiniov(uap->iov, uap->iovlen, &iov, EMSGSIZE);
if (error)
goto sctp_bad1;
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrsockaddr(to);
+#endif
so = (struct socket *)fp->f_data;
#ifdef MAC
@@ -2659,6 +2691,10 @@ sctp_generic_recvmsg(td, uap)
goto out;
}
}
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrsockaddr(fromsa);
+#endif
if (uap->msg_flags) {
error = copyout(&msg_flags, uap->msg_flags, sizeof (int));
if (error) {
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index d05ca3a..8829a9c 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -38,6 +38,7 @@
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
+#include "opt_ktrace.h"
#include "opt_mac.h"
#include <sys/param.h>
@@ -67,6 +68,9 @@ __FBSDID("$FreeBSD$");
#include <sys/jail.h>
#include <sys/syscallsubr.h>
#include <sys/sysctl.h>
+#ifdef KTRACE
+#include <sys/ktrace.h>
+#endif
#include <machine/stdarg.h>
@@ -2120,6 +2124,10 @@ kern_stat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp)
if (error)
return (error);
*sbp = sb;
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrstat(&sb);
+#endif
return (0);
}
@@ -2171,6 +2179,10 @@ kern_lstat(struct thread *td, char *path, enum uio_seg pathseg, struct stat *sbp
if (error)
return (error);
*sbp = sb;
+#ifdef KTRACE
+ if (KTRPOINT(td, KTR_STRUCT))
+ ktrstat(&sb);
+#endif
return (0);
}
diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
index 4572141..cf9f977 100644
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -151,6 +151,13 @@ struct ktr_csw {
#define KTR_USER 7
/*
+ * KTR_STRUCT - misc. structs
+ */
+#define KTR_STRUCT 8
+struct sockaddr;
+struct stat;
+
+/*
* KTR_DROP - If this bit is set in ktr_type, then at least one event
* between the previous record and this record was dropped.
*/
@@ -167,6 +174,7 @@ struct ktr_csw {
#define KTRFAC_PSIG (1<<KTR_PSIG)
#define KTRFAC_CSW (1<<KTR_CSW)
#define KTRFAC_USER (1<<KTR_USER)
+#define KTRFAC_STRUCT (1<<KTR_STRUCT)
/*
* trace flags (also in p_traceflags)
*/
@@ -185,6 +193,11 @@ void ktrsyscall(int, int narg, register_t args[]);
void ktrsysret(int, int, register_t);
void ktrprocexit(struct thread *);
void ktruserret(struct thread *);
+void ktrstruct(const char *, size_t, void *, size_t);
+#define ktrsockaddr(s) \
+ ktrstruct("sockaddr", 8, (s), ((struct sockaddr *)(s))->sa_len)
+#define ktrstat(s) \
+ ktrstruct("stat", 4, (s), sizeof(struct stat))
#else
OpenPOWER on IntegriCloud