Fix: Use get_domain_str on add context
[lttng-tools.git] / src / bin / lttng / commands / add_context.c
CommitLineData
d65106b1
DG
1/*
2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
3 *
d14d33bf
AM
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
d65106b1
DG
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
d14d33bf
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
d65106b1
DG
16 */
17
18#define _GNU_SOURCE
90b9a268 19#include <ctype.h>
d65106b1
DG
20#include <popt.h>
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <sys/stat.h>
25#include <sys/types.h>
26#include <unistd.h>
deaef3cf 27#include <assert.h>
d65106b1 28
3301e740
DG
29#include <urcu/list.h>
30
89b72577
JRJ
31#include <common/mi-lttng.h>
32
c399183f 33#include "../command.h"
d65106b1 34
b13d56d7
MD
35#define PRINT_LINE_LEN 80
36
d65106b1 37static char *opt_channel_name;
5440dc42 38static char *opt_session_name;
55cc08a6 39static int opt_kernel;
d65106b1 40static int opt_userspace;
d78d6610 41static char *opt_type;
89b72577 42
d78d6610
DG
43#if 0
44/* Not implemented yet */
eeac7d46 45static char *opt_cmd_name;
d65106b1 46static pid_t opt_pid;
d78d6610 47#endif
d65106b1
DG
48
49enum {
50 OPT_HELP = 1,
51 OPT_TYPE,
eeac7d46 52 OPT_USERSPACE,
679b4943 53 OPT_LIST_OPTIONS,
d65106b1
DG
54};
55
cd80958d 56static struct lttng_handle *handle;
89b72577 57static struct mi_writer *writer;
cd80958d 58
90b9a268
DG
59/*
60 * Taken from the LTTng ABI
61 */
62enum context_type {
63 CONTEXT_PID = 0,
aa3514e9 64 CONTEXT_PERF_COUNTER = 1, /* Backward compat. */
95da1297 65 CONTEXT_PROCNAME = 2,
90b9a268
DG
66 CONTEXT_PRIO = 3,
67 CONTEXT_NICE = 4,
68 CONTEXT_VPID = 5,
69 CONTEXT_TID = 6,
70 CONTEXT_VTID = 7,
71 CONTEXT_PPID = 8,
72 CONTEXT_VPPID = 9,
9197c5c4 73 CONTEXT_PTHREAD_ID = 10,
54773d68 74 CONTEXT_HOSTNAME = 11,
7c612c2e 75 CONTEXT_IP = 12,
aa3514e9
MD
76 CONTEXT_PERF_CPU_COUNTER = 13,
77 CONTEXT_PERF_THREAD_COUNTER = 14,
3301e740
DG
78};
79
90b9a268
DG
80/*
81 * Taken from the Perf ABI (all enum perf_*)
82 */
83enum perf_type {
84 PERF_TYPE_HARDWARE = 0,
85 PERF_TYPE_SOFTWARE = 1,
b13d56d7 86 PERF_TYPE_HW_CACHE = 3,
3301e740
DG
87};
88
90b9a268 89enum perf_count_hard {
b13d56d7
MD
90 PERF_COUNT_HW_CPU_CYCLES = 0,
91 PERF_COUNT_HW_INSTRUCTIONS = 1,
92 PERF_COUNT_HW_CACHE_REFERENCES = 2,
93 PERF_COUNT_HW_CACHE_MISSES = 3,
94 PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4,
95 PERF_COUNT_HW_BRANCH_MISSES = 5,
96 PERF_COUNT_HW_BUS_CYCLES = 6,
97 PERF_COUNT_HW_STALLED_CYCLES_FRONTEND = 7,
98 PERF_COUNT_HW_STALLED_CYCLES_BACKEND = 8,
90b9a268
DG
99};
100
101enum perf_count_soft {
102 PERF_COUNT_SW_CPU_CLOCK = 0,
103 PERF_COUNT_SW_TASK_CLOCK = 1,
104 PERF_COUNT_SW_PAGE_FAULTS = 2,
105 PERF_COUNT_SW_CONTEXT_SWITCHES = 3,
106 PERF_COUNT_SW_CPU_MIGRATIONS = 4,
107 PERF_COUNT_SW_PAGE_FAULTS_MIN = 5,
108 PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6,
109 PERF_COUNT_SW_ALIGNMENT_FAULTS = 7,
110 PERF_COUNT_SW_EMULATION_FAULTS = 8,
3301e740
DG
111};
112
b13d56d7
MD
113/*
114 * Generalized hardware cache events:
115 *
116 * { L1-D, L1-I, LLC, ITLB, DTLB, BPU } x
117 * { read, write, prefetch } x
118 * { accesses, misses }
119 */
120enum perf_hw_cache_id {
121 PERF_COUNT_HW_CACHE_L1D = 0,
122 PERF_COUNT_HW_CACHE_L1I = 1,
123 PERF_COUNT_HW_CACHE_LL = 2,
124 PERF_COUNT_HW_CACHE_DTLB = 3,
125 PERF_COUNT_HW_CACHE_ITLB = 4,
126 PERF_COUNT_HW_CACHE_BPU = 5,
127
128 PERF_COUNT_HW_CACHE_MAX, /* non-ABI */
129};
130
131enum perf_hw_cache_op_id {
132 PERF_COUNT_HW_CACHE_OP_READ = 0,
133 PERF_COUNT_HW_CACHE_OP_WRITE = 1,
134 PERF_COUNT_HW_CACHE_OP_PREFETCH = 2,
135
136 PERF_COUNT_HW_CACHE_OP_MAX, /* non-ABI */
137};
138
139enum perf_hw_cache_op_result_id {
140 PERF_COUNT_HW_CACHE_RESULT_ACCESS = 0,
141 PERF_COUNT_HW_CACHE_RESULT_MISS = 1,
142
143 PERF_COUNT_HW_CACHE_RESULT_MAX, /* non-ABI */
144};
145
d65106b1
DG
146static struct poptOption long_options[] = {
147 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
148 {"help", 'h', POPT_ARG_NONE, 0, OPT_HELP, 0, 0},
5440dc42 149 {"session", 's', POPT_ARG_STRING, &opt_session_name, 0, 0, 0},
d65106b1 150 {"channel", 'c', POPT_ARG_STRING, &opt_channel_name, 0, 0, 0},
d65106b1 151 {"kernel", 'k', POPT_ARG_VAL, &opt_kernel, 1, 0, 0},
d78d6610 152 {"userspace", 'u', POPT_ARG_NONE, 0, OPT_USERSPACE, 0, 0},
6caa2bcc 153 {"type", 't', POPT_ARG_STRING, &opt_type, OPT_TYPE, 0, 0},
679b4943 154 {"list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL},
d65106b1
DG
155 {0, 0, 0, 0, 0, 0, 0}
156};
157
90b9a268 158/*
b13d56d7 159 * Context options
90b9a268 160 */
aa3514e9 161#define PERF_HW(optstr, name, type, hide) \
b13d56d7 162 { \
aa3514e9 163 optstr, type, hide, \
b13d56d7
MD
164 .u.perf = { PERF_TYPE_HARDWARE, PERF_COUNT_HW_##name, },\
165 }
90b9a268 166
aa3514e9 167#define PERF_SW(optstr, name, type, hide) \
b13d56d7 168 { \
aa3514e9 169 optstr, type, hide, \
b13d56d7
MD
170 .u.perf = { PERF_TYPE_SOFTWARE, PERF_COUNT_SW_##name, },\
171 }
90b9a268 172
aa3514e9 173#define _PERF_HW_CACHE(optstr, name, type, op, result, hide) \
b13d56d7 174 { \
aa3514e9 175 optstr, type, hide, \
b13d56d7
MD
176 .u.perf = { \
177 PERF_TYPE_HW_CACHE, \
178 (uint64_t) PERF_COUNT_HW_CACHE_##name \
18829107
MD
179 | ((uint64_t) PERF_COUNT_HW_CACHE_OP_##op << 8) \
180 | ((uint64_t) PERF_COUNT_HW_CACHE_RESULT_##result << 16), \
b13d56d7
MD
181 }, \
182 }
183
aa3514e9
MD
184#define PERF_HW_CACHE(optstr, name, type, hide) \
185 _PERF_HW_CACHE(optstr "-loads", name, type, \
186 READ, ACCESS, hide), \
187 _PERF_HW_CACHE(optstr "-load-misses", name, type, \
188 READ, MISS, hide), \
189 _PERF_HW_CACHE(optstr "-stores", name, type, \
190 WRITE, ACCESS, hide), \
191 _PERF_HW_CACHE(optstr "-store-misses", name, type, \
192 WRITE, MISS, hide), \
193 _PERF_HW_CACHE(optstr "-prefetches", name, type, \
194 PREFETCH, ACCESS, hide), \
195 _PERF_HW_CACHE(optstr "-prefetch-misses", name, type, \
196 PREFETCH, MISS, hide)
b13d56d7
MD
197
198static
199const struct ctx_opts {
90b9a268 200 char *symbol;
b13d56d7 201 enum context_type ctx_type;
aa3514e9 202 int hide_help; /* Hide from --help */
b13d56d7
MD
203 union {
204 struct {
205 uint32_t type;
206 uint64_t config;
207 } perf;
208 } u;
209} ctx_opts[] = {
210 { "pid", CONTEXT_PID },
95da1297 211 { "procname", CONTEXT_PROCNAME },
b13d56d7
MD
212 { "prio", CONTEXT_PRIO },
213 { "nice", CONTEXT_NICE },
214 { "vpid", CONTEXT_VPID },
215 { "tid", CONTEXT_TID },
9197c5c4 216 { "pthread_id", CONTEXT_PTHREAD_ID },
b13d56d7
MD
217 { "vtid", CONTEXT_VTID },
218 { "ppid", CONTEXT_PPID },
219 { "vppid", CONTEXT_VPPID },
54773d68 220 { "hostname", CONTEXT_HOSTNAME },
7c612c2e 221 { "ip", CONTEXT_IP },
aa3514e9 222
b13d56d7 223 /* Perf options */
aa3514e9
MD
224
225 /* Perf per-CPU counters */
226 PERF_HW("perf:cpu:cpu-cycles", CPU_CYCLES,
227 CONTEXT_PERF_CPU_COUNTER, 0),
228 PERF_HW("perf:cpu:cycles", CPU_CYCLES,
229 CONTEXT_PERF_CPU_COUNTER, 0),
230 PERF_HW("perf:cpu:stalled-cycles-frontend", STALLED_CYCLES_FRONTEND,
231 CONTEXT_PERF_CPU_COUNTER, 0),
232 PERF_HW("perf:cpu:idle-cycles-frontend", STALLED_CYCLES_FRONTEND,
233 CONTEXT_PERF_CPU_COUNTER, 0),
234 PERF_HW("perf:cpu:stalled-cycles-backend", STALLED_CYCLES_BACKEND,
235 CONTEXT_PERF_CPU_COUNTER, 0),
236 PERF_HW("perf:cpu:idle-cycles-backend", STALLED_CYCLES_BACKEND,
237 CONTEXT_PERF_CPU_COUNTER, 0),
238 PERF_HW("perf:cpu:instructions", INSTRUCTIONS,
239 CONTEXT_PERF_CPU_COUNTER, 0),
240 PERF_HW("perf:cpu:cache-references", CACHE_REFERENCES,
241 CONTEXT_PERF_CPU_COUNTER, 0),
242 PERF_HW("perf:cpu:cache-misses", CACHE_MISSES,
243 CONTEXT_PERF_CPU_COUNTER, 0),
244 PERF_HW("perf:cpu:branch-instructions", BRANCH_INSTRUCTIONS,
245 CONTEXT_PERF_CPU_COUNTER, 0),
246 PERF_HW("perf:cpu:branches", BRANCH_INSTRUCTIONS,
247 CONTEXT_PERF_CPU_COUNTER, 0),
248 PERF_HW("perf:cpu:branch-misses", BRANCH_MISSES,
249 CONTEXT_PERF_CPU_COUNTER, 0),
250 PERF_HW("perf:cpu:bus-cycles", BUS_CYCLES,
251 CONTEXT_PERF_CPU_COUNTER, 0),
252
253 PERF_HW_CACHE("perf:cpu:L1-dcache", L1D,
254 CONTEXT_PERF_CPU_COUNTER, 0),
255 PERF_HW_CACHE("perf:cpu:L1-icache", L1I,
256 CONTEXT_PERF_CPU_COUNTER, 0),
257 PERF_HW_CACHE("perf:cpu:LLC", LL,
258 CONTEXT_PERF_CPU_COUNTER, 0),
259 PERF_HW_CACHE("perf:cpu:dTLB", DTLB,
260 CONTEXT_PERF_CPU_COUNTER, 0),
261 _PERF_HW_CACHE("perf:cpu:iTLB-loads", ITLB,
262 CONTEXT_PERF_CPU_COUNTER, READ, ACCESS, 0),
263 _PERF_HW_CACHE("perf:cpu:iTLB-load-misses", ITLB,
264 CONTEXT_PERF_CPU_COUNTER, READ, MISS, 0),
265 _PERF_HW_CACHE("perf:cpu:branch-loads", BPU,
266 CONTEXT_PERF_CPU_COUNTER, READ, ACCESS, 0),
267 _PERF_HW_CACHE("perf:cpu:branch-load-misses", BPU,
268 CONTEXT_PERF_CPU_COUNTER, READ, MISS, 0),
269
270 PERF_SW("perf:cpu:cpu-clock", CPU_CLOCK,
271 CONTEXT_PERF_CPU_COUNTER, 0),
272 PERF_SW("perf:cpu:task-clock", TASK_CLOCK,
273 CONTEXT_PERF_CPU_COUNTER, 0),
274 PERF_SW("perf:cpu:page-fault", PAGE_FAULTS,
275 CONTEXT_PERF_CPU_COUNTER, 0),
276 PERF_SW("perf:cpu:faults", PAGE_FAULTS,
277 CONTEXT_PERF_CPU_COUNTER, 0),
278 PERF_SW("perf:cpu:major-faults", PAGE_FAULTS_MAJ,
279 CONTEXT_PERF_CPU_COUNTER, 0),
280 PERF_SW("perf:cpu:minor-faults", PAGE_FAULTS_MIN,
281 CONTEXT_PERF_CPU_COUNTER, 0),
282 PERF_SW("perf:cpu:context-switches", CONTEXT_SWITCHES,
283 CONTEXT_PERF_CPU_COUNTER, 0),
284 PERF_SW("perf:cpu:cs", CONTEXT_SWITCHES,
285 CONTEXT_PERF_CPU_COUNTER, 0),
286 PERF_SW("perf:cpu:cpu-migrations", CPU_MIGRATIONS,
287 CONTEXT_PERF_CPU_COUNTER, 0),
288 PERF_SW("perf:cpu:migrations", CPU_MIGRATIONS,
289 CONTEXT_PERF_CPU_COUNTER, 0),
290 PERF_SW("perf:cpu:alignment-faults", ALIGNMENT_FAULTS,
291 CONTEXT_PERF_CPU_COUNTER, 0),
292 PERF_SW("perf:cpu:emulation-faults", EMULATION_FAULTS,
293 CONTEXT_PERF_CPU_COUNTER, 0),
294
295 /* Perf per-thread counters */
296 PERF_HW("perf:thread:cpu-cycles", CPU_CYCLES,
297 CONTEXT_PERF_THREAD_COUNTER, 0),
298 PERF_HW("perf:thread:cycles", CPU_CYCLES,
299 CONTEXT_PERF_THREAD_COUNTER, 0),
300 PERF_HW("perf:thread:stalled-cycles-frontend", STALLED_CYCLES_FRONTEND,
301 CONTEXT_PERF_THREAD_COUNTER, 0),
302 PERF_HW("perf:thread:idle-cycles-frontend", STALLED_CYCLES_FRONTEND,
303 CONTEXT_PERF_THREAD_COUNTER, 0),
304 PERF_HW("perf:thread:stalled-cycles-backend", STALLED_CYCLES_BACKEND,
305 CONTEXT_PERF_THREAD_COUNTER, 0),
306 PERF_HW("perf:thread:idle-cycles-backend", STALLED_CYCLES_BACKEND,
307 CONTEXT_PERF_THREAD_COUNTER, 0),
308 PERF_HW("perf:thread:instructions", INSTRUCTIONS,
309 CONTEXT_PERF_THREAD_COUNTER, 0),
310 PERF_HW("perf:thread:cache-references", CACHE_REFERENCES,
311 CONTEXT_PERF_THREAD_COUNTER, 0),
312 PERF_HW("perf:thread:cache-misses", CACHE_MISSES,
313 CONTEXT_PERF_THREAD_COUNTER, 0),
314 PERF_HW("perf:thread:branch-instructions", BRANCH_INSTRUCTIONS,
315 CONTEXT_PERF_THREAD_COUNTER, 0),
316 PERF_HW("perf:thread:branches", BRANCH_INSTRUCTIONS,
317 CONTEXT_PERF_THREAD_COUNTER, 0),
318 PERF_HW("perf:thread:branch-misses", BRANCH_MISSES,
319 CONTEXT_PERF_THREAD_COUNTER, 0),
320 PERF_HW("perf:thread:bus-cycles", BUS_CYCLES,
321 CONTEXT_PERF_THREAD_COUNTER, 0),
322
323 PERF_HW_CACHE("perf:thread:L1-dcache", L1D,
324 CONTEXT_PERF_THREAD_COUNTER, 0),
325 PERF_HW_CACHE("perf:thread:L1-icache", L1I,
326 CONTEXT_PERF_THREAD_COUNTER, 0),
327 PERF_HW_CACHE("perf:thread:LLC", LL,
328 CONTEXT_PERF_THREAD_COUNTER, 0),
329 PERF_HW_CACHE("perf:thread:dTLB", DTLB,
330 CONTEXT_PERF_THREAD_COUNTER, 0),
331 _PERF_HW_CACHE("perf:thread:iTLB-loads", ITLB,
332 CONTEXT_PERF_THREAD_COUNTER, READ, ACCESS, 0),
333 _PERF_HW_CACHE("perf:thread:iTLB-load-misses", ITLB,
334 CONTEXT_PERF_THREAD_COUNTER, READ, MISS, 0),
335 _PERF_HW_CACHE("perf:thread:branch-loads", BPU,
336 CONTEXT_PERF_THREAD_COUNTER, READ, ACCESS, 0),
337 _PERF_HW_CACHE("perf:thread:branch-load-misses", BPU,
338 CONTEXT_PERF_THREAD_COUNTER, READ, MISS, 0),
339
340 PERF_SW("perf:thread:cpu-clock", CPU_CLOCK,
341 CONTEXT_PERF_THREAD_COUNTER, 0),
342 PERF_SW("perf:thread:task-clock", TASK_CLOCK,
343 CONTEXT_PERF_THREAD_COUNTER, 0),
344 PERF_SW("perf:thread:page-fault", PAGE_FAULTS,
345 CONTEXT_PERF_THREAD_COUNTER, 0),
346 PERF_SW("perf:thread:faults", PAGE_FAULTS,
347 CONTEXT_PERF_THREAD_COUNTER, 0),
348 PERF_SW("perf:thread:major-faults", PAGE_FAULTS_MAJ,
349 CONTEXT_PERF_THREAD_COUNTER, 0),
350 PERF_SW("perf:thread:minor-faults", PAGE_FAULTS_MIN,
351 CONTEXT_PERF_THREAD_COUNTER, 0),
352 PERF_SW("perf:thread:context-switches", CONTEXT_SWITCHES,
353 CONTEXT_PERF_THREAD_COUNTER, 0),
354 PERF_SW("perf:thread:cs", CONTEXT_SWITCHES,
355 CONTEXT_PERF_THREAD_COUNTER, 0),
356 PERF_SW("perf:thread:cpu-migrations", CPU_MIGRATIONS,
357 CONTEXT_PERF_THREAD_COUNTER, 0),
358 PERF_SW("perf:thread:migrations", CPU_MIGRATIONS,
359 CONTEXT_PERF_THREAD_COUNTER, 0),
360 PERF_SW("perf:thread:alignment-faults", ALIGNMENT_FAULTS,
361 CONTEXT_PERF_THREAD_COUNTER, 0),
362 PERF_SW("perf:thread:emulation-faults", EMULATION_FAULTS,
363 CONTEXT_PERF_THREAD_COUNTER, 0),
364
365 /*
366 * Perf per-CPU counters, backward compatibilty for names.
367 * Hidden from help listing.
368 */
369 PERF_HW("perf:cpu-cycles", CPU_CYCLES,
370 CONTEXT_PERF_COUNTER, 1),
371 PERF_HW("perf:cycles", CPU_CYCLES,
372 CONTEXT_PERF_COUNTER, 1),
373 PERF_HW("perf:stalled-cycles-frontend", STALLED_CYCLES_FRONTEND,
374 CONTEXT_PERF_COUNTER, 1),
375 PERF_HW("perf:idle-cycles-frontend", STALLED_CYCLES_FRONTEND,
376 CONTEXT_PERF_COUNTER, 1),
377 PERF_HW("perf:stalled-cycles-backend", STALLED_CYCLES_BACKEND,
378 CONTEXT_PERF_COUNTER, 1),
379 PERF_HW("perf:idle-cycles-backend", STALLED_CYCLES_BACKEND,
380 CONTEXT_PERF_COUNTER, 1),
381 PERF_HW("perf:instructions", INSTRUCTIONS,
382 CONTEXT_PERF_COUNTER, 1),
383 PERF_HW("perf:cache-references", CACHE_REFERENCES,
384 CONTEXT_PERF_COUNTER, 1),
385 PERF_HW("perf:cache-misses", CACHE_MISSES,
386 CONTEXT_PERF_COUNTER, 1),
387 PERF_HW("perf:branch-instructions", BRANCH_INSTRUCTIONS,
388 CONTEXT_PERF_COUNTER, 1),
389 PERF_HW("perf:branches", BRANCH_INSTRUCTIONS,
390 CONTEXT_PERF_COUNTER, 1),
391 PERF_HW("perf:branch-misses", BRANCH_MISSES,
392 CONTEXT_PERF_COUNTER, 1),
393 PERF_HW("perf:bus-cycles", BUS_CYCLES,
394 CONTEXT_PERF_COUNTER, 1),
395
396 PERF_HW_CACHE("perf:L1-dcache", L1D,
397 CONTEXT_PERF_COUNTER, 1),
398 PERF_HW_CACHE("perf:L1-icache", L1I,
399 CONTEXT_PERF_COUNTER, 1),
400 PERF_HW_CACHE("perf:LLC", LL,
401 CONTEXT_PERF_COUNTER, 1),
402 PERF_HW_CACHE("perf:dTLB", DTLB,
403 CONTEXT_PERF_COUNTER, 1),
404 _PERF_HW_CACHE("perf:iTLB-loads", ITLB,
405 CONTEXT_PERF_COUNTER, READ, ACCESS, 1),
406 _PERF_HW_CACHE("perf:iTLB-load-misses", ITLB,
407 CONTEXT_PERF_COUNTER, READ, MISS, 1),
408 _PERF_HW_CACHE("perf:branch-loads", BPU,
409 CONTEXT_PERF_COUNTER, READ, ACCESS, 1),
410 _PERF_HW_CACHE("perf:branch-load-misses", BPU,
411 CONTEXT_PERF_COUNTER, READ, MISS, 1),
412
413 PERF_SW("perf:cpu-clock", CPU_CLOCK,
414 CONTEXT_PERF_COUNTER, 1),
415 PERF_SW("perf:task-clock", TASK_CLOCK,
416 CONTEXT_PERF_COUNTER, 1),
417 PERF_SW("perf:page-fault", PAGE_FAULTS,
418 CONTEXT_PERF_COUNTER, 1),
419 PERF_SW("perf:faults", PAGE_FAULTS,
420 CONTEXT_PERF_COUNTER, 1),
421 PERF_SW("perf:major-faults", PAGE_FAULTS_MAJ,
422 CONTEXT_PERF_COUNTER, 1),
423 PERF_SW("perf:minor-faults", PAGE_FAULTS_MIN,
424 CONTEXT_PERF_COUNTER, 1),
425 PERF_SW("perf:context-switches", CONTEXT_SWITCHES,
426 CONTEXT_PERF_COUNTER, 1),
427 PERF_SW("perf:cs", CONTEXT_SWITCHES,
428 CONTEXT_PERF_COUNTER, 1),
429 PERF_SW("perf:cpu-migrations", CPU_MIGRATIONS,
430 CONTEXT_PERF_COUNTER, 1),
431 PERF_SW("perf:migrations", CPU_MIGRATIONS,
432 CONTEXT_PERF_COUNTER, 1),
433 PERF_SW("perf:alignment-faults", ALIGNMENT_FAULTS,
434 CONTEXT_PERF_COUNTER, 1),
435 PERF_SW("perf:emulation-faults", EMULATION_FAULTS,
436 CONTEXT_PERF_COUNTER, 1),
437
b13d56d7 438 { NULL, -1 }, /* Closure */
90b9a268
DG
439};
440
aa3514e9
MD
441#undef PERF_HW_CACHE
442#undef _PERF_HW_CACHE
b13d56d7
MD
443#undef PERF_SW
444#undef PERF_HW
445
90b9a268 446/*
b13d56d7 447 * Context type for command line option parsing.
90b9a268 448 */
b13d56d7
MD
449struct ctx_type {
450 const struct ctx_opts *opt;
451 struct cds_list_head list;
90b9a268
DG
452};
453
454/*
455 * List of context type. Use to enable multiple context on a single command
456 * line entry.
457 */
458struct ctx_type_list {
459 struct cds_list_head head;
460} ctx_type_list = {
461 .head = CDS_LIST_HEAD_INIT(ctx_type_list.head),
462};
463
90b9a268
DG
464/*
465 * Pretty print context type.
466 */
467static void print_ctx_type(FILE *ofp)
468{
b13d56d7
MD
469 const char *indent = " ";
470 int indent_len = strlen(indent);
471 int len, i = 0;
90b9a268 472
76e3c5dd 473 fprintf(ofp, "%s", indent);
b13d56d7 474 len = indent_len;
90b9a268 475 while (ctx_opts[i].symbol != NULL) {
aa3514e9
MD
476 if (!ctx_opts[i].hide_help) {
477 if (len > indent_len) {
478 if (len + strlen(ctx_opts[i].symbol) + 2
479 >= PRINT_LINE_LEN) {
480 fprintf(ofp, ",\n");
481 fprintf(ofp, "%s", indent);
482 len = indent_len;
483 } else {
484 len += fprintf(ofp, ", ");
485 }
90b9a268 486 }
aa3514e9 487 len += fprintf(ofp, "%s", ctx_opts[i].symbol);
90b9a268
DG
488 }
489 i++;
490 }
90b9a268
DG
491}
492
d65106b1
DG
493/*
494 * usage
495 */
496static void usage(FILE *ofp)
497{
32a6298d 498 fprintf(ofp, "usage: lttng add-context -t TYPE [-k|-u] [OPTIONS]\n");
d65106b1 499 fprintf(ofp, "\n");
601d5acf
DG
500 fprintf(ofp, "If no channel is given (-c), the context is added to\n");
501 fprintf(ofp, "all channels.\n");
32a6298d 502 fprintf(ofp, "\n");
601d5acf 503 fprintf(ofp, "Otherwise the context is added only to the channel (-c).\n");
32a6298d
DG
504 fprintf(ofp, "\n");
505 fprintf(ofp, "Exactly one domain (-k or -u) must be specified.\n");
3301e740 506 fprintf(ofp, "\n");
d65106b1
DG
507 fprintf(ofp, "Options:\n");
508 fprintf(ofp, " -h, --help Show this help\n");
679b4943 509 fprintf(ofp, " --list-options Simple listing of options\n");
5eb00805
TD
510 fprintf(ofp, " -s, --session NAME Apply to session name\n");
511 fprintf(ofp, " -c, --channel NAME Apply to channel\n");
af87c45a 512 fprintf(ofp, " -k, --kernel Apply to the kernel tracer\n");
af87c45a 513 fprintf(ofp, " -u, --userspace Apply to the user-space tracer\n");
32a6298d
DG
514 fprintf(ofp, "\n");
515 fprintf(ofp, "Context:\n");
b13d56d7 516 fprintf(ofp, " -t, --type TYPE Context type. You can repeat that option on\n");
af87c45a
DG
517 fprintf(ofp, " the command line to specify multiple contexts at once.\n");
518 fprintf(ofp, " (--kernel preempts --userspace)\n");
b13d56d7 519 fprintf(ofp, " TYPE can be one of the strings below:\n");
90b9a268 520 print_ctx_type(ofp);
d65106b1 521 fprintf(ofp, "\n");
c455d428
FD
522 fprintf(ofp, "Note that the vpid, vppid and vtid context types represent the virtual process id,\n"
523 "virtual parent process id and virtual thread id as seen from the current execution context\n"
524 "as opposed to the pid, ppid and tid which are kernel internal data structures.\n\n");
90b9a268 525 fprintf(ofp, "Example:\n");
aa3514e9
MD
526 fprintf(ofp, "This command will add the context information 'prio' and two per-cpu\n"
527 "perf counters (hardware branch misses and cache misses), to all channels\n"
b13d56d7 528 "in the trace data output:\n");
aa3514e9 529 fprintf(ofp, "# lttng add-context -k -t prio -t perf:cpu:branch-misses -t perf:cpu:cache-misses\n");
d65106b1
DG
530 fprintf(ofp, "\n");
531}
532
90b9a268
DG
533/*
534 * Find context numerical value from string.
535 */
536static int find_ctx_type_idx(const char *opt)
537{
538 int ret = -1, i = 0;
539
540 while (ctx_opts[i].symbol != NULL) {
541 if (strcmp(opt, ctx_opts[i].symbol) == 0) {
542 ret = i;
543 goto end;
544 }
545 i++;
546 }
547
548end:
549 return ret;
550}
551
90b9a268
DG
552/*
553 * Add context to channel or event.
d65106b1 554 */
cd80958d 555static int add_context(char *session_name)
d65106b1 556{
89b72577 557 int ret = CMD_SUCCESS, warn = 0, success = 0;
7d29a247
DG
558 struct lttng_event_context context;
559 struct lttng_domain dom;
3301e740 560 struct ctx_type *type;
b13d56d7 561 char *ptr;
d65106b1 562
441c16a7
MD
563 memset(&context, 0, sizeof(context));
564 memset(&dom, 0, sizeof(dom));
565
cd80958d
DG
566 if (opt_kernel) {
567 dom.type = LTTNG_DOMAIN_KERNEL;
d78d6610 568 } else if (opt_userspace) {
55cc08a6 569 dom.type = LTTNG_DOMAIN_UST;
55cc08a6 570 } else {
deaef3cf 571 assert(0);
cd80958d
DG
572 }
573
574 handle = lttng_create_handle(session_name, &dom);
575 if (handle == NULL) {
af87c45a 576 ret = CMD_ERROR;
cd80958d
DG
577 goto error;
578 }
579
89b72577
JRJ
580 if (lttng_opt_mi) {
581 /* Open a contexts element */
582 ret = mi_lttng_writer_open_element(writer, config_element_contexts);
583 if (ret) {
584 goto error;
585 }
586 }
587
5eb00805 588 /* Iterate over all the context types given */
3301e740 589 cds_list_for_each_entry(type, &ctx_type_list.head, list) {
6775595e 590 context.ctx = (enum lttng_event_context_type) type->opt->ctx_type;
aa3514e9
MD
591 switch (context.ctx) {
592 case LTTNG_EVENT_CONTEXT_PERF_COUNTER:
593 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER:
594 case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
b13d56d7
MD
595 context.u.perf_counter.type = type->opt->u.perf.type;
596 context.u.perf_counter.config = type->opt->u.perf.config;
24546386
MD
597 strncpy(context.u.perf_counter.name, type->opt->symbol,
598 LTTNG_SYMBOL_NAME_LEN);
599 context.u.perf_counter.name[LTTNG_SYMBOL_NAME_LEN - 1] = '\0';
b13d56d7
MD
600 /* Replace : and - by _ */
601 while ((ptr = strchr(context.u.perf_counter.name, '-')) != NULL) {
602 *ptr = '_';
3301e740 603 }
b13d56d7
MD
604 while ((ptr = strchr(context.u.perf_counter.name, ':')) != NULL) {
605 *ptr = '_';
3301e740 606 }
aa3514e9
MD
607 break;
608 default:
609 break;
3301e740 610 }
55cc08a6
DG
611 DBG("Adding context...");
612
89b72577
JRJ
613 if (lttng_opt_mi) {
614 /* We leave context open the update the success of the command */
615 ret = mi_lttng_context(writer, &context, 1);
616 if (ret) {
617 ret = CMD_ERROR;
618 goto error;
619 }
620 }
621
601d5acf 622 ret = lttng_add_context(handle, &context, NULL, opt_channel_name);
55cc08a6 623 if (ret < 0) {
b58471ff 624 ERR("%s: %s", type->opt->symbol, lttng_strerror(ret));
d16c1a4c 625 warn = 1;
89b72577 626 success = 0;
d65106b1 627 } else {
601d5acf 628 if (opt_channel_name) {
b58471ff 629 MSG("%s context %s added to channel %s",
6fbe385e 630 get_domain_str(dom.type), type->opt->symbol,
b58471ff 631 opt_channel_name);
b58471ff
DG
632 } else {
633 MSG("%s context %s added to all channels",
6fbe385e 634 get_domain_str(dom.type), type->opt->symbol)
b58471ff 635 }
89b72577
JRJ
636 success = 1;
637 }
638
639 if (lttng_opt_mi) {
640 /* Is the single operation a success ? */
641 ret = mi_lttng_writer_write_element_bool(writer,
642 mi_lttng_element_success, success);
643 if (ret) {
644 ret = CMD_ERROR;
645 goto error;
646 }
647
648 /* Close the context element */
649 ret = mi_lttng_writer_close_element(writer);
650 if (ret) {
651 ret = CMD_ERROR;
652 goto error;
653 }
654 }
655 }
656
657 if (lttng_opt_mi) {
658 /* Close contexts element */
659 ret = mi_lttng_writer_close_element(writer);
660 if (ret) {
661 goto error;
d65106b1 662 }
d65106b1
DG
663 }
664
af87c45a
DG
665 ret = CMD_SUCCESS;
666
d65106b1 667error:
cd80958d
DG
668 lttng_destroy_handle(handle);
669
d16c1a4c
DG
670 /*
671 * This means that at least one add_context failed and tells the user to
672 * look on stderr for error(s).
673 */
89b72577 674 if (!ret && warn) {
d16c1a4c
DG
675 ret = CMD_WARNING;
676 }
d65106b1
DG
677 return ret;
678}
679
680/*
5eb00805 681 * Add context to channel or event.
d65106b1
DG
682 */
683int cmd_add_context(int argc, const char **argv)
684{
89b72577
JRJ
685 int index, opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS;
686 int success = 1;
d65106b1 687 static poptContext pc;
b13d56d7 688 struct ctx_type *type, *tmptype;
cd80958d 689 char *session_name = NULL;
d65106b1 690
636167b6
DG
691 if (argc < 2) {
692 usage(stderr);
5eb00805 693 ret = CMD_ERROR;
636167b6
DG
694 goto end;
695 }
696
d65106b1
DG
697 pc = poptGetContext(NULL, argc, argv, long_options, 0);
698 poptReadDefaultConfig(pc, 0);
699
700 while ((opt = poptGetNextOpt(pc)) != -1) {
701 switch (opt) {
702 case OPT_HELP:
5eb00805 703 usage(stdout);
d65106b1
DG
704 goto end;
705 case OPT_TYPE:
af87c45a
DG
706 /*
707 * Look up the index of opt_type in ctx_opts[] first, so we don't
708 * have to free(type) on failure.
709 */
6caa2bcc 710 index = find_ctx_type_idx(opt_type);
b13d56d7 711 if (index < 0) {
6caa2bcc 712 ERR("Unknown context type %s", opt_type);
5eb00805 713 ret = CMD_ERROR;
b13d56d7 714 goto end;
90b9a268 715 }
5eb00805 716
fd3d2d34 717 type = zmalloc(sizeof(struct ctx_type));
5eb00805
TD
718 if (type == NULL) {
719 perror("malloc ctx_type");
720 ret = CMD_FATAL;
721 goto end;
722 }
723
b13d56d7 724 type->opt = &ctx_opts[index];
109be0da 725 if (type->opt->symbol == NULL) {
6caa2bcc 726 ERR("Unknown context type %s", opt_type);
5eb00805
TD
727 free(type);
728 ret = CMD_ERROR;
729 goto end;
90b9a268 730 } else {
31746f93 731 cds_list_add_tail(&type->list, &ctx_type_list.head);
90b9a268 732 }
d65106b1 733 break;
eeac7d46
MD
734 case OPT_USERSPACE:
735 opt_userspace = 1;
d78d6610 736#if 0
eeac7d46 737 opt_cmd_name = poptGetOptArg(pc);
d78d6610 738#endif
eeac7d46 739 break;
679b4943
SM
740 case OPT_LIST_OPTIONS:
741 list_cmd_options(stdout, long_options);
679b4943 742 goto end;
d65106b1
DG
743 default:
744 usage(stderr);
745 ret = CMD_UNDEFINED;
746 goto end;
747 }
748 }
749
deaef3cf
PP
750 ret = print_missing_or_multiple_domains(opt_kernel + opt_userspace);
751
752 if (ret) {
753 ret = CMD_ERROR;
754 goto end;
755 }
756
ae856491
DG
757 if (!opt_type) {
758 ERR("Missing mandatory -t TYPE");
759 usage(stderr);
760 ret = CMD_ERROR;
761 goto end;
762 }
763
cd80958d
DG
764 if (!opt_session_name) {
765 session_name = get_session_name();
766 if (session_name == NULL) {
5eb00805 767 ret = CMD_ERROR;
cd80958d
DG
768 goto end;
769 }
770 } else {
771 session_name = opt_session_name;
772 }
773
89b72577
JRJ
774 /* Mi check */
775 if (lttng_opt_mi) {
776 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
777 if (!writer) {
778 ret = -LTTNG_ERR_NOMEM;
779 goto end;
780 }
781
782 /* Open command element */
783 ret = mi_lttng_writer_command_open(writer,
784 mi_lttng_element_command_add_context);
785 if (ret) {
786 ret = CMD_ERROR;
787 goto end;
788 }
789
790 /* Open output element */
791 ret = mi_lttng_writer_open_element(writer,
792 mi_lttng_element_command_output);
793 if (ret) {
794 ret = CMD_ERROR;
795 goto end;
796 }
797 }
798
799 command_ret = add_context(session_name);
800 if (command_ret) {
801 success = 0;
802 }
803
804 /* Mi closing */
805 if (lttng_opt_mi) {
806 /* Close output element */
807 ret = mi_lttng_writer_close_element(writer);
808 if (ret) {
809 ret = CMD_ERROR;
810 goto end;
811 }
3301e740 812
89b72577
JRJ
813 /* Success ? */
814 ret = mi_lttng_writer_write_element_bool(writer,
815 mi_lttng_element_command_success, success);
816 if (ret) {
817 ret = CMD_ERROR;
818 goto end;
819 }
820
821 /* Command element close */
822 ret = mi_lttng_writer_command_close(writer);
823 if (ret) {
824 ret = CMD_ERROR;
825 goto end;
826 }
827 }
828
829end:
1256f150
DT
830 if (!opt_session_name) {
831 free(session_name);
832 }
833
89b72577
JRJ
834 /* Mi clean-up */
835 if (writer && mi_lttng_writer_destroy(writer)) {
836 /* Preserve original error code */
837 ret = ret ? ret : LTTNG_ERR_MI_IO_FAIL;
838 }
839
3301e740 840 /* Cleanup allocated memory */
b13d56d7 841 cds_list_for_each_entry_safe(type, tmptype, &ctx_type_list.head, list) {
3301e740
DG
842 free(type);
843 }
844
89b72577
JRJ
845 /* Overwrite ret if an error occurred during add_context() */
846 ret = command_ret ? command_ret : ret;
847
ca1c3607 848 poptFreeContext(pc);
d65106b1
DG
849 return ret;
850}
This page took 0.079317 seconds and 4 git commands to generate.