* [PATCH bpf-next v2] scripts/bpf_doc.py: implement json output format
@ 2025-05-07 18:28 Ihor Solodrai
2025-05-07 19:43 ` Quentin Monnet
0 siblings, 1 reply; 3+ messages in thread
From: Ihor Solodrai @ 2025-05-07 18:28 UTC (permalink / raw)
To: qmo, andrii
Cc: bpf, ast, daniel, eddyz87, mykolal, dylan.reimerink, kernel-team
bpf_doc.py parses bpf.h header to collect information about various
API elements (such as BPF helpers) and then dump them in one of the
supported formats: rst docs and a C header.
It's useful for external tools to be able to consume this information
in an easy-to-parse format such as JSON. Implement JSON printers and
add --json command line argument.
v1: https://lore.kernel.org/bpf/20250506000605.497296-1-isolodrai@meta.com/
Signed-off-by: Ihor Solodrai <isolodrai@meta.com>
---
scripts/bpf_doc.py | 112 +++++++++++++++++++++++++++++++++++++++------
1 file changed, 98 insertions(+), 14 deletions(-)
diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py
index e74a01a85070..d669a0e16bf2 100755
--- a/scripts/bpf_doc.py
+++ b/scripts/bpf_doc.py
@@ -8,6 +8,7 @@
from __future__ import print_function
import argparse
+import json
import re
import sys, os
import subprocess
@@ -43,6 +44,14 @@ class APIElement(object):
self.ret = ret
self.attrs = attrs
+ def to_dict(self):
+ return {
+ 'proto': self.proto,
+ 'desc': self.desc,
+ 'ret': self.ret,
+ 'attrs': self.attrs
+ }
+
class Helper(APIElement):
"""
@@ -81,6 +90,11 @@ class Helper(APIElement):
return res
+ def to_dict(self):
+ d = super().to_dict()
+ d.update(self.proto_break_down())
+ return d
+
ATTRS = {
'__bpf_fastcall': 'bpf_fastcall'
@@ -675,7 +689,7 @@ COMMANDS
self.print_elem(command)
-class PrinterHelpers(Printer):
+class PrinterHelpersHeader(Printer):
"""
A printer for dumping collected information about helpers as C header to
be included from BPF program.
@@ -896,6 +910,43 @@ class PrinterHelpers(Printer):
print(') = (void *) %d;' % helper.enum_val)
print('')
+
+class PrinterHelpersJSON(Printer):
+ """
+ A printer for dumping collected information about helpers as a JSON file.
+ @parser: A HeaderParser with Helper objects
+ """
+
+ def __init__(self, parser):
+ self.elements = parser.helpers
+ self.elem_number_check(
+ parser.desc_unique_helpers,
+ parser.define_unique_helpers,
+ "helper",
+ "___BPF_FUNC_MAPPER",
+ )
+
+ def print_all(self):
+ helper_dicts = [helper.to_dict() for helper in self.elements]
+ out_dict = {'helpers': helper_dicts}
+ print(json.dumps(out_dict, indent=4))
+
+
+class PrinterSyscallJSON(Printer):
+ """
+ A printer for dumping collected syscall information as a JSON file.
+ @parser: A HeaderParser with APIElement objects
+ """
+
+ def __init__(self, parser):
+ self.elements = parser.commands
+ self.elem_number_check(parser.desc_syscalls, parser.enum_syscalls, 'syscall', 'bpf_cmd')
+
+ def print_all(self):
+ syscall_dicts = [syscall.to_dict() for syscall in self.elements]
+ out_dict = {'syscall': syscall_dicts}
+ print(json.dumps(out_dict, indent=4))
+
###############################################################################
# If script is launched from scripts/ from kernel tree and can access
@@ -910,6 +961,19 @@ printers = {
'syscall': PrinterSyscallRST,
}
+# target -> output format -> printer
+printers = {
+ 'helpers': {
+ 'rst': PrinterHelpersRST,
+ 'json': PrinterHelpersJSON,
+ 'header': PrinterHelpersHeader,
+ },
+ 'syscall': {
+ 'rst': PrinterSyscallRST,
+ 'json': PrinterSyscallJSON
+ },
+}
+
argParser = argparse.ArgumentParser(description="""
Parse eBPF header file and generate documentation for the eBPF API.
The RST-formatted output produced can be turned into a manual page with the
@@ -917,6 +981,8 @@ rst2man utility.
""")
argParser.add_argument('--header', action='store_true',
help='generate C header file')
+argParser.add_argument('--json', action='store_true',
+ help='generate a JSON')
if (os.path.isfile(bpfh)):
argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h',
default=bpfh)
@@ -924,17 +990,35 @@ else:
argParser.add_argument('--filename', help='path to include/uapi/linux/bpf.h')
argParser.add_argument('target', nargs='?', default='helpers',
choices=printers.keys(), help='eBPF API target')
-args = argParser.parse_args()
-
-# Parse file.
-headerParser = HeaderParser(args.filename)
-headerParser.run()
-# Print formatted output to standard output.
-if args.header:
- if args.target != 'helpers':
- raise NotImplementedError('Only helpers header generation is supported')
- printer = PrinterHelpers(headerParser)
-else:
- printer = printers[args.target](headerParser)
-printer.print_all()
+def error_die(message: str):
+ argParser.print_usage(file=sys.stderr)
+ print('Error: {}'.format(message), file=sys.stderr)
+ exit(1)
+
+def parse_and_dump():
+ args = argParser.parse_args()
+
+ # Parse file.
+ headerParser = HeaderParser(args.filename)
+ headerParser.run()
+
+ if args.header and args.json:
+ error_die('Use either --header or --json, not both')
+
+ output_format = 'rst'
+ if args.header:
+ output_format = 'header'
+ elif args.json:
+ output_format = 'json'
+
+ try:
+ printer = printers[args.target][output_format](headerParser)
+ # Print formatted output to standard output.
+ printer.print_all()
+ except KeyError:
+ error_die('Unsupported target/format combination: "{}", "{}"'
+ .format(args.target, output_format))
+
+if __name__ == "__main__":
+ parse_and_dump()
--
2.47.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH bpf-next v2] scripts/bpf_doc.py: implement json output format
2025-05-07 18:28 [PATCH bpf-next v2] scripts/bpf_doc.py: implement json output format Ihor Solodrai
@ 2025-05-07 19:43 ` Quentin Monnet
2025-05-07 19:59 ` Ihor Solodrai
0 siblings, 1 reply; 3+ messages in thread
From: Quentin Monnet @ 2025-05-07 19:43 UTC (permalink / raw)
To: ihor.solodrai, andrii
Cc: bpf, ast, daniel, eddyz87, mykolal, dylan.reimerink, kernel-team
2025-05-07 11:28 UTC-0700 ~ Ihor Solodrai <isolodrai@meta.com>
> bpf_doc.py parses bpf.h header to collect information about various
> API elements (such as BPF helpers) and then dump them in one of the
> supported formats: rst docs and a C header.
>
> It's useful for external tools to be able to consume this information
> in an easy-to-parse format such as JSON. Implement JSON printers and
> add --json command line argument.
>
> v1: https://lore.kernel.org/bpf/20250506000605.497296-1-isolodrai@meta.com/
>
> Signed-off-by: Ihor Solodrai <isolodrai@meta.com>
> ---
> scripts/bpf_doc.py | 112 +++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 98 insertions(+), 14 deletions(-)
>
> diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py
> index e74a01a85070..d669a0e16bf2 100755
> --- a/scripts/bpf_doc.py
> +++ b/scripts/bpf_doc.py
> @@ -8,6 +8,7 @@
> from __future__ import print_function
>
> import argparse
> +import json
> import re
> import sys, os
> import subprocess
> @@ -43,6 +44,14 @@ class APIElement(object):
> self.ret = ret
> self.attrs = attrs
>
> + def to_dict(self):
> + return {
> + 'proto': self.proto,
> + 'desc': self.desc,
> + 'ret': self.ret,
> + 'attrs': self.attrs
> + }
> +
>
> class Helper(APIElement):
> """
> @@ -81,6 +90,11 @@ class Helper(APIElement):
>
> return res
>
> + def to_dict(self):
> + d = super().to_dict()
> + d.update(self.proto_break_down())
> + return d
> +
>
> ATTRS = {
> '__bpf_fastcall': 'bpf_fastcall'
> @@ -675,7 +689,7 @@ COMMANDS
> self.print_elem(command)
>
>
> -class PrinterHelpers(Printer):
> +class PrinterHelpersHeader(Printer):
> """
> A printer for dumping collected information about helpers as C header to
> be included from BPF program.
> @@ -896,6 +910,43 @@ class PrinterHelpers(Printer):
> print(') = (void *) %d;' % helper.enum_val)
> print('')
>
> +
> +class PrinterHelpersJSON(Printer):
> + """
> + A printer for dumping collected information about helpers as a JSON file.
> + @parser: A HeaderParser with Helper objects
> + """
> +
> + def __init__(self, parser):
> + self.elements = parser.helpers
> + self.elem_number_check(
> + parser.desc_unique_helpers,
> + parser.define_unique_helpers,
> + "helper",
> + "___BPF_FUNC_MAPPER",
> + )
> +
> + def print_all(self):
> + helper_dicts = [helper.to_dict() for helper in self.elements]
> + out_dict = {'helpers': helper_dicts}
> + print(json.dumps(out_dict, indent=4))
> +
> +
> +class PrinterSyscallJSON(Printer):
> + """
> + A printer for dumping collected syscall information as a JSON file.
> + @parser: A HeaderParser with APIElement objects
> + """
> +
> + def __init__(self, parser):
> + self.elements = parser.commands
> + self.elem_number_check(parser.desc_syscalls, parser.enum_syscalls, 'syscall', 'bpf_cmd')
> +
> + def print_all(self):
> + syscall_dicts = [syscall.to_dict() for syscall in self.elements]
> + out_dict = {'syscall': syscall_dicts}
> + print(json.dumps(out_dict, indent=4))
> +
> ###############################################################################
>
> # If script is launched from scripts/ from kernel tree and can access
> @@ -910,6 +961,19 @@ printers = {
> 'syscall': PrinterSyscallRST,
> }
Can you please remove the old "printers" dict that is right above? It's
no longer used now that you redefine it below.
pw-bot: cr
>
> +# target -> output format -> printer
> +printers = {
> + 'helpers': {
> + 'rst': PrinterHelpersRST,
> + 'json': PrinterHelpersJSON,
> + 'header': PrinterHelpersHeader,
> + },
> + 'syscall': {
> + 'rst': PrinterSyscallRST,
> + 'json': PrinterSyscallJSON
> + },
> +}
> +
> argParser = argparse.ArgumentParser(description="""
> Parse eBPF header file and generate documentation for the eBPF API.
> The RST-formatted output produced can be turned into a manual page with the
[...]
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH bpf-next v2] scripts/bpf_doc.py: implement json output format
2025-05-07 19:43 ` Quentin Monnet
@ 2025-05-07 19:59 ` Ihor Solodrai
0 siblings, 0 replies; 3+ messages in thread
From: Ihor Solodrai @ 2025-05-07 19:59 UTC (permalink / raw)
To: Quentin Monnet, andrii
Cc: bpf, ast, daniel, eddyz87, mykolal, dylan.reimerink, kernel-team
On 2025-05-07 12:43 p.m., Quentin Monnet wrote:
> 2025-05-07 11:28 UTC-0700 ~ Ihor Solodrai <isolodrai@meta.com>
>> bpf_doc.py parses bpf.h header to collect information about various
>> API elements (such as BPF helpers) and then dump them in one of the
>> supported formats: rst docs and a C header.
>>
>> It's useful for external tools to be able to consume this information
>> in an easy-to-parse format such as JSON. Implement JSON printers and
>> add --json command line argument.
>>
>> v1: https://lore.kernel.org/bpf/20250506000605.497296-1-isolodrai@meta.com/
>>
>> Signed-off-by: Ihor Solodrai <isolodrai@meta.com>
>> ---
>> scripts/bpf_doc.py | 112 +++++++++++++++++++++++++++++++++++++++------
>> 1 file changed, 98 insertions(+), 14 deletions(-)
>>
>> diff --git a/scripts/bpf_doc.py b/scripts/bpf_doc.py
>> index e74a01a85070..d669a0e16bf2 100755
>> --- a/scripts/bpf_doc.py
>> +++ b/scripts/bpf_doc.py
>> @@ -8,6 +8,7 @@
>> from __future__ import print_function
>>
>> import argparse
>> +import json
>> import re
>> import sys, os
>> import subprocess
>> @@ -43,6 +44,14 @@ class APIElement(object):
>> self.ret = ret
>> self.attrs = attrs
>>
>> + def to_dict(self):
>> + return {
>> + 'proto': self.proto,
>> + 'desc': self.desc,
>> + 'ret': self.ret,
>> + 'attrs': self.attrs
>> + }
>> +
>>
>> class Helper(APIElement):
>> """
>> @@ -81,6 +90,11 @@ class Helper(APIElement):
>>
>> return res
>>
>> + def to_dict(self):
>> + d = super().to_dict()
>> + d.update(self.proto_break_down())
>> + return d
>> +
>>
>> ATTRS = {
>> '__bpf_fastcall': 'bpf_fastcall'
>> @@ -675,7 +689,7 @@ COMMANDS
>> self.print_elem(command)
>>
>>
>> -class PrinterHelpers(Printer):
>> +class PrinterHelpersHeader(Printer):
>> """
>> A printer for dumping collected information about helpers as C header to
>> be included from BPF program.
>> @@ -896,6 +910,43 @@ class PrinterHelpers(Printer):
>> print(') = (void *) %d;' % helper.enum_val)
>> print('')
>>
>> +
>> +class PrinterHelpersJSON(Printer):
>> + """
>> + A printer for dumping collected information about helpers as a JSON file.
>> + @parser: A HeaderParser with Helper objects
>> + """
>> +
>> + def __init__(self, parser):
>> + self.elements = parser.helpers
>> + self.elem_number_check(
>> + parser.desc_unique_helpers,
>> + parser.define_unique_helpers,
>> + "helper",
>> + "___BPF_FUNC_MAPPER",
>> + )
>> +
>> + def print_all(self):
>> + helper_dicts = [helper.to_dict() for helper in self.elements]
>> + out_dict = {'helpers': helper_dicts}
>> + print(json.dumps(out_dict, indent=4))
>> +
>> +
>> +class PrinterSyscallJSON(Printer):
>> + """
>> + A printer for dumping collected syscall information as a JSON file.
>> + @parser: A HeaderParser with APIElement objects
>> + """
>> +
>> + def __init__(self, parser):
>> + self.elements = parser.commands
>> + self.elem_number_check(parser.desc_syscalls, parser.enum_syscalls, 'syscall', 'bpf_cmd')
>> +
>> + def print_all(self):
>> + syscall_dicts = [syscall.to_dict() for syscall in self.elements]
>> + out_dict = {'syscall': syscall_dicts}
>> + print(json.dumps(out_dict, indent=4))
>> +
>> ###############################################################################
>>
>> # If script is launched from scripts/ from kernel tree and can access
>> @@ -910,6 +961,19 @@ printers = {
>> 'syscall': PrinterSyscallRST,
>> }
>
>
> Can you please remove the old "printers" dict that is right above? It's
> no longer used now that you redefine it below.
Sure, missed it...
Thanks.
>
> pw-bot: cr
>
>>
>> +# target -> output format -> printer
>> +printers = {
>> + 'helpers': {
>> + 'rst': PrinterHelpersRST,
>> + 'json': PrinterHelpersJSON,
>> + 'header': PrinterHelpersHeader,
>> + },
>> + 'syscall': {
>> + 'rst': PrinterSyscallRST,
>> + 'json': PrinterSyscallJSON
>> + },
>> +}
>> +
>> argParser = argparse.ArgumentParser(description="""
>> Parse eBPF header file and generate documentation for the eBPF API.
>> The RST-formatted output produced can be turned into a manual page with the
>
> [...]
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-05-07 19:59 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-07 18:28 [PATCH bpf-next v2] scripts/bpf_doc.py: implement json output format Ihor Solodrai
2025-05-07 19:43 ` Quentin Monnet
2025-05-07 19:59 ` Ihor Solodrai
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.