Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756010AbbLDRDs (ORCPT ); Fri, 4 Dec 2015 12:03:48 -0500 Received: from mx0a-00082601.pphosted.com ([67.231.145.42]:18633 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754633AbbLDRDr (ORCPT ); Fri, 4 Dec 2015 12:03:47 -0500 From: Josef Bacik To: , , Subject: [PATCH] trace-cmd: filter out specific pids Date: Fri, 4 Dec 2015 12:03:38 -0500 Message-ID: <1449248618-30556-1-git-send-email-jbacik@fb.com> X-Mailer: git-send-email 2.5.0 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [192.168.52.123] X-Proofpoint-Spam-Reason: safe X-FB-Internal: Safe X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2015-12-04_06:,, signatures=0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5311 Lines: 181 Sometimes it is a good idea to filter out events from the recording processes and even other pids, for example an external app that links against libtracecmd that watches syscalls probably doesn't want its own syscalls showing up in the events. So add the ability to filter _out_ certain pids for the events that are enabled. The recorder threads will add their pids to this list, but they are only filtered if the library consumer filters out a pid or if the trace-cmd record user tries to filter anything out. Thanks, Signed-off-by: Josef Bacik --- trace-cmd.h | 1 + trace-record.c | 44 +++++++++++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/trace-cmd.h b/trace-cmd.h index 6bbc97a..3a230b4 100644 --- a/trace-cmd.h +++ b/trace-cmd.h @@ -295,6 +295,7 @@ void tracecmd_start_threads(enum tracecmd_trace_type type, tracecmd_handle_init_func handle_init, int global); void tracecmd_stop_threads(enum tracecmd_trace_type type); int tracecmd_stream_loop(struct timeval *tv); +void tracecmd_filter_pid(int pid, int exclude); /* --- Plugin handling --- */ extern struct pevent_plugin_option trace_ftrace_options[]; diff --git a/trace-record.c b/trace-record.c index 7d3ea37..49a8280 100644 --- a/trace-record.c +++ b/trace-record.c @@ -114,6 +114,7 @@ static int save_stdout = -1; struct filter_pids { struct filter_pids *next; int pid; + int exclude; }; static struct filter_pids *filter_pids; @@ -747,13 +748,14 @@ static void reset_max_latency(void) fclose(fp); } -static void add_filter_pid(int pid) +static void add_filter_pid(int pid, int exclude) { struct filter_pids *p; char buf[100]; p = malloc_or_die(sizeof(*p)); p->next = filter_pids; + p->exclude = exclude; p->pid = pid; filter_pids = p; nr_filter_pids++; @@ -823,6 +825,8 @@ static void update_ftrace_pids(int reset) struct filter_pids *pid; for (pid = filter_pids; pid; pid = pid->next) { + if (pid->exclude) + continue; snprintf(buf, 100, "%d ", pid->pid); update_ftrace_pid(buf, reset); /* Only reset the first entry */ @@ -849,6 +853,7 @@ static char *make_pid_filter(char *curr_filter, const char *field) struct filter_pids *p; char *filter; char *orit; + char *match; char *str; int curr_len = 0; int len; @@ -875,7 +880,11 @@ static char *make_pid_filter(char *curr_filter, const char *field) orit = ""; else orit = "||"; - len = sprintf(str, "%s(%s==%d)", orit, field, p->pid); + if (p->exclude) + match = "!="; + else + match = "=="; + len = sprintf(str, "%s(%s%s%d)", orit, field, match, p->pid); str += len; } @@ -891,7 +900,7 @@ static void update_task_filter(void) int pid = getpid(); if (filter_task) - add_filter_pid(pid); + add_filter_pid(pid, 0); if (!filter_pids) return; @@ -903,6 +912,21 @@ static void update_task_filter(void) update_pid_event_filters(instance); } +void tracecmd_filter_pid(int pid, int exclude) +{ + struct buffer_instance *instance; + + add_filter_pid(pid, exclude); + common_pid_filter = make_pid_filter(NULL, "common_pid"); + + if (!filter_pids) + return; + + update_ftrace_pids(1); + for_all_instances(instance) + update_pid_event_filters(instance); +} + static pid_t trace_waitpid(enum tracecmd_trace_type type, pid_t pid, int *status, int options) { struct timeval tv = { 1, 0 }; @@ -977,7 +1001,7 @@ static void add_new_filter_pid(int pid) struct buffer_instance *instance; char buf[100]; - add_filter_pid(pid); + add_filter_pid(pid, 0); sprintf(buf, "%d", pid); update_ftrace_pid(buf, 0); @@ -999,7 +1023,7 @@ static void ptrace_attach(int pid) do_ptrace = 0; return; } - add_filter_pid(pid); + add_filter_pid(pid, 0); } static void enable_ptrace(void) @@ -1113,7 +1137,7 @@ static void run_cmd(enum tracecmd_trace_type type, int argc, char **argv) } } if (do_ptrace) { - add_filter_pid(pid); + add_filter_pid(pid, 0); ptrace_wait(type, pid); } else trace_waitpid(type, pid, &status, 0); @@ -2587,7 +2611,7 @@ void tracecmd_start_threads(enum tracecmd_trace_type type, memset(pids, 0, sizeof(*pids) * cpu_count * (buffers + 1)); for_all_instances(instance) { - int x; + int x, pid; for (x = 0; x < cpu_count; x++) { if (type & TRACE_TYPE_STREAM) { brass = pids[i].brass; @@ -2606,9 +2630,11 @@ void tracecmd_start_threads(enum tracecmd_trace_type type, pids[i].instance = instance; /* Make sure all output is flushed before forking */ fflush(stdout); - pids[i++].pid = create_recorder(instance, x, type, brass); + pid = pids[i++].pid = create_recorder(instance, x, type, brass); if (brass) close(brass[1]); + if (pid > 0) + add_filter_pid(pid, 1); } } recorder_threads = i; @@ -4088,7 +4114,7 @@ void trace_record (int argc, char **argv) die("strdup"); pid = strtok_r(pids, ",", &sav); while (pid) { - add_filter_pid(atoi(pid)); + add_filter_pid(atoi(pid), 0); pid = strtok_r(NULL, ",", &sav); } free(pids); -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/