diff --git a/userspace/libsinsp/container.cpp b/userspace/libsinsp/container.cpp index fa3d6db9a8..40290c9123 100644 --- a/userspace/libsinsp/container.cpp +++ b/userspace/libsinsp/container.cpp @@ -59,11 +59,11 @@ bool sinsp_container_manager::remove_inactive_containers() if(m_last_flush_time_ns == 0) { - m_last_flush_time_ns = m_inspector->m_lastevent_ts - m_inspector->m_inactive_container_scan_time_ns + 30 * ONE_SECOND_IN_NS; + m_last_flush_time_ns = m_inspector->m_lastevent_ts - m_inspector->m_containers_purging_scan_time_ns + 30 * ONE_SECOND_IN_NS; } if(m_inspector->m_lastevent_ts > - m_last_flush_time_ns + m_inspector->m_inactive_container_scan_time_ns) + m_last_flush_time_ns + m_inspector->m_containers_purging_scan_time_ns) { res = true; diff --git a/userspace/libsinsp/sinsp.cpp b/userspace/libsinsp/sinsp.cpp index be5fba0093..7f7bc97496 100644 --- a/userspace/libsinsp/sinsp.cpp +++ b/userspace/libsinsp/sinsp.cpp @@ -86,8 +86,8 @@ sinsp::sinsp(bool static_container, const std::string &static_id, const std::str m_parser = new sinsp_parser(this); m_thread_manager = new sinsp_thread_manager(this); m_max_fdtable_size = MAX_FD_TABLE_SIZE; - m_inactive_container_scan_time_ns = DEFAULT_INACTIVE_CONTAINER_SCAN_TIME_S * ONE_SECOND_IN_NS; - m_deleted_users_groups_scan_time_ns = DEFAULT_DELETED_USERS_GROUPS_SCAN_TIME_S * ONE_SECOND_IN_NS; + m_containers_purging_scan_time_ns = DEFAULT_INACTIVE_CONTAINER_SCAN_TIME_S * ONE_SECOND_IN_NS; + m_usergroups_purging_scan_time_ns = DEFAULT_DELETED_USERS_GROUPS_SCAN_TIME_S * ONE_SECOND_IN_NS; m_filter = NULL; m_fds_to_remove = new std::vector; m_machine_info = NULL; @@ -1297,7 +1297,7 @@ int32_t sinsp::next(OUT sinsp_evt **puevt) evt->m_evtnum = m_nevts; m_lastevent_ts = ts; - if(m_automatic_threadtable_purging) + if (m_auto_threads_purging) { // // Delayed removal of threads from the thread table, so that @@ -1315,9 +1315,7 @@ int32_t sinsp::next(OUT sinsp_evt **puevt) } } -#ifndef HAS_ANALYZER - - if(is_debug_enabled() && is_live()) + if (m_auto_stats_print && is_debug_enabled() && is_live()) { if(ts > m_next_stats_print_time_ns) { @@ -1330,18 +1328,15 @@ int32_t sinsp::next(OUT sinsp_evt **puevt) } } - // - // Run the periodic connection, thread and users/groups table cleanup - // - if(!is_offline()) + if (m_auto_containers_purging && !is_offline()) { m_container_manager.remove_inactive_containers(); + } -#if !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD) && !defined(__EMSCRIPTEN__) + if (m_auto_usergroups_purging && !is_offline()) + { m_usergroup_manager.clear_host_users_groups(); -#endif // !defined(CYGWING_AGENT) && !defined(MINIMAL_BUILD) } -#endif // HAS_ANALYZER // // Delayed removal of the fd, so that @@ -1662,7 +1657,10 @@ void sinsp::stop_capture() } /* Print scap stats */ - print_capture_stats(sinsp_logger::SEV_DEBUG); + if (m_auto_stats_print) + { + print_capture_stats(sinsp_logger::SEV_DEBUG); + } /* Print the number of threads and fds in our tables */ uint64_t thread_cnt = 0; @@ -2042,16 +2040,6 @@ bool sinsp::remove_inactive_threads() return m_thread_manager->remove_inactive_threads(); } -void sinsp::disable_automatic_threadtable_purging() -{ - m_automatic_threadtable_purging = false; -} - -void sinsp::set_thread_purge_interval_s(uint32_t val) -{ - m_inactive_thread_scan_time_ns = (uint64_t)val * ONE_SECOND_IN_NS; -} - void sinsp::set_thread_timeout_s(uint32_t val) { m_thread_timeout_ns = (uint64_t)val * ONE_SECOND_IN_NS; @@ -2105,20 +2093,20 @@ bool sinsp_thread_manager::remove_inactive_threads() // Set the first table scan for 30 seconds in, so that we can spot bugs in the logic without having // to wait for tens of minutes // - if(m_inspector->m_inactive_thread_scan_time_ns > 30 * ONE_SECOND_IN_NS) + if(m_inspector->m_threads_purging_scan_time_ns > 30 * ONE_SECOND_IN_NS) { m_last_flush_time_ns = - (m_inspector->m_lastevent_ts - m_inspector->m_inactive_thread_scan_time_ns + 30 * ONE_SECOND_IN_NS); + (m_inspector->m_lastevent_ts - m_inspector->m_threads_purging_scan_time_ns + 30 * ONE_SECOND_IN_NS); } else { m_last_flush_time_ns = - (m_inspector->m_lastevent_ts - m_inspector->m_inactive_thread_scan_time_ns); + (m_inspector->m_lastevent_ts - m_inspector->m_threads_purging_scan_time_ns); } } if(m_inspector->m_lastevent_ts > - m_last_flush_time_ns + m_inspector->m_inactive_thread_scan_time_ns) + m_last_flush_time_ns + m_inspector->m_threads_purging_scan_time_ns) { std::unordered_set to_delete; diff --git a/userspace/libsinsp/sinsp.h b/userspace/libsinsp/sinsp.h index c6f0a068d0..61a75e0eb6 100644 --- a/userspace/libsinsp/sinsp.h +++ b/userspace/libsinsp/sinsp.h @@ -383,18 +383,72 @@ class SINSP_PUBLIC sinsp : public capture_stats_source void set_min_log_severity(sinsp_logger::severity sev); /*! - * \brief set whether the library will automatically purge the threadtable - * at specific times. If not, client is responsible for thread lifetime - * management. If invoked, then the purge interval and thread timeout change - * defaults, but have no observable effect. + * \brief Enables or disables an automatic routine that periodically purges + * thread infos from the internal state. If disabled, the client is + * responsible of manually-handling the lifetime of threads. + * When the routine is run, then the purge interval and thread timeout + * change defaults, but with no observable effect. */ - void disable_automatic_threadtable_purging(); + void set_auto_threads_purging(bool enabled) + { + m_auto_threads_purging = enabled; + } + + /*! + * \brief Sets the interval (in seconds) at which the automatic threads + * purging routine runs (if enabled). + */ + inline void set_auto_threads_purging_interval_s(uint32_t val) + { + m_threads_purging_scan_time_ns = (uint64_t)val * ONE_SECOND_IN_NS; + } /*! - * \brief sets the interval at which the thread purge code runs. This does - * not run every event as it's mildly expensive if there are lots of threads + * \brief Enables or disables an automatic routine that periodically purges + * thread infos from the internal state. If disabled, the client is + * responsible of manually-handling the lifetime of containers. */ - void set_thread_purge_interval_s(uint32_t val); + void set_auto_containers_purging(bool enabled) + { + m_auto_containers_purging = enabled; + } + + /*! + * \brief Sets the interval (in seconds) at which the automatic containers + * purging routine runs (if enabled). + */ + inline void set_auto_containers_purging_interval_s(uint32_t val) + { + m_containers_purging_scan_time_ns = (uint64_t)val * ONE_SECOND_IN_NS; + } + + /*! + * \brief Enables or disables an automatic routine that periodically purges + * users and groups infos from the internal state. If disabled, the client + * is responsible of manually-handling the lifetime of users and groups. + */ + void set_auto_usergroups_purging(bool enabled) + { + m_auto_usergroups_purging = enabled; + } + + /*! + * \brief Sets the interval (in seconds) at which the automatic + * users and groups purging routine runs (if enabled). + */ + inline void set_auto_usergroups_purging_interval_s(uint32_t val) + { + m_usergroups_purging_scan_time_ns = (uint64_t)val * ONE_SECOND_IN_NS; + } + + /*! + * \brief Enables or disables an automatic routine that periodically logs + * the current capture stats. + */ + inline void set_auto_stats_print(bool enabled) + { + m_auto_stats_print = enabled; + } /*! * \brief sets the amount of time after which a thread which has seen no events @@ -1081,19 +1135,21 @@ VISIBILITY_PRIVATE // Some thread table limits // uint32_t m_max_fdtable_size; - bool m_automatic_threadtable_purging = true; + bool m_auto_threads_purging = true; uint64_t m_thread_timeout_ns = (uint64_t)1800 * ONE_SECOND_IN_NS; - uint64_t m_inactive_thread_scan_time_ns = (uint64_t)1200 * ONE_SECOND_IN_NS; + uint64_t m_threads_purging_scan_time_ns = (uint64_t)1200 * ONE_SECOND_IN_NS; // // Container limits // - uint64_t m_inactive_container_scan_time_ns; + bool m_auto_containers_purging = true; + uint64_t m_containers_purging_scan_time_ns; // // Users/groups limits // - uint64_t m_deleted_users_groups_scan_time_ns; + bool m_auto_usergroups_purging = true; + uint64_t m_usergroups_purging_scan_time_ns; // // How to render the data buffers @@ -1185,6 +1241,7 @@ VISIBILITY_PRIVATE // // End of second housekeeping // + bool m_auto_stats_print = true; uint64_t m_next_stats_print_time_ns; static unsigned int m_num_possible_cpus; diff --git a/userspace/libsinsp/test/container_engine/container_cache.ut.cpp b/userspace/libsinsp/test/container_engine/container_cache.ut.cpp index 4aab2f89cd..465d30b90e 100644 --- a/userspace/libsinsp/test/container_engine/container_cache.ut.cpp +++ b/userspace/libsinsp/test/container_engine/container_cache.ut.cpp @@ -42,7 +42,7 @@ TEST_F(sinsp_with_test_input, container_manager_cache_threadtable_lifecycle) ASSERT_EQ(test_container_id, container_info_check->m_id); // Arbitrary time travel to invoke removal / flush logic remove_inactive_containers - m_inspector.m_inactive_container_scan_time_ns = 0; + m_inspector.m_containers_purging_scan_time_ns = 0; m_inspector.m_container_manager.m_last_flush_time_ns = 1; m_inspector.m_container_manager.remove_inactive_containers(); const sinsp_container_info::ptr_t container_info_check_not_removed = m_inspector.m_container_manager.get_container(test_container_id); @@ -52,7 +52,7 @@ TEST_F(sinsp_with_test_input, container_manager_cache_threadtable_lifecycle) // Mock remove test_container1 container from threadtable tinfo = m_inspector.get_thread_ref(p4_t1_tid, false, true).get(); tinfo->m_container_id = ""; - m_inspector.m_inactive_container_scan_time_ns = 0; + m_inspector.m_containers_purging_scan_time_ns = 0; m_inspector.m_container_manager.m_last_flush_time_ns = 1; m_inspector.m_container_manager.remove_inactive_containers(); diff --git a/userspace/libsinsp/test/sinsp_with_test_input.h b/userspace/libsinsp/test/sinsp_with_test_input.h index 1b92e7332a..528ba925ca 100644 --- a/userspace/libsinsp/test/sinsp_with_test_input.h +++ b/userspace/libsinsp/test/sinsp_with_test_input.h @@ -322,7 +322,7 @@ class sinsp_with_test_input : public ::testing::Test { { /* We need to set these 2 variables to enable the remove_inactive_logic */ m_inspector.m_thread_manager->m_last_flush_time_ns = 1; - m_inspector.m_inactive_thread_scan_time_ns = 2; + m_inspector.m_threads_purging_scan_time_ns = 2; m_inspector.m_lastevent_ts = m_lastevent_ts; m_inspector.m_thread_timeout_ns = thread_timeout; diff --git a/userspace/libsinsp/user.cpp b/userspace/libsinsp/user.cpp index d856ee396d..532764ac81 100644 --- a/userspace/libsinsp/user.cpp +++ b/userspace/libsinsp/user.cpp @@ -220,11 +220,11 @@ bool sinsp_usergroup_manager::clear_host_users_groups() if(m_last_flush_time_ns == 0) { - m_last_flush_time_ns = m_inspector->m_lastevent_ts - m_inspector->m_deleted_users_groups_scan_time_ns + 60 * ONE_SECOND_IN_NS; + m_last_flush_time_ns = m_inspector->m_lastevent_ts - m_inspector->m_usergroups_purging_scan_time_ns + 60 * ONE_SECOND_IN_NS; } if(m_inspector->m_lastevent_ts > - m_last_flush_time_ns + m_inspector->m_deleted_users_groups_scan_time_ns) + m_last_flush_time_ns + m_inspector->m_usergroups_purging_scan_time_ns) { res = true; diff --git a/userspace/libsinsp/user.h b/userspace/libsinsp/user.h index c414f86680..48b1d7b02c 100644 --- a/userspace/libsinsp/user.h +++ b/userspace/libsinsp/user.h @@ -46,7 +46,7 @@ namespace libsinsp { namespace procfs_utils { class ns_helper; }} * * on PPME_{USER,GROUP}_ADDED, the new user/group is stored in the m_{user,group}_list, if not present. * * * Host users and groups lists are cleared once every DEFAULT_DELETED_USERS_GROUPS_SCAN_TIME_S (1 min by default), - * see sinsp::m_deleted_users_groups_scan_time_ns. + * see sinsp::m_usergroups_purging_scan_time_ns. * Then, the users and groups will be refreshed as explained above, every time a threadinfo is created. * This is needed to fetch deleted users/groups, or overwritten ones. * Note: PPME_USER_DELETED_E is never sent for host users; we miss