Skip to content

Commit

Permalink
chore(userspace/libsinsp): improve docs about thread info filtering
Browse files Browse the repository at this point in the history
Signed-off-by: Jason Dellaluce <[email protected]>
  • Loading branch information
jasondellaluce authored and Andreagit97 committed Jan 9, 2024
1 parent bd02e54 commit 3b22f05
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 25 deletions.
46 changes: 37 additions & 9 deletions userspace/libsinsp/sinsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -972,28 +972,56 @@ void sinsp::on_new_entry_from_proc(void* context,
}
else
{
auto sinsp_tinfo = find_thread(tid, true);

// in case the inspector is configured with an internal filter,
// we filter out thread infos in case we determine them not passing
// the given filter. Filtered out thread infos will not be dumped
// in capture files.
//
// In case we have a filter, we set the "filtered out" thread info
// flag as true by default and toggle it to false later when one of
// the following cases occurs:
// - One event referencing the thread info passes the filter
// - One event referencing one of the file descriptors
// owned by the thread info passes the filter
// However, when first adding a thread info or a file descriptor
// we have no guarantee that an event referencing them will actually
// ever occur, so we simulate an internal event right away and
// see if it gets filtered out or not.
sinsp_tinfo->m_filtered_out = false;
if(m_filter != nullptr && is_capture())
{
// note: the choice of PPME_SCAPEVENT_E is opinionated as by
// nature it will always pass filters using "evt.type=scapevent".
// However:
// 1. It does not represent a real-world use case given that
// PPME_SCAPEVENT_E is an internal-usage mock event
// 2. This approach is still not effective for evttype-based
// filtering: a filter like "evt.type=execve" will filter-out
// any simulated event that is not an execve. Performing
// correct thread info filtering based on the type of event
// would require scanning the whole capture file twice, which
// is a performance overhead not acceptable for some use cases.
scap_evt tscapevt = {};
tscapevt.type = PPME_SCAPEVENT_X;
tscapevt.tid = tid;
tscapevt.ts = 0;
tscapevt.type = PPME_SYSCALL_READ_X;
tscapevt.len = 0;
tscapevt.nparams = 0;
tscapevt.len = sizeof(scap_evt);

auto tinfo = find_thread(tid, true);
sinsp_evt tevt = {};
tevt.m_pevt = &tscapevt;
tevt.m_inspector = this;
tevt.m_info = &(g_infotables.m_event_info[PPME_SYSCALL_READ_X]);
tevt.m_info = &(g_infotables.m_event_info[PPME_SCAPEVENT_X]);
tevt.m_cpuid = 0;
tevt.m_evtnum = 0;
tevt.m_tinfo = tinfo.get();
tevt.m_inspector = this;
tevt.m_tinfo = sinsp_tinfo.get();
tevt.m_fdinfo = NULL;
tinfo->m_lastevent_fd = -1;
tinfo->m_lastevent_data = NULL;
sinsp_tinfo->m_lastevent_fd = -1;
sinsp_tinfo->m_lastevent_data = NULL;

tinfo->m_filtered_out = !m_filter->run(&tevt);
sinsp_tinfo->m_filtered_out = !m_filter->run(&tevt);
}

// we shouldn't see any fds yet
Expand Down
41 changes: 25 additions & 16 deletions userspace/libsinsp/threadinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -390,41 +390,50 @@ void sinsp_threadinfo::add_fd_from_scap(scap_fdinfo *fdi, OUT sinsp_fdinfo_t *re
return;
}

m_fdtable.add(fdi->fd, newfdi);
newfdi = m_fdtable.add(fdi->fd, newfdi);
if(m_inspector->m_filter != nullptr && m_inspector->is_capture())
{
sinsp_evt tevt;
scap_evt tscapevt;
//
// Initialize the fake events for filtering
//
tscapevt.ts = 0;
// in case the inspector is configured with an internal filter, we can
// filter-out thread infos (and their fd infos) to not dump them in
// captures unless actually used. Here, we simulate an internal event
// using the new file descriptor info to understand if we can set
// its thread info as non-filterable.

// note: just like the case of PPME_SCAPEVENT_E used for thread info
// filtering, the usage of PPME_SYSCALL_READ_X is opinionated. This
// kind of event has been chosen as a tradeoff of a lightweight and
// usually-ignored event (in the context of filtering), but that is also
// marked as using a file descriptor so that file-descriptor filter fields
// can extract meaningful values.
scap_evt tscapevt = {};
tscapevt.type = PPME_SYSCALL_READ_X;
tscapevt.len = 0;
tscapevt.tid = m_tid;
tscapevt.ts = 0;
tscapevt.nparams = 0;
tscapevt.len = sizeof(scap_evt);

tevt.m_inspector = m_inspector;
sinsp_evt tevt = {};
tevt.m_pevt = &tscapevt;
tevt.m_info = &(g_infotables.m_event_info[PPME_SYSCALL_READ_X]);
tevt.m_pevt = NULL;
tevt.m_cpuid = 0;
tevt.m_evtnum = 0;
tevt.m_pevt = &tscapevt;
tevt.m_inspector = m_inspector;
tevt.m_tinfo = this;
tevt.m_fdinfo = newfdi;
tscapevt.tid = m_tid;
int64_t tlefd = tevt.m_tinfo->m_lastevent_fd;
tevt.m_tinfo->m_lastevent_fd = fdi->fd;

if(m_inspector->m_filter->run(&tevt))
{
// keep the thread from being filtered out
// we mark the thread info as non-filterable due to one event
// using one of its file descriptor has passed the filter
m_filtered_out = false;
}
else
{
//
// This tells scap not to include this FD in the write file
//
// we can't say if the thread info for this fd is filterable or not,
// but we can mark the given file descriptor as filterable. This flag
// will prevent the fd info from being written in captures.
fdi->type = SCAP_FD_UNINITIALIZED;
}

Expand Down

0 comments on commit 3b22f05

Please sign in to comment.