aya-rs / aya-template Goto Github PK
View Code? Open in Web Editor NEWA cargo-generate template for Rust eBPF Projects using Aya
A cargo-generate template for Rust eBPF Projects using Aya
Due to use of std::os::unix::process::CommandExt
in
Line 1 in e86392d
CommandExt.exec()
in Line 63 in e86392d
cargo xtask build-ebpf
currently fails on Windows. There seems to be now compelling reason to use Unix-specific command executor, and generating BPF bytecode should be possible using Windows too. I think we should change it to the generic command runner https://doc.rust-lang.org/std/process/struct.Command.html#method.status which we already use in build_ebpf.rs
aya-template/xtask/src/build_ebpf.rs
Lines 56 to 60 in e86392d
This is a tracking issue for my refactor of #16 to use xtask instead of a Makefile.
The idea is to add a new target for cargo xtask
that can be used to easily run the compiled project, wrapping it with sudo -E
and possibly creating a build first. This should significantly streamline the local development workflow. Just cargo run
alone is not fit for this purpose since wrapping cargo run
with sudo -E
produces undesirable side effects and setting the cargo runner to sudo -E
breaks our xtask workflow.
A related idea would be to also provide a cargo xtask build
command that runs cargo xtask build-ebpf
before running cargo build
. I'm less convinced that this is really necessary, but I'm open to feedback.
I generated a kprobe project using aya-template
(as of commit afdb453). The cargo xtask build-ebpf
command worked but when running the combined program perf_event_open
failed. The files generated via the template can be found in dvogel/aya-perf-err-repro.
$ cargo xtask run
Finished dev [unoptimized + debuginfo] target(s) in 0.03s
Running `target/debug/xtask run`
Fresh unicode-ident v1.0.11
Fresh proc-macro2 v1.0.66
Fresh core v0.0.0 (/home/dvogel/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core)
Fresh quote v1.0.31
Fresh rustc-std-workspace-core v1.99.0 (/home/dvogel/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/rustc-std-workspace-core)
Fresh syn v2.0.27
Fresh compiler_builtins v0.1.92
Fresh rustversion v1.0.14
Fresh num_enum_derive v0.6.1
Fresh aya-bpf-cty v0.2.1 (https://github.com/aya-rs/aya#aed74d5a)
Fresh aya-bpf-macros v0.1.0 (https://github.com/aya-rs/aya#aed74d5a)
Fresh aya-perf-err-repro-common v0.1.0 (/home/dvogel/devel/certspook/aya-perf-err-repro/aya-perf-err-repro-common)
Fresh num_enum v0.6.1
Fresh aya-bpf-bindings v0.1.0 (https://github.com/aya-rs/aya#aed74d5a)
Fresh aya-bpf v0.1.0 (https://github.com/aya-rs/aya#aed74d5a)
Fresh aya-log-common v0.1.13 (https://github.com/aya-rs/aya#aed74d5a)
Fresh aya-log-parser v0.1.11-dev.0 (https://github.com/aya-rs/aya#aed74d5a)
Fresh aya-log-ebpf-macros v0.1.0 (https://github.com/aya-rs/aya#aed74d5a)
Fresh aya-log-ebpf v0.1.0 (https://github.com/aya-rs/aya#aed74d5a)
Fresh aya-perf-err-repro-ebpf v0.1.0 (/home/dvogel/devel/certspook/aya-perf-err-repro/aya-perf-err-repro-ebpf)
Finished dev [optimized] target(s) in 0.13s
Finished dev [unoptimized + debuginfo] target(s) in 0.23s
Error: `perf_event_open` failed
Caused by:
No such file or directory (os error 2)
Failed to run `sudo -E target/debug/aya-perf-err-repro`
Running with RUST_BACKTRACE=1 doesn't help since it is not an unhandled panic. My manpage for perf_event_open
says only:
ENOENT Returned if the type setting is not valid. This error is also returned for some unsupported generic events.
Running it under strace does show that there is an unrecognized type value of 0x6:
$ sudo strace -f -e perf_event_open ./target/debug/aya-perf-err-repro
strace: Process 1092879 attached
strace: Process 1092880 attached
strace: Process 1092881 attached
strace: Process 1092882 attached
strace: Process 1092883 attached
strace: Process 1092884 attached
strace: Process 1092885 attached
strace: Process 1092886 attached
strace: Process 1092887 attached
strace: Process 1092888 attached
strace: Process 1092889 attached
strace: Process 1092890 attached
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 0, -1, PERF_FLAG_FD_CLOEXEC) = 11
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 1, -1, PERF_FLAG_FD_CLOEXEC) = 12
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 2, -1, PERF_FLAG_FD_CLOEXEC) = 13
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 3, -1, PERF_FLAG_FD_CLOEXEC) = 14
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 4, -1, PERF_FLAG_FD_CLOEXEC) = 15
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 5, -1, PERF_FLAG_FD_CLOEXEC) = 16
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 6, -1, PERF_FLAG_FD_CLOEXEC) = 17
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 7, -1, PERF_FLAG_FD_CLOEXEC) = 18
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 8, -1, PERF_FLAG_FD_CLOEXEC) = 19
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 9, -1, PERF_FLAG_FD_CLOEXEC) = 20
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 10, -1, PERF_FLAG_FD_CLOEXEC) = 21
[pid 1092878] perf_event_open({type=PERF_TYPE_SOFTWARE, size=0x88 /* PERF_ATTR_SIZE_??? */, config=PERF_COUNT_SW_BPF_OUTPUT, sample_period=1, sample_type=PERF_SAMPLE_RAW, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 11, -1, PERF_FLAG_FD_CLOEXEC) = 22
[pid 1092878] perf_event_open({type=0x6 /* PERF_TYPE_??? */, size=0x88 /* PERF_ATTR_SIZE_??? */, config=0, sample_period=0, sample_type=0, read_format=0, precise_ip=0 /* arbitrary skid */, ...}, -1, 0, -1, PERF_FLAG_FD_CLOEXEC) = -1 ENOENT (No such file or directory)
[pid 1092883] +++ exited with 0 +++
[pid 1092884] +++ exited with 0 +++
[pid 1092890] +++ exited with 0 +++
[pid 1092888] +++ exited with 0 +++
[pid 1092881] +++ exited with 0 +++
[pid 1092889] +++ exited with 0 +++
[pid 1092882] +++ exited with 0 +++
[pid 1092887] +++ exited with 0 +++
[pid 1092886] +++ exited with 0 +++
[pid 1092879] +++ exited with 0 +++
[pid 1092880] +++ exited with 0 +++
[pid 1092885] +++ exited with 0 +++
Error: `perf_event_open` failed
Caused by:
No such file or directory (os error 2)
+++ exited with 1 +++
And looking in the kernel headers it appears the perf types stop at 6:
enum perf_type_id {
PERF_TYPE_HARDWARE = 0,
PERF_TYPE_SOFTWARE = 1,
PERF_TYPE_TRACEPOINT = 2,
PERF_TYPE_HW_CACHE = 3,
PERF_TYPE_RAW = 4,
PERF_TYPE_BREAKPOINT = 5,
PERF_TYPE_MAX, /* non-ABI */
};
In case my kernel spelunking above is misguided and this is due to a configuration of my system, I'll include some details that might be relevant:
$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"
$ uname -r
6.1.0-7-amd64
$ cat /boot/config-$(uname -r) | grep -E '(BPF|PERF)'
CONFIG_BPF=y
CONFIG_HAVE_EBPF_JIT=y
CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y
# BPF subsystem
CONFIG_BPF_SYSCALL=y
CONFIG_BPF_JIT=y
# CONFIG_BPF_JIT_ALWAYS_ON is not set
CONFIG_BPF_JIT_DEFAULT_ON=y
CONFIG_BPF_UNPRIV_DEFAULT_OFF=y
# CONFIG_BPF_PRELOAD is not set
CONFIG_BPF_LSM=y
# end of BPF subsystem
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_GUEST_PERF_EVENTS=y
CONFIG_PERF_EVENTS=y
# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
CONFIG_PERF_EVENTS_INTEL_UNCORE=m
CONFIG_PERF_EVENTS_INTEL_RAPL=m
CONFIG_PERF_EVENTS_INTEL_CSTATE=m
CONFIG_PERF_EVENTS_AMD_POWER=m
CONFIG_PERF_EVENTS_AMD_UNCORE=y
# CONFIG_PERF_EVENTS_AMD_BRS is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_HAVE_PERF_EVENTS_NMI=y
CONFIG_HAVE_HARDLOCKUP_DETECTOR_PERF=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_IPV6_SEG6_BPF=y
CONFIG_NETFILTER_XT_MATCH_BPF=m
# CONFIG_BPFILTER is not set
CONFIG_CLS_U32_PERF=y
CONFIG_NET_CLS_BPF=m
CONFIG_NET_ACT_BPF=m
CONFIG_BPF_STREAM_PARSER=y
CONFIG_LWTUNNEL_BPF=y
# CONFIG_PCIEASPM_PERFORMANCE is not set
# CONFIG_PCIE_BUS_PERFORMANCE is not set
CONFIG_INTEL_IDXD_PERFMON=y
# CONFIG_DEVFREQ_GOV_PERFORMANCE is not set
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
CONFIG_HARDLOCKUP_DETECTOR_PERF=y
CONFIG_BPF_EVENTS=y
CONFIG_TEST_BPF=m
Finally, I am able to run the kprobetcp example from the Aya book.
The majority of the build time is spend installing cargo-generate
๐ข
I created an empty project using the command
cargo generate https://github.com/aya-rs/aya-template
And start compilation using
cd test1
cargo build
And get error
error: couldn't read test1/src/../../target/bpfel-unknown-none/debug/test1: No such file or directory (os error 2)
--> test1/src/main.rs:26:29
|
26 | let mut bpf = Bpf::load(include_bytes_aligned!(
| _____________________________^
27 | | "../../target/bpfel-unknown-none/debug/test1"
28 | | ))?;
| |_____^
|
= note: this error originates in the macro `include_bytes` which comes from the expansion of the macro `include_bytes_aligned` (in Nightly builds, run with -Z macro-backtrace for more info)
error: could not compile `test1` due to previous error
Update README.md for xdp program by removing --path
flag which does not exist in the generated program
Switch from
sudo target/debug/{{project-name}} --path target/bpfel-unknown-none/debug/{{project-name}}
to
sudo target/debug/{{project-name}} target/bpfel-unknown-none/debug/{{project-name}}
currently a freshly generated kprobe project shows the following clippy issues:
$ cargo xtask build-ebpf && cargo +nightly clippy
warning: the borrowed expression implements the required traits
--> xtask/src/build_ebpf.rs:58:22
|
58 | .current_dir(&dir)
| ^^^^ help: change this to: `dir`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
= note: `#[warn(clippy::needless_borrow)]` on by default
warning: variables can be used directly in the `format!` string
--> xtask/src/run.rs:50:20
|
50 | let bin_path = format!("target/{}/kprobetcp", profile);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
= note: `#[warn(clippy::uninlined_format_args)]` on by default
help: change this to
|
50 - let bin_path = format!("target/{}/kprobetcp", profile);
50 + let bin_path = format!("target/{profile}/kprobetcp");
|
warning: accessing first element with `args.get(0)`
--> xtask/src/run.rs:61:28
|
61 | let err = Command::new(args.get(0).expect("No first argument"))
| ^^^^^^^^^^^ help: try: `args.first()`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#get_first
= note: `#[warn(clippy::get_first)]` on by default
warning: variables can be used directly in the `format!` string
--> xtask/src/main.rs:30:9
|
30 | eprintln!("{:#}", e);
| ^^^^^^^^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
help: change this to
|
30 - eprintln!("{:#}", e);
30 + eprintln!("{e:#}");
|
warning: `xtask` (bin "xtask") generated 4 warnings (run `cargo clippy --fix --bin "xtask"` to apply 4 suggestions)
Checking kprobetcp v0.1.0 (/home/dmitris/code/tmp/kprobetcp/kprobetcp)
warning: unused variable: `opt`
--> kprobetcp/src/main.rs:15:9
|
15 | let opt = Opt::parse();
| ^^^ help: if this is intentional, prefix it with an underscore: `_opt`
|
= note: `#[warn(unused_variables)]` on by default
warning: `kprobetcp` (bin "kprobetcp") generated 1 warning (run `cargo clippy --fix --bin "kprobetcp"` to apply 1 suggestion)
Finished dev [unoptimized + debuginfo] target(s) in 0.27s
@vadorovsky on Discord today:
I would also replace structopt crate with clap https://crates.io/crates/clap.
clap since 3.0 has all structopt's functionality in and it will likely become a standard
https://discord.com/channels/855676609003651072/855676609003651075/957984334051155988
Adding an issue for the discussion we had on twitter...
The current interactive cli flow allows you to define a tracepoint where you get to specify the tracepoint's category and name. That's great! It's pretty common where you define more than one hook though. Wonder if the template can support a flow like that.
Isn't it unnecessary since we already have rust-toolchain.toml
?
https://github.com/aya-rs/aya-template/blob/347d37c9149a3041dc41cc9730866ffefa2c418c/%7B%7Bproject-name%7D%7D-ebpf/rust-toolchain.toml
If we need, I'd like to update it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.