linux-kselftest.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Michal Rostecki <mrostecki@opensuse.org>
To: bpf@vger.kernel.org
Cc: Michal Rostecki <mrostecki@opensuse.org>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Martin KaFai Lau <kafai@fb.com>, Song Liu <songliubraving@fb.com>,
	Yonghong Song <yhs@fb.com>, Andrii Nakryiko <andriin@fb.com>,
	Quentin Monnet <quentin.monnet@netronome.com>,
	Jakub Kicinski <kuba@kernel.org>,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
	Shuah Khan <shuah@kernel.org>,
	linux-kselftest@vger.kernel.org (open list:KERNEL SELFTEST
	FRAMEWORK)
Subject: [PATCH bpf-next v2 2/5] bpftool: Make probes which emit dmesg warnings optional
Date: Fri, 21 Feb 2020 04:16:57 +0100	[thread overview]
Message-ID: <20200221031702.25292-3-mrostecki@opensuse.org> (raw)
In-Reply-To: <20200221031702.25292-1-mrostecki@opensuse.org>

Probes related to bpf_probe_write_user and bpf_trace_printk helpers emit
dmesg warnings which might be confusing for people running bpftool on
production environments. This change filters them out by default and
introduces the new positional argument "full" which enables all
available probes.

Signed-off-by: Michal Rostecki <mrostecki@opensuse.org>
---
 tools/bpf/bpftool/feature.c | 80 +++++++++++++++++++++++++++++++++----
 1 file changed, 73 insertions(+), 7 deletions(-)

diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c
index 345e4a2b4f53..0731804b8160 100644
--- a/tools/bpf/bpftool/feature.c
+++ b/tools/bpf/bpftool/feature.c
@@ -3,6 +3,7 @@
 
 #include <ctype.h>
 #include <errno.h>
+#include <regex.h>
 #include <string.h>
 #include <unistd.h>
 #include <net/if.h>
@@ -22,6 +23,9 @@
 # define PROC_SUPER_MAGIC	0x9fa0
 #endif
 
+/* Regex pattern for filtering out probes which emit dmesg warnings */
+#define FILTER_OUT_PATTERN "(trace|write_user)"
+
 enum probe_component {
 	COMPONENT_UNSPEC,
 	COMPONENT_KERNEL,
@@ -57,6 +61,35 @@ static void uppercase(char *str, size_t len)
 		str[i] = toupper(str[i]);
 }
 
+/* Filtering utility functions */
+
+static bool
+check_filters(const char *name, regex_t *filter_out)
+{
+	char err_buf[100];
+	int ret;
+
+	/* Do not probe if filter_out was defined and string matches against the
+	 * pattern.
+	 */
+	if (filter_out) {
+		ret = regexec(filter_out, name, 0, NULL, 0);
+		switch (ret) {
+		case 0:
+			return false;
+		case REG_NOMATCH:
+			break;
+		default:
+			regerror(ret, filter_out, err_buf, ARRAY_SIZE(err_buf));
+			p_err("could not match regex: %s", err_buf);
+			free(filter_out);
+			exit(1);
+		}
+	}
+
+	return true;
+}
+
 /* Printing utility functions */
 
 static void
@@ -515,7 +548,8 @@ probe_map_type(enum bpf_map_type map_type, const char *define_prefix,
 
 static void
 probe_helpers_for_progtype(enum bpf_prog_type prog_type, bool supported_type,
-			   const char *define_prefix, __u32 ifindex)
+			   const char *define_prefix, regex_t *filter_out,
+			   __u32 ifindex)
 {
 	const char *ptype_name = prog_type_name[prog_type];
 	char feat_name[128];
@@ -542,6 +576,9 @@ probe_helpers_for_progtype(enum bpf_prog_type prog_type, bool supported_type,
 	}
 
 	for (id = 1; id < ARRAY_SIZE(helper_name); id++) {
+		if (!check_filters(helper_name[id], filter_out))
+			continue;
+
 		if (!supported_type)
 			res = false;
 		else
@@ -634,7 +671,8 @@ section_program_types(bool *supported_types, const char *define_prefix,
 			    define_prefix);
 
 	for (i = BPF_PROG_TYPE_UNSPEC + 1; i < ARRAY_SIZE(prog_type_name); i++)
-		probe_prog_type(i, supported_types, define_prefix, ifindex);
+		probe_prog_type(i, supported_types, define_prefix,
+				ifindex);
 
 	print_end_section();
 }
@@ -655,7 +693,8 @@ static void section_map_types(const char *define_prefix, __u32 ifindex)
 }
 
 static void
-section_helpers(bool *supported_types, const char *define_prefix, __u32 ifindex)
+section_helpers(bool *supported_types, const char *define_prefix,
+		regex_t *filter_out, __u32 ifindex)
 {
 	unsigned int i;
 
@@ -681,7 +720,7 @@ section_helpers(bool *supported_types, const char *define_prefix, __u32 ifindex)
 		       define_prefix);
 	for (i = BPF_PROG_TYPE_UNSPEC + 1; i < ARRAY_SIZE(prog_type_name); i++)
 		probe_helpers_for_progtype(i, supported_types[i],
-					   define_prefix, ifindex);
+					   define_prefix, filter_out, ifindex);
 
 	print_end_section();
 }
@@ -701,8 +740,13 @@ static int do_probe(int argc, char **argv)
 	enum probe_component target = COMPONENT_UNSPEC;
 	const char *define_prefix = NULL;
 	bool supported_types[128] = {};
+	regex_t *filter_out = NULL;
+	bool full_mode = false;
+	char regerror_buf[100];
 	__u32 ifindex = 0;
 	char *ifname;
+	int reg_ret;
+	int ret = 0;
 
 	/* Detection assumes user has sufficient privileges (CAP_SYS_ADMIN).
 	 * Let's approximate, and restrict usage to root user only.
@@ -740,6 +784,9 @@ static int do_probe(int argc, char **argv)
 				      strerror(errno));
 				return -1;
 			}
+		} else if (is_prefix(*argv, "full")) {
+			full_mode = true;
+			NEXT_ARG();
 		} else if (is_prefix(*argv, "macros") && !define_prefix) {
 			define_prefix = "";
 			NEXT_ARG();
@@ -764,6 +811,22 @@ static int do_probe(int argc, char **argv)
 		}
 	}
 
+	/* If full mode is not acivated, filter out probes which emit dmesg
+	 * messages.
+	 */
+	if (!full_mode) {
+		filter_out = malloc(sizeof(regex_t));
+		reg_ret = regcomp(filter_out, FILTER_OUT_PATTERN, REG_EXTENDED);
+		if (reg_ret) {
+			regerror(reg_ret, filter_out, regerror_buf,
+				 ARRAY_SIZE(regerror_buf));
+			p_err("could not compile regex: %s",
+			      regerror_buf);
+			ret = -1;
+			goto cleanup;
+		}
+	}
+
 	if (json_output) {
 		define_prefix = NULL;
 		jsonw_start_object(json_wtr);
@@ -775,7 +838,7 @@ static int do_probe(int argc, char **argv)
 		goto exit_close_json;
 	section_program_types(supported_types, define_prefix, ifindex);
 	section_map_types(define_prefix, ifindex);
-	section_helpers(supported_types, define_prefix, ifindex);
+	section_helpers(supported_types, define_prefix, filter_out, ifindex);
 	section_misc(define_prefix, ifindex);
 
 exit_close_json:
@@ -783,7 +846,10 @@ static int do_probe(int argc, char **argv)
 		/* End root object */
 		jsonw_end_object(json_wtr);
 
-	return 0;
+cleanup:
+	free(filter_out);
+
+	return ret;
 }
 
 static int do_help(int argc, char **argv)
@@ -794,7 +860,7 @@ static int do_help(int argc, char **argv)
 	}
 
 	fprintf(stderr,
-		"Usage: %s %s probe [COMPONENT] [macros [prefix PREFIX]]\n"
+		"Usage: %s %s probe [COMPONENT] [full] [macros [prefix PREFIX]]\n"
 		"       %s %s help\n"
 		"\n"
 		"       COMPONENT := { kernel | dev NAME }\n"
-- 
2.25.0


  parent reply	other threads:[~2020-02-21  3:16 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-21  3:16 [PATCH bpf-next v2 0/5] bpftool: Make probes which emit dmesg warnings optional Michal Rostecki
2020-02-21  3:16 ` [PATCH bpf-next v2 1/5] bpftool: Move out sections to separate functions Michal Rostecki
2020-02-21 11:27   ` Quentin Monnet
2020-02-21  3:16 ` Michal Rostecki [this message]
2020-02-21 11:28   ` [PATCH bpf-next v2 2/5] bpftool: Make probes which emit dmesg warnings optional Quentin Monnet
2020-02-21 22:44     ` Alexei Starovoitov
2020-02-25 12:18       ` Michal Rostecki
2020-02-21  3:16 ` [PATCH bpf-next v2 3/5] bpftool: Update documentation of "bpftool feature" command Michal Rostecki
2020-02-21 11:28   ` Quentin Monnet
2020-02-21  3:16 ` [PATCH bpf-next v2 4/5] bpftool: Update bash completion for " Michal Rostecki
2020-02-21 11:29   ` Quentin Monnet
2020-02-21  3:17 ` [PATCH bpf-next v2 5/5] selftests/bpf: Add test " Michal Rostecki
2020-02-21 11:28   ` Quentin Monnet
2020-02-25 13:25     ` Michal Rostecki
2020-02-25 13:55     ` Michal Rostecki
2020-02-25 14:54       ` Quentin Monnet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200221031702.25292-3-mrostecki@opensuse.org \
    --to=mrostecki@opensuse.org \
    --cc=andriin@fb.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=kafai@fb.com \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=quentin.monnet@netronome.com \
    --cc=shuah@kernel.org \
    --cc=songliubraving@fb.com \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).