2019-01-04 09:36 UTC-0800 ~ Y Song <ys114...@gmail.com>
On Fri, Jan 4, 2019 at 6:27 AM Quentin Monnet
<quentin.mon...@netronome.com> wrote:

2019-01-03 22:35 UTC-0800 ~ Y Song <ys114...@gmail.com>
On Thu, Jan 3, 2019 at 9:27 AM Quentin Monnet
<quentin.mon...@netronome.com> wrote:

Add probes to dump a number of options set (or not set) for compiling
the kernel image. These parameters provide information about what BPF
components should be available on the system. A number of them are not
directly related to eBPF, but are in fact used in the kernel as
conditions on which to compile, or not to compile, some of the eBPF
helper functions.

Sample output:

     # bpftool feature probe kernel
     Scanning system configuration...
     ...
     CONFIG_BPF is set to y
     CONFIG_BPF_SYSCALL is set to y
     CONFIG_HAVE_EBPF_JIT is set to y
     ...

     # bpftool --pretty --json feature probe kernel
     {
         "system_config": {
             ...
             "CONFIG_BPF": "y",
             "CONFIG_BPF_SYSCALL": "y",
             "CONFIG_HAVE_EBPF_JIT": "y",
             ...
         }
     }

v3:
- Add a comment about /proc/config.gz not being supported as a path for
   the config file at this time.
- Use p_info() instead of p_err() on failure to get options from config
   file, as bpftool keeps probing other parameters and that would
   possibly create duplicate "error" entries for JSON.

v2:
- Remove C-style macros output from this patch.
- NOT addressed: grouping of those config options into subsections
   (I don't see an easy way of grouping them at the moment, please see
   also the discussion on v1 thread).

Signed-off-by: Quentin Monnet <quentin.mon...@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
---
  tools/bpf/bpftool/feature.c | 142 ++++++++++++++++++++++++++++++++++++
  1 file changed, 142 insertions(+)

diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c
index 37fe79f59015..05c16fe67005 100644
--- a/tools/bpf/bpftool/feature.c
+++ b/tools/bpf/bpftool/feature.c
@@ -48,6 +48,30 @@ print_bool_feature(const char *feat_name, const char 
*plain_name, bool res)
                 printf("%s is %savailable\n", plain_name, res ? "" : "NOT ");
  }

+static void print_kernel_option(const char *name, const char *value)
+{
+       char *endptr;
+       int res;
+
+       if (json_output) {
+               if (!value) {
+                       jsonw_null_field(json_wtr, name);
+                       return;
+               }
+               errno = 0;
+               res = strtol(value, &endptr, 0);
+               if (!errno && *endptr == '\n')
+                       jsonw_int_field(json_wtr, name, res);
+               else
+                       jsonw_string_field(json_wtr, name, value);
+       } else {
+               if (value)
+                       printf("%s is set to %s\n", name, value);
+               else
+                       printf("%s is not set\n", name);
+       }
+}
+
  static void
  print_start_section(const char *json_title, const char *plain_title)
  {
@@ -190,6 +214,123 @@ static void probe_jit_kallsyms(void)
         }
  }

+static char *get_kernel_config_option(FILE *fd, const char *option)
+{
+       size_t line_n = 0, optlen = strlen(option);
+       char *res, *strval, *line = NULL;
+       ssize_t n;
+
+       rewind(fd);
+       while ((n = getline(&line, &line_n, fd)) > 0) {
+               if (strncmp(line, option, optlen))
+                       continue;
+               /* Check we have at least '=', value, and '\n' */
+               if (strlen(line) < optlen + 3)
+                       continue;
+               if (*(line + optlen) != '=')
+                       continue;
+
+               /* Trim ending '\n' */
+               line[strlen(line) - 1] = '\0';
+
+               /* Copy and return config option value */
+               strval = line + optlen + 1;
+               res = strdup(strval);
+               free(line);
+               return res;
+       }
+       free(line);
+
+       return NULL;
+}
+
+static void probe_kernel_image_config(void)
+{
+       const char * const options[] = {
+               "CONFIG_BPF",
+               "CONFIG_BPF_SYSCALL",
+               "CONFIG_HAVE_EBPF_JIT",
+               "CONFIG_BPF_JIT",
+               "CONFIG_BPF_JIT_ALWAYS_ON",
+               "CONFIG_NET",
+               "CONFIG_XDP_SOCKETS",
+               "CONFIG_CGROUPS",
+               "CONFIG_CGROUP_BPF",
+               "CONFIG_CGROUP_NET_CLASSID",
+               "CONFIG_BPF_EVENTS",
+               "CONFIG_LWTUNNEL_BPF",
+               "CONFIG_NET_ACT_BPF",
+               "CONFIG_NET_CLS_ACT",
+               "CONFIG_NET_CLS_BPF",
+               "CONFIG_NET_SCH_INGRESS",
+               "CONFIG_XFRM",
+               "CONFIG_SOCK_CGROUP_DATA",
+               "CONFIG_IP_ROUTE_CLASSID",
+               "CONFIG_IPV6_SEG6_BPF",
+               "CONFIG_FUNCTION_ERROR_INJECTION",
+               "CONFIG_BPF_KPROBE_OVERRIDE",
+               "CONFIG_BPF_LIRC_MODE2",
+               "CONFIG_NETFILTER_XT_MATCH_BPF",
+               "CONFIG_TEST_BPF",
+               "CONFIG_BPFILTER",
+               "CONFIG_BPFILTER_UMH",
+               "CONFIG_BPF_STREAM_PARSER",

The list does not have any tracing specific configs like
CONFIG_KPROBES, CONFIG_UPROBES, etc.
Should we check those as well?

I didn't find any BPF items for which compiling would depend on those
options, that's why they are not in the list at the moment. But yeah,

That is true. They are kind of independent for compilations.

they are definitely useful to tell if kprobe-attached programs have any
chance to work, so it would make sense I guess... What options do you
have in mind exactly? CONFIG_KPROBES and CONFIG_UPROBES, do you believe
CONFING_KPROBE_EVENTS and CONFIG_UPROBE_EVENTS would also be relevant?

The following list should be a good start:
CONFIG_TRACING
CONFIG_KPROBE_EVENTS
CONFIG_UPROBE_EVENTS
CONFIG_BPF_EVENTS
CONFIG_FTRACE_SYSCALLS

No need for CONFIG_KPROBES and CONFIG_UPROBES which
are implied by CONFIG_KPROBE_EVENTS and CONFIG_UPROBE_EVENTS respectively,
and BPF mostly hooked to the events.

TRACING will enable tracepoint.
BPF_EVENTS depends on KPROBE_EVENTS or UPROBE_EVENTS, and PERF_EVENTS.
Having both CONFIG_KPROBE_EVENTS and CONFIG_UPROBE_EVENTS will tell
whether one of them or both are supported.
CONFIG_FTRACE_SYSCALLS needed to tell whether syscall tracepoints will
be supported or not
so bpf programs attached to these syscall tracepoints will work.

Sounds good. CONFIG_BPF_EVENTS is in the list already, I'll add the other ones for v4 once bpf-next reopens. Thanks a lot for the details!

Quentin

Reply via email to