Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Terzolo <andreaterzolo3@gmail.com>
Co-authored-by: Mauro Ezequiel Moltrasio <mmoltras@redhat.com>
  • Loading branch information
Andreagit97 and Molter73 committed Oct 12, 2023
1 parent 3d60d0e commit 0e01b59
Showing 1 changed file with 106 additions and 87 deletions.
193 changes: 106 additions & 87 deletions userspace/libpman/src/configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,92 @@ int pman_get_required_buffers()

static char byte_array[] = "BPF_TRACE_RAW_TP";

bool check_BPF_TRACE_RAW_TP(void)
bool check_location(const char* path)
{
bool res = false;

// On success `faccessat` returns 0.
if(faccessat(0, path, R_OK, AT_EACCESS) != 0)
{
return false;
}

char *file_content = NULL;
FILE *f = fopen(path, "r");
if(!f)
{
return false;
}

// Seek to the end of file
if(fseek(f, 0, SEEK_END))
{
goto cleanup;
}

// Return the dimension of the file
long sz = ftell(f);
if (sz < 0)
{
goto cleanup;
}

// Seek again to the beginning of the file
if(fseek(f, 0, SEEK_SET))
{
goto cleanup;
}

// pre-alloc memory to read all of BTF data
file_content = malloc(sz);
if (!file_content)
{
goto cleanup;
}

// read all of BTF data
if(fread(file_content, 1, sz, f) < sz)
{
goto cleanup;
}

// Search 'BPF_TRACE_RAW_TP' byte array
int z = 0;
for(int j = 0; j< sz; j++)
{
if(file_content[j] == byte_array[z])
{
z++;
if(z == sizeof(byte_array) / sizeof(*byte_array))
{
res = true;
break;
}
}
else
{
z = 0;
}
}

cleanup:
if(f)
{
fclose(f);
}
if(file_content)
{
free(file_content);
}
return res;
}

bool probe_BPF_TRACE_RAW_TP_type(void)
{
// These locations are taken from libbpf library:
// https://elixir.bootlin.com/linux/latest/source/tools/lib/bpf/btf.c#L4767
const char *locations[] = {
/* try canonical vmlinux BTF through sysfs first */
"/sys/kernel/btf/vmlinux",
/* fall back to trying to find vmlinux on disk otherwise */
"/boot/vmlinux-%1$s",
"/lib/modules/%1$s/vmlinux-%1$s",
"/lib/modules/%1$s/build/vmlinux",
Expand All @@ -187,97 +265,31 @@ bool check_BPF_TRACE_RAW_TP(void)
"/usr/lib/debug/boot/vmlinux-%1$s.debug",
"/usr/lib/debug/lib/modules/%1$s/vmlinux",
};
char path[PATH_MAX + 1];
struct utsname buf;
char *data = NULL;
FILE *f = NULL;
uname(&buf);

for (int i = 0; i < sizeof(locations) / sizeof(*locations); i++)
// Try canonical `vmlinux` BTF through `sysfs` first.
if(check_location(locations[0]))
{
snprintf(path, PATH_MAX, locations[i], buf.release);

// On success `faccessat` returns 0.
if(faccessat(0, path, R_OK, AT_EACCESS) != 0)
{
// The file doesn't exist, loop on the next one.
continue;
}

f = fopen(path, "r");
if(!f)
{
goto loop_again;
}

// Seek to the end of file
if(fseek(f, 0, SEEK_END))
{
goto loop_again;
}

// Return the dimension of the file
long sz = ftell(f);
if (sz < 0)
{
goto loop_again;
}

// Seek again to the beginning of the file
if(fseek(f, 0, SEEK_SET))
{
goto loop_again;
}

// pre-alloc memory to read all of BTF data
data = malloc(sz);
if (!data)
{
goto loop_again;
}
return true;
}

// read all of BTF data
if(fread(data, 1, sz, f) < sz)
{
goto loop_again;
}
// Fall back to trying to find `vmlinux` on disk otherwise
struct utsname buf = {};
if(uname(&buf) == -1)
{
return false;
}

// Search 'BPF_TRACE_RAW_TP' byte array
int z = 0;
for(int j = 0; j< sz; j++)
{
if(data[j] == byte_array[z])
{
z++;
if(z == sizeof(byte_array) / sizeof(*byte_array))
{
fclose(f);
free(data);
return true;
}
}
else
{
z = 0;
}
}
loop_again:
char path[PATH_MAX + 1];

if(f)
{
fclose(f);
f = NULL;
}
if(data)
// Skip vmlinux since we already tested it.
for (int i = 1; i < sizeof(locations) / sizeof(*locations); i++)
{
snprintf(path, PATH_MAX, locations[i], buf.release);
if(check_location(path))
{
free(data);
data = NULL;
return true;
}
}

// Clear the errno for `pman_print_error`
errno = 0;
pman_print_error("prog 'BPF_TRACE_RAW_TP' is not supported");
return false;
}

Expand All @@ -302,7 +314,14 @@ bool pman_check_support()
// to check for the `BPF_TRACE_RAW_TP` one. If `BPF_TRACE_FENTRY` is defined we are
// sure `BPF_TRACE_RAW_TP` is defined as well, in all other cases, we need to search
// for it in the `vmlinux` file.
return check_BPF_TRACE_RAW_TP();
res = probe_BPF_TRACE_RAW_TP_type();
if(!res)
{
// Clear the errno for `pman_print_error`
errno = 0;
pman_print_error("prog 'BPF_TRACE_RAW_TP' is not supported");
return res;
}
}

/* Probe result depends on the success of map creation, no additional
Expand Down

0 comments on commit 0e01b59

Please sign in to comment.