diff options
author | markj <markj@FreeBSD.org> | 2016-04-10 01:25:48 +0000 |
---|---|---|
committer | markj <markj@FreeBSD.org> | 2016-04-10 01:25:48 +0000 |
commit | 61ede4b2ecba0e7719312562eabb9f52e4d7ecfd (patch) | |
tree | fd9e73d2a0133421cd4a8af938b3c790bd50e959 /cddl/contrib/opensolaris | |
parent | 7a70a2258262a6c228b3b459dfeb426e68e58e32 (diff) | |
download | FreeBSD-src-61ede4b2ecba0e7719312562eabb9f52e4d7ecfd.zip FreeBSD-src-61ede4b2ecba0e7719312562eabb9f52e4d7ecfd.tar.gz |
Implement support for boot-time DTrace.
This allows one to enable DTrace probes relatively early during boot,
during SI_SUB_DTRACE_ANON, before dtrace(1) can invoked. The desired
enabling is created using dtrace -A, which writes a /boot/dtrace.dof
file and uses nextboot(8) to ensure that DTrace kernel modules are loaded
and that the DOF file describing the enabling is loaded by loader(8)
during the subsequent boot. The trace output can then be fetched with
dtrace -a.
With this commit, boot-time DTrace is only functional on i386 and amd64: on
other architectures, the high-resolution timer frequency is initialized
during SI_SUB_CLOCKS and is thus not available when the anonymous
tracing state is initialized. On x86, the TSC is used and is thus available
earlier.
MFC after: 1 month
Relnotes: yes
Diffstat (limited to 'cddl/contrib/opensolaris')
-rw-r--r-- | cddl/contrib/opensolaris/cmd/dtrace/dtrace.c | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c index d8bdaa6..d065cdc 100644 --- a/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c +++ b/cddl/contrib/opensolaris/cmd/dtrace/dtrace.c @@ -50,6 +50,9 @@ #ifdef illumos #include <libproc.h> #endif +#ifdef __FreeBSD__ +#include <spawn.h> +#endif typedef struct dtrace_cmd { void (*dc_func)(struct dtrace_cmd *); /* function to compile arg */ @@ -397,7 +400,41 @@ dof_prune(const char *fname) free(buf); } -#ifdef illumos +#ifdef __FreeBSD__ +/* + * Use nextboot(8) to tell the loader to load DTrace kernel modules during + * the next boot of the system. The nextboot(8) configuration is removed during + * boot, so it will not persist indefinitely. + */ +static void +bootdof_add(void) +{ + char * const nbargv[] = { + "nextboot", "-a", + "-e", "dtraceall_load=\"YES\"", + "-e", "dtrace_dof_load=\"YES\"", + "-e", "dtrace_dof_name=\"/boot/dtrace.dof\"", + "-e", "dtrace_dof_type=\"dtrace_dof\"", + NULL, + }; + pid_t child; + int err, status; + + err = posix_spawnp(&child, "nextboot", NULL, NULL, nbargv, + NULL); + if (err != 0) { + error("failed to execute nextboot: %s", strerror(err)); + exit(E_ERROR); + } + + if (waitpid(child, &status, 0) != child) + fatal("waiting for nextboot"); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { + error("nextboot returned with status %d", status); + exit(E_ERROR); + } +} +#else static void etcsystem_prune(void) { @@ -508,7 +545,7 @@ etcsystem_add(void) error("added forceload directives to %s\n", g_ofile); } -#endif /* illumos */ +#endif /* !__FreeBSD__ */ static void print_probe_info(const dtrace_probeinfo_t *p) @@ -643,24 +680,24 @@ anon_prog(const dtrace_cmd_t *dcp, dof_hdr_t *dof, int n) p = (uchar_t *)dof; q = p + dof->dofh_loadsz; -#ifdef illumos - oprintf("dof-data-%d=0x%x", n, *p++); - - while (p < q) - oprintf(",0x%x", *p++); - - oprintf(";\n"); -#else +#ifdef __FreeBSD__ /* - * On FreeBSD, the DOF data is handled as a kernel environment (kenv) - * string. We use two hex characters per DOF byte. + * On FreeBSD, the DOF file is read directly during boot - just write + * two hex characters per byte. */ - oprintf("dof-data-%d=%02x", n, *p++); + oprintf("dof-data-%d=", n); while (p < q) oprintf("%02x", *p++); oprintf("\n"); +#else + oprintf("dof-data-%d=0x%x", n, *p++); + + while (p < q) + oprintf(",0x%x", *p++); + + oprintf(";\n"); #endif dtrace_dof_destroy(g_dtp, dof); @@ -1725,8 +1762,7 @@ main(int argc, char *argv[]) #else /* * On FreeBSD, anonymous DOF data is written to - * the DTrace DOF file that the boot loader will - * read if booting with the DTrace option. + * the DTrace DOF file. */ g_ofile = "/boot/dtrace.dof"; #endif @@ -1765,7 +1801,10 @@ main(int argc, char *argv[]) * that itself contains a #pragma D option quiet. */ error("saved anonymous enabling in %s\n", g_ofile); -#ifdef illumos + +#ifdef __FreeBSD__ + bootdof_add(); +#else etcsystem_add(); error("run update_drv(1M) or reboot to enable changes\n"); #endif |