From cf949731294dba0a85d3e7ec505fb6742f5bedeb Mon Sep 17 00:00:00 2001 From: Aldo Lacuku Date: Wed, 6 Nov 2024 14:59:40 +0100 Subject: [PATCH] fix(proc/scan): scan all existing threads By scanning only /proc we missed the threads of a given process. It scans all threads under a given process in /proc/pid/task. Signed-off-by: Aldo Lacuku --- plugins/k8smeta/src/plugin.cpp | 75 ++++++++++++++++-------- plugins/k8smeta/test/src/parsing_pod.cpp | 3 +- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/plugins/k8smeta/src/plugin.cpp b/plugins/k8smeta/src/plugin.cpp index eccc6e08..d7349117 100644 --- a/plugins/k8smeta/src/plugin.cpp +++ b/plugins/k8smeta/src/plugin.cpp @@ -302,42 +302,65 @@ void my_plugin::do_initial_proc_scan() continue; } - // Example of the path: `/proc/1/cgroup` - proc_path = std::string(proc_root) - .append("/") - .append(file_name.c_str()) - .append("/cgroup"); + // Now scan /proc/pid/task for threads + std::string task_dir = proc_root + "/" + file_name.c_str() + "/task"; + std::filesystem::directory_iterator task_iter(task_dir); - std::ifstream file(proc_path); - - if(file.is_open()) + for(const auto& task_entry : task_iter) { - // Read the first line from the file - if(std::getline(file, cgroup_line)) + auto task_file_name = task_entry.path().filename(); + tid = strtol(task_file_name.c_str(), NULL, 10); + + if(tid == 0 || !task_entry.is_directory()) { - std::string pod_uid = - get_pod_uid_from_cgroup_string(cgroup_line); - if(!pod_uid.empty()) - { - m_thread_id_pod_uid_map[tid] = pod_uid; - SPDLOG_TRACE("Found thread with tid '{}' and pod uid '{}'", - tid, pod_uid); - } + SPDLOG_WARN("Found task entry `{}` in process `{}` that is not " + "a number", + task_file_name.c_str(), file_name.c_str()); + continue; // skip if not a thread id directory } - else + // Example of the path: `/proc/1/task/200/cgroup` + proc_path = std::string(proc_root) + .append("/") + .append(file_name.c_str()) + .append("/task/") + .append(task_file_name.c_str()) + .append("/cgroup"); + + std::ifstream file(proc_path); + + if(file.is_open()) { - SPDLOG_WARN("cannot retrieve the cgroup first line for '{}'. " + // Read the first line from the file + if(std::getline(file, cgroup_line)) + { + std::string pod_uid = + get_pod_uid_from_cgroup_string(cgroup_line); + if(!pod_uid.empty()) + { + m_thread_id_pod_uid_map[tid] = pod_uid; + SPDLOG_TRACE( + "Found thread with tid '{}' and pod uid '{}'", + tid, pod_uid); + } + } + else + { + SPDLOG_WARN( + "Cannot retrieve the cgroup first line for '{}'. " "Error: {}. Skip it", proc_path, file.eof() ? "Empty file" : strerror(errno)); + } + file.close(); + } + else + { + SPDLOG_WARN("Cannot open '{}'. Error: {}. Skip it.", proc_path, + strerror(errno)); } - file.close(); - } - else - { - SPDLOG_WARN("cannot open '{}'. Error: {}. Skip it.", proc_path, - strerror(errno)); } + SPDLOG_DEBUG("Thread scan correctly completed for process `{}`", + file_name.c_str()); } SPDLOG_INFO( "Process scan correctly completed. Found '{}' threads inside pods.", diff --git a/plugins/k8smeta/test/src/parsing_pod.cpp b/plugins/k8smeta/test/src/parsing_pod.cpp index ae878104..0fdb8b51 100644 --- a/plugins/k8smeta/test/src/parsing_pod.cpp +++ b/plugins/k8smeta/test/src/parsing_pod.cpp @@ -424,7 +424,8 @@ TEST_F(sinsp_with_test_input, plugin_k8s_proc_scan_in_the_plugin) #define PLUGIN_PROC_SCAN_UNDER_TMP_PROC \ int32_t mock_tid = (1 << 16) - 1; \ - std::string mock_proc_dir = "/tmp/proc/" + std::to_string(mock_tid); \ + std::string mock_proc_dir = "/tmp/proc/" + std::to_string(mock_tid) + \ + "/task/" + std::to_string(mock_tid); \ std::string mock_proc_cgroup = mock_proc_dir + "/cgroup"; \ std::string expected_pod_uid = "1d34c7bb-7d94-4f00-bed9-fe4eca61d446"; \ \