On Tue, Sep 22, 2026 at 7:30 AM Andrii Nakryiko
<[email protected]> wrote:
>
> On Thu, Sep 17, 2026 at 9:09 PM Thiébaud Weksteen <[email protected]> wrote:
> >
> > When generating a light skeleton (bpftool gen skeleton -L),
> > bpf_object__load() skips loading programs marked as non-autoload (e.g.
> > SEC("?...")), so the generated loader program only records and populates
> > file descriptors for autoloaded programs.
> >
> > Previously, bpftool emitted struct bpf_prog_desc fields, link fields,
> > and attach/detach/destroy functions for all programs in the BPF object,
> > causing the loader program to store subsequent program FDs into
> > incorrect skeleton struct fields when non-autoload programs were
> > present.
> >
> > Furthermore, bpf_object__load() can update a program's autoload status
> > during preparation (e.g. for struct_ops programs when resolving kernel
> > BTF members or adjusting autoload based on map autocreate settings).
> > Move bpf_object__gen_loader() and bpf_object__load() out of gen_trace()
> > into do_skeleton() before counting programs and emitting struct fields so
> > that struct field declarations and attach/detach/destroy functions all
> > observe the final post-load autoload state.
> >
> > Skip programs with !bpf_program__autoload(prog) when counting programs
> > and generating progs/links struct fields as well as attach, detach, and
> > destroy functions for light skeletons.
>
> This seems like error prone behavior to me. Wouldn't it be better to
> hard fail if the BPF object has non-autoloaded BPF programs instead,
> as clearly it's not meant to be used with a light skeleton that
> doesn't support such programs? So why not emit a meaningful error and
> exit?
Thanks for the feedback. This was my first approach [1]. I think it
also makes sense. I can send an updated version that addresses
Quentin's feedback ("goto out") if that is the overall preference.
[1] https://lore.kernel.org/bpf/[email protected]/
>
> Or I don't know, let's teach light skeleton how to support
> non-loadable programs maybe, not sure what that would take, but worth
> considering to bridge the gap?
This is technically possible, but I'm not sure this is what we want:
it could be implemented by adding a field to struct bpf_prog_desc and
change the behaviour of the loader depending on that field. The issue
is that, for signed light skeleton, we probably want to ignore this
field (for the same reason we are already ignoring initial_value; to
keep the attested blob authoritative). In that case, we end up
silently skipping any non-autoloaded program within a signed light
skeleton. I prefer the hard fail option discussed above, or silently
skipping for all kinds of light skeletons (this patch).
Thanks