program: Allow passing extra targets for CO-RE relocations#1814
program: Allow passing extra targets for CO-RE relocations#1814lmb merged 1 commit intocilium:mainfrom
Conversation
|
Very interesting idea! Essentially, you're plumbing the btf type of a map value into the relocation process, correct? Something like: Seems like a very useful pattern, so I wonder if this is something we could generalise. |
That's correct. Let me add some more details on what we're doing. We have a process that creates a shared map with a value structure like: struct sockets_value {
// Fields that are always present must go at the beginning. Ideally these
// fields aren't never changed, however it's possible to change their order,
// type, etc. as CO-RE will produce relocations for the gadgets using them.
__u64 foo;
__u64 bar;
// These fields are optional and can be disabled in the socket enricher
// operator. Gadgets using these fields MUST check if they exist by using
// bpf_core_field_exists() and get their size with bpf_core_field_size().
char cwd[SE_PATH_MAX];
char exepath[SE_PATH_MAX];
};The cwd and exepath fields require a lot of memory in some cases, so we made them configurable. We dynamically generate the BTF data for that structure and pass it to the relocation process to allow eBPF programs to read and write those fields at the correct offset. The programs that write and read the eBPF map are on the same process, so we don't pin it, and given that the BTF information of the map is generated, we don't need something like |
|
Yeah, makes sense re not pinning the map. I was thinking about how this could fit tetragon which does have persistent maps. It could be interesting to use this mechanism to handle backwards compat. The one thing I'm unsure is whether passing it as another target in CORERelocate does make sense this way. The function operates on the assumption that all passed specs share a "namespace" aka the kernel. My gut feeling says that it'd be good to distinguish between the relocation target being the kernel vs. custom BTF. Maybe it makes sense to run two relocations? |
I tried to prototype something but it's not that straightforward. The main issue that I'm facing is that the relocations don't have any information about their target, so I need to run them against all targets and see if any of them successfully resolves. Something like: I was using the poison boolean to check if a fixup is unresolved, but then I realized for One issue that I see with this approach is that it'll be harder to check if a relocation is ambiguous between the kernel and custom types. Do you think it's still worth it to separate the relocations? If yes, do you have any suggestion about the implementation? Does my idea work I should I try something different? |
|
All right, had another look at the CORE headers and such. I think your idea is the most straightforward. If a user passes an extra BTF with conflicting types they will get an ambiguous relocation error anyways. Can we do the following:
|
f72d1b7 to
aff3143
Compare
|
@lmb thanks a lot for the clear information, it was so easy to make those changes! I also removed the logic calling |
This commit introduces a new ExtraRelocationTargets field on ProgramOptions to llow users to pass additional targets (besides the kernel types) to perform CO-RE relocations. The KernelModuleTypes field is removed as ExtraRelocationTargets covers its functionality. This is used in Inspektor Gadget to perform relocations against a shared map that contains fields whose sizes change according to the runtime configuration. Signed-off-by: Mauricio Vásquez <[email protected]>
aff3143 to
640b158
Compare
Allow users to pass additional targets (besides the kernel and modules types) to perform CO-RE relocations.
This is used in Inspektor Gadget to perform relocations against a shared map that contains fields whose sizes change according to the runtime configuration.
cc @alban
Ref inspektor-gadget/inspektor-gadget#4543