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
This commit is contained in:
+39
-1
@@ -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)
|
||||
@@ -480,6 +481,40 @@ ktrnamei(path)
|
||||
ktr_submitrequest(curthread, req);
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -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];
|
||||
|
||||
+10
-1
@@ -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 *name, u_int namelen, void *old,
|
||||
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));
|
||||
|
||||
|
||||
@@ -157,6 +157,12 @@ struct ktr_csw {
|
||||
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 *);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -83,6 +83,9 @@ getpoints(char *s)
|
||||
case 'w':
|
||||
facs |= KTRFAC_CSW;
|
||||
break;
|
||||
case 'y':
|
||||
facs |= KTRFAC_SYSCTL;
|
||||
break;
|
||||
case '+':
|
||||
facs |= DEF_POINTS;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user