Skip site navigation (1)Skip section navigation (2)
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>