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

Don't drop events while requesting CPU usage from driver #18

Merged
merged 6 commits into from
Mar 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions userspace/libscap/scap-int.h
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ int32_t scap_update_suppressed(scap_t *handle,
// Wrapper around strerror using buffer in handle
const char *scap_strerror(scap_t *handle, int errnum);

struct ppm_proclist_info *scap_procfs_get_threadlist(scap_t *handle);

//
// ASSERT implementation
//
Expand Down
9 changes: 2 additions & 7 deletions userspace/libscap/scap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2324,14 +2324,9 @@ struct ppm_proclist_info* scap_get_threadlist(scap_t* handle)
}
}

if(handle->m_bpf)
if(handle->m_bpf || handle->m_udig)
{
return scap_bpf_get_threadlist(handle);
}
else if(handle->m_udig)
{
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "scap_get_threadlist not supported on udig captures");
return NULL;
return scap_procfs_get_threadlist(handle);
}
else
{
Expand Down
4 changes: 0 additions & 4 deletions userspace/libscap/scap.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,7 @@ struct iovec;
//
// Core types
//
#ifndef __APPLE__
#include <time.h>
#endif
#include "uthash.h"
#include "../common/sysdig_types.h"
#include "../../driver/ppm_events_public.h"
Expand Down Expand Up @@ -537,7 +535,6 @@ struct ppm_syscall_desc {
#define UDIG_RING_DESCS_SM_FNAME "udig_descs"
#define UDIG_RING_SIZE (8 * 1024 * 1024)

#ifndef __APPLE__
struct udig_ring_buffer_status {
volatile uint64_t m_buffer_lock;
volatile int m_initialized;
Expand All @@ -546,7 +543,6 @@ struct udig_ring_buffer_status {
volatile struct timespec m_last_print_time;
struct udig_consumer_t m_consumer;
};
#endif // __APPLE__

typedef struct ppm_ring_buffer_info ppm_ring_buffer_info;

Expand Down
108 changes: 0 additions & 108 deletions userspace/libscap/scap_bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1424,114 +1424,6 @@ int32_t scap_bpf_load(scap_t *handle, const char *bpf_probe)
#endif // MINIMAL_BUILD
}

struct ppm_proclist_info *scap_bpf_get_threadlist(scap_t *handle)
{
DIR *dir_p = NULL;
DIR *taskdir_p = NULL;
FILE *fp = NULL;
struct ppm_proclist_info *res = NULL;
struct dirent *dir_entry_p;
char procdirname[SCAP_MAX_PATH_SIZE];

handle->m_driver_procinfo->n_entries = 0;

snprintf(procdirname, sizeof(procdirname), "%s/proc", scap_get_host_root());

dir_p = opendir(procdirname);
if(dir_p == NULL)
{
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "error opening the %s directory", procdirname);
goto error;
}

while((dir_entry_p = readdir(dir_p)) != NULL)
{
char tasksdirname[SCAP_MAX_PATH_SIZE];
struct dirent *taskdir_entry_p;
DIR *taskdir_p;

if(strspn(dir_entry_p->d_name, "0123456789") != strlen(dir_entry_p->d_name))
{
continue;
}

snprintf(tasksdirname, sizeof(tasksdirname), "%s/%s/task", procdirname, dir_entry_p->d_name);

taskdir_p = opendir(tasksdirname);
if(taskdir_p == NULL)
{
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "error opening the %s directory", tasksdirname);
continue;
}

while((taskdir_entry_p = readdir(taskdir_p)) != NULL)
{
char filename[SCAP_MAX_PATH_SIZE];
unsigned long utime;
unsigned long stime;
int tid;

if(strspn(taskdir_entry_p->d_name, "0123456789") != strlen(taskdir_entry_p->d_name))
{
continue;
}

snprintf(filename, sizeof(filename), "%s/%s/stat", tasksdirname, taskdir_entry_p->d_name);

fp = fopen(filename, "r");
if(fp == NULL)
{
continue;
}

if(fscanf(fp, "%d %*[^)] %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %lu %lu", &tid, &utime, &stime) != 3)
{
fclose(fp);
fp = NULL;
continue;
}

if(handle->m_driver_procinfo->n_entries == handle->m_driver_procinfo->max_entries)
{
if(!scap_alloc_proclist_info(handle, handle->m_driver_procinfo->n_entries + 256))
{
goto error;
}
}

handle->m_driver_procinfo->entries[handle->m_driver_procinfo->n_entries].pid = tid;
handle->m_driver_procinfo->entries[handle->m_driver_procinfo->n_entries].utime = utime;
handle->m_driver_procinfo->entries[handle->m_driver_procinfo->n_entries].stime = stime;
++handle->m_driver_procinfo->n_entries;

fclose(fp);
fp = NULL;
}

closedir(taskdir_p);
taskdir_p = NULL;
}

res = handle->m_driver_procinfo;
error:
if(dir_p)
{
closedir(dir_p);
}

if(taskdir_p)
{
closedir(taskdir_p);
}

if(fp)
{
fclose(fp);
}

return res;
}

int32_t scap_bpf_get_stats(scap_t* handle, OUT scap_stats* stats)
{
int j;
Expand Down
1 change: 0 additions & 1 deletion userspace/libscap/scap_bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ int32_t scap_bpf_enable_page_faults(scap_t* handle);
int32_t scap_bpf_start_dropping_mode(scap_t* handle, uint32_t sampling_ratio);
int32_t scap_bpf_stop_dropping_mode(scap_t* handle);
int32_t scap_bpf_enable_tracers_capture(scap_t* handle);
struct ppm_proclist_info *scap_bpf_get_threadlist(scap_t *handle);
int32_t scap_bpf_get_stats(scap_t* handle, OUT scap_stats* stats);
int32_t scap_bpf_get_n_tracepoint_hit(scap_t* handle, long* ret);

Expand Down
1 change: 1 addition & 0 deletions userspace/libscap/scap_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ limitations under the License.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _WIN32
#include <winsock2.h>
#else
Expand Down
109 changes: 109 additions & 0 deletions userspace/libscap/scap_procs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1524,3 +1524,112 @@ int32_t scap_check_suppressed(scap_t *handle, scap_evt *pevent, bool *suppressed

return SCAP_SUCCESS;
}

struct ppm_proclist_info *scap_procfs_get_threadlist(scap_t *handle)
{
struct ppm_proclist_info *res = NULL;
#ifdef __linux__
DIR *dir_p = NULL;
DIR *taskdir_p = NULL;
FILE *fp = NULL;
struct dirent *dir_entry_p;
char procdirname[SCAP_MAX_PATH_SIZE];

handle->m_driver_procinfo->n_entries = 0;

snprintf(procdirname, sizeof(procdirname), "%s/proc", scap_get_host_root());

dir_p = opendir(procdirname);
if(dir_p == NULL)
{
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "error opening the %s directory", procdirname);
goto error;
}

while((dir_entry_p = readdir(dir_p)) != NULL)
{
char tasksdirname[SCAP_MAX_PATH_SIZE];
struct dirent *taskdir_entry_p;
DIR *taskdir_p;

if(strspn(dir_entry_p->d_name, "0123456789") != strlen(dir_entry_p->d_name))
{
continue;
}

snprintf(tasksdirname, sizeof(tasksdirname), "%s/%s/task", procdirname, dir_entry_p->d_name);

taskdir_p = opendir(tasksdirname);
if(taskdir_p == NULL)
{
snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "error opening the %s directory", tasksdirname);
continue;
}

while((taskdir_entry_p = readdir(taskdir_p)) != NULL)
{
char filename[SCAP_MAX_PATH_SIZE];
unsigned long utime;
unsigned long stime;
int tid;

if(strspn(taskdir_entry_p->d_name, "0123456789") != strlen(taskdir_entry_p->d_name))
{
continue;
}

snprintf(filename, sizeof(filename), "%s/%s/stat", tasksdirname, taskdir_entry_p->d_name);

fp = fopen(filename, "r");
if(fp == NULL)
{
continue;
}

if(fscanf(fp, "%d %*[^)] %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %lu %lu", &tid, &utime, &stime) != 3)
{
fclose(fp);
fp = NULL;
continue;
}

if(handle->m_driver_procinfo->n_entries == handle->m_driver_procinfo->max_entries)
{
if(!scap_alloc_proclist_info(handle, handle->m_driver_procinfo->n_entries + 256))
{
goto error;
}
}

handle->m_driver_procinfo->entries[handle->m_driver_procinfo->n_entries].pid = tid;
handle->m_driver_procinfo->entries[handle->m_driver_procinfo->n_entries].utime = utime;
handle->m_driver_procinfo->entries[handle->m_driver_procinfo->n_entries].stime = stime;
++handle->m_driver_procinfo->n_entries;

fclose(fp);
fp = NULL;
}

closedir(taskdir_p);
taskdir_p = NULL;
}

res = handle->m_driver_procinfo;
error:
if(dir_p)
{
closedir(dir_p);
}

if(taskdir_p)
{
closedir(taskdir_p);
}

if(fp)
{
fclose(fp);
}
#endif /* __linux__ */
return res;
}
82 changes: 44 additions & 38 deletions userspace/libsinsp/sinsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1062,6 +1062,48 @@ uint64_t sinsp::max_buf_used()
}
}

void sinsp::get_procs_cpu_from_driver(uint64_t ts)
{
if(ts <= m_next_flush_time_ns)
{
return;
}

uint64_t next_full_second = ts - (ts % ONE_SECOND_IN_NS) + ONE_SECOND_IN_NS;

if(m_next_flush_time_ns == 0)
{
m_next_flush_time_ns = next_full_second;
return;
}

m_next_flush_time_ns = next_full_second;

uint64_t procrequest_tod = sinsp_utils::get_current_time_ns();
leodido marked this conversation as resolved.
Show resolved Hide resolved
if(procrequest_tod - m_last_procrequest_tod <= ONE_SECOND_IN_NS / 2)
{
return;
}

m_last_procrequest_tod = procrequest_tod;

m_meinfo.m_pli = scap_get_threadlist(m_h);
if(m_meinfo.m_pli == NULL)
{
throw sinsp_exception(string("scap error: ") + scap_getlasterr(m_h));
}

m_meinfo.m_n_procinfo_evts = m_meinfo.m_pli->n_entries;
if(m_meinfo.m_n_procinfo_evts > 0)
{
m_meinfo.m_cur_procinfo_evt = -1;

m_meinfo.m_piscapevt->ts = m_next_flush_time_ns - (ONE_SECOND_IN_NS + 1);
add_meta_event_callback(&schedule_next_threadinfo_evt, &m_meinfo);
schedule_next_threadinfo_evt(this, &m_meinfo);
}
}

int32_t sinsp::next(OUT sinsp_evt **puevt)
{
sinsp_evt* evt;
Expand Down Expand Up @@ -1155,45 +1197,9 @@ int32_t sinsp::next(OUT sinsp_evt **puevt)
//
// If required, retrieve the processes cpu from the kernel
//
if(m_get_procs_cpu_from_driver && is_live() && !m_udig)
if(m_get_procs_cpu_from_driver && is_live())
{
if(ts > m_next_flush_time_ns)
{
if(m_next_flush_time_ns != 0)
{
struct timeval tod;
gettimeofday(&tod, NULL);

uint64_t procrequest_tod = (uint64_t)tod.tv_sec * 1000000000 + tod.tv_usec * 1000;

if(procrequest_tod - m_last_procrequest_tod > ONE_SECOND_IN_NS / 2)
{
m_last_procrequest_tod = procrequest_tod;
m_next_flush_time_ns = ts - (ts % ONE_SECOND_IN_NS) + ONE_SECOND_IN_NS;

m_meinfo.m_pli = scap_get_threadlist(m_h);
if(m_meinfo.m_pli == NULL)
{
throw sinsp_exception(string("scap error: ") + scap_getlasterr(m_h));
}

m_meinfo.m_n_procinfo_evts = m_meinfo.m_pli->n_entries;

if(m_meinfo.m_n_procinfo_evts > 0)
{
m_meinfo.m_cur_procinfo_evt = -1;

m_meinfo.m_piscapevt->ts = m_next_flush_time_ns - (ONE_SECOND_IN_NS + 1);
add_meta_event_callback(&schedule_next_threadinfo_evt, &m_meinfo);
schedule_next_threadinfo_evt(this, &m_meinfo);
}

return SCAP_TIMEOUT;
}
}

m_next_flush_time_ns = ts - (ts % ONE_SECOND_IN_NS) + ONE_SECOND_IN_NS;
}
get_procs_cpu_from_driver(ts);
}

//
Expand Down
Loading