413 lines
12 KiB
Diff
413 lines
12 KiB
Diff
From 51355e66be3eeec6ebe79faa88324c788e5a3829 Mon Sep 17 00:00:00 2001
|
|
From: fly_1997 <flylove7@outlook.com>
|
|
Date: Wed, 27 Nov 2024 05:13:26 +0800
|
|
Subject: [PATCH 3/5] fix failed to connect to the sdk and command execution is
|
|
stuck
|
|
|
|
---
|
|
src/common/utils.cpp | 16 ++++
|
|
src/common/utils.h | 1 +
|
|
.../collect/system/command/command_base.cpp | 48 +++++++++++-
|
|
.../collect/system/command/command_base.h | 9 +++
|
|
.../system/command/command_collector.cpp | 9 ++-
|
|
src/plugin/collect/system/kernel_config.cpp | 1 +
|
|
src/plugin_mgr/config.cpp | 17 -----
|
|
src/plugin_mgr/config.h | 1 -
|
|
src/plugin_mgr/message_manager.cpp | 76 +++++++++++++++++--
|
|
src/plugin_mgr/message_manager.h | 3 +-
|
|
src/sdk/oe_client.cpp | 12 ++-
|
|
11 files changed, 160 insertions(+), 33 deletions(-)
|
|
|
|
diff --git a/src/common/utils.cpp b/src/common/utils.cpp
|
|
index 4e12a57..a300a6a 100644
|
|
--- a/src/common/utils.cpp
|
|
+++ b/src/common/utils.cpp
|
|
@@ -156,4 +156,20 @@ std::vector<std::string> SplitString(const std::string &str, const std::string &
|
|
}
|
|
return tokens;
|
|
}
|
|
+bool CreateDir(const std::string &path)
|
|
+{
|
|
+ size_t pos = 0;
|
|
+ do {
|
|
+ pos = path.find_first_of("/", pos + 1);
|
|
+ std::string subPath = path.substr(0, pos);
|
|
+ struct stat buffer;
|
|
+ if (stat(subPath.c_str(), &buffer) == 0) {
|
|
+ continue;
|
|
+ }
|
|
+ if (mkdir(subPath.c_str(), S_IRWXU | S_IRWXG) != 0) {
|
|
+ return false;
|
|
+ }
|
|
+ } while (pos != std::string::npos);
|
|
+ return true;
|
|
+}
|
|
}
|
|
diff --git a/src/common/utils.h b/src/common/utils.h
|
|
index ba787fe..48b72bd 100644
|
|
--- a/src/common/utils.h
|
|
+++ b/src/common/utils.h
|
|
@@ -28,6 +28,7 @@ bool EndWith(const std::string &s, const std::string &ending);
|
|
std::string Concat(const std::vector<std::string>& strings, const std::string &split);
|
|
// 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);
|
|
}
|
|
|
|
#endif // !COMMON_UTILS_H
|
|
\ No newline at end of file
|
|
diff --git a/src/plugin/collect/system/command/command_base.cpp b/src/plugin/collect/system/command/command_base.cpp
|
|
index d5a30dd..bf658b8 100644
|
|
--- a/src/plugin/collect/system/command/command_base.cpp
|
|
+++ b/src/plugin/collect/system/command/command_base.cpp
|
|
@@ -10,6 +10,45 @@
|
|
* See the Mulan PSL v2 for more details.
|
|
******************************************************************************/
|
|
#include "command_base.h"
|
|
+#include <unistd.h>
|
|
+#include <sys/wait.h>
|
|
+
|
|
+int PopenProcess::Pclose()
|
|
+{
|
|
+ if (fclose(stream) == EOF) {
|
|
+ return -1;
|
|
+ }
|
|
+ stream = nullptr;
|
|
+ if (kill(pid, SIGTERM) == -1) {
|
|
+ return -1;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void PopenProcess::Popen(const std::string &cmd)
|
|
+{
|
|
+ int pipeFd[2];
|
|
+ if (pipe(pipeFd) == -1) {
|
|
+ return;
|
|
+ }
|
|
+ pid = fork();
|
|
+ if (pid == -1) {
|
|
+ close(pipeFd[0]);
|
|
+ close(pipeFd[1]);
|
|
+ } else if (pid == 0) {
|
|
+ close(pipeFd[0]);
|
|
+ dup2(pipeFd[1], STDOUT_FILENO);
|
|
+ close(pipeFd[1]);
|
|
+ execl("/bin/bash", "bash", "-c", cmd.data(), nullptr);
|
|
+ _exit(1);
|
|
+ }
|
|
+ close(pipeFd[1]);
|
|
+ stream = fdopen(pipeFd[0], "r");
|
|
+ if (!stream) {
|
|
+ close(pipeFd[0]);
|
|
+ return;
|
|
+ }
|
|
+}
|
|
|
|
CommandBase::CommandBase()
|
|
{
|
|
@@ -23,18 +62,19 @@ CommandBase::CommandBase()
|
|
bool CommandBase::ValidateArgs(const oeaware::Topic& topic)
|
|
{
|
|
auto cmd = GetCommand(topic);
|
|
- FILE *pipe = popen(cmd.c_str(), "r");
|
|
- if (!pipe) {
|
|
+ PopenProcess p;
|
|
+ p.Popen(cmd);
|
|
+ if (!p.stream) {
|
|
return false;
|
|
}
|
|
char buffer[128];
|
|
bool isValid = false;
|
|
- if (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
|
|
+ if (fgets(buffer, sizeof(buffer), p.stream) != nullptr) {
|
|
if (strstr(buffer, "Linux") != nullptr || strstr(buffer, "procs") != nullptr) {
|
|
isValid = true;
|
|
}
|
|
}
|
|
- pclose(pipe);
|
|
+ p.Pclose();
|
|
return isValid;
|
|
}
|
|
|
|
diff --git a/src/plugin/collect/system/command/command_base.h b/src/plugin/collect/system/command/command_base.h
|
|
index eb75c49..a6d7627 100644
|
|
--- a/src/plugin/collect/system/command/command_base.h
|
|
+++ b/src/plugin/collect/system/command/command_base.h
|
|
@@ -44,4 +44,13 @@ public:
|
|
void Close();
|
|
};
|
|
|
|
+class PopenProcess {
|
|
+public:
|
|
+ int Pclose();
|
|
+ void Popen(const std::string &cmd);
|
|
+
|
|
+ FILE *stream;
|
|
+ pid_t pid;
|
|
+};
|
|
+
|
|
#endif
|
|
diff --git a/src/plugin/collect/system/command/command_collector.cpp b/src/plugin/collect/system/command/command_collector.cpp
|
|
index 6c54555..640a406 100644
|
|
--- a/src/plugin/collect/system/command/command_collector.cpp
|
|
+++ b/src/plugin/collect/system/command/command_collector.cpp
|
|
@@ -32,15 +32,16 @@ CommandCollector::CommandCollector(): oeaware::Interface()
|
|
void CommandCollector::CollectThread(const oeaware::Topic &topic, CommandBase* collector)
|
|
{
|
|
std::string cmd = collector->GetCommand(topic);
|
|
- FILE* pipe = popen(cmd.c_str(), "r");
|
|
- if (!pipe) {
|
|
+ PopenProcess p;
|
|
+ p.Popen(cmd);
|
|
+ if (!p.stream) {
|
|
return;
|
|
}
|
|
char buffer[256];
|
|
- while (collector->isRunning && fgets(buffer, sizeof(buffer), pipe) != nullptr) {
|
|
+ while (collector->isRunning && fgets(buffer, sizeof(buffer), p.stream) != nullptr) {
|
|
collector->ParseLine(std::string(buffer));
|
|
}
|
|
- pclose(pipe);
|
|
+ p.Pclose();
|
|
|
|
collector->Close();
|
|
}
|
|
diff --git a/src/plugin/collect/system/kernel_config.cpp b/src/plugin/collect/system/kernel_config.cpp
|
|
index 63aafea..6bdfc8a 100644
|
|
--- a/src/plugin/collect/system/kernel_config.cpp
|
|
+++ b/src/plugin/collect/system/kernel_config.cpp
|
|
@@ -113,6 +113,7 @@ static bool IsSymlink(const std::string &path)
|
|
}
|
|
return S_ISLNK(st.st_mode);
|
|
}
|
|
+
|
|
void KernelConfig::GetAllEth()
|
|
{
|
|
const std::string path = "/sys/class/net";
|
|
diff --git a/src/plugin_mgr/config.cpp b/src/plugin_mgr/config.cpp
|
|
index 341880b..8cd1432 100644
|
|
--- a/src/plugin_mgr/config.cpp
|
|
+++ b/src/plugin_mgr/config.cpp
|
|
@@ -15,23 +15,6 @@
|
|
#include "default_path.h"
|
|
|
|
namespace oeaware {
|
|
-bool CreateDir(const std::string &path)
|
|
-{
|
|
- size_t pos = 0;
|
|
- do {
|
|
- pos = path.find_first_of("/", pos + 1);
|
|
- std::string subPath = path.substr(0, pos);
|
|
- struct stat buffer;
|
|
- if (stat(subPath.c_str(), &buffer) == 0) {
|
|
- continue;
|
|
- }
|
|
- if (mkdir(subPath.c_str(), S_IRWXU | S_IRWXG) != 0) {
|
|
- return false;
|
|
- }
|
|
- } while (pos != std::string::npos);
|
|
- return true;
|
|
-}
|
|
-
|
|
bool CheckPluginList(YAML::Node pluginListItem)
|
|
{
|
|
if (pluginListItem["name"].IsNull()) {
|
|
diff --git a/src/plugin_mgr/config.h b/src/plugin_mgr/config.h
|
|
index 640ab00..19e6d33 100644
|
|
--- a/src/plugin_mgr/config.h
|
|
+++ b/src/plugin_mgr/config.h
|
|
@@ -130,7 +130,6 @@ private:
|
|
};
|
|
|
|
std::string GetPath();
|
|
-bool CreateDir(const std::string &path);
|
|
}
|
|
|
|
#endif
|
|
diff --git a/src/plugin_mgr/message_manager.cpp b/src/plugin_mgr/message_manager.cpp
|
|
index 1ffa4cc..bfa5b0c 100644
|
|
--- a/src/plugin_mgr/message_manager.cpp
|
|
+++ b/src/plugin_mgr/message_manager.cpp
|
|
@@ -11,6 +11,7 @@
|
|
******************************************************************************/
|
|
#include "message_manager.h"
|
|
#include <thread>
|
|
+#include <pwd.h>
|
|
#include <securec.h>
|
|
#include "default_path.h"
|
|
#include "utils.h"
|
|
@@ -41,15 +42,56 @@ int Epoll::EventWait(struct epoll_event *events, int maxEvents, int timeout)
|
|
return epoll_wait(epfd, events, maxEvents, timeout);
|
|
}
|
|
|
|
+static std::vector<std::string> GetUserFromGroup(const std::string &groupName)
|
|
+{
|
|
+ std::vector<std::string> users;
|
|
+ std::ifstream file("/etc/group");
|
|
+ if (!file.is_open()) {
|
|
+ return users;
|
|
+ }
|
|
+ std::string line;
|
|
+ size_t userPartIndex = 3;
|
|
+ while (std::getline(file, line)) {
|
|
+ std::vector<std::string> parts = SplitString(line, ":");
|
|
+ if (parts.size() > userPartIndex && parts[0] == groupName) {
|
|
+ std::vector<std::string> userParts = SplitString(parts[userPartIndex], ",");
|
|
+ users.insert(users.end(), userParts.begin(), userParts.end());
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ file.close();
|
|
+ return users;
|
|
+}
|
|
+
|
|
+static int GetUid(const std::string &name)
|
|
+{
|
|
+ struct passwd pwd;
|
|
+ struct passwd *result;
|
|
+ char buf[1024];
|
|
+ int res = getpwnam_r(name.c_str(), &pwd, buf, sizeof(buf), &result);
|
|
+ if (res != 0 || result == nullptr) {
|
|
+ return -1;
|
|
+ }
|
|
+ return pwd.pw_uid;
|
|
+}
|
|
+
|
|
void TcpSocket::InitGroups()
|
|
{
|
|
std::vector<std::string> groupNames{"oeaware", "root"};
|
|
+ groups[0].emplace_back(0);
|
|
for (auto &groupName : groupNames) {
|
|
auto gid = GetGidByGroupName(groupName);
|
|
if (gid < 0) {
|
|
continue;
|
|
}
|
|
- groups.emplace_back(gid);
|
|
+ auto users = GetUserFromGroup(groupName);
|
|
+ for (auto &user : users) {
|
|
+ auto uid = GetUid(user);
|
|
+ if (uid < 0) {
|
|
+ continue;
|
|
+ }
|
|
+ groups[gid].emplace_back(uid);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -68,6 +110,11 @@ bool TcpSocket::StartListen()
|
|
ERROR(logger, path << " chmod error!");
|
|
return false;
|
|
}
|
|
+ std::string cmd = "setfacl -m g:oeaware:rw " + path;
|
|
+ auto ret = system(cmd.c_str());
|
|
+ if (ret) {
|
|
+ WARN(logger, "failed to set the communication permission of the oeaware user group.");
|
|
+ }
|
|
if (domainSocket->Listen() < 0) {
|
|
ERROR(logger, "listen error!");
|
|
return false;
|
|
@@ -136,7 +183,6 @@ static void GetEventResult(Message &msg, EventResultQueue sendMessage)
|
|
}
|
|
|
|
const int DISCONNECTED = -1;
|
|
-const int DISCONNECTED_AND_UNSUBCRIBE = -2;
|
|
|
|
void TcpMessageHandler::Init(EventQueue newRecvMessage, EventResultQueue newSendMessage, EventQueue newRecvData)
|
|
{
|
|
@@ -240,6 +286,23 @@ void TcpMessageHandler::Start()
|
|
}
|
|
}
|
|
|
|
+bool TcpSocket::CheckFileGroups(const std::string &path)
|
|
+{
|
|
+ struct stat st;
|
|
+ if (lstat(path.c_str(), &st) < 0) {
|
|
+ return false;
|
|
+ }
|
|
+ for (auto &p : groups) {
|
|
+ bool ok = std::any_of(p.second.begin(), p.second.end(), [&](uid_t uid) {
|
|
+ return uid == st.st_uid;
|
|
+ });
|
|
+ if (ok) {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
+
|
|
void TcpSocket::SaveConnection()
|
|
{
|
|
struct sockaddr_un un;
|
|
@@ -255,12 +318,12 @@ void TcpSocket::SaveConnection()
|
|
memcpy_s(name, maxNameLength, un.sun_path, len);
|
|
name[len] = 0;
|
|
bool isSdk = false;
|
|
- if (strcmp(name, DEFAULT_SDK_CONN_PATH.c_str()) == 0) {
|
|
+ if (len > 0) {
|
|
isSdk = true;
|
|
}
|
|
// check permission
|
|
- if (isSdk && !CheckFileGroups(DEFAULT_SDK_CONN_PATH, groups)) {
|
|
- WARN(logger, "sdk permission error");
|
|
+ if (isSdk && !CheckFileGroups(name)) {
|
|
+ WARN(logger, "sdk permission error, " << name);
|
|
return;
|
|
}
|
|
if (!epoll->EventCtl(EPOLL_CTL_ADD, conn)) {
|
|
@@ -274,6 +337,9 @@ void TcpSocket::SaveConnection()
|
|
type |= CMD_CONN;
|
|
}
|
|
tcpMessageHandler.AddConn(conn, type);
|
|
+ if (isSdk) {
|
|
+ INFO(logger, "a sdk connection is established, " << name);
|
|
+ }
|
|
DEBUG(logger, "client connected!");
|
|
}
|
|
|
|
diff --git a/src/plugin_mgr/message_manager.h b/src/plugin_mgr/message_manager.h
|
|
index 38f544d..3c67096 100644
|
|
--- a/src/plugin_mgr/message_manager.h
|
|
+++ b/src/plugin_mgr/message_manager.h
|
|
@@ -73,12 +73,13 @@ private:
|
|
bool StartListen();
|
|
void SaveConnection();
|
|
void HandleEvents(struct epoll_event *events, int num);
|
|
+ bool CheckFileGroups(const std::string &path);
|
|
private:
|
|
log4cplus::Logger logger;
|
|
std::unique_ptr<DomainSocket> domainSocket;
|
|
std::unique_ptr<Epoll> epoll;
|
|
TcpMessageHandler tcpMessageHandler;
|
|
- std::vector<gid_t> groups;
|
|
+ std::unordered_map<int, std::vector<uid_t>> groups;
|
|
const int maxRequestNum = 20;
|
|
const int maxNameLength = 108;
|
|
};
|
|
diff --git a/src/sdk/oe_client.cpp b/src/sdk/oe_client.cpp
|
|
index 9452a37..040433a 100644
|
|
--- a/src/sdk/oe_client.cpp
|
|
+++ b/src/sdk/oe_client.cpp
|
|
@@ -80,7 +80,17 @@ void Impl::HandleRecv()
|
|
}
|
|
int Impl::Init()
|
|
{
|
|
- domainSocket = std::make_shared<DomainSocket>(DEFAULT_SDK_CONN_PATH);
|
|
+ auto home = getenv("HOME");
|
|
+ std::string homeDir;
|
|
+ if (home == nullptr) {
|
|
+ homeDir = "/var/run/oeAware";
|
|
+ } else {
|
|
+ homeDir = home;
|
|
+ homeDir += "/.oeaware";
|
|
+ }
|
|
+
|
|
+ CreateDir(homeDir);
|
|
+ domainSocket = std::make_shared<DomainSocket>(homeDir + "/oeaware-sdk.sock");
|
|
domainSocket->SetRemotePath(DEFAULT_SERVER_LISTEN_PATH);
|
|
resultQueue = std::make_shared<SafeQueue<Result>>();
|
|
int sock = domainSocket->Socket();
|
|
--
|
|
2.33.0
|
|
|