oeAware-manager/0006-add-one-time-command-collection.patch
fly_1997 f807f0f894 fix header, spe memory free, cycles sample bugs
(cherry picked from commit f990ed00c3b7ec2393dff9d2eb60da1939e1ff4a)
2024-12-11 19:12:08 +08:00

511 lines
17 KiB
Diff

From 55a03b46318e4c977b7e84508c998775e9db34ba Mon Sep 17 00:00:00 2001
From: fly_1997 <flylove7@outlook.com>
Date: Tue, 3 Dec 2024 09:13:09 +0800
Subject: [PATCH 1/4] add one-time command collection
---
src/common/utils.cpp | 29 +++
src/common/utils.h | 3 +
src/plugin/collect/system/CMakeLists.txt | 2 +
.../collect/system/command/command_base.h | 2 +-
.../system/command/command_collector.cpp | 5 +-
src/plugin/collect/system/kernel_config.cpp | 223 ++++++++++--------
src/plugin/collect/system/kernel_config.h | 25 +-
tests/CMakeLists.txt | 2 +-
8 files changed, 175 insertions(+), 116 deletions(-)
diff --git a/src/common/utils.cpp b/src/common/utils.cpp
index a300a6a..ddd5235 100644
--- a/src/common/utils.cpp
+++ b/src/common/utils.cpp
@@ -13,6 +13,7 @@
#include <algorithm>
#include <fstream>
#include <regex>
+#include <securec.h>
#include <curl/curl.h>
#include <sys/stat.h>
#include <grp.h>
@@ -172,4 +173,32 @@ bool CreateDir(const std::string &path)
} while (pos != std::string::npos);
return true;
}
+
+bool SetDataListTopic(DataList *dataList, const std::string &instanceName, const std::string &topicName,
+ const std::string &params)
+{
+ dataList->topic.instanceName = new char[instanceName.size() + 1];
+ if (dataList->topic.instanceName == nullptr) {
+ return false;
+ }
+ strcpy_s(dataList->topic.instanceName, instanceName.size() + 1, instanceName.data());
+ dataList->topic.topicName = new char[topicName.size() + 1];
+ if (dataList->topic.topicName == nullptr) {
+ delete[] dataList->topic.instanceName;
+ dataList->topic.instanceName = nullptr;
+ return false;
+ }
+ strcpy_s(dataList->topic.topicName, topicName.size() + 1, topicName.data());
+ dataList->topic.params = new char[params.size() + 1];
+ if (dataList->topic.params == nullptr) {
+ delete[] dataList->topic.instanceName;
+ delete[] dataList->topic.topicName;
+ dataList->topic.instanceName = nullptr;
+ dataList->topic.topicName = nullptr;
+ return false;
+ }
+ strcpy_s(dataList->topic.params, params.size() + 1, params.data());
+ return true;
+}
+
}
diff --git a/src/common/utils.h b/src/common/utils.h
index 48b72bd..ceadf36 100644
--- a/src/common/utils.h
+++ b/src/common/utils.h
@@ -13,6 +13,7 @@
#define COMMON_UTILS_H
#include <string>
#include <vector>
+#include "data_list.h"
namespace oeaware {
bool Download(const std::string &url, const std::string &path);
@@ -29,6 +30,8 @@ std::string Concat(const std::vector<std::string>& strings, const std::string &s
// Separate "str" with the separator "split"
std::vector<std::string> SplitString(const std::string &str, const std::string &split);
bool CreateDir(const std::string &path);
+bool SetDataListTopic(DataList *dataList, const std::string &instanceName, const std::string &topicName,
+ const std::string &params);
}
#endif // !COMMON_UTILS_H
\ No newline at end of file
diff --git a/src/plugin/collect/system/CMakeLists.txt b/src/plugin/collect/system/CMakeLists.txt
index af4a239..b7d2666 100644
--- a/src/plugin/collect/system/CMakeLists.txt
+++ b/src/plugin/collect/system/CMakeLists.txt
@@ -10,5 +10,7 @@ add_library(system_collector SHARED
./command/command_collector.cpp
./command/command_base.cpp
)
+target_include_directories(system_collector PRIVATE src/common)
+target_link_libraries(system_collector common)
set_target_properties(system_collector PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${PLUGIN_OUTPUT_LIBRARY_DIRECTORY})
\ No newline at end of file
diff --git a/src/plugin/collect/system/command/command_base.h b/src/plugin/collect/system/command/command_base.h
index ef9bd7c..8653a60 100644
--- a/src/plugin/collect/system/command/command_base.h
+++ b/src/plugin/collect/system/command/command_base.h
@@ -34,7 +34,7 @@ public:
std::string nowType;
oeaware::Topic topic;
std::unordered_map<std::string, std::vector<std::string>> attrsFirst;
- std::vector<std::string> skipLine{"---swap--"};
+ std::vector<std::string> skipLine{"---swap--", "Average:"};
static std::vector<std::string> command;
static std::vector<std::string> illegal;
CommandBase();
diff --git a/src/plugin/collect/system/command/command_collector.cpp b/src/plugin/collect/system/command/command_collector.cpp
index 640a406..1f6ac1e 100644
--- a/src/plugin/collect/system/command/command_collector.cpp
+++ b/src/plugin/collect/system/command/command_collector.cpp
@@ -9,8 +9,8 @@
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
******************************************************************************/
-
#include "command_collector.h"
+#include <unistd.h>
CommandCollector::CommandCollector(): oeaware::Interface()
{
@@ -41,8 +41,9 @@ void CommandCollector::CollectThread(const oeaware::Topic &topic, CommandBase* c
while (collector->isRunning && fgets(buffer, sizeof(buffer), p.stream) != nullptr) {
collector->ParseLine(std::string(buffer));
}
+ int waitTime = 10 * 1000;
+ usleep(waitTime);
p.Pclose();
-
collector->Close();
}
diff --git a/src/plugin/collect/system/kernel_config.cpp b/src/plugin/collect/system/kernel_config.cpp
index 3d25251..145251c 100644
--- a/src/plugin/collect/system/kernel_config.cpp
+++ b/src/plugin/collect/system/kernel_config.cpp
@@ -17,7 +17,9 @@
#include <securec.h>
#include <dirent.h>
#include <sys/stat.h>
+#include "utils.h"
#include "command_base.h"
+#include "data_register.h"
KernelConfig::KernelConfig(): oeaware::Interface()
{
@@ -35,6 +37,31 @@ KernelConfig::KernelConfig(): oeaware::Interface()
}
}
+bool KernelConfig::InitCmd(std::stringstream &ss, const std::string &topicType)
+{
+ std::string cmd;
+ std::string word;
+ while (ss >> word) {
+ if (word == cmdSeparator) {
+ if (!CommandBase::ValidateCmd(cmd)) {
+ return false;
+ }
+ getCmds[topicType].emplace_back(cmd);
+ cmd = "";
+ continue;
+ }
+ if (!cmd.empty()) {
+ cmd += " ";
+ }
+ cmd += word;
+ }
+ if (!CommandBase::ValidateCmd(cmd)) {
+ return false;
+ }
+ getCmds[topicType].emplace_back(cmd);
+ return true;
+}
+
oeaware::Result KernelConfig::OpenTopic(const oeaware::Topic &topic)
{
if (find(topicStr.begin(), topicStr.end(), topic.topicName) == topicStr.end()) {
@@ -42,9 +69,12 @@ oeaware::Result KernelConfig::OpenTopic(const oeaware::Topic &topic)
}
std::stringstream ss(topic.params);
std::string word;
- while (ss >> word) {
- if (topic.topicName == "get_kernel_config") {
- getTopics[topic.GetType()].insert(word);
+ std::string topicType = topic.GetType();
+ if (topic.topicName == "get_cmd" && !InitCmd(ss, topicType)) {
+ return oeaware::Result(FAILED, "params invalid.");
+ } else if (topic.topicName == "get_kernel_config") {
+ while (ss >> word) {
+ getTopics[topicType].insert(word);
}
}
return oeaware::Result(OK);
@@ -53,87 +83,11 @@ oeaware::Result KernelConfig::OpenTopic(const oeaware::Topic &topic)
void KernelConfig::CloseTopic(const oeaware::Topic &topic)
{
getTopics.erase(topic.GetType());
+ getCmds.erase(topic.GetType());
setSystemParams.clear();
cmdRun.clear();
}
-void KernelConfig::InitFileParam()
-{
- for (auto &v : kernelParamPath) {
- std::string path = v[1];
- std::ifstream file(path);
- if (!file.is_open()) {
- continue;
- }
- std::string key = v[0];
- std::string line;
- std::string value = "";
- while (std::getline(file, line)) {
- if (line.empty()) {
- continue;
- }
- value += line;
- value += '\n';
- }
- kernelParams[key] = value;
- file.close();
- }
-}
-
-void KernelConfig::AddCommandParam(const std::string &cmd)
-{
- FILE *pipe = popen(cmd.data(), "r");
- if (!pipe) {
- return;
- }
- char buffer[1024];
- std::string value;
- while (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
- value += buffer;
- }
- pclose(pipe);
- auto v = oeaware::SplitString(cmd, " ");
- std::vector<std::string> skipSpace;
- for (auto &word : v) {
- if (word.empty()) continue;
- skipSpace.emplace_back(word);
- }
- if (skipSpace.size() > 1 && v[0] == "ethtool") {
- kernelParams[v[0] + "@" + v[1]] = value;
- return;
- }
- kernelParams[cmd] = value;
-}
-
-static bool IsSymlink(const std::string &path)
-{
- struct stat st;
- if (lstat(path.c_str(), &st) != 0) {
- perror("lstat failed");
- return false;
- }
- return S_ISLNK(st.st_mode);
-}
-
-void KernelConfig::GetAllEth()
-{
- const std::string path = "/sys/class/net";
- std::vector<std::string> interfaces;
- DIR* dir = opendir(path.c_str());
- if (dir == nullptr) {
- WARN(logger, "failed to open directory: " << path << ".");
- return;
- }
- struct dirent* entry;
- while ((entry = readdir(dir)) != nullptr) {
- std::string name(entry->d_name);
- if (name != "." && name != ".." && IsSymlink(path + "/" + name)) {
- allEths.push_back(name);
- }
- }
- closedir(dir);
-}
-
oeaware::Result KernelConfig::Enable(const std::string &param)
{
(void)param;
@@ -156,21 +110,12 @@ oeaware::Result KernelConfig::Enable(const std::string &param)
sysctlParams[values[0]] = values[1];
}
pclose(pipe);
- InitFileParam();
- GetAllEth();
- AddCommandParam("lscpu");
- AddCommandParam("ifconfig");
- for (auto &eth : allEths) {
- AddCommandParam("ethtool " + eth);
- }
-
return oeaware::Result(OK);
}
void KernelConfig::Disable()
{
sysctlParams.clear();
- kernelParams.clear();
setSystemParams.clear();
getTopics.clear();
cmdRun.clear();
@@ -196,32 +141,103 @@ void KernelConfig::UpdateData(const DataList &dataList)
return;
}
-void KernelConfig::PublishKernelConfig()
+std::vector<std::string> KernelConfig::getCmdGroup{"cat", "grep", "awk", "pgrep", "ls", "ethtool"};
+
+static void SetKernelData(KernelData *data, const std::string &ret)
{
- if (getTopics.empty()) {
+ data->kernelData = new KernelDataNode();
+ if (data->kernelData == nullptr) {
+ return;
+ }
+ data->len = 1;
+ data->kernelData->key = new char[1];
+ if (data->kernelData->key == nullptr) {
+ delete data->kernelData;
+ data->kernelData = nullptr;
+ return;
+ }
+ data->kernelData->key[0] = 0;
+ data->kernelData->value = new char[ret.size() + 1];
+ if (data->kernelData->value == nullptr) {
+ delete data->kernelData;
+ delete[] data->kernelData->key;
+ data->kernelData->key = nullptr;
+ data->kernelData = nullptr;
return;
}
+ strcpy_s(data->kernelData->value, ret.size() + 1, ret.data());
+ data->kernelData->next = nullptr;
+}
+
+void KernelConfig::PublishCmd()
+{
+ for (auto &p : getCmds) {
+ oeaware::Topic topic = oeaware::Topic::GetTopicFromType(p.first);
+ DataList dataList;
+ if (!oeaware::SetDataListTopic(&dataList, topic.instanceName, topic.topicName, topic.params)) {
+ continue;
+ }
+ KernelData *data = new KernelData();
+ if (data == nullptr) {
+ WARN(logger, "KernelData failed to allocate memory.");
+ continue;
+ }
+ std::string cmd = "";
+ for (auto &cmdPart : p.second) {
+ if (!cmd.empty()) {
+ cmd += " | ";
+ }
+ cmd += cmdPart;
+ }
+ PopenProcess pipe;
+ pipe.Popen(cmd);
+ char buffer[1024];
+ std::string ret = "";
+ while (fgets(buffer, sizeof(buffer), pipe.stream) != nullptr) {
+ ret += buffer;
+ }
+ if (pipe.Pclose() < 0) {
+ WARN(logger, "pipe close error.");
+ }
+ SetKernelData(data, ret);
+ dataList.len = 1;
+ dataList.data = new void* [1];
+ if (dataList.data == nullptr) {
+ oeaware::Register::GetInstance().GetDataFreeFunc("kernel_config")(data);
+ continue;
+ }
+ dataList.data[0] = data;
+ Publish(dataList);
+ }
+}
+
+void KernelConfig::PublishKernelParams()
+{
for (auto &p : getTopics) {
oeaware::Topic topic = oeaware::Topic::GetTopicFromType(p.first);
DataList dataList;
- dataList.topic.instanceName = new char[topic.instanceName.size() + 1];
- strcpy_s(dataList.topic.instanceName, topic.instanceName.size() + 1, topic.instanceName.data());
- dataList.topic.topicName = new char[topic.topicName.size() + 1];
- strcpy_s(dataList.topic.topicName, topic.topicName.size() + 1, topic.topicName.data());
- dataList.topic.params = new char[topic.params.size() + 1];
- strcpy_s(dataList.topic.params, topic.params.size() + 1, topic.params.data());
+ if (!oeaware::SetDataListTopic(&dataList, topic.instanceName, topic.topicName, topic.params)) {
+ continue;
+ }
KernelData *data = new KernelData();
+ if (data == nullptr) {
+ WARN(logger, "KernelData failed to allocate memory.");
+ continue;
+ }
KernelDataNode *tmp = nullptr;
for (auto &name : p.second) {
std::string value = "";
if (sysctlParams.count(name)) {
value = sysctlParams[name];
- } else if (kernelParams.count(name)) {
- value = kernelParams[name];
} else {
+ WARN(logger, "invalid params: " << name << ".");
continue;
}
KernelDataNode *newNode = createNode(name.data(), value.data());
+ if (newNode == nullptr) {
+ WARN(logger, "KernelDataNode failed to allocate memory.");
+ continue;
+ }
if (data->kernelData == NULL) {
data->kernelData = newNode;
tmp = newNode;
@@ -239,6 +255,15 @@ void KernelConfig::PublishKernelConfig()
}
}
+void KernelConfig::PublishKernelConfig()
+{
+ if (getTopics.empty() && getCmds.empty()) {
+ return;
+ }
+ PublishCmd();
+ PublishKernelParams();
+}
+
void KernelConfig::WriteSysParam(const std::string &path, const std::string &value)
{
std::ofstream sysFile(path);
diff --git a/src/plugin/collect/system/kernel_config.h b/src/plugin/collect/system/kernel_config.h
index 32049d4..4c6eb99 100644
--- a/src/plugin/collect/system/kernel_config.h
+++ b/src/plugin/collect/system/kernel_config.h
@@ -20,10 +20,11 @@
/*
* topic: get_kernel_config, obtain the kernel parameter information.
* params: kernel params name, including
- * 1. sysctl -a -N
- * 2. kernel_version, os_release, meminfo, zone_reclaim_mode
- * 3. lscpu, ifconfig, ethtool@{name}.
- * params :
+ * 1. sysctl -a -N
+ *
+ * topic: get_cmd, the trustlist command is supported.
+ * params: each command is seqarated by "@@", include "cat", "grep", "awk", "pgrep", "ls", "ethtool".
+ *
* topic: set_kernel_config, modify kernel parameters.
* DataList:
* data: KernelData, [key, value]:
@@ -41,29 +42,27 @@ public:
void Disable() override;
void Run() override;
private:
+ void PublishCmd();
+ void PublishKernelParams();
void PublishKernelConfig();
void SetKernelConfig();
+ bool InitCmd(std::stringstream &ss, const std::string &topicType);
void InitFileParam();
void AddCommandParam(const std::string &cmd);
void WriteSysParam(const std::string &path, const std::string &value);
void GetAllEth();
- std::vector<std::string> topicStr = {"get_kernel_config", "set_kernel_config"};
-
- const std::vector<std::vector<std::string>> kernelParamPath{{"kernel_version", "/proc/version"},
- {"os_release", "/etc/os-release"}, {"meminfo", "/proc/meminfo"},
- {"zone_reclaim_mode", "/proc/sys/vm/zone_reclaim_mode"}};
+ std::vector<std::string> topicStr = {"get_kernel_config", "get_cmd", "set_kernel_config"};
// key: topic type, value: parameters to be queried.
std::unordered_map<std::string, std::unordered_set<std::string>> getTopics;
+ std::unordered_map<std::string, std::vector<std::string>> getCmds;
std::vector<std::pair<std::string, std::string>> setSystemParams;
std::unordered_map<std::string, std::string> sysctlParams;
- // Stores system parameters, include lscpu, ifconfig, file path.
- std::unordered_map<std::string, std::string> kernelParams;
-
std::vector<std::string> cmdRun;
+ static std::vector<std::string> getCmdGroup;
static std::vector<std::string> cmdGroup;
- std::vector<std::string> allEths;
+ const std::string cmdSeparator = "@@";
};
#endif
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index dec13ac..11079f2 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -25,7 +25,7 @@ add_executable(pmu_count_test
pmu_count_test.cpp
)
-target_link_libraries(serialize_test PRIVATE curl GTest::gtest_main)
+target_link_libraries(serialize_test PRIVATE common GTest::gtest_main)
target_link_libraries(logger_test PRIVATE GTest::gtest_main log4cplus)
target_link_libraries(safe_queue_test PRIVATE GTest::gtest_main)
target_link_libraries(pmu_count_test PRIVATE GTest::gtest_main)
--
2.33.0