33#include <argp.h>
44#include <signal.h>
55#include <stdio.h>
6+ #include <stdlib.h>
67#include <sys/resource.h>
78#include <bpf/bpf.h>
89#include <bpf/libbpf.h>
@@ -53,6 +54,22 @@ int main(int argc, char **argv)
5354 int iter_fd ;
5455 ssize_t ret ;
5556 int err ;
57+ LIBBPF_OPTS (bpf_iter_attach_opts , opts );
58+ union bpf_iter_link_info linfo ;
59+ pid_t pid_filter = 0 ;
60+
61+ /* The user can provide a process id as first argument to the executable. This can be used
62+ * to filter out all tasks not belonging to a particular process.
63+ */
64+ if (argc > 1 ) {
65+ errno = 0 ;
66+ pid_filter = (pid_t )strtol (argv [1 ], NULL , 10 );
67+ err = - errno ;
68+ if (err != 0 || pid_filter < 0 ) {
69+ fprintf (stderr , "Failed to parse pid '%s'\n" , argv [1 ]);
70+ return err ;
71+ }
72+ }
5673
5774 /* Set up libbpf errors and debug info callback */
5875 libbpf_set_print (libbpf_print_fn );
@@ -68,12 +85,25 @@ int main(int argc, char **argv)
6885 goto cleanup ;
6986 }
7087
71- /* Attach tracepoints */
72- err = task_iter_bpf__attach (skel );
73- if (err ) {
88+ /* Attach BPF iterator program */
89+ memset (& linfo , 0 , sizeof (linfo ));
90+ linfo .task .pid = pid_filter ; /* If the pid is set to zero, no filtering logic is applied */
91+ opts .link_info = & linfo ;
92+ opts .link_info_len = sizeof (linfo );
93+ skel -> links .get_tasks = bpf_program__attach_iter (skel -> progs .get_tasks , & opts );
94+ if (!skel -> links .get_tasks ) {
95+ err = - errno ;
7496 fprintf (stderr , "Failed to attach BPF skeleton\n" );
7597 goto cleanup ;
7698 }
99+ /* Alternatively, if the user doesn't want to provide any option, the following simplified
100+ * version can be used:
101+ * err = task_iter_bpf__attach(skel);
102+ * if (err) {
103+ * fprintf(stderr, "Failed to attach BPF skeleton\n");
104+ * goto cleanup;
105+ * }
106+ */
77107
78108 iter_fd = bpf_iter_create (bpf_link__fd (skel -> links .get_tasks ));
79109 if (iter_fd < 0 ) {
0 commit comments