// SPDX-License-Identifier: GPL-3.0-or-later
#include "ebpf.h"
#include "ebpf_dcstat.h"
static char *dcstat_counter_dimension_name[NETDATA_DCSTAT_IDX_END] = { "ratio", "reference", "slow", "miss" };
static netdata_syscall_stat_t dcstat_counter_aggregated_data[NETDATA_DCSTAT_IDX_END];
static netdata_publish_syscall_t dcstat_counter_publish_aggregated[NETDATA_DCSTAT_IDX_END];
netdata_dcstat_pid_t *dcstat_vector = NULL;
netdata_publish_dcstat_t **dcstat_pid = NULL;
static struct bpf_link **probe_links = NULL;
static struct bpf_object *objects = NULL;
static netdata_idx_t dcstat_hash_values[NETDATA_DCSTAT_IDX_END];
static netdata_idx_t *dcstat_values = NULL;
static int read_thread_closed = 1;
struct config dcstat_config = { .first_section = NULL,
.last_section = NULL,
.mutex = NETDATA_MUTEX_INITIALIZER,
.index = { .avl_tree = { .root = NULL, .compar = appconfig_section_compare },
.rwlock = AVL_LOCK_INITIALIZER } };
struct netdata_static_thread dcstat_threads = {"DCSTAT KERNEL",
NULL, NULL, 1, NULL,
NULL, NULL};
static ebpf_local_maps_t dcstat_maps[] = {{.name = "dcstat_global", .internal_input = NETDATA_DIRECTORY_CACHE_END,
.user_input = 0, .type = NETDATA_EBPF_MAP_STATIC,
.map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED},
{.name = "dcstat_pid", .internal_input = ND_EBPF_DEFAULT_PID_SIZE,
.user_input = 0,
.type = NETDATA_EBPF_MAP_RESIZABLE | NETDATA_EBPF_MAP_PID,
.map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED},
{.name = "dcstat_ctrl", .internal_input = NETDATA_CONTROLLER_END,
.user_input = 0,
.type = NETDATA_EBPF_MAP_CONTROLLER,
.map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED},
{.name = NULL, .internal_input = 0, .user_input = 0,
.type = NETDATA_EBPF_MAP_CONTROLLER,
.map_fd = ND_EBPF_MAP_FD_NOT_INITIALIZED}};
static ebpf_specify_name_t dc_optional_name[] = { {.program_name = "netdata_lookup_fast",
.function_to_attach = "lookup_fast",
.optional = NULL,
.retprobe = CONFIG_BOOLEAN_NO},
{.program_name = NULL}};
/*****************************************************************
*
* COMMON FUNCTIONS
*
*****************************************************************/
/**
* Update publish
*
* Update publish values before to write dimension.
*
* @param out structure that will receive data.
* @param cache_access number of access to directory cache.
* @param not_found number of files not found on the file system
*/
void dcstat_update_publish(netdata_publish_dcstat_t *out, uint64_t cache_access, uint64_t not_found)
{
calculated_number successful_access = (calculated_number) (((long long)cache_access) - ((long long)not_found));
calculated_number ratio = (cache_access) ? successful_access/(calculated_number)cache_access : 0;
out->ratio = (long long )(ratio*100);
}
/*****************************************************************
*
* FUNCTIONS TO CLOSE THE THREAD
*
*****************************************************************/
/**
* Clean PID structures
*
* Clean the allocated structures.
*/
void clean_dcstat_pid_structures() {
struct pid_stat *pids = root_of_pids;
while (pids) {
freez(dcstat_pid[pids->pid]);
pids = pids->next;
}
}
/**
* Clean names
*
* Clean the optional names allocated during startup.
*/
void ebpf_dcstat_clean_names()
{
size_t i = 0;
while (dc_optional_name[i].program_name) {
freez(dc_optional_name[i].optional);
i++;
}
}
/**
* Clean up the main thread.
*
* @param ptr thread data.
*/