Commit | Line | Data |
---|---|---|
5e0cbfb0 PP |
1 | --- |
2 | id: lttng-adaptation-layer | |
3 | --- | |
4 | ||
5 | The steps to write the LTTng adaptation layer are, in your | |
6 | LTTng-modules copy's source code tree: | |
7 | ||
8 | 1. In `instrumentation/events/lttng-module`, | |
9 | add a header <code><em>subsys</em>.h</code> for your custom | |
10 | subsystem <code><em>subsys</em></code> and write your | |
11 | tracepoint definitions using LTTng-modules macros in it. | |
12 | Those macros look like the mainline kernel equivalents, | |
13 | but they present subtle, yet important differences. | |
14 | 2. In `probes`, create the C source file of the LTTng probe kernel | |
15 | module for your subsystem. It should be named | |
16 | <code>lttng-probe-<em>subsys</em>.c</code>. | |
17 | 3. Edit `probes/Makefile` so that the LTTng-modules project | |
18 | builds your custom LTTng probe kernel module. | |
19 | 4. Build and install LTTng kernel modules. | |
20 | ||
21 | Following our `hello_world` event example, here's the content of | |
22 | `instrumentation/events/lttng-module/hello.h`: | |
23 | ||
24 | ~~~ c | |
25 | #undef TRACE_SYSTEM | |
26 | #define TRACE_SYSTEM hello | |
27 | ||
28 | #if !defined(_TRACE_HELLO_H) || defined(TRACE_HEADER_MULTI_READ) | |
29 | #define _TRACE_HELLO_H | |
30 | ||
31 | #include <linux/tracepoint.h> | |
32 | ||
33 | LTTNG_TRACEPOINT_EVENT( | |
34 | /* format identical to mainline version for those */ | |
35 | hello_world, | |
36 | TP_PROTO(int foo, const char* bar), | |
37 | TP_ARGS(foo, bar), | |
38 | ||
39 | /* possible differences */ | |
40 | TP_STRUCT__entry( | |
41 | __field(int, my_int) | |
42 | __field(char, char0) | |
43 | __field(char, char1) | |
44 | __string(product, bar) | |
45 | ), | |
46 | ||
47 | /* notice the use of tp_assign()/tp_strcpy() and no semicolons */ | |
48 | TP_fast_assign( | |
49 | tp_assign(my_int, foo) | |
50 | tp_assign(char0, bar[0]) | |
51 | tp_assign(char1, bar[1]) | |
52 | tp_strcpy(product, bar) | |
53 | ), | |
54 | ||
55 | /* This one is actually not used by LTTng either, but must be | |
56 | * present for the moment. | |
57 | */ | |
58 | TP_printk("", 0) | |
59 | ||
60 | /* no semicolon after this either */ | |
61 | ) | |
62 | ||
63 | #endif | |
64 | ||
65 | /* other difference: do NOT include <trace/define_trace.h> */ | |
66 | #include "../../../probes/define_trace.h" | |
67 | ~~~ | |
68 | ||
69 | Some possible entries for `TP_STRUCT__entry()` and `TP_fast_assign()`, | |
70 | in the case of LTTng-modules, are shown in the | |
71 | [LTTng-modules reference](#doc-lttng-modules-ref) section. | |
72 | ||
73 | The best way to learn how to use the above macros is to inspect | |
74 | existing LTTng tracepoint definitions in `instrumentation/events/lttng-module` | |
75 | header files. Compare them with the Linux kernel mainline versions | |
76 | in `include/trace/events`. | |
77 | ||
78 | The next step is writing the LTTng probe kernel module C source file. | |
79 | This one is named <code>lttng-probe-<em>subsys</em>.c</code> | |
80 | in `probes`. You may always use the following template: | |
81 | ||
82 | ~~~ c | |
83 | #include <linux/module.h> | |
84 | #include "../lttng-tracer.h" | |
85 | ||
86 | /* Build time verification of mismatch between mainline TRACE_EVENT() | |
87 | * arguments and LTTng adaptation layer LTTNG_TRACEPOINT_EVENT() arguments. | |
88 | */ | |
89 | #include <trace/events/hello.h> | |
90 | ||
91 | /* create LTTng tracepoint probes */ | |
92 | #define LTTNG_PACKAGE_BUILD | |
93 | #define CREATE_TRACE_POINTS | |
94 | #define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module | |
95 | ||
96 | #include "../instrumentation/events/lttng-module/hello.h" | |
97 | ||
98 | MODULE_LICENSE("GPL and additional rights"); | |
99 | MODULE_AUTHOR("Your name <your-email>"); | |
100 | MODULE_DESCRIPTION("LTTng hello probes"); | |
101 | MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "." | |
102 | __stringify(LTTNG_MODULES_MINOR_VERSION) "." | |
103 | __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION) | |
104 | LTTNG_MODULES_EXTRAVERSION); | |
105 | ~~~ | |
106 | ||
107 | Just replace `hello` with your subsystem name. In this example, | |
108 | `<trace/events/hello.h>`, which is the original mainline tracepoint | |
109 | definition header, is included for verification purposes: the | |
110 | LTTng-modules build system is able to emit an error at build time when | |
111 | the arguments of the mainline `TRACE_EVENT()` definitions do not match | |
112 | the ones of the LTTng-modules adaptation layer | |
113 | (`LTTNG_TRACEPOINT_EVENT()`). | |
114 | ||
115 | Edit `probes/Makefile` and add your new kernel module object | |
116 | next to existing ones: | |
117 | ||
118 | ~~~ makefile | |
119 | # ... | |
120 | ||
121 | obj-m += lttng-probe-module.o | |
122 | obj-m += lttng-probe-power.o | |
123 | ||
124 | obj-m += lttng-probe-hello.o | |
125 | ||
126 | # ... | |
127 | ~~~ | |
128 | ||
129 | Time to build! Point to your custom Linux kernel source tree using | |
130 | the `KERNELDIR` variable: | |
131 | ||
132 | <pre class="term"> | |
133 | make <strong>KERNELDIR=/path/to/custom/linux</strong> | |
134 | </pre> | |
135 | ||
136 | Finally, install modules: | |
137 | ||
138 | <pre class="term"> | |
139 | sudo make modules_install | |
140 | </pre> |