8000 feat(userspace/libsinsp)!: isolate `sinsp_threadinfo` from `sinsp` by ekoops · Pull Request #2335 · falcosecurity/libs · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat(userspace/libsinsp)!: isolate sinsp_threadinfo from sinsp #2335

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

Merged
merged 4 commits into from
Apr 17, 2025

Conversation

ekoops
Copy link
Contributor
@ekoops ekoops commented Apr 8, 2025

What type of PR is this?

Uncomment one (or more) /kind <> lines:

/kind bug

/kind cleanup

/kind design

/kind documentation

/kind failing-test

/kind feature

Any specific area of the project related to this PR?

Uncomment one (or more) /area <> lines:

/area API-version

/area build

/area CI

/area driver-kmod

/area driver-bpf

/area driver-modern-bpf

/area libscap-engine-bpf

/area libscap-engine-gvisor

/area libscap-engine-kmod

/area libscap-engine-modern-bpf

/area libscap-engine-nodriver

/area libscap-engine-noop

/area libscap-engine-source-plugin

/area libscap-engine-savefile

/area libscap

/area libpman

/area libsinsp

/area tests

/area proposals

Does this PR require a change in the driver versions?

/version driver-API-version-major

/version driver-API-version-minor

/version driver-API-version-patch

/version driver-SCHEMA-version-major

/version driver-SCHEMA-version-minor

/version driver-SCHEMA-version-patch

What this PR does / why we need it:

This PR is part of a series #2343.
It removes sinsp_threadinfo dependency on sinsp by selectively providing each single dependency the component needs.

In order to avoid code duplication in the event processor, this PR adds sinsp_thread_info::create_unique_attorney sinsp_threadinfo_factory's inner classes following the attorney-client idiom (this helps to limit access to sinsp_threadinfo_factory private methods).

Moreover, this PR also removes some related and unused sinsp APIs: sinsp::get_fdinfo_factory() and sinsp::get_fdtable_factory().

Finally, it changes the sinsp_threadinfo constructor to accept the dependencies.

Which issue(s) this PR fixes:

Fixes #

Special notes for your reviewer:

Does this PR introduce a user-facing change?:

feat(userspace/libsinsp)!: isolate immutable `sinsp_threadinfo` deps
feat(userspace/libsinsp)!: isolate mutable `sinsp_threadinfo` deps
feat(userspace/libsinsp)!: remove unused `sinsp` public APIs

Copy link
github-actions bot commented Apr 8, 2025

Perf diff from master - unit tests

     5.96%     -0.66%  [.] sinsp_parser::reset
     5.77%     -0.31%  [.] sinsp_evt::get_type
     2.84%     -0.31%  [.] gzfile_read
     0.47%     +0.30%  [.] libsinsp::events::is_unknown_event
     6.03%     +0.29%  [.] sinsp::next
     1.88%     -0.24%  [.] sinsp_thread_manager::get_thread_ref
     0.05%     +0.22%  [.] scap_get_event_info_table
    36.12%     -0.21%  [.] sinsp_thread_manager::create_thread_dependencies
     0.42%     -0.21%  [.] scap_next
     0.92%     +0.21%  [.] user_group_updater::user_group_updater

Heap diff from master - unit tests

peak heap memory consumption: 79.90K
peak RSS (including heaptrack overhead): 0B
total memory leaked: 0B

Heap diff from master - scap file

peak heap memory consumption: 2.04K
peak RSS (including heaptrack overhead): 0B
total memory leaked: 0B

Benchmarks diff from master

Comparing gbench_data.json to /root/actions-runner/_work/libs/libs/build/gbench_data.json
Benchmark                                                         Time             CPU      Time Old      Time New       CPU Old       CPU New
----------------------------------------------------------------------------------------------------------------------------------------------
BM_sinsp_split_mean                                            +0.0004         +0.0004           149           149           149           149
BM_sinsp_split_median                                          +0.0043         +0.0042           149           150           149           150
BM_sinsp_split_stddev                                          -0.0051         -0.0050             1             1             1             1
BM_sinsp_split_cv                                              -0.0055         -0.0053             0             0             0             0
BM_sinsp_concatenate_paths_relative_path_mean                  -0.0249         -0.0250            60            58            60            58
BM_sinsp_concatenate_paths_relative_path_median                -0.0282         -0.0282            60            58            60            58
BM_sinsp_concatenate_paths_relative_path_stddev                +0.8480         +0.8466             1             1             1             1
BM_sinsp_concatenate_paths_relative_path_cv                    +0.8951         +0.8939             0             0             0             0
BM_sinsp_concatenate_paths_empty_path_mean                     +0.0617         +0.0616            24            25            24            25
BM_sinsp_concatenate_paths_empty_path_median                   +0.0579         +0.0578            24            25            24            25
BM_sinsp_concatenate_paths_empty_path_stddev                   +3.6067         +3.5929             0             0             0             0
BM_sinsp_concatenate_paths_empty_path_cv                       +3.3388         +3.3263             0             0             0             0
BM_sinsp_concatenate_paths_absolute_path_mean                  +0.0852         +0.0851            56            61            56            61
BM_sinsp_concatenate_paths_absolute_path_median                +0.0828         +0.0827            56            61            56            61
BM_sinsp_concatenate_paths_absolute_path_stddev                +5.4077         +5.4030             0             1             0             1
BM_sinsp_concatenate_paths_absolute_path_cv                    +4.9048         +4.9011             0             0             0             0

Copy link
codecov bot commented Apr 8, 2025

Codecov Report

Attention: Patch coverage is 80.43478% with 9 lines in your changes missing coverage. Please review.

Project coverage is 77.02%. Comparing base (4927c63) to head (138dc83).
Report is 5 commits behind head on master.

Files with missing lines Patch % Lines
userspace/libsinsp/threadinfo.cpp 76.00% 6 Missing ⚠️
userspace/libsinsp/sinsp.cpp 75.00% 2 Missing ⚠️
userspace/libsinsp/sinsp_threadinfo_factory.h 91.66% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2335      +/-   ##
==========================================
- Coverage   77.03%   77.02%   -0.01%     
==========================================
  Files         228      228              
  Lines       30270    30266       -4     
  Branches     4636     4635       -1     
==========================================
- Hits        23319    23313       -6     
- Misses       6951     6953       +2     
Flag Coverage Δ
libsinsp 77.02% <80.43%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ekoops ekoops force-pushed the ekoops/isolate-threadinfo branch from 2c3e142 to 5d3a9ce Compare April 8, 2025 13:52
@@ -381,14 +388,13 @@ void sinsp_threadinfo::add_fd_from_scap(scap_fdinfo* fdi) {
tevt.set_info(&(g_infotables.m_event_info[PPME_SYSCALL_READ_X]));
tevt.set_cpuid(0);
tevt.set_num(0);
tevt.set_inspector(m_inspector);
Copy link
Contributor Author
@ekoops ekoops Apr 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the following line as the inspector is not anymore available in threadinfo. By inspecting the code, and by looking at the tests results, I couldn't find evidence this line was needed, but I'd be happier if someone could confirm that we don't actually need it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just tried to run sinsp-example in capture mode, configuring a filter to trigger that code path. It seems to work fine. I ran it using the following command:

sudo ./libsinsp/examples/sinsp-example -s ./scap_files/kexec_arm64.scap -f fd.type=ipv4

@FedeDP
Copy link
Contributor
FedeDP commented Apr 9, 2025

/milestone 0.21.0

@poiana poiana added this to the 0.21.0 milestone Apr 9, 2025
@ekoops ekoops force-pushed the ekoops/isolate-threadinfo branch 2 times, most recently from d74f7d0 to cf37cf5 Compare April 9, 2025 14:46
@github-project-automation github-project-automation bot moved this from Todo to In progress in Falco Roadmap Apr 9, 2025
@ekoops ekoops force-pushed the ekoops/isolate-threadinfo branch from cf37cf5 to 64dce56 Compare April 9, 2025 17:15
@ekoops
Copy link
Contributor Author
ekoops commented Apr 9, 2025

I broke down the big commit in 3 commits. 2 of them are still big, but I hope reviewers can better reason about the changes in this way.

Comment on lines 213 to 214
fdi.m_name = ipv4tuple_to_string(&fdi.m_sockinfo.m_ipv4info,
m_hostname_and_port_resolution_enabled);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_hostname_and_port_resolution_enabled looks like a global thing (at least a per-thread-manager thing), so maybe we can pass it as a parameter from sinsp_thread_manager::fix_sockets_coming_from_proc

m_inspector->is_hostname_and_port_resolution_enabled());
m_network_interfaces.update_fd(*newfdi);
newfdi->m_name = ipv4tuple_to_string(&newfdi->m_sockinfo.m_ipv4info,
m_hostname_and_port_resolution_enabled);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this only gets called from sinsp::on_new_entry_from_proc AFAICT, so we can pass m_hostname_and_port_resolution_enabled from there as an argument

@@ -356,7 +360,7 @@ void sinsp_threadinfo::add_fd_from_scap(scap_fdinfo* fdi) {
}

auto addedfdi = m_fdtable.add(fdi->fd, std::move(newfdi));
if(m_inspector->m_filter != nullptr && m_inspector->is_capture()) {
if(m_inspector->m_filter != nullptr && m_sinsp_mode.is_capture()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole if can live in the caller, just return addedfdi rather than void

@@ -540,7 +544,7 @@ void sinsp_threadinfo::set_user(uint32_t uid) {
m_uid = uid;
if(const scap_userinfo* user = m_inspector->m_usergroup_manager->get_user(container_id, uid);
!user) {
const auto notify = m_inspector->is_live() || m_inspector->is_syscall_plugin();
const auto notify = m_sinsp_mode.is_live() || is_syscall_plugin_enabled();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (and set_group) could get a bool notify passed in; the ultimate callers of this are:

  • sinsp::on_new_entry_from_proc
  • sinsp_thread_manager::get_thread_ref
  • sinsp_parser::parse_*_exit

The latter two (still) have a sinsp* m_sinsp, so could call a method on it to figure out whether we need to notify.

Same for the usergroup_manager, it could get passed in.

(the usergroup_updater could take the same two parameters in its constructor)

@@ -630,7 +634,7 @@ void sinsp_threadinfo::set_args(const std::vector<std::string>& args) {
}

void sinsp_threadinfo::set_env(const char* env, size_t len) {
if(len == SCAP_MAX_ENV_SIZE && m_inspector->large_envs_enabled()) {
if(len == SCAP_MAX_ENV_SIZE && is_large_envs_enabled()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can pass this flag from the caller (same story as for set_user, they all have a sinsp* available, though sinsp_threadinfo::init might become a bit cluttered)

Comment on lines 204 to 205
if(m_bound_server_ports.find(fdi.m_sockinfo.m_ipv4info.m_fields.m_sport) !=
m_bound_server_ports.end()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bound_server_ports could be a parameter too

@@ -360,7 +363,7 @@ void sinsp_threadinfo::add_fd_from_scap(scap_fdinfo* fdi) {
}

auto addedfdi = m_fdtable.add(fdi->fd, std::move(newfdi));
if(m_inspector->m_filter != nullptr && m_sinsp_mode.is_capture()) {
if(m_filter != nullptr && m_sinsp_mode.is_capture()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned in the previous commit's comments, this could all live in the caller

Comment on lines 501 to 502
const auto accessor =
m_thread_manager->get_field_accessor(sinsp_thread_manager::s_container_id_field_name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouch. All the dynamic table stuff should be cached somewhere. I don't have a checkout of libs fresh enough to see how get_container_id is used, but maybe we can pass some sort of proxy to the method that would have all this cached?

@@ -510,8 +511,7 @@ std::string sinsp_threadinfo::get_container_user() {

const auto container_id = get_container_id();
if(!container_id.empty()) {
auto table = m_inspector->m_thread_manager->get_table(
sinsp_thread_manager::s_containers_table_name);
auto table = m_thread_manager->get_table(sinsp_thread_manager::s_containers_table_name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Umm a thread manager is a table, not sure its responsibility is to provide info about other tables... (not your code, I know)

@ekoops
Copy link
Contributor Author
ekoops commented Apr 14, 2025

As the number of requested changes is high, I decided to split this work in multiple PRs. I'm gonna keep track of all these related works in #2343.

@ekoops ekoops force-pushed the ekoops/isolate-threadinfo branch from b3f5a39 to 4cba8fb Compare April 16, 2025 10:09
@poiana poiana removed the size/XL label Apr 16, 2025
@poiana poiana added the size/L label Apr 16, 2025
@ekoops ekoops force-pushed the ekoops/isolate-threadinfo branch from 4cba8fb to 382547d Compare April 16, 2025 10:13
@ekoops
Copy link
Contributor Author
ekoops commented Apr 16, 2025

As the other related works have been merged (refer to #2343), I rebased this one to align it with those changes.

ekoops added 4 commits April 16, 2025 12:26
Remove `sinsp_threadinfo` dependency on `sinsp` fields that are
immutable from the `sinsp_threadinfo` perspective by selectively
providing each single dependency the component needs. In order to
avoid code duplication in the event processor, add
`sinsp_threadinfo_factory`'s `create_unique_attorney` inner class
following the attorney-client idiom to limit access to
`sinsp_threadinfo_factory::create_unique` private method.

BREAKING CHANGE: update `sinsp_threadinfo` constructor

Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
Remove `sinsp_threadinfo` dependency on `sinsp` fields that are
mutable from the `sinsp_threadinfo` perspective by selectively
providing each single dependency the component needs. In order to
solve a cyclic dependency problem with the thread manager and the
thread info factory, add `sinsp_threadinfo_factory`'s
`set_thread_manager_attorney` inner class following the
attorney-client idiom to limit access to
`sinsp_threadinfo_factory::set_thread_manager` private method.

BREAKING CHANGE: update `sinsp_threadinfo` constructor

Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
Remove unused `sinsp::get_fdinfo_factory()` and
`sinsp::get_fdtable_factory()` from `sinsp` public API.

BREAKING CHANGE: remove `sinsp::get_fdinfo_factory()` and
`sinsp::get_fdtable_factory()`

Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
Reduce threadinfo's params resources waste by moving them into a
separate struct provided at construction phase and shared among all
threadinfo instances.

BREAKING CHANGE: update `sinsp_threadinfo` constructor

Signed-off-by: Leonardo Di Giovanna <leonardodigiovanna1@gmail.com>
@ekoops ekoops force-pushed the ekoops/isolate-threadinfo branch from 382547d to 138dc83 Compare April 16, 2025 10:28
Copy link
Contributor
@FedeDP FedeDP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/approve

@poiana
Copy link
Contributor
poiana commented Apr 16, 2025

LGTM label has been added.

Git tree hash: 83d0704f37b253247c11c6b4a87dcf28004d63b6

@FedeDP
Copy link
Contributor
FedeDP commented Apr 16, 2025

cc @mstemm PTAL 🙏

@poiana
Copy link
Contributor
poiana commented Apr 16, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: ekoops, FedeDP

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@ekoops ekoops requested review from mstemm and gnosek April 16, 2025 10:34
@poiana poiana merged commit 7ceeac9 into falcosecurity:master Apr 17, 2025
46 of 47 checks passed
@github-project-automation github-project-automation bot moved this from In progress to Done in Falco Roadmap Apr 17, 2025
@ekoops ekoops deleted the ekoops/isolate-threadinfo branch April 18, 2025 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

6 participants
0