2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; only version 2
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25 #include <sys/types.h>
28 #include <urcu/list.h>
34 static char *opt_event_name
;
35 static char *opt_channel_name
;
36 static char *opt_perf_name
;
37 static char *opt_session_name
;
38 static int *opt_kernel
;
39 static int opt_pid_all
;
40 static int opt_userspace
;
41 static int opt_perf_type
= -1;
42 static int opt_perf_id
= -1;
50 struct ctx_type_list
{
51 struct cds_list_head head
;
56 struct cds_list_head list
;
59 static struct ctx_type_list ctx_type_list
= {
60 .head
= CDS_LIST_HEAD_INIT(ctx_type_list
.head
),
63 static struct poptOption long_options
[] = {
64 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
65 {"help", 'h', POPT_ARG_NONE
, 0, OPT_HELP
, 0, 0},
66 {"session", 's', POPT_ARG_STRING
, &opt_session_name
, 0, 0, 0},
67 {"channel", 'c', POPT_ARG_STRING
, &opt_channel_name
, 0, 0, 0},
68 {"event", 'e', POPT_ARG_STRING
, &opt_event_name
, 0, 0, 0},
69 {"kernel", 'k', POPT_ARG_VAL
, &opt_kernel
, 1, 0, 0},
70 {"userspace", 'u', POPT_ARG_VAL
, &opt_userspace
, 1, 0, 0},
71 {"all", 0, POPT_ARG_VAL
, &opt_pid_all
, 1, 0, 0},
72 {"pid", 'p', POPT_ARG_INT
, &opt_pid
, 0, 0, 0},
73 {"type", 't', POPT_ARG_INT
, 0, OPT_TYPE
, 0, 0},
74 {"perf-name", 0, POPT_ARG_STRING
, &opt_perf_name
, 0, 0, 0},
75 {"perf-type", 0, POPT_ARG_INT
, &opt_perf_type
, 0, 0, 0},
76 {"perf-id", 0, POPT_ARG_INT
, &opt_perf_id
, 0, 0, 0},
83 static void usage(FILE *ofp
)
85 fprintf(ofp
, "usage: lttng add-context [options] [context_options]\n");
88 fprintf(ofp
, "If no event name is given (-e), the context will be added to "
89 "all events in the channel.\n");
90 fprintf(ofp
, "If no channel and no event is given (-c/-e), the context "
91 "will be added to all events in all channels\n");
93 fprintf(ofp
, "Options:\n");
94 fprintf(ofp
, " -h, --help Show this help\n");
95 fprintf(ofp
, " -s, --session Apply on session name\n");
96 fprintf(ofp
, " -c, --channel NAME Apply on channel\n");
97 fprintf(ofp
, " -e, --event NAME Apply on event\n");
98 fprintf(ofp
, " -k, --kernel Apply for the kernel tracer\n");
99 fprintf(ofp
, " -u, --userspace Apply for the user-space tracer\n");
100 fprintf(ofp
, " --all If -u, apply on all traceable apps\n");
101 fprintf(ofp
, " -p, --pid PID If -u, apply on a specific PID\n");
102 fprintf(ofp
, " -t, --type TYPE Context type. TYPE must be a numerical value:\n");
103 fprintf(ofp
, " KERNEL_CONTEXT_PID = 0\n");
104 fprintf(ofp
, " KERNEL_CONTEXT_PERF_COUNTER = 1\n");
105 fprintf(ofp
, " KERNEL_CONTEXT_COMM = 2\n");
106 fprintf(ofp
, " KERNEL_CONTEXT_PRIO = 3\n");
107 fprintf(ofp
, " KERNEL_CONTEXT_NICE = 4\n");
108 fprintf(ofp
, " KERNEL_CONTEXT_VPID = 5\n");
109 fprintf(ofp
, " KERNEL_CONTEXT_TID = 6\n");
110 fprintf(ofp
, " KERNEL_CONTEXT_VTID = 7\n");
111 fprintf(ofp
, " KERNEL_CONTEXT_PPID = 8\n");
112 fprintf(ofp
, " KERNEL_CONTEXT_VPPID = 9\n");
114 fprintf(ofp
, "Context options:\n");
115 fprintf(ofp
, " --perf-name NAME Perf event name\n");
116 fprintf(ofp
, " --perf-type TYPE Perf event type. TYPE must be a numeric value:\n");
117 fprintf(ofp
, " PERF_TYPE_HARDWARE = 0\n");
118 fprintf(ofp
, " PERF_TYPE_SOFTWARE = 1\n");
119 fprintf(ofp
, " --perf-id ID Perf event id. ID must be a numeric value:\n");
120 fprintf(ofp
, " Hardware IDs (0):\n");
121 fprintf(ofp
, " PERF_COUNT_HW_CPU_CYCLES = 0\n");
122 fprintf(ofp
, " PERF_COUNT_HW_INSTRUCTIONS = 1\n");
123 fprintf(ofp
, " PERF_COUNT_HW_CACHE_REFERENCES = 2\n");
124 fprintf(ofp
, " PERF_COUNT_HW_CACHE_MISSES = 3\n");
125 fprintf(ofp
, " PERF_COUNT_HW_BRANCH_INSTRUCTIONS = 4\n");
126 fprintf(ofp
, " PERF_COUNT_HW_BRANCH_MISSES = 5\n");
127 fprintf(ofp
, " PERF_COUNT_HW_BUS_CYCLES = 6\n");
128 fprintf(ofp
, " Software IDs (1):\n");
129 fprintf(ofp
, " PERF_COUNT_SW_CPU_CLOCK = 0\n");
130 fprintf(ofp
, " PERF_COUNT_SW_TASK_CLOCK = 1\n");
131 fprintf(ofp
, " PERF_COUNT_SW_PAGE_FAULTS = 2\n");
132 fprintf(ofp
, " PERF_COUNT_SW_CONTEXT_SWITCHES = 3\n");
133 fprintf(ofp
, " PERF_COUNT_SW_CPU_MIGRATIONS = 4\n");
134 fprintf(ofp
, " PERF_COUNT_SW_PAGE_FAULTS_MIN = 5\n");
135 fprintf(ofp
, " PERF_COUNT_SW_PAGE_FAULTS_MAJ = 6\n");
142 * Add context to channel or event.
144 static int add_context(void)
146 int ret
= CMD_SUCCESS
;
147 struct lttng_event_context context
;
148 struct lttng_domain dom
;
149 struct ctx_type
*type
;
151 if (set_session_name(opt_session_name
) < 0) {
156 /* Iterate over all context type given */
157 cds_list_for_each_entry(type
, &ctx_type_list
.head
, list
) {
158 context
.ctx
= type
->type
;
159 if (type
->type
== LTTNG_KERNEL_CONTEXT_PERF_COUNTER
) {
161 if (opt_perf_type
== -1) {
162 ERR("No perf event type given. Please use --perf-type TYPE.");
165 context
.u
.perf_counter
.type
= opt_perf_type
;
166 if (opt_perf_id
== -1) {
167 ERR("No perf event id given. Please use --perf-id ID.");
170 context
.u
.perf_counter
.config
= opt_perf_id
;
171 if (opt_perf_name
== NULL
) {
172 ERR("No perf name given. Please use --perf-name NAME.");
175 strncpy(context
.u
.perf_counter
.name
, opt_perf_name
,
176 LTTNG_SYMBOL_NAME_LEN
);
180 /* Create kernel domain */
181 dom
.type
= LTTNG_DOMAIN_KERNEL
;
183 DBG("Adding kernel context");
184 ret
= lttng_add_context(&dom
, &context
, opt_event_name
,
189 if (type
->type
== LTTNG_KERNEL_CONTEXT_PERF_COUNTER
) {
190 MSG("Perf counter context added");
192 MSG("Kernel context %d added", type
->type
);
195 } else if (opt_userspace
) { /* User-space tracer action */
197 * TODO: Waiting on lttng UST 2.0
200 } else if (opt_pid
!= 0) {
202 ret
= CMD_NOT_IMPLEMENTED
;
205 ERR("Please specify a tracer (kernel or user-space)");
217 * Add context on channel or event.
219 int cmd_add_context(int argc
, const char **argv
)
221 int opt
, ret
= CMD_SUCCESS
;
223 static poptContext pc
;
224 struct ctx_type
*type
;
231 pc
= poptGetContext(NULL
, argc
, argv
, long_options
, 0);
232 poptReadDefaultConfig(pc
, 0);
234 while ((opt
= poptGetNextOpt(pc
)) != -1) {
241 /* Mandatory field */
242 tmp
= poptGetOptArg(pc
);
249 type
= malloc(sizeof(struct ctx_type
));
251 perror("malloc ctx_type");
255 type
->type
= atoi(tmp
);
256 cds_list_add(&type
->list
, &ctx_type_list
.head
);
268 /* Cleanup allocated memory */
269 cds_list_for_each_entry(type
, &ctx_type_list
.head
, list
) {