Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gadgets/run: Support iterators programs. #1866

Merged
merged 8 commits into from
Oct 27, 2023

Conversation

mauriciovasquezbernal
Copy link
Member

@mauriciovasquezbernal mauriciovasquezbernal commented Jul 18, 2023

This PR implements support for bpf iterators in the run command.

    This commit introduces support for ebpf iterators in the run command.
    
    As in the tracers (print_ map) case, BTF is a key component as it's used
    to convert binary data to a human readable format. In this case, getting
    the BTF information is not straightforward as it's not present on the
    iterator program directly, instead, the gadget developers have to define
    a dummy variable to guarantee the compiler generates this information for
    us:
    
    const struct myevent *gadget_iter_type __attribute__((unused));
    
    Inspektor Gadget loads and attachs all iterators programs of type task
    it found. When the gadget is run, it reads the results of the iterator
    and uses the BTF information provided above to format the d

The snapshot process and snapshot gadget are ported. They have almost the same functionality, some things that we can't support now are:

  • snapshot/process: Tree view, requires custom userspace logic
  • snapshot/socket: Proto string output, needs enum to string (will be done later on)

How to use

Snapshot process

$ go run -exec "sudo -E" ./cmd/ig/. run --prog @./gadgets/snapshot_process_x86.bpf.o --definition @./gadgets/snapshot_process.yaml 
INFO[0000] Experimental features enabled                
RUNTIME.CONTAINERNAME                                            RUNTIME.CONTAINERIMAGENAME         TGID    PID     COMM             UID      GID      PPID   
local-registry                                                                                      3092    3092    registry         0        0        3072   
buildx_buildkit_amazing_wozniak0                                                                    52766   52766   docker-init      0        0        52747  
buildx_buildkit_amazing_wozniak0                                                                    52790   52790   buildkitd        0        0        52766  
test-ig-close                                                                                       241219  241219  sh               0        0        241168 
mycontainer2                                                                                        306374  306374  sh               0        0        306354 
mycontainer2                                                                                        446574  446574  nc               1001     1005     306374 

Snapshot socket

$ go run -exec "sudo -E" ./cmd/ig/. run --prog @./gadgets/snapshot_socket_x86.bpf.o --definition @./gadgets/sna
pshot_socket.yaml 
INFO[0000] Experimental features enabled                
RUNTIME.CONTAINERNAME                                    RUNTIME.CONTAINERIMAGENAME     SRC                           DST                           STATE     
mycontainer2                                                                            127.0.0.1:8555                0.0.0.0:0                     10        

Fixes #1918

TODO:

  • Array support in json formatter
  • --sort support (doesn't work for strings yet)
  • Integration tests
  • Support other kind of iterators (future PR?)
  • Merge gadgets: Define metadata format #2107
  • Validate metadata
  • Support metadata generation
  • Discuss about gadgets: Make gadget type dynamic approach

Related #1724

@alban
Copy link
Member

alban commented Jul 20, 2023

In order to support both binary struct printed with bpf_seq_write() (parsed according to the BTF type) and text of arbitrary length printed with bpf_seq_printf_btf() (see #1724), I wrote the following PoC:

commit ddfacce

Support for bpf_seq_printf_btf() could be added later. I just wanted to validate that it is fine to use binary structs in bpf iterators even if we want to support bpf_seq_printf_btf() later.


The event struct should have placeholder fields for each text field of arbitrary length:

typedef u64 field_placeholder_btf;

struct myevent {
	__u32 tgid;
	__u32 pid;

	field_placeholder_btf user;
	field_placeholder_btf user_ns;
...

The bpf program should write an event with bpf_seq_write(), followed by
as many NULL-terminated strings as there are fields of type
field_placeholder_btf in the event struct:

	bpf_seq_write(seq, &event, sizeof(event));

	ptr.type_id = bpf_core_type_id_kernel(struct user_struct);
	ptr.ptr = BPF_CORE_READ(task, cred, user);
	bpf_seq_printf_btf(seq, &ptr, sizeof(ptr), 0);
	bpf_seq_write(seq, &nul, 1);

	ptr.type_id = bpf_core_type_id_kernel(struct user_namespace);
	ptr.ptr = BPF_CORE_READ(task, cred, user_ns);
	bpf_seq_printf_btf(seq, &ptr, sizeof(ptr), 0);
	bpf_seq_write(seq, &nul, 1);

Then it will be placed in virtual columns:

$ go run -exec 'sudo -E' ./cmd/ig/... run --definition=@gadgets/snapshot_process.yaml --prog=@gadgets/snapshot_process_x86.bpf.o
INFO[0000] Experimental features enabled
RUNTIME.CONTAINERNAME                                                   RUNTIME.CONTAINERIMAGENAME            TGID    PID     COMM             UID      GID      USER.BTF_STRING                         USER_NS.BTF_STRING
minikube-cri-o                                                                                                120839  120839  conmon           0        0        (struct user_struct){
 .__count = (re   (struct user_namespace){
 .uid_map =

Columns are difficult to read when they have multilines content. It can
also be displayed in yaml or json:

$ go run -exec 'sudo -E' ./cmd/ig/... run --definition=@gadgets/snapshot_process.yaml --prog=@gadgets/snapshot_process_x86.bpf.o -o yaml
- btfstrings:
  - |
    (struct user_struct){
     .__count = (refcount_t){
      .refs = (atomic_t){
       .counter = (int)2028,
    ...
  - "(struct user_namespace){\n .uid_map = (struct uid_gid_map){\n  .nr_extents ..."
  data: null
  k8s: {}
  mountnsid: 4026533928
  raw_data: AAAAAALINwACyDcA2bg3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgIAPAAAAAAY29ubW9uAAAAAAAAAAAAAA==
  runtime:
    containerId: 8879a64ab1d48ef8958e1d613acc429cce08ea611430a73fc584a41526525fae
    containerName: minikube-cri-o
    runtimeName: docker
  type: normal

Copy link
Member

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks cool!
I have some comments nonetheless:

pkg/gadgets/run/tracer/run.go Outdated Show resolved Hide resolved
pkg/gadgets/run/tracer/tracer.go Outdated Show resolved Hide resolved
pkg/columns/formatter/json/json.go Outdated Show resolved Hide resolved
pkg/gadgets/run/tracer/tracer.go Outdated Show resolved Hide resolved
pkg/gadgets/run/tracer/tracer.go Show resolved Hide resolved
pkg/gadgets/run/tracer/tracer.go Show resolved Hide resolved
gadgets/snapshot_process.bpf.c Outdated Show resolved Hide resolved
gadgets/snapshot_process.yaml Outdated Show resolved Hide resolved
gadgets/snapshot_socket.bpf.c Outdated Show resolved Hide resolved
integration/run_helpers.go Outdated Show resolved Hide resolved
Base automatically changed from mauricio/new-metadata-file to main October 18, 2023 21:03
@mauriciovasquezbernal mauriciovasquezbernal force-pushed the mauricio/snapshotters-run branch 4 times, most recently from ca0715d to 41e1ea8 Compare October 19, 2023 18:51
@mauriciovasquezbernal mauriciovasquezbernal changed the base branch from main to burak/mauro/gadget-params October 19, 2023 18:52
@mauriciovasquezbernal mauriciovasquezbernal force-pushed the mauricio/snapshotters-run branch 2 times, most recently from a2787df to 6ef5a79 Compare October 19, 2023 19:17
Copy link
Member

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works perfectly! Thank you!

$ sudo -E ./ig run -c competent_yalow ghcr.io/inspektor-gadget/gadget/snapshot_process:test
INFO[0000] Experimental features enabled                
RUNTIME.CONTAINERNAME            COMM              PID               TID               PPID             UID              GID             
competent_yalow                  nginx             63124             63124             63100            0                0               
competent_yalow                  nginx             63172             63172             63124            101              101             
competent_yalow                  nginx             63173             63173             63124            101              101             
competent_yalow                  nginx             63174             63174             63124            101              101             
competent_yalow                  nginx             63175             63175             63124            101              101             
competent_yalow                  nginx             63176             63176             63124            101              101             
competent_yalow                  nginx             63177             63177             63124            101              101             
competent_yalow                  nginx             63178             63178             63124            101              101             
competent_yalow                  nginx             63179             63179             63124            101              101             
$ sudo -E ./ig run -c competent_yalow ghcr.io/inspektor-gadget/gadget/snapshot_socket:test
INFO[0000] Experimental features enabled                
RUNTIME.CONTAINERNAME                                              SRC                                 DST                               
competent_yalow                                                    [::]:80                             [::]:0                            
competent_yalow                                                    0.0.0.0:80                          0.0.0.0:0

cmd/common/registry.go Outdated Show resolved Hide resolved
pkg/gadgets/run/tracer/run.go Show resolved Hide resolved
pkg/gadgets/run/types/metadata.go Outdated Show resolved Hide resolved
@mauriciovasquezbernal mauriciovasquezbernal force-pushed the mauricio/snapshotters-run branch 4 times, most recently from 6160b3d to 4e66675 Compare October 24, 2023 12:57
@mauriciovasquezbernal
Copy link
Member Author

I updated the PR to include runTypes.GadgetInfo instead of gadgets.GadgetType in GadgetContext That's more flexible and can be used by #2168.

Base automatically changed from burak/mauro/gadget-params to main October 27, 2023 15:45
Signed-off-by: Mauricio Vásquez <mauriciov@microsoft.com>
The gadget type is used to determine the flags that are supported by
a given gadget. In the case of containerized gadgets, this changes
according to the gadget being run, hence the previous approach wasn't
totally right. This commit makes this field more "dyanmic", specifically
it:
- Introduces logic to get this field according to get gadget's behavior
- Adds this to GadgetInfo
- Moves flag creation to PreRunE (once gadget type is known)
- Introduces the "run" gadget type

Signed-off-by: Mauricio Vásquez <mauriciov@microsoft.com>
Signed-off-by: Mauricio Vásquez <mauriciov@microsoft.com>
As in the tracers case, BTF is a key component as it's used to convert
binary data to a human readable format. Inspektor Gadget loads and
attaches all iterators programs it finds. When the gadget is run,
it reads the results of the iterator and uses the BTF information
provided above to format the data.

Signed-off-by: Mauricio Vásquez <mauriciov@microsoft.com>
Signed-off-by: Mauricio Vásquez <mauriciov@microsoft.com>
Signed-off-by: Mauricio Vásquez <mauriciov@microsoft.com>
Signed-off-by: Mauricio Vásquez <mauriciov@microsoft.com>
Signed-off-by: Mauricio Vásquez <mauriciov@microsoft.com>
@mauriciovasquezbernal mauriciovasquezbernal merged commit c0f4cd4 into main Oct 27, 2023
50 checks passed
@mauriciovasquezbernal mauriciovasquezbernal deleted the mauricio/snapshotters-run branch October 27, 2023 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

run: Support iterator programs
3 participants