diff options
| author | Steven Rostedt <srostedt@redhat.com> | 2010-02-16 11:37:43 -0500 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2010-02-16 11:37:43 -0500 |
| commit | ae7be6735ae6ceaffb001cc39d3f833d34cb5255 (patch) | |
| tree | fbc26a2c42ddaf2bd1b4780c64aeab4e49028bf1 | |
| parent | 4d477302e1fc73d50e462fdc9e67a2ded9e38885 (diff) | |
trace-cmd: Add trace-cmd report -v option
Add a -v option to trace-cmd report to negate all filters specified
after it. That is, records that match those filters will not be
displayed.
./trace-cmd report -F sched -v -F 'sched_switch: next_prio > 100'
This will display all sched events except sched_switch events where
the next_prio is greater than 100.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
| -rw-r--r-- | trace-cmd.c | 3 | ||||
| -rw-r--r-- | trace-read.c | 29 |
2 files changed, 26 insertions, 6 deletions
diff --git a/trace-cmd.c b/trace-cmd.c index a50773e..c8e507a 100644 --- a/trace-cmd.c +++ b/trace-cmd.c | |||
| @@ -1035,13 +1035,14 @@ void usage(char **argv) | |||
| 1035 | " Disables the tracer (may reset trace file)\n" | 1035 | " Disables the tracer (may reset trace file)\n" |
| 1036 | " Used in conjunction with start\n" | 1036 | " Used in conjunction with start\n" |
| 1037 | "\n" | 1037 | "\n" |
| 1038 | " %s report [-i file] [--cpu cpu] [-e][-f][-l][-P][-E][-F filter]\n" | 1038 | " %s report [-i file] [--cpu cpu] [-e][-f][-l][-P][-E][-F filter][-v]\n" |
| 1039 | " -i input file [default trace.dat]\n" | 1039 | " -i input file [default trace.dat]\n" |
| 1040 | " -e show file endianess\n" | 1040 | " -e show file endianess\n" |
| 1041 | " -f show function list\n" | 1041 | " -f show function list\n" |
| 1042 | " -P show printk list\n" | 1042 | " -P show printk list\n" |
| 1043 | " -E show event files stored\n" | 1043 | " -E show event files stored\n" |
| 1044 | " -F filter to filter output on\n" | 1044 | " -F filter to filter output on\n" |
| 1045 | " -v will negate all -F after it (Not show matches)\n" | ||
| 1045 | " -l show latency format (default with latency tracers)\n" | 1046 | " -l show latency format (default with latency tracers)\n" |
| 1046 | "\n" | 1047 | "\n" |
| 1047 | " %s split [options] -o file [start [end]]\n" | 1048 | " %s split [options] -o file [start [end]]\n" |
diff --git a/trace-read.c b/trace-read.c index 97c8f52..ee56530 100644 --- a/trace-read.c +++ b/trace-read.c | |||
| @@ -41,10 +41,12 @@ | |||
| 41 | static struct filter { | 41 | static struct filter { |
| 42 | struct filter *next; | 42 | struct filter *next; |
| 43 | const char *filter; | 43 | const char *filter; |
| 44 | int neg; | ||
| 44 | } *filter_strings; | 45 | } *filter_strings; |
| 45 | static struct filter **filter_next = &filter_strings; | 46 | static struct filter **filter_next = &filter_strings; |
| 46 | 47 | ||
| 47 | static struct event_filter *event_filters; | 48 | static struct event_filter *event_filters; |
| 49 | static struct event_filter *event_filter_out; | ||
| 48 | 50 | ||
| 49 | static unsigned int page_size; | 51 | static unsigned int page_size; |
| 50 | static int input_fd; | 52 | static int input_fd; |
| @@ -197,13 +199,14 @@ static void test_save(struct record *record, int cpu) | |||
| 197 | } | 199 | } |
| 198 | #endif | 200 | #endif |
| 199 | 201 | ||
| 200 | static void add_filter(const char *filter) | 202 | static void add_filter(const char *filter, int neg) |
| 201 | { | 203 | { |
| 202 | struct filter *ftr; | 204 | struct filter *ftr; |
| 203 | 205 | ||
| 204 | ftr = malloc_or_die(sizeof(*ftr)); | 206 | ftr = malloc_or_die(sizeof(*ftr)); |
| 205 | ftr->filter = filter; | 207 | ftr->filter = filter; |
| 206 | ftr->next = NULL; | 208 | ftr->next = NULL; |
| 209 | ftr->neg = neg; | ||
| 207 | 210 | ||
| 208 | /* must maintain order of command line */ | 211 | /* must maintain order of command line */ |
| 209 | *filter_next = ftr; | 212 | *filter_next = ftr; |
| @@ -212,6 +215,7 @@ static void add_filter(const char *filter) | |||
| 212 | 215 | ||
| 213 | static void process_filters(struct tracecmd_input *handle) | 216 | static void process_filters(struct tracecmd_input *handle) |
| 214 | { | 217 | { |
| 218 | struct event_filter *event_filter; | ||
| 215 | struct pevent *pevent; | 219 | struct pevent *pevent; |
| 216 | struct filter *filter; | 220 | struct filter *filter; |
| 217 | char *errstr; | 221 | char *errstr; |
| @@ -219,11 +223,17 @@ static void process_filters(struct tracecmd_input *handle) | |||
| 219 | 223 | ||
| 220 | pevent = tracecmd_get_pevent(handle); | 224 | pevent = tracecmd_get_pevent(handle); |
| 221 | event_filters = pevent_filter_alloc(pevent); | 225 | event_filters = pevent_filter_alloc(pevent); |
| 226 | event_filter_out = pevent_filter_alloc(pevent); | ||
| 222 | 227 | ||
| 223 | while (filter_strings) { | 228 | while (filter_strings) { |
| 224 | filter = filter_strings; | 229 | filter = filter_strings; |
| 225 | filter_strings = filter->next; | 230 | filter_strings = filter->next; |
| 226 | ret = pevent_filter_add_filter_str(event_filters, | 231 | if (filter->neg) |
| 232 | event_filter = event_filter_out; | ||
| 233 | else | ||
| 234 | event_filter = event_filters; | ||
| 235 | |||
| 236 | ret = pevent_filter_add_filter_str(event_filter, | ||
| 227 | filter->filter, | 237 | filter->filter, |
| 228 | &errstr); | 238 | &errstr); |
| 229 | if (ret < 0) | 239 | if (ret < 0) |
| @@ -311,7 +321,9 @@ static void read_data_info(struct tracecmd_input *handle) | |||
| 311 | switch (ret) { | 321 | switch (ret) { |
| 312 | case FILTER_NONE: | 322 | case FILTER_NONE: |
| 313 | case FILTER_MATCH: | 323 | case FILTER_MATCH: |
| 314 | show_data(handle, record, next); | 324 | ret = pevent_filter_match(event_filter_out, record); |
| 325 | if (ret != FILTER_MATCH) | ||
| 326 | show_data(handle, record, next); | ||
| 315 | break; | 327 | break; |
| 316 | } | 328 | } |
| 317 | free_record(record); | 329 | free_record(record); |
| @@ -319,6 +331,7 @@ static void read_data_info(struct tracecmd_input *handle) | |||
| 319 | } while (record); | 331 | } while (record); |
| 320 | 332 | ||
| 321 | pevent_filter_free(event_filters); | 333 | pevent_filter_free(event_filters); |
| 334 | pevent_filter_free(event_filter_out); | ||
| 322 | 335 | ||
| 323 | show_test(handle); | 336 | show_test(handle); |
| 324 | } | 337 | } |
| @@ -343,6 +356,7 @@ void trace_report (int argc, char **argv) | |||
| 343 | int latency_format = 0; | 356 | int latency_format = 0; |
| 344 | int show_events = 0; | 357 | int show_events = 0; |
| 345 | int print_events = 0; | 358 | int print_events = 0; |
| 359 | int neg = 0; | ||
| 346 | int c; | 360 | int c; |
| 347 | 361 | ||
| 348 | if (argc < 2) | 362 | if (argc < 2) |
| @@ -360,7 +374,7 @@ void trace_report (int argc, char **argv) | |||
| 360 | {NULL, 0, NULL, 0} | 374 | {NULL, 0, NULL, 0} |
| 361 | }; | 375 | }; |
| 362 | 376 | ||
| 363 | c = getopt_long (argc-1, argv+1, "+hi:fepPlEF:", | 377 | c = getopt_long (argc-1, argv+1, "+hi:fepPlEF:v", |
| 364 | long_options, &option_index); | 378 | long_options, &option_index); |
| 365 | if (c == -1) | 379 | if (c == -1) |
| 366 | break; | 380 | break; |
| @@ -372,7 +386,7 @@ void trace_report (int argc, char **argv) | |||
| 372 | input_file = optarg; | 386 | input_file = optarg; |
| 373 | break; | 387 | break; |
| 374 | case 'F': | 388 | case 'F': |
| 375 | add_filter(optarg); | 389 | add_filter(optarg, neg); |
| 376 | break; | 390 | break; |
| 377 | case 'f': | 391 | case 'f': |
| 378 | show_funcs = 1; | 392 | show_funcs = 1; |
| @@ -392,6 +406,11 @@ void trace_report (int argc, char **argv) | |||
| 392 | case 'l': | 406 | case 'l': |
| 393 | latency_format = 1; | 407 | latency_format = 1; |
| 394 | break; | 408 | break; |
| 409 | case 'v': | ||
| 410 | if (neg) | ||
| 411 | die("Only 1 -v can be used"); | ||
| 412 | neg = 1; | ||
| 413 | break; | ||
| 395 | case 0: | 414 | case 0: |
| 396 | switch(option_index) { | 415 | switch(option_index) { |
| 397 | case 0: | 416 | case 0: |
