From 9b1ab30deb57321fd3aa1c99195bc2165f4ab39d Mon Sep 17 00:00:00 2001 From: fly_1997 Date: Mon, 29 Apr 2024 17:43:41 +0800 Subject: [PATCH] fix spec file and some bugs (cherry picked from commit ca6063d6790f27ef39fb17c5ec7e917c99d83dce) --- 0001-fix-remove-plugin-bug-and-refactor.patch | 1080 +++++++++++ ...nd-replace-raw-poniters-with-smart-p.patch | 1599 +++++++++++++++++ ...-description-extract-class-and-fix-b.patch | 1034 +++++++++++ ...e-error-and-check-plugin-list-config.patch | 200 +++ oeAware-manager.spec | 22 +- 5 files changed, 3927 insertions(+), 8 deletions(-) create mode 100644 0001-fix-remove-plugin-bug-and-refactor.patch create mode 100644 0002-add-error-code-and-replace-raw-poniters-with-smart-p.patch create mode 100644 0003-add-client-error-description-extract-class-and-fix-b.patch create mode 100644 0004-fix-auto-enable-error-and-check-plugin-list-config.patch diff --git a/0001-fix-remove-plugin-bug-and-refactor.patch b/0001-fix-remove-plugin-bug-and-refactor.patch new file mode 100644 index 0000000..1f15f19 --- /dev/null +++ b/0001-fix-remove-plugin-bug-and-refactor.patch @@ -0,0 +1,1080 @@ +From 47fb3c3a0097675ebc9ee2cdc20806638cb57b4d Mon Sep 17 00:00:00 2001 +From: fly_1997 +Date: Thu, 25 Apr 2024 10:31:05 +0800 +Subject: [PATCH 1/4] fix remove plugin bug and refactor + +--- + src/client/client.cpp | 33 +++++---- + src/client/client.h | 8 +-- + src/client/cmd_handler.h | 3 +- + src/plugin_mgr/dep_handler.cpp | 52 ++++++-------- + src/plugin_mgr/dep_handler.h | 15 ++-- + src/plugin_mgr/instance_run_handler.cpp | 77 +++++++++++---------- + src/plugin_mgr/instance_run_handler.h | 45 +++++------- + src/plugin_mgr/memory_store.h | 67 ++++++++++++++++++ + src/plugin_mgr/message_manager.cpp | 2 +- + src/plugin_mgr/message_manager.h | 9 ++- + src/plugin_mgr/plugin.cpp | 24 +++---- + src/plugin_mgr/plugin.h | 21 ++---- + src/plugin_mgr/plugin_manager.cpp | 92 ++++++++++++------------- + src/plugin_mgr/plugin_manager.h | 21 +++--- + 14 files changed, 253 insertions(+), 216 deletions(-) + create mode 100644 src/plugin_mgr/memory_store.h + +diff --git a/src/client/client.cpp b/src/client/client.cpp +index 2377c4b..72fb6a2 100644 +--- a/src/client/client.cpp ++++ b/src/client/client.cpp +@@ -11,6 +11,21 @@ + ******************************************************************************/ + #include "client.h" + ++const std::string Client::OPT_STRING = "Qqd:t:l:r:e:"; ++const struct option Client::long_options[] = { ++ {"help", no_argument, NULL, 'h'}, ++ {"load", required_argument, NULL, 'l'}, ++ {"type", required_argument, NULL, 't'}, ++ {"remove", required_argument, NULL, 'r'}, ++ {"query", required_argument, NULL, 'q'}, ++ {"query-dep", required_argument, NULL, 'Q'}, ++ {"enable", required_argument, NULL, 'e'}, ++ {"disable", required_argument, NULL, 'd'}, ++ {"list", no_argument, NULL, 'L'}, ++ {"download", required_argument, NULL, 'D'}, ++ {0, 0, 0, 0}, ++}; ++ + static void print_error(const Msg &msg) { + for (int i = 0; i < msg.payload_size(); ++i) { + printf("%s\n", msg.payload(i).c_str()); +@@ -40,20 +55,6 @@ void Client::run_cmd(int cmd) { + this->cmd_handler->res_handler(res); + } + +-const std::string Client::OPT_STRING = "Qqd:t:l:r:e:"; +-const struct option Client::long_options[] = { +- {"help", no_argument, NULL, 'h'}, +- {"load", required_argument, NULL, 'l'}, +- {"type", required_argument, NULL, 't'}, +- {"remove", required_argument, NULL, 'r'}, +- {"query", required_argument, NULL, 'q'}, +- {"query-dep", required_argument, NULL, 'Q'}, +- {"enable", required_argument, NULL, 'e'}, +- {"disable", required_argument, NULL, 'd'}, +- {"list", no_argument, NULL, 'L'}, +- {"download", required_argument, NULL, 'D'}, +- {0, 0, 0, 0}, +-}; + int Client::arg_parse(int argc, char *argv[]) { + int cmd = -1; + int opt; +@@ -95,10 +96,12 @@ int Client::arg_parse(int argc, char *argv[]) { + } + return cmd; + } ++ + void Client::arg_error(const std::string &msg) { + std::cerr << "oeawarectl: " << msg << "\n"; + exit(EXIT_FAILURE); + } ++ + void Client::close() { + tcp_socket.clear(); +-} +\ No newline at end of file ++} +diff --git a/src/client/client.h b/src/client/client.h +index 0c2b053..9528f13 100644 +--- a/src/client/client.h ++++ b/src/client/client.h +@@ -31,9 +31,9 @@ private: + + TcpSocket tcp_socket; + CmdHandler *cmd_handler; +- const static std::string OPT_STRING; +- const static int MAX_OPT_SIZE = 11; +- const static struct option long_options[MAX_OPT_SIZE]; ++ static const std::string OPT_STRING; ++ static const int MAX_OPT_SIZE = 20; ++ static const struct option long_options[MAX_OPT_SIZE]; + }; + +-#endif // !CLIENT_H +\ No newline at end of file ++#endif // !CLIENT_H +diff --git a/src/client/cmd_handler.h b/src/client/cmd_handler.h +index 0056430..4afae4c 100644 +--- a/src/client/cmd_handler.h ++++ b/src/client/cmd_handler.h +@@ -21,7 +21,6 @@ static std::string arg; + + class CmdHandler { + public: +- CmdHandler(){} + virtual void handler(Msg &msg) = 0; + virtual void res_handler(Msg &msg) = 0; + }; +@@ -80,4 +79,4 @@ void set_type(char* _type); + void set_arg(char* _arg); + void print_help(); + +-#endif // !CLIENT_CMD_HANDLER_H +\ No newline at end of file ++#endif // !CLIENT_CMD_HANDLER_H +diff --git a/src/plugin_mgr/dep_handler.cpp b/src/plugin_mgr/dep_handler.cpp +index f2e9ba3..9a6ddc5 100644 +--- a/src/plugin_mgr/dep_handler.cpp ++++ b/src/plugin_mgr/dep_handler.cpp +@@ -14,28 +14,22 @@ + #include + + void DepHandler::add_arc_node(Node* node, const std::vector &dep_nodes) { +- ArcNode *arc_head = new ArcNode(); +- node->head = arc_head; ++ ArcNode *arc_head = node->head; + node->cnt = dep_nodes.size(); + int real_cnt = 0; + bool state = true; +- for (auto val : dep_nodes) { ++ for (auto name : dep_nodes) { + ArcNode *tmp = new ArcNode(); +- tmp->val = val; +- tmp->node_name = node->val; +- tmp->next = arc_head->next; +- if (arc_head->next != nullptr) { +- arc_head->next->pre = tmp; +- } +- +- tmp->pre = arc_head; ++ tmp->arc_name = name; ++ tmp->node_name = node->name; ++ tmp->next = arc_head->next; + arc_head->next = tmp; + +- if (nodes.count(val)) { +- arc_nodes[val][tmp] = true; ++ if (nodes.count(name)) { ++ arc_nodes[name][tmp] = true; + real_cnt++; + } else { +- arc_nodes[val][tmp] = false; ++ arc_nodes[name][tmp] = false; + state = false; + } + } +@@ -46,15 +40,14 @@ void DepHandler::add_arc_node(Node* node, const std::vector &dep_no + + void DepHandler::add_node(std::string name, std::vector dep_nodes) { + Node *cur_node = add_new_node(name); +- change_arc_nodes(name, true); +- add_arc_node(cur_node, dep_nodes); + this->nodes[name] = cur_node; ++ add_arc_node(cur_node, dep_nodes); ++ change_arc_nodes(name, true); + } + + void DepHandler::del_node(std::string name) { + del_node_and_arc_nodes(get_node(name)); + this->nodes.erase(name); +- change_arc_nodes(name, false); + } + + +@@ -65,8 +58,9 @@ Node* DepHandler::get_node(std::string name) { + + Node* DepHandler::add_new_node(std::string name) { + Node *cur_node = new Node(name); ++ cur_node->head = new ArcNode(); ++ + tail->next = cur_node; +- cur_node->pre = tail; + tail = cur_node; + return cur_node; + } +@@ -74,18 +68,15 @@ Node* DepHandler::add_new_node(std::string name) { + + + void DepHandler::del_node_and_arc_nodes(Node *node) { +- Node *pre = node->pre; + Node *next = node->next; +- pre->next = next; +- if (next != nullptr) +- next->pre = pre; + ArcNode *arc = node->head; + while(arc) { + ArcNode *tmp = arc->next; + if (arc != node->head){ +- arc_nodes[node->val].erase(arc); +- if (arc_nodes[node->val].empty()) { +- arc_nodes.erase(node->val); ++ std::string name = arc->arc_name; ++ arc_nodes[name].erase(arc); ++ if (arc_nodes[name].empty()) { ++ arc_nodes.erase(name); + } + } + delete arc; +@@ -95,6 +86,7 @@ void DepHandler::del_node_and_arc_nodes(Node *node) { + delete node; + } + void DepHandler::change_arc_nodes(std::string name, bool state) { ++ if (!nodes[name]->state || !arc_nodes.count(name)) return; + std::unordered_map &mp = arc_nodes[name]; + for (auto &vec : mp) { + vec.second = state; +@@ -127,7 +119,7 @@ void DepHandler::query_node_top(std::string name, std::vectornext != nullptr) { +- query.emplace_back(std::vector{name, p->next->val}); ++ query.emplace_back(std::vector{name, p->next->arc_name}); + p = p->next; + } + } +@@ -137,8 +129,8 @@ void DepHandler::query_node(std::string name, std::vector{name}); + for (auto cur = p->head->next; cur != nullptr; cur = cur->next) { +- query.emplace_back(std::vector{name, cur->val}); +- query_node(cur->val, query); ++ query.emplace_back(std::vector{name, cur->arc_name}); ++ query_node(cur->arc_name, query); + } + } + +@@ -149,9 +141,9 @@ std::vector DepHandler::get_pre_dependencies(std::string name) { + while (!q.empty()) { + auto &node = q.front(); + q.pop(); +- res.emplace_back(node->val); ++ res.emplace_back(node->name); + for (auto arc_node = node->head->next; arc_node != nullptr; arc_node = arc_node->next) { +- q.push(nodes[arc_node->val]); ++ q.push(nodes[arc_node->arc_name]); + } + } + return res; +diff --git a/src/plugin_mgr/dep_handler.h b/src/plugin_mgr/dep_handler.h +index a18f439..8ff91e2 100644 +--- a/src/plugin_mgr/dep_handler.h ++++ b/src/plugin_mgr/dep_handler.h +@@ -19,23 +19,21 @@ + + struct ArcNode { + ArcNode *next; +- ArcNode *pre; +- std::string val; ++ std::string arc_name; + std::string node_name; +- ArcNode() : next(nullptr), pre(nullptr) {} ++ ArcNode() : next(nullptr) {} + }; + + // a instance node + struct Node { + Node *next; +- Node *pre; + ArcNode *head; +- std::string val; ++ std::string name; + int cnt; + int real_cnt; + bool state; // dependency closed-loop +- Node() : next(nullptr), pre(nullptr), head(nullptr), state(true), cnt(0), real_cnt(0) {} +- Node(std::string val): val(val), next(nullptr), pre(nullptr), head(nullptr), state(true), cnt(0), real_cnt(0) {} ++ Node() : next(nullptr), head(nullptr), state(true), cnt(0), real_cnt(0) {} ++ Node(std::string name): name(name), next(nullptr), head(nullptr), state(true), cnt(0), real_cnt(0) {} + }; + + class DepHandler { +@@ -55,6 +53,9 @@ public: + void query_node(std::string name, std::vector> &query); + // query all instance dependencies + void query_all_top(std::vector> &query); ++ bool have_dep(const std::string &name) { ++ return arc_nodes.count(name); ++ } + bool is_empty() const { + return nodes.empty(); + } +diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp +index a7f8b49..162079e 100644 +--- a/src/plugin_mgr/instance_run_handler.cpp ++++ b/src/plugin_mgr/instance_run_handler.cpp +@@ -13,7 +13,7 @@ + #include + #include + +-void* get_ring_buf(Instance *instance) { ++static void* get_ring_buf(Instance *instance) { + if (instance == nullptr) { + return nullptr; + } +@@ -32,19 +32,19 @@ static void reflash_ring_buf(Instance *instance) { + ((CollectorInstance*)instance)->get_interface()->reflash_ring_buf(); + } + +-static void run_aware(Instance *instance, std::vector &deps, std::unordered_map *all_instance) { ++void InstanceRunHandler::run_aware(Instance *instance, std::vector &deps) { + void *a[MAX_DEPENDENCIES_SIZE]; + for (int i = 0; i < deps.size(); ++i) { +- Instance *ins = (*all_instance)[deps[i]]; ++ Instance *ins = memory_store->get_instance(deps[i]); + a[i] = get_ring_buf(ins); + } + ((ScenarioInstance*)instance)->get_interface()->aware(a, (int)deps.size()); + } + +-static void run_tune(Instance *instance, std::vector &deps, std::unordered_map *all_instance) { ++void InstanceRunHandler::run_tune(Instance *instance, std::vector &deps) { + void *a[MAX_DEPENDENCIES_SIZE]; + for (int i = 0; i < deps.size(); ++i) { +- Instance *ins = (*all_instance)[deps[i]]; ++ Instance *ins = memory_store->get_instance(deps[i]); + a[i] = get_ring_buf(ins); + } + ((TuneInstance*)instance)->get_interface()->tune(a, (int)deps.size()); +@@ -67,6 +67,7 @@ void InstanceRunHandler::insert_instance(Instance *instance) { + } + INFO("[PluginManager] " << instance->get_name() << " instance insert into running queue."); + } ++ + void InstanceRunHandler::delete_instance(Instance *instance) { + switch (instance->get_type()) { + case PluginType::COLLECTOR: +@@ -85,7 +86,6 @@ void InstanceRunHandler::delete_instance(Instance *instance) { + INFO("[PluginManager] " << instance->get_name() << " instance delete from running queue."); + } + +- + void InstanceRunHandler::handle_instance() { + InstanceRunMessage msg; + while(this->recv_queue_try_pop(msg)){ +@@ -100,6 +100,7 @@ void InstanceRunHandler::handle_instance() { + } + } + } ++ + template + static std::vector get_deps(Instance *instance) { + std::string deps = ((T*)instance)->get_interface()->get_dep(); +@@ -127,12 +128,12 @@ void InstanceRunHandler::adjust_collector_queue(const std::vector & + } + if (ok) continue; + if (flag) { +- if (find(m_dep) && !collector.count(m_dep)) { +- this->insert_instance((*this->all_instance)[m_dep]); ++ if (is_instance_exist(m_dep) && !collector.count(m_dep)) { ++ this->insert_instance(memory_store->get_instance(m_dep)); + } + } else { +- if (find(m_dep) && collector.count(m_dep)) { +- this->delete_instance((*this->all_instance)[m_dep]); ++ if (is_instance_exist(m_dep) && collector.count(m_dep)) { ++ this->delete_instance(memory_store->get_instance(m_dep)); + } + } + } +@@ -143,26 +144,35 @@ void InstanceRunHandler::check_scenario_dependency(const std::vectorget_interface()->get_cycle(); +- if (time % t != 0) return; +- reflash_ring_buf(instance); ++void InstanceRunHandler::schedule_collector(uint64_t time) { ++ for (auto &p : collector) { ++ Instance *instance = p.second; ++ int t = ((CollectorInstance*)instance)->get_interface()->get_cycle(); ++ if (time % t != 0) return; ++ reflash_ring_buf(instance); ++ } + } + +-static void schedule_scenario(Instance *instance, unsigned long long time, InstanceRunHandler *instance_run_handler) { +- int t = ((ScenarioInstance*)instance)->get_interface()->get_cycle(); +- if (time % t != 0) return; +- std::vector origin_deps = get_deps(instance); +- run_aware(instance, origin_deps, instance_run_handler->get_all_instance()); +- std::vector cur_deps = get_deps(instance); +- instance_run_handler->check_scenario_dependency(origin_deps, cur_deps); ++void InstanceRunHandler::schedule_scenario(uint64_t time) { ++ for (auto &p : scenario) { ++ Instance *instance = p.second; ++ int t = ((ScenarioInstance*)instance)->get_interface()->get_cycle(); ++ if (time % t != 0) return; ++ std::vector origin_deps = get_deps(instance); ++ run_aware(instance, origin_deps); ++ std::vector cur_deps = get_deps(instance); ++ check_scenario_dependency(origin_deps, cur_deps); ++ } + } + +-static void schedule_tune(Instance *instance, unsigned long long time, InstanceRunHandler *instance_run_handler) { +- int t = ((TuneInstance*)instance)->get_interface()->get_cycle(); +- if (time % t != 0) return; +- std::vector deps = get_deps(instance); +- run_tune(instance, deps, instance_run_handler->get_all_instance()); ++void InstanceRunHandler::schedule_tune(uint64_t time) { ++ for (auto &p : tune) { ++ Instance *instance = p.second; ++ int t = ((TuneInstance*)instance)->get_interface()->get_cycle(); ++ if (time % t != 0) return; ++ std::vector deps = get_deps(instance); ++ run_tune(instance, deps); ++ } + } + + void start(InstanceRunHandler *instance_run_handler) { +@@ -170,16 +180,9 @@ void start(InstanceRunHandler *instance_run_handler) { + INFO("[PluginManager] instance schedule started!"); + while(true) { + instance_run_handler->handle_instance(); +- for (auto &p : instance_run_handler->get_collector()) { +- schedule_collector(p.second, time); +- } +- for (auto &p : instance_run_handler->get_scenario()) { +- schedule_scenario(p.second, time, instance_run_handler); +- } +- +- for (auto &p : instance_run_handler->get_tune()) { +- schedule_tune(p.second, time, instance_run_handler); +- } ++ instance_run_handler->schedule_collector(time); ++ instance_run_handler->schedule_scenario(time); ++ instance_run_handler->schedule_tune(time); + + usleep(instance_run_handler->get_cycle() * 1000); + time += instance_run_handler->get_cycle(); +@@ -189,4 +192,4 @@ void start(InstanceRunHandler *instance_run_handler) { + void InstanceRunHandler::run() { + std::thread t(start, this); + t.detach(); +-} +\ No newline at end of file ++} +diff --git a/src/plugin_mgr/instance_run_handler.h b/src/plugin_mgr/instance_run_handler.h +index 4730ce8..c9a8dfc 100644 +--- a/src/plugin_mgr/instance_run_handler.h ++++ b/src/plugin_mgr/instance_run_handler.h +@@ -15,13 +15,12 @@ + #include "safe_queue.h" + #include "plugin.h" + #include "logger.h" ++#include "memory_store.h" + #include + #include + #include + #include + +-const int DEFAULT_CYCLE_SIZE = 10; +-const int MAX_DEPENDENCIES_SIZE = 20; + enum class RunType { + ENABLED, + DISABLED, +@@ -32,9 +31,6 @@ class InstanceRunMessage { + public: + InstanceRunMessage() {} + InstanceRunMessage(RunType type, Instance *instance) : type(type), instance(instance) {} +- void init() { +- +- } + RunType get_type() { + return type; + } +@@ -51,11 +47,12 @@ class InstanceRunHandler { + public: + InstanceRunHandler() : cycle(DEFAULT_CYCLE_SIZE) {} + void run(); ++ void schedule_collector(uint64_t time); ++ void schedule_scenario(uint64_t time); ++ void schedule_tune(uint64_t time); + void handle_instance(); +- void delete_instance(Instance *instance); +- void insert_instance(Instance *instance); +- void set_all_instance(std::unordered_map *all_instance) { +- this->all_instance = all_instance; ++ void set_memory_store(MemoryStore *memory_store) { ++ this->memory_store = memory_store; + } + void set_cycle(int cycle) { + this->cycle = cycle; +@@ -63,20 +60,8 @@ public: + int get_cycle() { + return cycle; + } +- bool find(std::string name) { +- return (*this->all_instance).count(name); +- } +- std::unordered_map get_collector() { +- return this->collector; +- } +- std::unordered_map get_scenario() { +- return this->scenario; +- } +- std::unordered_map get_tune() { +- return this->tune; +- } +- std::unordered_map* get_all_instance() { +- return this->all_instance; ++ bool is_instance_exist(const std::string &name) { ++ return memory_store->is_instance_exist(name); + } + void recv_queue_push(InstanceRunMessage &msg) { + this->recv_queue.push(msg); +@@ -87,16 +72,22 @@ public: + bool recv_queue_try_pop(InstanceRunMessage &msg) { + return this->recv_queue.try_pop(msg); + } +- void check_scenario_dependency(const std::vector &deps, const std::vector &m_deps); + private: ++ void run_aware(Instance *instance, std::vector &deps); ++ void run_tune(Instance *instance, std::vector &deps); ++ void delete_instance(Instance *instance); ++ void insert_instance(Instance *instance); + void adjust_collector_queue(const std::vector &deps, const std::vector &m_deps, bool flag); +- ++ void check_scenario_dependency(const std::vector &deps, const std::vector &m_deps); ++ + std::unordered_map collector; + std::unordered_map scenario; + std::unordered_map tune; + SafeQueue recv_queue; +- std::unordered_map *all_instance; ++ MemoryStore *memory_store; + int cycle; ++ static const int DEFAULT_CYCLE_SIZE = 10; ++ static const int MAX_DEPENDENCIES_SIZE = 20; + }; + +-#endif // !PLUGIN_MGR_INSTANCE_RUN_HANDLER_H +\ No newline at end of file ++#endif // !PLUGIN_MGR_INSTANCE_RUN_HANDLER_H +diff --git a/src/plugin_mgr/memory_store.h b/src/plugin_mgr/memory_store.h +new file mode 100644 +index 0000000..190fcdd +--- /dev/null ++++ b/src/plugin_mgr/memory_store.h +@@ -0,0 +1,67 @@ ++/****************************************************************************** ++ * Copyright (c) 2024 Huawei Technologies Co., Ltd. ++ * oeAware is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ ******************************************************************************/ ++#ifndef PLUGIN_MGR_MEMORY_STORE_H ++#define PLUGIN_MGR_MEMORY_STORE_H ++#include "plugin.h" ++#include "logger.h" ++#include ++ ++//OeAware memory storage, which is used to store plugins and instances in the memory. ++class MemoryStore { ++public: ++ void add_plugin(const std::string &name, Plugin *plugin) { ++ this->plugins.insert(std::make_pair(name, plugin)); ++ } ++ void add_instance(const std::string &name, Instance *instance) { ++ this->instances.insert(std::make_pair(name, instance)); ++ } ++ Plugin* get_plugin(const std::string &name) const { ++ return this->plugins.at(name); ++ } ++ Instance* get_instance(const std::string &name) const { ++ return this->instances.at(name); ++ } ++ void delete_plugin(const std::string &name) { ++ Plugin *plugin = plugins.at(name); ++ this->plugins.erase(name); ++ delete plugin; ++ } ++ void delete_instance(const std::string &name) { ++ Instance *instance = instances.at(name); ++ this->instances.erase(name); ++ } ++ bool is_plugin_exist(const std::string &name) const { ++ return this->plugins.count(name); ++ } ++ bool is_instance_exist(const std::string &name) const { ++ return this->instances.count(name); ++ } ++ std::vector get_all_plugins() { ++ std::vector res; ++ for (auto &p : plugins) { ++ res.emplace_back(p.second); ++ } ++ return res; ++ } ++ std::vector get_all_instances() { ++ std::vector res; ++ for (auto &p : instances) { ++ res.emplace_back(p.second); ++ } ++ return res; ++ } ++private: ++ std::unordered_map plugins; ++ std::unordered_map instances; ++}; ++ ++#endif // !PLUGIN_MGR_MEMORY_STORE_H +diff --git a/src/plugin_mgr/message_manager.cpp b/src/plugin_mgr/message_manager.cpp +index 92f467f..296c682 100644 +--- a/src/plugin_mgr/message_manager.cpp ++++ b/src/plugin_mgr/message_manager.cpp +@@ -80,7 +80,7 @@ void TcpSocket::serve_accept(SafeQueue *handler_msg, SafeQueue + for (int i = 0; i < num; ++i) { + int cur_fd = evs[i].data.fd; + if (cur_fd == sock) { +- conn = accept(cur_fd, NULL, NULL); ++ int conn = accept(cur_fd, NULL, NULL); + struct epoll_event ev; + ev.events = EPOLLIN; + ev.data.fd = conn; +diff --git a/src/plugin_mgr/message_manager.h b/src/plugin_mgr/message_manager.h +index d900c6f..d1faad3 100644 +--- a/src/plugin_mgr/message_manager.h ++++ b/src/plugin_mgr/message_manager.h +@@ -68,15 +68,14 @@ private: + + class TcpSocket { + public: +- TcpSocket() : conn(-1) {} +- int domain_listen(const char *name); ++ TcpSocket() {} + bool init(); + void serve_accept(SafeQueue *handler_msg, SafeQueue *res_msg); ++private: ++ int domain_listen(const char *name); ++ + int sock; +- struct sockaddr_in addr; +- int conn; + int epfd; +- struct epoll_event ev; + }; + + class MessageManager { +diff --git a/src/plugin_mgr/plugin.cpp b/src/plugin_mgr/plugin.cpp +index 091e73b..1a2db0d 100644 +--- a/src/plugin_mgr/plugin.cpp ++++ b/src/plugin_mgr/plugin.cpp +@@ -11,6 +11,11 @@ + ******************************************************************************/ + #include "plugin.h" + ++const std::string Instance::PLUGIN_ENABLED = "running"; ++const std::string Instance::PLUGIN_DISABLED = "close"; ++const std::string Instance::PLUGIN_STATE_ON = "available"; ++const std::string Instance::PLUGIN_STATE_OFF = "unavailable"; ++ + int Plugin::load(const std::string dl_path) { + void *handler = dlopen(dl_path.c_str(), RTLD_LAZY); + if (handler == nullptr) { +@@ -20,17 +25,8 @@ int Plugin::load(const std::string dl_path) { + return 0; + } + +-std::string plugin_type_to_string(PluginType type) { +- switch (type) { +- case PluginType::COLLECTOR: { +- return COLLECTOR_TEXT; +- } +- case PluginType::SCENARIO: { +- return SCENARIO_TEXT; +- } +- case PluginType::TUNE: { +- return TUNE_TEXT; +- } +- } +- return ""; +-} +\ No newline at end of file ++std::string Instance::get_info() const { ++ std::string state_text = this->state ? PLUGIN_STATE_ON : PLUGIN_STATE_OFF; ++ std::string run_text = this->enabled ? PLUGIN_ENABLED : PLUGIN_DISABLED; ++ return name + "(" + state_text + ", " + run_text + ")"; ++} +diff --git a/src/plugin_mgr/plugin.h b/src/plugin_mgr/plugin.h +index 892cb74..11b4748 100644 +--- a/src/plugin_mgr/plugin.h ++++ b/src/plugin_mgr/plugin.h +@@ -16,15 +16,6 @@ + #include + #include + +-const std::string PLUGIN_ENABLED = "running"; +-const std::string PLUGIN_DISABLED = "close"; +-const std::string PLUGIN_STATE_ON = "available"; +-const std::string PLUGIN_STATE_OFF = "unavailable"; +- +-const std::string COLLECTOR_TEXT = "collector"; +-const std::string SCENARIO_TEXT = "scenario"; +-const std::string TUNE_TEXT = "tune"; +- + enum class PluginType { + COLLECTOR, + SCENARIO, +@@ -67,17 +58,17 @@ public: + bool get_enabled() const { + return this->enabled; + } +- std::string get_info() const { +- std::string state_text = this->state ? PLUGIN_STATE_ON : PLUGIN_STATE_OFF; +- std::string run_text = this->enabled ? PLUGIN_ENABLED : PLUGIN_DISABLED; +- return name + "(" + state_text + ", " + run_text + ")"; +- } ++ std::string get_info() const; + private: + std::string name; + std::string plugin_name; + PluginType type; + bool state; + bool enabled; ++ const static std::string PLUGIN_ENABLED; ++ const static std::string PLUGIN_DISABLED; ++ const static std::string PLUGIN_STATE_ON; ++ const static std::string PLUGIN_STATE_OFF; + }; + + class CollectorInstance : public Instance { +@@ -163,4 +154,4 @@ private: + std::string name; + }; + +-#endif +\ No newline at end of file ++#endif +diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp +index ec9b85e..47f9451 100644 +--- a/src/plugin_mgr/plugin_manager.cpp ++++ b/src/plugin_mgr/plugin_manager.cpp +@@ -16,15 +16,11 @@ + #include + #include + ++const std::string PluginManager::COLLECTOR_TEXT = "collector"; ++const std::string PluginManager::SCENARIO_TEXT = "scenario"; ++const std::string PluginManager::TUNE_TEXT = "tune"; + const static int ST_MODE_MASK = 0777; + +-bool PluginManager::check(char **deps, int len) { +- for (int i = 0; i < len; ++i) { +- if (!is_instance_exist(deps[i])) return false; +- } +- return true; +-} +- + void PluginManager::init(Config *config) { + plugin_types[COLLECTOR_TEXT] = PluginType::COLLECTOR; + plugin_types[SCENARIO_TEXT] = PluginType::SCENARIO; +@@ -32,24 +28,29 @@ void PluginManager::init(Config *config) { + this->config = config; + } + +-bool PluginManager::remove(const std::string name) { +- if (!plugins.count(name)) return false; +- Plugin *plugin = plugins[name]; ++bool PluginManager::remove(const std::string &name) { ++ if (!memory_store.is_plugin_exist(name)) return false; ++ Plugin *plugin = memory_store.get_plugin(name); ++ std::vector instance_names; + for (int i = 0; i < plugin->get_instance_len(); ++i) { + Instance *instance = plugin->get_instance(i); + std::string iname = instance->get_name(); +- instances.erase(iname); ++ if (dep_handler->have_dep(iname)) { ++ return false; ++ } ++ instance_names.emplace_back(iname); ++ } ++ for(auto &iname : instance_names) { ++ memory_store.delete_instance(iname); + dep_handler->del_node(iname); +- INFO("[PluginManager] instance : " << instance->get_name()); + } +- delete plugin; +- plugins.erase(name); ++ memory_store.delete_plugin(name); + update_instance_state(); + return true; + } + bool PluginManager::query_all_plugins(Message &res) { +- for (auto &t : plugins) { +- Plugin *p = t.second; ++ std::vector all_plugins = memory_store.get_all_plugins(); ++ for (auto &p : all_plugins) { + res.add_payload(p->get_name()); + for (int i = 0; i < p->get_instance_len(); ++i) { + std::string info = p->get_instance(i)->get_info(); +@@ -60,11 +61,11 @@ bool PluginManager::query_all_plugins(Message &res) { + } + + bool PluginManager::query_plugin(std::string name, Message &res) { +- if (!plugins.count(name)) { ++ if (!memory_store.is_plugin_exist(name)) { + res.add_payload("no such plugin!"); + return true; + } +- Plugin *plugin = plugins[name]; ++ Plugin *plugin = memory_store.get_plugin(name); + res.add_payload(name); + for (int i = 0; i < plugin->get_instance_len(); ++i) { + std::string info = plugin->get_instance(i)->get_info(); +@@ -106,10 +107,6 @@ std::vector get_dep(T *interface) { + template + void PluginManager::save_instance(Plugin *plugin, T *interface_list, int len) { + if (interface_list == nullptr) return; +- std::unordered_map tmp_interfaces; +- for (int i = 0; i < len; ++i) { +- tmp_interfaces[interface_list[i].get_name()] = true; +- } + for (int i = 0; i < len; ++i) { + T *interface = interface_list + i; + Instance *instance = new U(); +@@ -127,7 +124,7 @@ void PluginManager::save_instance(Plugin *plugin, T *interface_list, int len) { + instance->set_state(dep_handler->get_node_state(name)); + ((U*)instance)->set_interface(interface); + DEBUG("[PluginManager] Instance: " << name.c_str()); +- this->instances[name] = instance; ++ memory_store.add_instance(name, instance); + plugin->add_instance(instance); + } + } +@@ -163,17 +160,18 @@ bool PluginManager::load_instance(Plugin *plugin) { + } + + void PluginManager::update_instance_state() { +- for (auto &v : instances) { +- if (dep_handler->get_node_state(v.first)) { +- v.second->set_state(true); ++ std::vector all_instances = memory_store.get_all_instances(); ++ for (auto &instance : all_instances) { ++ if (dep_handler->get_node_state(instance->get_name())) { ++ instance->set_state(true); + } else { +- v.second->set_state(false); ++ instance->set_state(false); + } + } + } + + bool PluginManager::load_plugin(const std::string name, PluginType type) { +- if (plugins.count(name)) { ++ if (memory_store.is_plugin_exist(name)) { + WARN("[PluginManager] " << name << " already loaded!"); + return false; + } +@@ -188,21 +186,21 @@ bool PluginManager::load_plugin(const std::string name, PluginType type) { + delete plugin; + return false; + } +- plugins[name] = plugin; ++ memory_store.add_plugin(name, plugin); + return true; + } + +-std::string generate_dot(std::unordered_map instances, const std::vector> &query) { ++std::string generate_dot(MemoryStore &memory_store, const std::vector> &query) { + std::string res; + res += "digraph G {\n"; + std::unordered_map> sub_graph; + for (auto &vec : query) { +- Instance *instance = instances[vec[0]]; ++ Instance *instance = memory_store.get_instance(vec[0]); + sub_graph[instance->get_plugin_name()].emplace_back(vec[0]); + if (vec.size() == 1) { + continue; + } +- instance = instances[vec[1]]; ++ instance = memory_store.get_instance(vec[1]); + sub_graph[instance->get_plugin_name()].emplace_back(vec[1]); + res += vec[0] + "->" + vec[1] + ";"; + } +@@ -229,7 +227,7 @@ bool PluginManager::query_top(std::string name, Message &res) { + res.add_payload("Instance not available!"); + return false; + } +- std::string dot_text = generate_dot(instances, query); ++ std::string dot_text = generate_dot(memory_store, query); + res.add_payload(dot_text); + return true; + } +@@ -242,17 +240,17 @@ bool PluginManager::query_all_tops(Message &res) { + res.add_payload("No instance available!"); + return false; + } +- std::string dot_text = generate_dot(instances, query); ++ std::string dot_text = generate_dot(memory_store, query); + res.add_payload(dot_text); + return true; + } + + bool PluginManager::instance_enabled(std::string name) { +- if (!instances.count(name)) { ++ if (!memory_store.is_instance_exist(name)) { + WARN("[PluginManager] " << name << " instance can't load!"); + return false; + } +- Instance *instance = instances[name]; ++ Instance *instance = memory_store.get_instance(name); + if (!instance->get_state()) { + WARN("[PluginManager] " << name << " instance is unavailable, lacking dependencies!"); + return false; +@@ -263,7 +261,7 @@ bool PluginManager::instance_enabled(std::string name) { + } + std::vector pre_dependencies = dep_handler->get_pre_dependencies(name); + for (int i = pre_dependencies.size() - 1; i >= 0; --i) { +- instance = instances[pre_dependencies[i]]; ++ instance = memory_store.get_instance(pre_dependencies[i]); + if (instance->get_enabled()) { + continue; + } +@@ -275,11 +273,11 @@ bool PluginManager::instance_enabled(std::string name) { + } + + bool PluginManager::instance_disabled(std::string name) { +- if (!instances.count(name)) { ++ if (!memory_store.is_instance_exist(name)) { + WARN("[PluginManager] " << name << " instance can't load!"); + return false; + } +- Instance *instance = instances[name]; ++ Instance *instance = memory_store.get_instance(name); + if (!instance->get_state()) { + WARN("[PluginManager] " << name << " instance is unavailable, lacking dependencies!"); + return false; +@@ -341,11 +339,11 @@ void PluginManager::pre_enable() { + EnableItem item = config->get_enable_list(i); + if (item.get_enabled()) { + std::string name = item.get_name(); +- if (!plugins.count(name)) { ++ if (!memory_store.is_plugin_exist(name)) { + WARN("[PluginManager] plugin " << name << " cannot be enabled, because it does not exist."); + continue; + } +- Plugin *plugin = plugins[name]; ++ Plugin *plugin = memory_store.get_plugin(name); + for (int j = 0; j < plugin->get_instance_len(); ++j) { + instance_enabled(plugin->get_instance(i)->get_name()); + } +@@ -380,7 +378,7 @@ static bool check_load_msg(Message &msg, std::unordered_mapget_type()) { + case PluginType::COLLECTOR: { + CollectorInterface *collector_interface = ((CollectorInstance*)instance)->get_interface(); +@@ -397,7 +395,7 @@ void* PluginManager::get_data_buffer(std::string name) { + } + + void PluginManager::instance_dep_check(std::string name, Message &res) { +- Plugin *plugin = plugins[name]; ++ Plugin *plugin = memory_store.get_plugin(name); + for (int i = 0; i < plugin->get_instance_len(); ++i) { + std::string instance_name = plugin->get_instance(i)->get_name(); + std::vector> query; +@@ -405,7 +403,7 @@ void PluginManager::instance_dep_check(std::string name, Message &res) { + std::vector lack; + for (auto &item : query) { + if (item.size() < 2) continue; +- if (!instances.count(item[1])) { ++ if (!memory_store.is_instance_exist(item[1])) { + lack.emplace_back(item[1]); + } + } +@@ -437,7 +435,7 @@ static bool file_exist(const std::string &file_name) { + } + + int PluginManager::run() { +- instance_run_handler->set_all_instance(&instances); ++ instance_run_handler->set_memory_store(&memory_store); + instance_run_handler->run(); + while (true) { + Message msg; +@@ -483,7 +481,7 @@ int PluginManager::run() { + res.add_payload(name + " removed!"); + INFO("[PluginManager] " << name << " removed!"); + } else { +- res.add_payload(name + " does not exist!"); ++ res.add_payload(name + " remove failed!"); + } + break; + } +@@ -562,4 +560,4 @@ int PluginManager::run() { + res_msg->push(res); + } + return 0; +-} +\ No newline at end of file ++} +diff --git a/src/plugin_mgr/plugin_manager.h b/src/plugin_mgr/plugin_manager.h +index 415e5ea..f648931 100644 +--- a/src/plugin_mgr/plugin_manager.h ++++ b/src/plugin_mgr/plugin_manager.h +@@ -13,11 +13,10 @@ + #define PLUGIN_MGR_PLUGIN_MANAGER_H + + #include "instance_run_handler.h" +-#include "plugin.h" + #include "config.h" ++#include "memory_store.h" + #include "dep_handler.h" + #include "message_manager.h" +-#include "logger.h" + #include + #include + #include +@@ -39,7 +38,6 @@ public: + void* get_data_buffer(std::string name); + private: + void pre_load_plugin(PluginType type); +- bool check(char **deps, int len); + bool query_all_plugins(Message &res); + bool query_plugin(std::string name, Message &res); + bool query_top(std::string name, Message &res); +@@ -54,24 +52,23 @@ private: + bool load_instance(Plugin *plugin); + bool load_plugin(const std::string path, PluginType type); + void batch_load(); +- bool remove(const std::string name); ++ bool remove(const std::string &name); + void batch_remove(); + void add_list(Message &msg); +- bool is_instance_exist(std::string name) { +- return this->instances.find(name) != this->instances.end(); +- } + void update_instance_state(); + private: + InstanceRunHandler *instance_run_handler; + Config *config; + SafeQueue *handler_msg; + SafeQueue *res_msg; +- std::unordered_map plugins; +- std::unordered_map instances; +- DepHandler *dep_handler; +- std::unordered_map plugin_types; ++ MemoryStore memory_store; ++ DepHandler *dep_handler; ++ std::unordered_map plugin_types; ++ static const std::string COLLECTOR_TEXT; ++ static const std::string SCENARIO_TEXT; ++ static const std::string TUNE_TEXT; + }; + + bool check_permission(std::string path, int mode); + +-#endif +\ No newline at end of file ++#endif +-- +2.33.0 + diff --git a/0002-add-error-code-and-replace-raw-poniters-with-smart-p.patch b/0002-add-error-code-and-replace-raw-poniters-with-smart-p.patch new file mode 100644 index 0000000..b2e7b26 --- /dev/null +++ b/0002-add-error-code-and-replace-raw-poniters-with-smart-p.patch @@ -0,0 +1,1599 @@ +From 97949b2f4a1e894493c21f813f067d099f39176c Mon Sep 17 00:00:00 2001 +From: fly_1997 +Date: Sun, 28 Apr 2024 10:09:30 +0800 +Subject: [PATCH 2/4] add error code and replace raw poniters with smart + pointers + +--- + oeAware.service | 2 +- + src/common/message_protocol.h | 15 +- + src/plugin_mgr/CMakeLists.txt | 4 +- + src/plugin_mgr/config.cpp | 10 +- + src/plugin_mgr/dep_handler.cpp | 43 ++- + src/plugin_mgr/dep_handler.h | 25 +- + src/plugin_mgr/error_code.cpp | 29 ++ + src/plugin_mgr/error_code.h | 33 ++ + src/plugin_mgr/instance_run_handler.cpp | 65 ++-- + src/plugin_mgr/instance_run_handler.h | 30 +- + src/plugin_mgr/main.cpp | 21 +- + src/plugin_mgr/memory_store.h | 24 +- + src/plugin_mgr/message_manager.cpp | 1 - + src/plugin_mgr/message_manager.h | 9 +- + src/plugin_mgr/plugin.h | 16 +- + src/plugin_mgr/plugin_manager.cpp | 389 ++++++++++++++---------- + src/plugin_mgr/plugin_manager.h | 55 ++-- + 17 files changed, 443 insertions(+), 328 deletions(-) + create mode 100644 src/plugin_mgr/error_code.cpp + create mode 100644 src/plugin_mgr/error_code.h + +diff --git a/oeAware.service b/oeAware.service +index 9260492..3ab4b69 100644 +--- a/oeAware.service ++++ b/oeAware.service +@@ -4,7 +4,7 @@ After=network.target + + [Service] + Type=simple +-ExecStart=/usr/bin/oeAware /etc/oeAware/config.yaml ++ExecStart=/usr/bin/oeaware /etc/oeAware/config.yaml + ExecStop=kill -9 $MAINPID + Restart=on-failure + RestartSec=1 +diff --git a/src/common/message_protocol.h b/src/common/message_protocol.h +index 1226e0b..3771298 100644 +--- a/src/common/message_protocol.h ++++ b/src/common/message_protocol.h +@@ -24,7 +24,6 @@ const int MAX_RECV_BUFF_SIZE = 16384; + const int MAX_EVENT_SIZE = 1024; + const int PROTOCOL_LENGTH_SIZE = sizeof(size_t); + const int HEADER_LENGTH_SIZE = sizeof(size_t); +- + const int HEADER_STATE_OK = 0; + const int HEADER_STATE_FAILED = 1; + +@@ -39,7 +38,8 @@ enum class Opt { + QUERY_ALL_TOP, + LIST, + DOWNLOAD, +- RESPONSE, ++ RESPONSE_OK, ++ RESPONSE_ERROR, + SHUTDOWN, + }; + +@@ -70,6 +70,9 @@ class Msg { + void set_opt(Opt opt) { + this->_opt = opt; + } ++ Opt get_opt() const { ++ return this->_opt; ++ } + private: + Opt _opt; + std::vector _payload; +@@ -80,17 +83,17 @@ private: + friend class boost::serialization::access; + template + void serialize(Archive &ar, const unsigned int version) { +- ar & state_code; ++ ar & code; + } + public: + void set_state_code(int code) { +- this->state_code = code; ++ this->code = code; + } + int get_state_code() { +- return this->state_code; ++ return this->code; + } + private: +- int state_code; ++ int code; + }; + + class MessageProtocol { +diff --git a/src/plugin_mgr/CMakeLists.txt b/src/plugin_mgr/CMakeLists.txt +index 09fa80a..a32c800 100644 +--- a/src/plugin_mgr/CMakeLists.txt ++++ b/src/plugin_mgr/CMakeLists.txt +@@ -12,7 +12,7 @@ include_directories(/usr/include) + include_directories(../common) + link_directories(/usr/lib64) + +-add_executable (oeAware ++add_executable (oeaware + ${SOURCE} + ) +-target_link_libraries(oeAware common) ++target_link_libraries(oeaware common) +diff --git a/src/plugin_mgr/config.cpp b/src/plugin_mgr/config.cpp +index bd87937..b997b8f 100644 +--- a/src/plugin_mgr/config.cpp ++++ b/src/plugin_mgr/config.cpp +@@ -52,14 +52,14 @@ bool Config::load(const std::string path) { + YAML::Node enable_list = node["enable_list"]; + if (enable_list.IsSequence()) { + for (int i = 0; i < enable_list.size(); ++i) { +- YAML::Node instances = enable_list[i]["instances"]; ++ YAML::Node plugin = enable_list[i]["name"]; + std::string name = enable_list[i]["name"].as(); + EnableItem enable_item(name); +- if (instances.IsNull()) { ++ if (plugin.IsScalar()) { + enable_item.set_enabled(true); +- } else if (instances.IsSequence()) { +- for (int j = 0; j < instances.size(); ++j) { +- std::string i_name = instances[j]["name"].as(); ++ } else if (plugin.IsSequence()) { ++ for (int j = 0; j < plugin.size(); ++j) { ++ std::string i_name = plugin[j].as(); + enable_item.add_instance(i_name); + } + } else { +diff --git a/src/plugin_mgr/dep_handler.cpp b/src/plugin_mgr/dep_handler.cpp +index 9a6ddc5..eff333c 100644 +--- a/src/plugin_mgr/dep_handler.cpp ++++ b/src/plugin_mgr/dep_handler.cpp +@@ -13,13 +13,13 @@ + #include + #include + +-void DepHandler::add_arc_node(Node* node, const std::vector &dep_nodes) { +- ArcNode *arc_head = node->head; ++void DepHandler::add_arc_node(std::shared_ptr node, const std::vector &dep_nodes) { ++ std::shared_ptr arc_head = node->head; + node->cnt = dep_nodes.size(); + int real_cnt = 0; + bool state = true; + for (auto name : dep_nodes) { +- ArcNode *tmp = new ArcNode(); ++ std::shared_ptr tmp = std::make_shared(); + tmp->arc_name = name; + tmp->node_name = node->name; + tmp->next = arc_head->next; +@@ -39,7 +39,7 @@ void DepHandler::add_arc_node(Node* node, const std::vector &dep_no + + + void DepHandler::add_node(std::string name, std::vector dep_nodes) { +- Node *cur_node = add_new_node(name); ++ std::shared_ptr cur_node = add_new_node(name); + this->nodes[name] = cur_node; + add_arc_node(cur_node, dep_nodes); + change_arc_nodes(name, true); +@@ -51,27 +51,24 @@ void DepHandler::del_node(std::string name) { + } + + +-Node* DepHandler::get_node(std::string name) { ++std::shared_ptr DepHandler::get_node(std::string name) { + return this->nodes[name]; + } + + +-Node* DepHandler::add_new_node(std::string name) { +- Node *cur_node = new Node(name); +- cur_node->head = new ArcNode(); +- ++std::shared_ptr DepHandler::add_new_node(std::string name) { ++ std::shared_ptr cur_node = std::make_shared(name); ++ cur_node->head = std::make_shared(); + tail->next = cur_node; + tail = cur_node; + return cur_node; + } + +- +- +-void DepHandler::del_node_and_arc_nodes(Node *node) { +- Node *next = node->next; +- ArcNode *arc = node->head; ++void DepHandler::del_node_and_arc_nodes(std::shared_ptr node) { ++ std::shared_ptr next = node->next; ++ std::shared_ptr arc = node->head; + while(arc) { +- ArcNode *tmp = arc->next; ++ std::shared_ptr tmp = arc->next; + if (arc != node->head){ + std::string name = arc->arc_name; + arc_nodes[name].erase(arc); +@@ -79,19 +76,16 @@ void DepHandler::del_node_and_arc_nodes(Node *node) { + arc_nodes.erase(name); + } + } +- delete arc; +- arc = tmp; +- ++ arc = tmp; + } +- delete node; + } + void DepHandler::change_arc_nodes(std::string name, bool state) { + if (!nodes[name]->state || !arc_nodes.count(name)) return; +- std::unordered_map &mp = arc_nodes[name]; ++ std::unordered_map, bool> &mp = arc_nodes[name]; + for (auto &vec : mp) { + vec.second = state; + if (nodes.count(vec.first->node_name)) { +- Node *tmp = nodes[vec.first->node_name]; ++ std::shared_ptr tmp = nodes[vec.first->node_name]; + if (state) { + tmp->real_cnt++; + if (tmp->real_cnt == tmp->cnt) { +@@ -101,6 +95,7 @@ void DepHandler::change_arc_nodes(std::string name, bool state) { + tmp->real_cnt--; + tmp->state = false; + } ++ change_arc_nodes(vec.first->node_name, state); + } + } + } +@@ -113,7 +108,7 @@ void DepHandler::query_all_top(std::vector> &query) { + } + + void DepHandler::query_node_top(std::string name, std::vector> &query) { +- ArcNode *p = nodes[name]->head; ++ std::shared_ptr p = nodes[name]->head; + if (p->next == nullptr) { + query.emplace_back(std::vector{name}); + return; +@@ -126,7 +121,7 @@ void DepHandler::query_node_top(std::string name, std::vector> &query) { + if (!nodes.count(name)) return; +- Node *p = nodes[name]; ++ std::shared_ptr p = nodes[name]; + query.emplace_back(std::vector{name}); + for (auto cur = p->head->next; cur != nullptr; cur = cur->next) { + query.emplace_back(std::vector{name, cur->arc_name}); +@@ -136,7 +131,7 @@ void DepHandler::query_node(std::string name, std::vector DepHandler::get_pre_dependencies(std::string name) { + std::vector res; +- std::queue q; ++ std::queue> q; + q.push(nodes[name]); + while (!q.empty()) { + auto &node = q.front(); +diff --git a/src/plugin_mgr/dep_handler.h b/src/plugin_mgr/dep_handler.h +index 8ff91e2..cc8570a 100644 +--- a/src/plugin_mgr/dep_handler.h ++++ b/src/plugin_mgr/dep_handler.h +@@ -16,9 +16,10 @@ + #include + #include + #include ++#include + + struct ArcNode { +- ArcNode *next; ++ std::shared_ptr next; + std::string arc_name; + std::string node_name; + ArcNode() : next(nullptr) {} +@@ -26,8 +27,8 @@ struct ArcNode { + + // a instance node + struct Node { +- Node *next; +- ArcNode *head; ++ std::shared_ptr next; ++ std::shared_ptr head; + std::string name; + int cnt; + int real_cnt; +@@ -39,10 +40,10 @@ struct Node { + class DepHandler { + public: + DepHandler() { +- this->head = new Node(); ++ this->head = std::make_shared(); + this->tail = head; + } +- Node* get_node(std::string name); ++ std::shared_ptr get_node(std::string name); + bool get_node_state(std::string name) { + return this->nodes[name]->state; + } +@@ -64,15 +65,15 @@ public: + } + private: + void query_node_top(std::string name, std::vector> &query); +- void add_arc_node(Node* node, const std::vector &dep_nodes); ++ void add_arc_node(std::shared_ptr node, const std::vector &dep_nodes); + void change_arc_nodes(std::string name, bool state); +- void del_node_and_arc_nodes(Node *node); +- Node* add_new_node(std::string name); ++ void del_node_and_arc_nodes(std::shared_ptr node); ++ std::shared_ptr add_new_node(std::string name); + +- std::unordered_map> arc_nodes; +- std::unordered_map nodes; +- Node * head; +- Node *tail; ++ std::unordered_map, bool>> arc_nodes; ++ std::unordered_map> nodes; ++ std::shared_ptr head; ++ std::shared_ptr tail; + }; + + #endif // !PLUGIN_MGR_DEP_HANDLER_H +diff --git a/src/plugin_mgr/error_code.cpp b/src/plugin_mgr/error_code.cpp +new file mode 100644 +index 0000000..252e4c2 +--- /dev/null ++++ b/src/plugin_mgr/error_code.cpp +@@ -0,0 +1,29 @@ ++#include "error_code.h" ++ ++const std::unordered_map ErrorText::error_codes = { ++ {ErrorCode::ENABLE_INSTANCE_NOT_LOAD, "instance is not loaded"}, ++ {ErrorCode::ENABLE_INSTANCE_UNAVAILABLE, "instance is unavailable"}, ++ {ErrorCode::ENABLE_INSTANCE_ALREADY_ENABLED, "instance is already enabled"}, ++ {ErrorCode::DISABLE_INSTANCE_NOT_LOAD, "instance is not loaded"}, ++ {ErrorCode::DISABLE_INSTANCE_UNAVAILABLE, "instance is unavailable"}, ++ {ErrorCode::DISABLE_INSTANCE_ALREADY_DISABLED, "instance is already disabled"}, ++ {ErrorCode::REMOVE_PLUGIN_NOT_EXIST, "plugin does not exist"}, ++ {ErrorCode::REMOVE_INSTANCE_IS_RUNNING, "instance is running"}, ++ {ErrorCode::REMOVE_INSTANCE_HAVE_DEP, "instance with pre-dependency"}, ++ {ErrorCode::LOAD_PLUGIN_FILE_NOT_EXIST, "plugin file does not exist"}, ++ {ErrorCode::LOAD_PLUGIN_FILE_PERMISSION_DEFINED, "plugin file permission defined"}, ++ {ErrorCode::LOAD_PLUGIN_EXIST, "plugin already loaded"}, ++ {ErrorCode::LOAD_PLUGIN_DLOPEN_FAILED, "plugin dlopen failed"}, ++ {ErrorCode::LOAD_PLUGIN_DLSYM_FAILED, "plugin dlsym failed"}, ++ {ErrorCode::QUERY_PLUGIN_NOT_EXIST, "plugin does not exist"}, ++ {ErrorCode::QUERY_DEP_NOT_EXIST, "instance does not exist"}, ++ {ErrorCode::DOWNLOAD_NOT_FOUND, "unable to find a match"}, ++}; ++std::string ErrorText::get_error_text(ErrorCode code) { ++ auto it = ErrorText::error_codes.find(code); ++ if (it != ErrorText::error_codes.end()) { ++ return it->second; ++ } else { ++ return "unknown error."; ++ } ++} +\ No newline at end of file +diff --git a/src/plugin_mgr/error_code.h b/src/plugin_mgr/error_code.h +new file mode 100644 +index 0000000..f58d5ed +--- /dev/null ++++ b/src/plugin_mgr/error_code.h +@@ -0,0 +1,33 @@ ++#ifndef PLUGIN_MGR_ERROR_CODE_H ++#define PLUGIN_MGR_ERROR_CODE_H ++#include ++#include ++ ++enum class ErrorCode { ++ ENABLE_INSTANCE_NOT_LOAD, ++ ENABLE_INSTANCE_UNAVAILABLE, ++ ENABLE_INSTANCE_ALREADY_ENABLED, ++ DISABLE_INSTANCE_NOT_LOAD, ++ DISABLE_INSTANCE_UNAVAILABLE, ++ DISABLE_INSTANCE_ALREADY_DISABLED, ++ REMOVE_PLUGIN_NOT_EXIST, ++ REMOVE_INSTANCE_IS_RUNNING, ++ REMOVE_INSTANCE_HAVE_DEP, ++ LOAD_PLUGIN_FILE_NOT_EXIST, ++ LOAD_PLUGIN_FILE_PERMISSION_DEFINED, ++ LOAD_PLUGIN_EXIST, ++ LOAD_PLUGIN_DLOPEN_FAILED, ++ LOAD_PLUGIN_DLSYM_FAILED, ++ QUERY_PLUGIN_NOT_EXIST, ++ QUERY_DEP_NOT_EXIST, ++ DOWNLOAD_NOT_FOUND, ++ OK, ++}; ++ ++class ErrorText { ++public: ++ static std::string get_error_text(ErrorCode code); ++ static const std::unordered_map error_codes; ++}; ++ ++#endif // !PLUGIN_MGR_ERROR_CODE_H +\ No newline at end of file +diff --git a/src/plugin_mgr/instance_run_handler.cpp b/src/plugin_mgr/instance_run_handler.cpp +index 162079e..862e806 100644 +--- a/src/plugin_mgr/instance_run_handler.cpp ++++ b/src/plugin_mgr/instance_run_handler.cpp +@@ -13,74 +13,74 @@ + #include + #include + +-static void* get_ring_buf(Instance *instance) { ++static void* get_ring_buf(std::shared_ptr instance) { + if (instance == nullptr) { + return nullptr; + } + switch (instance->get_type()) { + case PluginType::COLLECTOR: +- return ((CollectorInstance*)instance)->get_interface()->get_ring_buf(); ++ return (std::dynamic_pointer_cast(instance))->get_interface()->get_ring_buf(); + case PluginType::SCENARIO: +- return ((ScenarioInstance*)instance)->get_interface()->get_ring_buf(); ++ return (std::dynamic_pointer_cast(instance))->get_interface()->get_ring_buf(); + case PluginType::TUNE: + break; + } + return nullptr; + } + +-static void reflash_ring_buf(Instance *instance) { +- ((CollectorInstance*)instance)->get_interface()->reflash_ring_buf(); ++static void reflash_ring_buf(std::shared_ptr instance) { ++ (std::dynamic_pointer_cast(instance))->get_interface()->reflash_ring_buf(); + } + +-void InstanceRunHandler::run_aware(Instance *instance, std::vector &deps) { ++void InstanceRunHandler::run_aware(std::shared_ptr instance, std::vector &deps) { + void *a[MAX_DEPENDENCIES_SIZE]; + for (int i = 0; i < deps.size(); ++i) { +- Instance *ins = memory_store->get_instance(deps[i]); ++ std::shared_ptr ins = memory_store.get_instance(deps[i]); + a[i] = get_ring_buf(ins); + } +- ((ScenarioInstance*)instance)->get_interface()->aware(a, (int)deps.size()); ++ (std::dynamic_pointer_cast(instance))->get_interface()->aware(a, (int)deps.size()); + } + +-void InstanceRunHandler::run_tune(Instance *instance, std::vector &deps) { ++void InstanceRunHandler::run_tune(std::shared_ptr instance, std::vector &deps) { + void *a[MAX_DEPENDENCIES_SIZE]; + for (int i = 0; i < deps.size(); ++i) { +- Instance *ins = memory_store->get_instance(deps[i]); ++ std::shared_ptr ins = memory_store.get_instance(deps[i]); + a[i] = get_ring_buf(ins); + } +- ((TuneInstance*)instance)->get_interface()->tune(a, (int)deps.size()); ++ (std::dynamic_pointer_cast(instance))->get_interface()->tune(a, (int)deps.size()); + } + +-void InstanceRunHandler::insert_instance(Instance *instance) { ++void InstanceRunHandler::insert_instance(std::shared_ptr instance) { + switch (instance->get_type()) { + case PluginType::COLLECTOR: + collector[instance->get_name()] = instance; +- ((CollectorInstance*)instance)->get_interface()->enable(); ++ (std::dynamic_pointer_cast(instance))->get_interface()->enable(); + break; + case PluginType::SCENARIO: + scenario[instance->get_name()] = instance; +- ((ScenarioInstance*)instance)->get_interface()->enable(); ++ (std::dynamic_pointer_cast(instance))->get_interface()->enable(); + break; + case PluginType::TUNE: + tune[instance->get_name()] = instance; +- ((TuneInstance*)instance)->get_interface()->enable(); ++ (std::dynamic_pointer_cast(instance))->get_interface()->enable(); + break; + } + INFO("[PluginManager] " << instance->get_name() << " instance insert into running queue."); + } + +-void InstanceRunHandler::delete_instance(Instance *instance) { ++void InstanceRunHandler::delete_instance(std::shared_ptr instance) { + switch (instance->get_type()) { + case PluginType::COLLECTOR: + collector.erase(instance->get_name()); +- ((CollectorInstance*)instance)->get_interface()->disable(); ++ (std::dynamic_pointer_cast(instance))->get_interface()->disable(); + break; + case PluginType::SCENARIO: + scenario.erase(instance->get_name()); +- ((ScenarioInstance*)instance)->get_interface()->disable(); ++ (std::dynamic_pointer_cast(instance))->get_interface()->disable(); + break; + case PluginType::TUNE: + tune.erase(instance->get_name()); +- ((TuneInstance*)instance)->get_interface()->disable(); ++ (std::dynamic_pointer_cast(instance))->get_interface()->disable(); + break; + } + INFO("[PluginManager] " << instance->get_name() << " instance delete from running queue."); +@@ -89,21 +89,22 @@ void InstanceRunHandler::delete_instance(Instance *instance) { + void InstanceRunHandler::handle_instance() { + InstanceRunMessage msg; + while(this->recv_queue_try_pop(msg)){ +- Instance *instance = msg.get_instance(); ++ std::shared_ptr instance = msg.get_instance(); + switch (msg.get_type()){ + case RunType::ENABLED: +- insert_instance(instance); ++ insert_instance(std::move(instance)); + break; + case RunType::DISABLED: +- delete_instance(instance); ++ delete_instance(std::move(instance)); + break; + } + } + } + + template +-static std::vector get_deps(Instance *instance) { +- std::string deps = ((T*)instance)->get_interface()->get_dep(); ++static std::vector get_deps(std::shared_ptr instance) { ++ std::shared_ptr t_instance = std::dynamic_pointer_cast(instance); ++ std::string deps = (t_instance)->get_interface()->get_dep(); + std::string dep = ""; + std::vector vec; + for (int i = 0; i < deps.length(); ++i) { +@@ -129,11 +130,11 @@ void InstanceRunHandler::adjust_collector_queue(const std::vector & + if (ok) continue; + if (flag) { + if (is_instance_exist(m_dep) && !collector.count(m_dep)) { +- this->insert_instance(memory_store->get_instance(m_dep)); ++ this->insert_instance(memory_store.get_instance(m_dep)); + } + } else { + if (is_instance_exist(m_dep) && collector.count(m_dep)) { +- this->delete_instance(memory_store->get_instance(m_dep)); ++ this->delete_instance(memory_store.get_instance(m_dep)); + } + } + } +@@ -146,8 +147,8 @@ void InstanceRunHandler::check_scenario_dependency(const std::vectorget_interface()->get_cycle(); ++ std::shared_ptr instance = p.second; ++ int t = (std::dynamic_pointer_cast(instance))->get_interface()->get_cycle(); + if (time % t != 0) return; + reflash_ring_buf(instance); + } +@@ -155,8 +156,8 @@ void InstanceRunHandler::schedule_collector(uint64_t time) { + + void InstanceRunHandler::schedule_scenario(uint64_t time) { + for (auto &p : scenario) { +- Instance *instance = p.second; +- int t = ((ScenarioInstance*)instance)->get_interface()->get_cycle(); ++ std::shared_ptr instance = p.second; ++ int t = (std::dynamic_pointer_cast(instance))->get_interface()->get_cycle(); + if (time % t != 0) return; + std::vector origin_deps = get_deps(instance); + run_aware(instance, origin_deps); +@@ -167,8 +168,8 @@ void InstanceRunHandler::schedule_scenario(uint64_t time) { + + void InstanceRunHandler::schedule_tune(uint64_t time) { + for (auto &p : tune) { +- Instance *instance = p.second; +- int t = ((TuneInstance*)instance)->get_interface()->get_cycle(); ++ std::shared_ptr instance = p.second; ++ int t = (std::dynamic_pointer_cast(instance))->get_interface()->get_cycle(); + if (time % t != 0) return; + std::vector deps = get_deps(instance); + run_tune(instance, deps); +diff --git a/src/plugin_mgr/instance_run_handler.h b/src/plugin_mgr/instance_run_handler.h +index c9a8dfc..83f9f4a 100644 +--- a/src/plugin_mgr/instance_run_handler.h ++++ b/src/plugin_mgr/instance_run_handler.h +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + enum class RunType { + ENABLED, +@@ -30,30 +31,27 @@ enum class RunType { + class InstanceRunMessage { + public: + InstanceRunMessage() {} +- InstanceRunMessage(RunType type, Instance *instance) : type(type), instance(instance) {} ++ InstanceRunMessage(RunType type, std::shared_ptr instance) : type(type), instance(instance) {} + RunType get_type() { + return type; + } +- Instance* get_instance() { ++ std::shared_ptr get_instance() { + return instance; + } + private: + RunType type; +- Instance *instance; ++ std::shared_ptr instance; + }; + + // A handler to schedule plugin instance + class InstanceRunHandler { + public: +- InstanceRunHandler() : cycle(DEFAULT_CYCLE_SIZE) {} ++ InstanceRunHandler(MemoryStore &memory_store) : memory_store(memory_store), cycle(DEFAULT_CYCLE_SIZE) {} + void run(); + void schedule_collector(uint64_t time); + void schedule_scenario(uint64_t time); + void schedule_tune(uint64_t time); + void handle_instance(); +- void set_memory_store(MemoryStore *memory_store) { +- this->memory_store = memory_store; +- } + void set_cycle(int cycle) { + this->cycle = cycle; + } +@@ -61,7 +59,7 @@ public: + return cycle; + } + bool is_instance_exist(const std::string &name) { +- return memory_store->is_instance_exist(name); ++ return memory_store.is_instance_exist(name); + } + void recv_queue_push(InstanceRunMessage &msg) { + this->recv_queue.push(msg); +@@ -73,18 +71,18 @@ public: + return this->recv_queue.try_pop(msg); + } + private: +- void run_aware(Instance *instance, std::vector &deps); +- void run_tune(Instance *instance, std::vector &deps); +- void delete_instance(Instance *instance); +- void insert_instance(Instance *instance); ++ void run_aware(std::shared_ptr instance, std::vector &deps); ++ void run_tune(std::shared_ptr instance, std::vector &deps); ++ void delete_instance(std::shared_ptr instance); ++ void insert_instance(std::shared_ptr instance); + void adjust_collector_queue(const std::vector &deps, const std::vector &m_deps, bool flag); + void check_scenario_dependency(const std::vector &deps, const std::vector &m_deps); + +- std::unordered_map collector; +- std::unordered_map scenario; +- std::unordered_map tune; ++ std::unordered_map> collector; ++ std::unordered_map> scenario; ++ std::unordered_map> tune; + SafeQueue recv_queue; +- MemoryStore *memory_store; ++ MemoryStore &memory_store; + int cycle; + static const int DEFAULT_CYCLE_SIZE = 10; + static const int MAX_DEPENDENCIES_SIZE = 20; +diff --git a/src/plugin_mgr/main.cpp b/src/plugin_mgr/main.cpp +index 8ec0577..92f48bb 100644 +--- a/src/plugin_mgr/main.cpp ++++ b/src/plugin_mgr/main.cpp +@@ -13,10 +13,25 @@ + + Logger logger; + ++void print_help() { ++ printf("Usage: ./oeaware [path]\n" ++ " ./oeaware --help\n" ++ "Examples:\n" ++ " ./oeaware /etc/oeAware/config.yaml\n"); ++} ++ + int main(int argc, char **argv) { + Config config; + if (argc < 2) { +- ERROR("System need config arg!"); ++ ERROR("System need a argument!"); ++ exit(EXIT_FAILURE); ++ } ++ if (std::string(argv[1]) == "--help") { ++ print_help(); ++ exit(EXIT_SUCCESS); ++ } ++ if (!file_exist(argv[1])) { ++ ERROR("Config file " << argv[1] << " does not exist!"); + exit(EXIT_FAILURE); + } + std::string config_path(argv[1]); +@@ -36,8 +51,8 @@ int main(int argc, char **argv) { + message_manager.init(&config); + message_manager.run(); + INFO("[PluginManager] Start plugin manager!"); +- PluginManager plugin_manager(&handler_msg, &res_msg); +- plugin_manager.init(&config); ++ PluginManager plugin_manager(config, handler_msg, res_msg); ++ plugin_manager.init(); + plugin_manager.pre_load(); + plugin_manager.run(); + return 0; +diff --git a/src/plugin_mgr/memory_store.h b/src/plugin_mgr/memory_store.h +index 190fcdd..ac3ff98 100644 +--- a/src/plugin_mgr/memory_store.h ++++ b/src/plugin_mgr/memory_store.h +@@ -14,29 +14,27 @@ + #include "plugin.h" + #include "logger.h" + #include ++#include + + //OeAware memory storage, which is used to store plugins and instances in the memory. + class MemoryStore { + public: +- void add_plugin(const std::string &name, Plugin *plugin) { ++ void add_plugin(const std::string &name, std::shared_ptr plugin) { + this->plugins.insert(std::make_pair(name, plugin)); + } +- void add_instance(const std::string &name, Instance *instance) { ++ void add_instance(const std::string &name, std::shared_ptr instance) { + this->instances.insert(std::make_pair(name, instance)); + } +- Plugin* get_plugin(const std::string &name) const { ++ std::shared_ptr get_plugin(const std::string &name) const { + return this->plugins.at(name); + } +- Instance* get_instance(const std::string &name) const { ++ std::shared_ptr get_instance(const std::string &name) const { + return this->instances.at(name); + } + void delete_plugin(const std::string &name) { +- Plugin *plugin = plugins.at(name); + this->plugins.erase(name); +- delete plugin; + } + void delete_instance(const std::string &name) { +- Instance *instance = instances.at(name); + this->instances.erase(name); + } + bool is_plugin_exist(const std::string &name) const { +@@ -45,23 +43,23 @@ public: + bool is_instance_exist(const std::string &name) const { + return this->instances.count(name); + } +- std::vector get_all_plugins() { +- std::vector res; ++ std::vector> get_all_plugins() { ++ std::vector> res; + for (auto &p : plugins) { + res.emplace_back(p.second); + } + return res; + } +- std::vector get_all_instances() { +- std::vector res; ++ std::vector> get_all_instances() { ++ std::vector> res; + for (auto &p : instances) { + res.emplace_back(p.second); + } + return res; + } + private: +- std::unordered_map plugins; +- std::unordered_map instances; ++ std::unordered_map> plugins; ++ std::unordered_map> instances; + }; + + #endif // !PLUGIN_MGR_MEMORY_STORE_H +diff --git a/src/plugin_mgr/message_manager.cpp b/src/plugin_mgr/message_manager.cpp +index 296c682..e2fd3b6 100644 +--- a/src/plugin_mgr/message_manager.cpp ++++ b/src/plugin_mgr/message_manager.cpp +@@ -68,7 +68,6 @@ static void recv_msg(Msg &msg, MessageHeader &header, SafeQueue *res_ms + for (int i = 0; i < res.get_payload_len(); ++i) { + msg.add_payload(res.get_payload(i)); + } +- header.set_state_code(res.get_state_code()); + } + + void TcpSocket::serve_accept(SafeQueue *handler_msg, SafeQueue *res_msg){ +diff --git a/src/plugin_mgr/message_manager.h b/src/plugin_mgr/message_manager.h +index d1faad3..4cd7311 100644 +--- a/src/plugin_mgr/message_manager.h ++++ b/src/plugin_mgr/message_manager.h +@@ -28,7 +28,7 @@ enum class MessageType { + + class Message { + public: +- Message() : type(MessageType::EXTERNAL), state_code(HEADER_STATE_OK) {} ++ Message() : type(MessageType::EXTERNAL) {} + Message(Opt opt) : opt(opt) {} + Message(Opt opt, MessageType type) : opt(opt), type(type) {} + Message(Opt opt, std::vector payload) : opt(opt), payload(payload) {} +@@ -53,16 +53,9 @@ public: + int get_payload_len() const { + return this->payload.size(); + } +- void set_state_code(int code) { +- this->state_code = code; +- } +- int get_state_code() const { +- return this->state_code; +- } + private: + Opt opt; + MessageType type; +- int state_code; + std::vector payload; + }; + +diff --git a/src/plugin_mgr/plugin.h b/src/plugin_mgr/plugin.h +index 11b4748..69837af 100644 +--- a/src/plugin_mgr/plugin.h ++++ b/src/plugin_mgr/plugin.h +@@ -14,6 +14,7 @@ + #include "interface.h" + #include + #include ++#include + #include + + enum class PluginType { +@@ -122,11 +123,8 @@ private: + class Plugin { + public: + Plugin(std::string name, PluginType type) : name(name), type(type), handler(nullptr) { } +- ~Plugin() { +- for (int i = 0; i < instances.size(); ++i) { +- delete instances[i]; +- } +- dlclose(this->handler); ++ ~Plugin() { ++ dlclose(handler); + } + int load(const std::string dl_path); + std::string get_name() const { +@@ -135,21 +133,21 @@ public: + PluginType get_type() const { + return this->type; + } +- void add_instance(Instance *ins) { ++ void add_instance(std::shared_ptr ins) { + instances.emplace_back(ins); + } +- Instance* get_instance(int i) const { ++ std::shared_ptr get_instance(int i) const { + return instances[i]; + } + size_t get_instance_len() const { + return instances.size(); + } +- void * get_handler() const { ++ void* get_handler() const { + return handler; + } + private: + void *handler; +- std::vector instances; ++ std::vector> instances; + PluginType type; + std::string name; + }; +diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp +index 47f9451..e7e32bf 100644 +--- a/src/plugin_mgr/plugin_manager.cpp ++++ b/src/plugin_mgr/plugin_manager.cpp +@@ -21,61 +21,64 @@ const std::string PluginManager::SCENARIO_TEXT = "scenario"; + const std::string PluginManager::TUNE_TEXT = "tune"; + const static int ST_MODE_MASK = 0777; + +-void PluginManager::init(Config *config) { ++void PluginManager::init() { + plugin_types[COLLECTOR_TEXT] = PluginType::COLLECTOR; + plugin_types[SCENARIO_TEXT] = PluginType::SCENARIO; + plugin_types[TUNE_TEXT] = PluginType::TUNE; +- this->config = config; + } + +-bool PluginManager::remove(const std::string &name) { +- if (!memory_store.is_plugin_exist(name)) return false; +- Plugin *plugin = memory_store.get_plugin(name); ++ErrorCode PluginManager::remove(const std::string &name) { ++ if (!memory_store.is_plugin_exist(name)) { ++ return ErrorCode::REMOVE_PLUGIN_NOT_EXIST; ++ } ++ std::shared_ptr plugin = memory_store.get_plugin(name); + std::vector instance_names; + for (int i = 0; i < plugin->get_instance_len(); ++i) { +- Instance *instance = plugin->get_instance(i); ++ std::shared_ptr instance = plugin->get_instance(i); + std::string iname = instance->get_name(); +- if (dep_handler->have_dep(iname)) { +- return false; ++ if (instance->get_enabled()) { ++ return ErrorCode::REMOVE_INSTANCE_IS_RUNNING; ++ } ++ if (dep_handler.have_dep(iname)) { ++ return ErrorCode::REMOVE_INSTANCE_HAVE_DEP; + } + instance_names.emplace_back(iname); + } + for(auto &iname : instance_names) { + memory_store.delete_instance(iname); +- dep_handler->del_node(iname); ++ dep_handler.del_node(iname); + } + memory_store.delete_plugin(name); + update_instance_state(); +- return true; ++ return ErrorCode::OK; + } +-bool PluginManager::query_all_plugins(Message &res) { +- std::vector all_plugins = memory_store.get_all_plugins(); ++ErrorCode PluginManager::query_all_plugins(std::string &res) { ++ std::vector> all_plugins = memory_store.get_all_plugins(); + for (auto &p : all_plugins) { +- res.add_payload(p->get_name()); ++ res += p->get_name() + "\n"; + for (int i = 0; i < p->get_instance_len(); ++i) { + std::string info = p->get_instance(i)->get_info(); +- res.add_payload(" " + info); ++ res += "\t" + info + "\n"; + } + } +- return 1; ++ return ErrorCode::OK; + } + +-bool PluginManager::query_plugin(std::string name, Message &res) { ++ErrorCode PluginManager::query_plugin(const std::string &name, std::string &res) { + if (!memory_store.is_plugin_exist(name)) { +- res.add_payload("no such plugin!"); +- return true; ++ return ErrorCode::QUERY_PLUGIN_NOT_EXIST; + } +- Plugin *plugin = memory_store.get_plugin(name); +- res.add_payload(name); ++ std::shared_ptr plugin = memory_store.get_plugin(name); ++ res += name + "\n"; + for (int i = 0; i < plugin->get_instance_len(); ++i) { + std::string info = plugin->get_instance(i)->get_info(); +- res.add_payload(" " + info); ++ res += "\t" + info + "\n"; + } +- return true; ++ return ErrorCode::OK; + } + + template +-int PluginManager::load_dl_instance(Plugin *plugin, T **interface_list) { ++int PluginManager::load_dl_instance(std::shared_ptr plugin, T **interface_list) { + int (*get_instance)(T**) = (int(*)(T**))dlsym(plugin->get_handler(), "get_instance"); + if (get_instance == nullptr) { + ERROR("[PluginManager] dlsym error!\n"); +@@ -105,11 +108,11 @@ std::vector get_dep(T *interface) { + } + + template +-void PluginManager::save_instance(Plugin *plugin, T *interface_list, int len) { ++void PluginManager::save_instance(std::shared_ptr plugin, T *interface_list, int len) { + if (interface_list == nullptr) return; + for (int i = 0; i < len; ++i) { + T *interface = interface_list + i; +- Instance *instance = new U(); ++ std::shared_ptr instance = std::make_shared(); + std::string name = interface->get_name(); + instance->set_name(name); + instance->set_plugin_name(plugin->get_name()); +@@ -117,19 +120,19 @@ void PluginManager::save_instance(Plugin *plugin, T *interface_list, int len) { + instance->set_enabled(false); + if (plugin->get_type() == PluginType::COLLECTOR) { + DEBUG("[PluginManager] add node"); +- dep_handler->add_node(name); ++ dep_handler.add_node(name); + } else { +- dep_handler->add_node(name, get_dep(interface)); ++ dep_handler.add_node(name, get_dep(interface)); + } +- instance->set_state(dep_handler->get_node_state(name)); +- ((U*)instance)->set_interface(interface); ++ instance->set_state(dep_handler.get_node_state(name)); ++ (std::dynamic_pointer_cast(instance))->set_interface(interface); + DEBUG("[PluginManager] Instance: " << name.c_str()); + memory_store.add_instance(name, instance); + plugin->add_instance(instance); + } + } + +-bool PluginManager::load_instance(Plugin *plugin) { ++bool PluginManager::load_instance(std::shared_ptr plugin) { + int len = 0; + DEBUG("plugin: " << plugin->get_name()); + switch (plugin->get_type()) { +@@ -160,9 +163,9 @@ bool PluginManager::load_instance(Plugin *plugin) { + } + + void PluginManager::update_instance_state() { +- std::vector all_instances = memory_store.get_all_instances(); ++ std::vector> all_instances = memory_store.get_all_instances(); + for (auto &instance : all_instances) { +- if (dep_handler->get_node_state(instance->get_name())) { ++ if (dep_handler.get_node_state(instance->get_name())) { + instance->set_state(true); + } else { + instance->set_state(false); +@@ -170,24 +173,28 @@ void PluginManager::update_instance_state() { + } + } + +-bool PluginManager::load_plugin(const std::string name, PluginType type) { ++ErrorCode PluginManager::load_plugin(const std::string name, PluginType type) { ++ std::string plugin_path = get_path(type) + "/" + name; ++ if (!file_exist(plugin_path)) { ++ return ErrorCode::LOAD_PLUGIN_FILE_NOT_EXIST; ++ } ++ if (!check_permission(plugin_path, S_IRUSR | S_IRGRP)) { ++ return ErrorCode::LOAD_PLUGIN_FILE_PERMISSION_DEFINED; ++ } + if (memory_store.is_plugin_exist(name)) { +- WARN("[PluginManager] " << name << " already loaded!"); +- return false; ++ return ErrorCode::LOAD_PLUGIN_EXIST; + } + const std::string dl_path = get_path(type) + '/' + name; +- Plugin *plugin = new Plugin(name, type); ++ std::shared_ptr plugin = std::make_shared(name, type); + int error = plugin->load(dl_path); + if (error) { +- WARN("[PluginManager] " << name << " load error!"); +- return false; ++ return ErrorCode::LOAD_PLUGIN_DLOPEN_FAILED; + } + if (!this->load_instance(plugin)) { +- delete plugin; +- return false; ++ return ErrorCode::LOAD_PLUGIN_DLSYM_FAILED; + } + memory_store.add_plugin(name, plugin); +- return true; ++ return ErrorCode::OK; + } + + std::string generate_dot(MemoryStore &memory_store, const std::vector> &query) { +@@ -195,7 +202,7 @@ std::string generate_dot(MemoryStore &memory_store, const std::vector> sub_graph; + for (auto &vec : query) { +- Instance *instance = memory_store.get_instance(vec[0]); ++ std::shared_ptr instance = memory_store.get_instance(vec[0]); + sub_graph[instance->get_plugin_name()].emplace_back(vec[0]); + if (vec.size() == 1) { + continue; +@@ -219,47 +226,37 @@ std::string generate_dot(MemoryStore &memory_store, const std::vector> query; +- dep_handler->query_node(name, query); +- if (query.empty()) { +- res.add_payload("Instance not available!"); +- return false; +- } +- std::string dot_text = generate_dot(memory_store, query); +- res.add_payload(dot_text); +- return true; ++ dep_handler.query_node(name, query); ++ res = generate_dot(memory_store, query); ++ return ErrorCode::OK; + } + +-bool PluginManager::query_all_tops(Message &res) { ++ErrorCode PluginManager::query_all_tops(std::string &res) { + std::vector> query; +- dep_handler->query_all_top(query); ++ dep_handler.query_all_top(query); + DEBUG("[PluginManager] query size:" << query.size()); +- if (query.empty()) { +- res.add_payload("No instance available!"); +- return false; +- } +- std::string dot_text = generate_dot(memory_store, query); +- res.add_payload(dot_text); +- return true; ++ res = generate_dot(memory_store, query); ++ return ErrorCode::OK; + } + +-bool PluginManager::instance_enabled(std::string name) { ++ErrorCode PluginManager::instance_enabled(std::string name) { + if (!memory_store.is_instance_exist(name)) { +- WARN("[PluginManager] " << name << " instance can't load!"); +- return false; ++ return ErrorCode::ENABLE_INSTANCE_NOT_LOAD; + } +- Instance *instance = memory_store.get_instance(name); ++ std::shared_ptr instance = memory_store.get_instance(name); + if (!instance->get_state()) { +- WARN("[PluginManager] " << name << " instance is unavailable, lacking dependencies!"); +- return false; ++ return ErrorCode::ENABLE_INSTANCE_UNAVAILABLE; + } + if (instance->get_enabled()) { +- WARN("[PluginManager] " << name << " instance was enabled!"); +- return false; ++ return ErrorCode::ENABLE_INSTANCE_ALREADY_ENABLED; + } +- std::vector pre_dependencies = dep_handler->get_pre_dependencies(name); ++ std::vector pre_dependencies = dep_handler.get_pre_dependencies(name); + for (int i = pre_dependencies.size() - 1; i >= 0; --i) { + instance = memory_store.get_instance(pre_dependencies[i]); + if (instance->get_enabled()) { +@@ -267,29 +264,25 @@ bool PluginManager::instance_enabled(std::string name) { + } + instance->set_enabled(true); + instance_run_handler->recv_queue_push(InstanceRunMessage(RunType::ENABLED, instance)); +- INFO("[PluginManager] " << name << " instance enabled!"); ++ DEBUG("[PluginManager] " << instance->get_name() << " instance enabled."); + } +- return true; ++ return ErrorCode::OK; + } + +-bool PluginManager::instance_disabled(std::string name) { ++ErrorCode PluginManager::instance_disabled(std::string name) { + if (!memory_store.is_instance_exist(name)) { +- WARN("[PluginManager] " << name << " instance can't load!"); +- return false; ++ return ErrorCode::DISABLE_INSTANCE_NOT_LOAD; + } +- Instance *instance = memory_store.get_instance(name); ++ std::shared_ptr instance = memory_store.get_instance(name); + if (!instance->get_state()) { +- WARN("[PluginManager] " << name << " instance is unavailable, lacking dependencies!"); +- return false; ++ return ErrorCode::DISABLE_INSTANCE_UNAVAILABLE; + } + if (!instance->get_enabled()) { +- WARN("[PluginManager] " << name << " instance was disabled!"); +- return false; ++ return ErrorCode::DISABLE_INSTANCE_ALREADY_DISABLED; + } + instance->set_enabled(false); + instance_run_handler->recv_queue_push(InstanceRunMessage(RunType::DISABLED, instance)); +- INFO("[PluginManager] " << name << " instance disabled!"); +- return true; ++ return ErrorCode::OK; + } + + static bool end_with(const std::string &s, const std::string &ending) { +@@ -320,30 +313,46 @@ static std::string get_plugin_in_dir(const std::string &path) { + return res; + } + +-void PluginManager::add_list(Message &res) { +- std::string list_text; +- list_text += "Download Packages:\n"; +- for (int i = 0; i < config->get_plugin_list_size(); ++i) { +- PluginInfo info = config->get_plugin_list(i); +- list_text += info.get_name() + "\n"; ++ErrorCode PluginManager::add_list(std::string &res) { ++ res += "Download Packages:\n"; ++ for (int i = 0; i < config.get_plugin_list_size(); ++i) { ++ PluginInfo info = config.get_plugin_list(i); ++ res += info.get_name() + "\n"; + } +- list_text += "Installed Plugins:\n"; +- list_text += get_plugin_in_dir(DEFAULT_COLLECTOR_PATH); +- list_text += get_plugin_in_dir(DEFAULT_SCENARIO_PATH); +- list_text += get_plugin_in_dir(DEFAULT_TUNE_PATH); +- res.add_payload(list_text); ++ res += "Installed Plugins:\n"; ++ res += get_plugin_in_dir(DEFAULT_COLLECTOR_PATH); ++ res += get_plugin_in_dir(DEFAULT_SCENARIO_PATH); ++ res += get_plugin_in_dir(DEFAULT_TUNE_PATH); ++ return ErrorCode::OK; ++} ++ ++ErrorCode PluginManager::download(const std::string &name, std::string &res) { ++ std::string url; ++ std::string type; ++ for (int i = 0; i < config.get_plugin_list_size(); ++i) { ++ PluginInfo info = config.get_plugin_list(i); ++ if (info.get_name() == name) { ++ url = info.get_url(); ++ break; ++ } ++ } ++ if (url.empty()) { ++ return ErrorCode::DOWNLOAD_NOT_FOUND; ++ } ++ res += url; ++ return ErrorCode::OK; + } + + void PluginManager::pre_enable() { +- for (int i = 0; i < config->get_enable_list_size(); ++i) { +- EnableItem item = config->get_enable_list(i); ++ for (int i = 0; i < config.get_enable_list_size(); ++i) { ++ EnableItem item = config.get_enable_list(i); + if (item.get_enabled()) { + std::string name = item.get_name(); + if (!memory_store.is_plugin_exist(name)) { + WARN("[PluginManager] plugin " << name << " cannot be enabled, because it does not exist."); + continue; + } +- Plugin *plugin = memory_store.get_plugin(name); ++ std::shared_ptr plugin = memory_store.get_plugin(name); + for (int j = 0; j < plugin->get_instance_len(); ++j) { + instance_enabled(plugin->get_instance(i)->get_name()); + } +@@ -373,19 +382,15 @@ void PluginManager::pre_load() { + pre_enable(); + } + +-static bool check_load_msg(Message &msg, std::unordered_map &plugin_types) { +- return msg.get_payload_len() == 2 && plugin_types.count(msg.get_payload(1)); +-} +- + void* PluginManager::get_data_buffer(std::string name) { +- Instance *instance = memory_store.get_instance(name); ++ std::shared_ptr instance = memory_store.get_instance(name); + switch (instance->get_type()) { + case PluginType::COLLECTOR: { +- CollectorInterface *collector_interface = ((CollectorInstance*)instance)->get_interface(); ++ CollectorInterface *collector_interface = (std::dynamic_pointer_cast(instance))->get_interface(); + return collector_interface->get_ring_buf(); + } + case PluginType::SCENARIO: { +- ScenarioInterface *scenario_interface = ((ScenarioInstance*)instance)->get_interface(); ++ ScenarioInterface *scenario_interface = (std::dynamic_pointer_cast(instance))->get_interface(); + return scenario_interface->get_ring_buf(); + } + default: +@@ -394,12 +399,13 @@ void* PluginManager::get_data_buffer(std::string name) { + return nullptr; + } + +-void PluginManager::instance_dep_check(std::string name, Message &res) { +- Plugin *plugin = memory_store.get_plugin(name); ++std::string PluginManager::instance_dep_check(const std::string &name) { ++ std::shared_ptr plugin = memory_store.get_plugin(name); ++ std::string res; + for (int i = 0; i < plugin->get_instance_len(); ++i) { + std::string instance_name = plugin->get_instance(i)->get_name(); + std::vector> query; +- dep_handler->query_node(instance_name, query); ++ dep_handler.query_node(instance_name, query); + std::vector lack; + for (auto &item : query) { + if (item.size() < 2) continue; +@@ -408,13 +414,13 @@ void PluginManager::instance_dep_check(std::string name, Message &res) { + } + } + if (!lack.empty()) { +- std::string info = instance_name + " needed the following dependencies:"; +- for (auto &dep : lack) { +- info += "\n " + dep; ++ for (int i = 0; i < lack.size(); ++i) { ++ res += "\t" + lack[i]; ++ if (i != lack.size() - 1) res += '\n'; + } +- res.add_payload(info); + } + } ++ return res; + } + + // Check the file permission. The file owner is root. +@@ -429,76 +435,110 @@ bool check_permission(std::string path, int mode) { + return true; + } + +-static bool file_exist(const std::string &file_name) { ++bool file_exist(const std::string &file_name) { + std::ifstream file(file_name); + return file.good(); + } + + int PluginManager::run() { +- instance_run_handler->set_memory_store(&memory_store); + instance_run_handler->run(); + while (true) { + Message msg; + Message res; +- res.set_opt(Opt::RESPONSE); +- this->handler_msg->wait_and_pop(msg); ++ this->handler_msg.wait_and_pop(msg); + if (msg.get_opt() == Opt::SHUTDOWN) break; + switch (msg.get_opt()) { + case Opt::LOAD: { +- if (!check_load_msg(msg, plugin_types)) { +- WARN("[PluginManager] args error!"); +- res.add_payload("args error!"); +- break; +- } + std::string plugin_name = msg.get_payload(0); + PluginType type = plugin_types[msg.get_payload(1)]; +- std::string plugin_path = get_path(type) + "/" + plugin_name; + if (!end_with(plugin_name, ".so")) break; +- if (!file_exist(plugin_path)) { +- WARN("[PluginManager] plugin " << plugin_name << " does not exist!"); +- res.add_payload("plugin does not exist!"); +- break; +- } +- if (!check_permission(plugin_path, S_IRUSR | S_IRGRP)) { +- WARN("[PluginManager] plugin " << plugin_name << " does not have the execute permission!"); +- res.add_payload("does not have the execute permission!"); +- break; +- } +- if(this->load_plugin(plugin_name, type)) { +- INFO("[PluginManager] plugin " << plugin_name << " loaded."); +- res.add_payload("plugin load succeed!"); +- instance_dep_check(plugin_name, res); +- DEBUG("[PluginManager] instance dependency checked!"); ++ ErrorCode ret_code = load_plugin(plugin_name, type); ++ if(ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] " << plugin_name << "plugin loaded."); ++ res.set_opt(Opt::RESPONSE_OK); ++ std::string lack_dep = instance_dep_check(plugin_name); ++ if (!lack_dep.empty()) { ++ INFO("[PluginManager] " << plugin_name << " requires the following dependencies:\n" << lack_dep); ++ res.add_payload(lack_dep); ++ } + } else { +- INFO("[PluginManager] plugin " << plugin_name << " load error!"); +- res.add_payload("plugin load failed!"); ++ WARN("[PluginManager] " << plugin_name << " " << ErrorText::get_error_text(ret_code) << "."); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); + } + break; + } + case Opt::REMOVE: { + std::string name = msg.get_payload(0); +- if (remove(name)) { +- res.add_payload(name + " removed!"); +- INFO("[PluginManager] " << name << " removed!"); ++ ErrorCode ret_code = remove(name); ++ if (ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] " << name << " plugin removed."); ++ res.set_opt(Opt::RESPONSE_OK); + } else { +- res.add_payload(name + " remove failed!"); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); ++ INFO("[PluginManager] " << name << " " << ErrorText::get_error_text(ret_code) + "."); + } + break; + } + case Opt::QUERY_ALL: { +- query_all_plugins(res); ++ std::string res_text; ++ ErrorCode ret_code = query_all_plugins(res_text); ++ if (ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] query all plugins information."); ++ res.set_opt(Opt::RESPONSE_OK); ++ res.add_payload(res_text); ++ } else { ++ WARN("[PluginManager] query all plugins failed, because " << ErrorText::get_error_text(ret_code) + "."); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); ++ } + break; + } + case Opt::QUERY: { +- query_plugin(msg.get_payload(0), res); ++ std::string res_text; ++ std::string name = msg.get_payload(0); ++ ErrorCode ret_code = query_plugin(name, res_text); ++ if (ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] " << name << " plugin query successfully."); ++ res.set_opt(Opt::RESPONSE_OK); ++ res.add_payload(res_text); ++ } else { ++ WARN("[PluginManager] " << name << " " << ErrorText::get_error_text(ret_code) + "."); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); ++ } + break; + } + case Opt::QUERY_TOP: { +- query_top(msg.get_payload(0), res); ++ std::string res_text; ++ std::string name = msg.get_payload(0); ++ ErrorCode ret_code = query_top(name , res_text); ++ if (ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] query " << name << " instance dependencies."); ++ res.set_opt(Opt::RESPONSE_OK); ++ res.add_payload(res_text); ++ } else { ++ WARN("[PluginManager] query "<< name << " instance dependencies failed, because " ++ << ErrorText::get_error_text(ret_code) << "."); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); ++ } + break; + } + case Opt::QUERY_ALL_TOP: { +- query_all_tops(res); ++ std::string res_text; ++ ErrorCode ret_code = query_all_tops(res_text); ++ if (ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] query all instances dependencies."); ++ res.set_opt(Opt::RESPONSE_OK); ++ res.add_payload(res_text); ++ } else { ++ WARN("[PluginManager] query all instances dependencies failed. because " ++ << ErrorText::get_error_text(ret_code) << "."); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); ++ } + break; + } + case Opt::ENABLED: { +@@ -508,10 +548,15 @@ int PluginManager::run() { + break; + } + std::string instance_name = msg.get_payload(0); +- if (instance_enabled(instance_name)) { +- res.add_payload("instance enabled!"); ++ ErrorCode ret_code = instance_enabled(instance_name); ++ if (ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] " << instance_name << " enabled successful."); ++ res.set_opt(Opt::RESPONSE_OK); + } else { +- res.add_payload("instance enabled failed!"); ++ WARN("[PluginManager] " << instance_name << " enabled failed. because " ++ << ErrorText::get_error_text(ret_code) + "."); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); + } + break; + } +@@ -522,42 +567,50 @@ int PluginManager::run() { + break; + } + std::string instance_name = msg.get_payload(0); +- if (instance_disabled(instance_name)) { +- res.add_payload("instance disabled!"); ++ ErrorCode ret_code = instance_disabled(instance_name); ++ if (ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] " << instance_name << " disabled successful."); ++ res.set_opt(Opt::RESPONSE_OK); + } else { +- res.add_payload("instance disabled failed!"); ++ WARN("[PluginManager] " << instance_name << " " << ErrorText::get_error_text(ret_code) << "."); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); + } + break; + } + case Opt::LIST: { +- add_list(res); ++ std::string res_text; ++ ErrorCode ret_code = add_list(res_text); ++ if (ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] query plugin_list."); ++ res.set_opt(Opt::RESPONSE_OK); ++ res.add_payload(res_text); ++ } else { ++ WARN("[PluginManager] query plugin_list failed, because " << ErrorText::get_error_text(ret_code) << "."); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); ++ } + break; + } + case Opt::DOWNLOAD: { ++ std::string res_text; + std::string name = msg.get_payload(0); +- std::string url = ""; +- std::string type = ""; +- for (int i = 0; i < config->get_plugin_list_size(); ++i) { +- PluginInfo info = config->get_plugin_list(i); +- if (info.get_name() == name) { +- url = info.get_url(); +- break; +- } +- } +- if (url.empty()) { +- WARN("[PluginManager] unable to find a match: " << name); +- res.set_state_code(HEADER_STATE_FAILED); +- res.add_payload("unable to find a match: " + name); +- break; ++ ErrorCode ret_code = download(name, res_text); ++ if (ret_code == ErrorCode::OK) { ++ INFO("[PluginManager] download " << name << " from " << res_text << "."); ++ res.set_opt(Opt::RESPONSE_OK); ++ res.add_payload(res_text); ++ } else { ++ WARN("[PluginManager] download " << name << " failed, because " << ErrorText::get_error_text(ret_code) + "."); ++ res.set_opt(Opt::RESPONSE_ERROR); ++ res.add_payload(ErrorText::get_error_text(ret_code)); + } +- res.add_payload(url); +- INFO("[PluginManager] download " << name << " from " << url << "."); + } + default: + break; + } + if (msg.get_type() == MessageType::EXTERNAL) +- res_msg->push(res); ++ res_msg.push(res); + } + return 0; + } +diff --git a/src/plugin_mgr/plugin_manager.h b/src/plugin_mgr/plugin_manager.h +index f648931..8d240cc 100644 +--- a/src/plugin_mgr/plugin_manager.h ++++ b/src/plugin_mgr/plugin_manager.h +@@ -17,6 +17,7 @@ + #include "memory_store.h" + #include "dep_handler.h" + #include "message_manager.h" ++#include "error_code.h" + #include + #include + #include +@@ -24,45 +25,43 @@ + + class PluginManager { + public: +- PluginManager(SafeQueue *handler_msg, SafeQueue *res_msg) { +- this->handler_msg = handler_msg; +- this->res_msg = res_msg; +- dep_handler = new DepHandler(); +- instance_run_handler = new InstanceRunHandler(); +- } +- ~PluginManager() { } ++ PluginManager(Config &config, SafeQueue &handler_msg, SafeQueue &res_msg) : ++ config(config), handler_msg(handler_msg), res_msg(res_msg) { ++ instance_run_handler.reset(new InstanceRunHandler(memory_store)); ++ } + int run(); + void pre_load(); + void pre_enable(); +- void init(Config *config); ++ void init(); + void* get_data_buffer(std::string name); + private: + void pre_load_plugin(PluginType type); +- bool query_all_plugins(Message &res); +- bool query_plugin(std::string name, Message &res); +- bool query_top(std::string name, Message &res); +- bool query_all_tops(Message &res); +- bool instance_enabled(std::string name); +- bool instance_disabled(std::string name); +- void instance_dep_check(std::string name, Message &res); ++ ErrorCode load_plugin(const std::string path, PluginType type); ++ ErrorCode remove(const std::string &name); ++ ErrorCode query_all_plugins(std::string &res); ++ ErrorCode query_plugin(const std::string &name, std::string &res); ++ ErrorCode query_top(const std::string &name, std::string &res); ++ ErrorCode query_all_tops(std::string &res); ++ ErrorCode instance_enabled(std::string name); ++ ErrorCode instance_disabled(std::string name); ++ ErrorCode add_list(std::string &res); ++ ErrorCode download(const std::string &name, std::string &res); ++ std::string instance_dep_check(const std::string &name); + template +- int load_dl_instance(Plugin *plugin, T **interface_list); ++ int load_dl_instance(std::shared_ptr plugin, T **interface_list); + template +- void save_instance(Plugin *plugin, T *interface_list, int len); +- bool load_instance(Plugin *plugin); +- bool load_plugin(const std::string path, PluginType type); ++ void save_instance(std::shared_ptr plugin, T *interface_list, int len); ++ bool load_instance(std::shared_ptr plugin); + void batch_load(); +- bool remove(const std::string &name); + void batch_remove(); +- void add_list(Message &msg); + void update_instance_state(); + private: +- InstanceRunHandler *instance_run_handler; +- Config *config; +- SafeQueue *handler_msg; +- SafeQueue *res_msg; ++ std::unique_ptr instance_run_handler; ++ Config &config; ++ SafeQueue &handler_msg; ++ SafeQueue &res_msg; + MemoryStore memory_store; +- DepHandler *dep_handler; ++ DepHandler dep_handler; + std::unordered_map plugin_types; + static const std::string COLLECTOR_TEXT; + static const std::string SCENARIO_TEXT; +@@ -70,5 +69,5 @@ private: + }; + + bool check_permission(std::string path, int mode); +- +-#endif ++bool file_exist(const std::string &file_name); ++#endif +-- +2.33.0 + diff --git a/0003-add-client-error-description-extract-class-and-fix-b.patch b/0003-add-client-error-description-extract-class-and-fix-b.patch new file mode 100644 index 0000000..a8187b8 --- /dev/null +++ b/0003-add-client-error-description-extract-class-and-fix-b.patch @@ -0,0 +1,1034 @@ +From 72ec3921622e81b1faf0adda88cb40aa63bb4504 Mon Sep 17 00:00:00 2001 +From: fly_1997 +Date: Sun, 28 Apr 2024 20:13:37 +0800 +Subject: [PATCH 3/4] add client error description, extract class, and fix bugs + +--- + oeAware.service => oeaware.service | 0 + src/client/arg_parse.cpp | 104 ++++++++++++++++++ + src/client/arg_parse.h | 37 +++++++ + src/client/client.cpp | 92 +++------------- + src/client/client.h | 15 ++- + src/client/cmd_handler.cpp | 165 ++++++++++++++++------------- + src/client/cmd_handler.h | 38 +++---- + src/client/main.cpp | 10 +- + src/common/utils.cpp | 38 ++++--- + src/plugin_mgr/config.cpp | 29 ++++- + src/plugin_mgr/config.h | 27 ++++- + src/plugin_mgr/error_code.cpp | 1 + + src/plugin_mgr/error_code.h | 1 + + src/plugin_mgr/plugin_manager.cpp | 33 +++--- + src/plugin_mgr/plugin_manager.h | 4 +- + 15 files changed, 363 insertions(+), 231 deletions(-) + rename oeAware.service => oeaware.service (100%) + create mode 100644 src/client/arg_parse.cpp + create mode 100644 src/client/arg_parse.h + +diff --git a/oeAware.service b/oeaware.service +similarity index 100% +rename from oeAware.service +rename to oeaware.service +diff --git a/src/client/arg_parse.cpp b/src/client/arg_parse.cpp +new file mode 100644 +index 0000000..cbf0b8e +--- /dev/null ++++ b/src/client/arg_parse.cpp +@@ -0,0 +1,104 @@ ++/****************************************************************************** ++ * Copyright (c) 2024 Huawei Technologies Co., Ltd. ++ * oeAware is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ ******************************************************************************/ ++#include "arg_parse.h" ++#include ++#include ++ ++const std::string ArgParse::OPT_STRING = "Qqd:t:l:r:e:"; ++const struct option ArgParse::long_options[] = { ++ {"help", no_argument, NULL, 'h'}, ++ {"load", required_argument, NULL, 'l'}, ++ {"type", required_argument, NULL, 't'}, ++ {"remove", required_argument, NULL, 'r'}, ++ {"query", required_argument, NULL, 'q'}, ++ {"query-dep", required_argument, NULL, 'Q'}, ++ {"enable", required_argument, NULL, 'e'}, ++ {"disable", required_argument, NULL, 'd'}, ++ {"list", no_argument, NULL, 'L'}, ++ {"install", required_argument, NULL, 'i'}, ++ {0, 0, 0, 0}, ++}; ++ ++void ArgParse::arg_error(const std::string &msg) { ++ std::cerr << "oeawarectl: " << msg << "\n"; ++ exit(EXIT_FAILURE); ++} ++ ++void ArgParse::set_type(char *_type) { ++ type = _type; ++} ++ ++void ArgParse::set_arg(char *_arg) { ++ arg = std::string(_arg); ++} ++ ++void ArgParse::print_help() { ++ std::cout << "oeawarectl [options]...\n" ++ " options\n" ++ " -l|--load [plugin] load plugin and need plugin type.\n" ++ " -t|--type [plugin_type] assign plugin type. there are three types:\n" ++ " collector: collection plugin.\n" ++ " scenario: awareness plugin.\n" ++ " tune: tune plugin.\n" ++ " -r|--remove [plugin] remove plugin from system.\n" ++ " -e|--enable [instance] enable the plugin instance.\n" ++ " -d|--disable [instance] disable the plugin instance.\n" ++ " -q query all plugins information.\n" ++ " --query [plugin] query the plugin information.\n" ++ " -Q query all instances dependencies.\n" ++ " --query-dep [instance] query the instance dependency.\n" ++ " --list the list of supported plugins.\n" ++ " --install [plugin] install plugin from the list.\n" ++ " --help show this help message.\n"; ++} ++ ++int ArgParse::init(int argc, char *argv[]) { ++ int cmd = -1; ++ int opt; ++ bool help = false; ++ opterr = 0; ++ while((opt = getopt_long(argc, argv, OPT_STRING.c_str(), long_options, nullptr)) != -1) { ++ std::string full_opt; ++ switch (opt) { ++ case 't': ++ set_type(optarg); ++ break; ++ case 'h': ++ help = true; ++ break; ++ case '?': ++ arg_error("unknown option. See --help."); ++ return -1; ++ default: { ++ if (opt == 'l' || opt == 'r' || opt == 'q' || opt == 'Q' || opt == 'e' || opt == 'd' || opt == 'L' || opt == 'i') { ++ if (cmd != -1) { ++ arg_error("invalid option. See --help.\n"); ++ return -1; ++ } ++ cmd = opt; ++ if (optarg) { ++ set_arg(optarg); ++ } ++ } ++ } ++ ++ } ++ } ++ if (help) { ++ print_help(); ++ exit(EXIT_SUCCESS); ++ } ++ if (cmd < 0) { ++ arg_error("no option."); ++ } ++ return cmd; ++} +diff --git a/src/client/arg_parse.h b/src/client/arg_parse.h +new file mode 100644 +index 0000000..8535e9c +--- /dev/null ++++ b/src/client/arg_parse.h +@@ -0,0 +1,37 @@ ++/****************************************************************************** ++ * Copyright (c) 2024 Huawei Technologies Co., Ltd. ++ * oeAware is licensed under Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, ++ * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, ++ * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ ******************************************************************************/ ++#ifndef CLIENT_ARG_PARSE_H ++#define CLIENT_ARG_PARSE_H ++#include ++ ++class ArgParse { ++public: ++ static void arg_error(const std::string &msg); ++ static void print_help(); ++ int init(int argc, char *argv[]); ++ void set_type(char* _type); ++ void set_arg(char* _arg); ++ std::string get_type() const { ++ return this->type; ++ } ++ std::string get_arg() const { ++ return this->arg; ++ } ++private: ++ std::string arg; ++ std::string type; ++ static const std::string OPT_STRING; ++ static const int MAX_OPT_SIZE = 20; ++ static const struct option long_options[MAX_OPT_SIZE]; ++}; ++ ++#endif // !CLIENT_ARG_PARSE_H +diff --git a/src/client/client.cpp b/src/client/client.cpp +index 72fb6a2..39a0072 100644 +--- a/src/client/client.cpp ++++ b/src/client/client.cpp +@@ -11,97 +11,39 @@ + ******************************************************************************/ + #include "client.h" + +-const std::string Client::OPT_STRING = "Qqd:t:l:r:e:"; +-const struct option Client::long_options[] = { +- {"help", no_argument, NULL, 'h'}, +- {"load", required_argument, NULL, 'l'}, +- {"type", required_argument, NULL, 't'}, +- {"remove", required_argument, NULL, 'r'}, +- {"query", required_argument, NULL, 'q'}, +- {"query-dep", required_argument, NULL, 'Q'}, +- {"enable", required_argument, NULL, 'e'}, +- {"disable", required_argument, NULL, 'd'}, +- {"list", no_argument, NULL, 'L'}, +- {"download", required_argument, NULL, 'D'}, +- {0, 0, 0, 0}, +-}; +- +-static void print_error(const Msg &msg) { +- for (int i = 0; i < msg.payload_size(); ++i) { +- printf("%s\n", msg.payload(i).c_str()); +- } ++void Client::cmd_groups_init() { ++ cmd_handler_groups.insert(std::make_pair('l', new LoadHandler())); ++ cmd_handler_groups.insert(std::make_pair('q', new QueryHandler())); ++ cmd_handler_groups.insert(std::make_pair('r', new RemoveHandler())); ++ cmd_handler_groups.insert(std::make_pair('Q', new QueryTopHandler())); ++ cmd_handler_groups.insert(std::make_pair('e', new EnabledHandler())); ++ cmd_handler_groups.insert(std::make_pair('d', new DisabledHandler())); ++ cmd_handler_groups.insert(std::make_pair('L', new ListHandler())); ++ cmd_handler_groups.insert(std::make_pair('i', new InstallHandler(arg_parse.get_arg()))); + } +- +-bool Client::init() { ++bool Client::init(int argc, char *argv[]) { ++ if ((cmd = arg_parse.init(argc, argv)) < 0) { ++ return false; ++ } ++ cmd_groups_init(); + return this->tcp_socket.init(); + } + +-void Client::run_cmd(int cmd) { ++void Client::run_cmd() { + Msg msg; + Msg res; + MessageHeader header; +- this->cmd_handler = get_cmd_handler(cmd); +- this->cmd_handler->handler(msg); ++ this->cmd_handler = cmd_handler_groups[cmd]; ++ this->cmd_handler->handler(arg_parse, msg); + if(!this->tcp_socket.send_msg(msg)) { + return; + } + if (!this->tcp_socket.recv_msg(res, header)) { + return; + } +- if (header.get_state_code() == HEADER_STATE_FAILED) { +- print_error(res); +- return; +- } + this->cmd_handler->res_handler(res); + } + +-int Client::arg_parse(int argc, char *argv[]) { +- int cmd = -1; +- int opt; +- bool help = false; +- opterr = 0; +- while((opt = getopt_long(argc, argv, OPT_STRING.c_str(), long_options, nullptr)) != -1) { +- std::string full_opt; +- switch (opt) { +- case 't': +- set_type(optarg); +- break; +- case 'h': +- help = true; +- break; +- case '?': +- arg_error("unknown option. See --help."); +- return -1; +- default: { +- if (opt == 'l' || opt == 'r' || opt == 'q' || opt == 'Q' || opt == 'e' || opt == 'd' || opt == 'L' || opt == 'D') { +- if (cmd != -1) { +- arg_error("invalid option. See --help.\n"); +- return -1; +- } +- cmd = opt; +- if (optarg) { +- set_arg(optarg); +- } +- } +- } +- +- } +- } +- if (help) { +- print_help(); +- exit(EXIT_SUCCESS); +- } +- if (cmd < 0) { +- arg_error("no option."); +- } +- return cmd; +-} +- +-void Client::arg_error(const std::string &msg) { +- std::cerr << "oeawarectl: " << msg << "\n"; +- exit(EXIT_FAILURE); +-} +- + void Client::close() { + tcp_socket.clear(); + } +diff --git a/src/client/client.h b/src/client/client.h +index 9528f13..9e60251 100644 +--- a/src/client/client.h ++++ b/src/client/client.h +@@ -13,7 +13,7 @@ + #define CLIENT_H + #include "tcp_socket.h" + #include "cmd_handler.h" +-#include ++#include + + class Client { + public: +@@ -22,18 +22,17 @@ public: + if (cmd_handler) + delete cmd_handler; + } +- bool init(); +- void run_cmd(int cmd); ++ bool init(int argc, char *argv[]); ++ void run_cmd(); + void close(); +- int arg_parse(int argc, char *argv[]); + private: +- void arg_error(const std::string &msg); ++ void cmd_groups_init(); + ++ int cmd; + TcpSocket tcp_socket; ++ ArgParse arg_parse; + CmdHandler *cmd_handler; +- static const std::string OPT_STRING; +- static const int MAX_OPT_SIZE = 20; +- static const struct option long_options[MAX_OPT_SIZE]; ++ std::unordered_map cmd_handler_groups; + }; + + #endif // !CLIENT_H +diff --git a/src/client/cmd_handler.cpp b/src/client/cmd_handler.cpp +index 8cdf8d2..1f2b8a5 100644 +--- a/src/client/cmd_handler.cpp ++++ b/src/client/cmd_handler.cpp +@@ -13,42 +13,13 @@ + #include "utils.h" + #include + +-CmdHandler* get_cmd_handler(int cmd) { +- switch (cmd) { +- case 'l': +- return new LoadHandler(); +- case 'q': +- return new QueryHandler(); +- case 'r': +- return new RemoveHandler(); +- case 'Q': +- return new QueryTopHandler(); +- case 'e': +- return new EnabledHandler(); +- case 'd': +- return new DisabledHandler(); +- case 'L': +- return new ListHandler(); +- case 'D': +- return new DownloadHandler(); +- default: +- return nullptr; +- } +- return nullptr; +-} +- +-void set_type(char *_type) { +- type = _type; +-} ++std::unordered_set LoadHandler::types = {"collector", "scenario", "tune"}; + +-void set_arg(char *_arg) { +- arg = std::string(_arg); +-} +- +-void LoadHandler::handler(Msg &msg) { +- if (type.empty()) { +- printf("plugin type needed!\n"); +- exit(EXIT_FAILURE); ++void LoadHandler::handler(const ArgParse &arg_parse, Msg &msg) { ++ std::string arg = arg_parse.get_arg(); ++ std::string type = arg_parse.get_type(); ++ if (arg.empty() || type.empty() || !types.count(type)) { ++ ArgParse::arg_error("args error."); + } + msg.add_payload(arg); + msg.add_payload(type); +@@ -56,12 +27,24 @@ void LoadHandler::handler(Msg &msg) { + } + + void LoadHandler::res_handler(Msg &msg) { +- for (int i = 0; i < msg.payload_size(); ++i) { +- printf("%s\n", msg.payload(i).c_str()); ++ if (msg.get_opt() == Opt::RESPONSE_OK) { ++ std::cout << "Plugin loaded successfully."; ++ if (msg.payload_size()) { ++ std::cout << "But plugin requires the following dependencies to run.\n"; ++ for (int i = 0; i < msg.payload_size(); ++i) { ++ std::cout << msg.payload(i) << '\n'; ++ } ++ } else { ++ std::cout << '\n'; ++ } ++ } else { ++ std::cout << "Plugin loaded failed, because "<< msg.payload(0) << ".\n"; + } ++ + } + +-void QueryHandler::handler(Msg &msg) { ++void QueryHandler::handler(const ArgParse &arg_parse, Msg &msg) { ++ std::string arg = arg_parse.get_arg(); + if (arg.empty()) { + msg.set_opt(Opt::QUERY_ALL); + } else { +@@ -70,37 +53,57 @@ void QueryHandler::handler(Msg &msg) { + } + } + ++void QueryHandler::print_format() { ++ std::cout << "format:\n" ++ "[plugin]\n" ++ "\t[instance]([dependency status], [running status])\n" ++ "dependency status: available means satisfying dependency, otherwise unavailable.\n" ++ "running status: running means that instance is running, otherwise close.\n"; ++} ++ + void QueryHandler::res_handler(Msg &msg) { +- int len = msg.payload_size(); +- if (len == 0) { +- printf("no plugins loaded!\n"); ++ if (msg.get_opt() == Opt::RESPONSE_ERROR) { ++ std::cout << "Plugin query failed, because " << msg.payload(0).c_str() <<".\n"; + return; +- } ++ } ++ int len = msg.payload_size(); ++ std::cout << "Show plugins and instances status.\n"; ++ std::cout << "------------------------------------------------------------\n"; + for (int i = 0; i < len; ++i) { +- printf("%s\n", msg.payload(i).c_str()); ++ std::cout << msg.payload(i).c_str(); + } ++ std::cout << "------------------------------------------------------------\n"; ++ print_format(); + } + +-void RemoveHandler::handler(Msg &msg) { ++void RemoveHandler::handler(const ArgParse &arg_parse, Msg &msg) { ++ std::string arg = arg_parse.get_arg(); + msg.add_payload(arg); + msg.set_opt(Opt::REMOVE); + } + + void RemoveHandler::res_handler(Msg &msg) { +- printf("%s\n", msg.payload(0).c_str()); ++ if (msg.get_opt() == Opt::RESPONSE_OK) { ++ std::cout << "plugin remove successful.\n"; ++ } else { ++ std::cout << "plugin remove failed, because " << msg.payload(0) << ".\n"; ++ } + } + + void generate_png_from_dot(const std::string &dot_file, const std::string &png_file) { + std::string command = "dot -Tpng " + dot_file + " -o " + png_file; + std::system(command.c_str()); + } ++ + void write_to_file(const std::string &file_name, const std::string &text) { + std::ofstream out(file_name); + if (!out.is_open()) return; + out << text; + out.close(); + } +-void QueryTopHandler::handler(Msg &msg) { ++ ++void QueryTopHandler::handler(const ArgParse &arg_parse, Msg &msg) { ++ std::string arg = arg_parse.get_arg(); + if (arg.empty()) { + msg.set_opt(Opt::QUERY_ALL_TOP); + } else { +@@ -110,70 +113,80 @@ void QueryTopHandler::handler(Msg &msg) { + } + + void QueryTopHandler::res_handler(Msg &msg) { +- std::string text; +- for(int i = 0; i < msg.payload_size(); ++i) { +- text += msg.payload(i).c_str(); ++ if (msg.get_opt() == Opt::RESPONSE_ERROR) { ++ std::cout << "Query instance dependencies failed, because "<< msg.payload(0) << ".\n"; ++ return; + } ++ std::string text = msg.payload(0); + write_to_file("dep.dot", text); + generate_png_from_dot("dep.dot", "dep.png"); ++ std::cout << "Generate dependencies graph dep.png.\n"; + } + +-void EnabledHandler::handler(Msg &msg) { ++void EnabledHandler::handler(const ArgParse &arg_parse, Msg &msg) { ++ std::string arg = arg_parse.get_arg(); + msg.add_payload(arg); + msg.set_opt(Opt::ENABLED); + } + + void EnabledHandler::res_handler(Msg &msg) { +- printf("%s\n", msg.payload(0).c_str()); ++ if (msg.get_opt() == Opt::RESPONSE_OK) { ++ std::cout << "instance enabled.\n"; ++ } else { ++ std::cout << "instance enabled failed, because "<< msg.payload(0) << ".\n"; ++ } + } + +-void DisabledHandler::handler(Msg &msg) { ++void DisabledHandler::handler(const ArgParse &arg_parse, Msg &msg) { ++ std::string arg = arg_parse.get_arg(); + msg.add_payload(arg); + msg.set_opt(Opt::DISABLED); + } + + void DisabledHandler::res_handler(Msg &msg) { +- printf("%s\n", msg.payload(0).c_str()); ++ if (msg.get_opt() == Opt::RESPONSE_OK) { ++ std::cout << "instance disabled.\n"; ++ } else { ++ std::cout << "instance disabled failed, because "<< msg.payload(0) << ".\n"; ++ } + } + +-void ListHandler::handler(Msg &msg) { ++void ListHandler::handler(const ArgParse &arg_parse, Msg &msg) { + msg.set_opt(Opt::LIST); + } + + void ListHandler::res_handler(Msg &msg) { ++ if (msg.get_opt() == Opt::RESPONSE_ERROR) { ++ std::cerr << "query list failed, because "<< msg.payload(0) << ".\n"; ++ return; ++ } ++ std::cout << "plugin list as follows.\n"; ++ std::cout << "------------------------------------------------------------\n"; + for (int i = 0; i < msg.payload_size(); ++i) { +- printf("%s", msg.payload(i).c_str()); ++ std::cout << msg.payload(i); + } ++ std::cout << "------------------------------------------------------------\n"; + } + +-void DownloadHandler::handler(Msg &msg) { ++void InstallHandler::handler(const ArgParse &arg_parse, Msg &msg) { ++ std::string arg = arg_parse.get_arg(); + msg.set_opt(Opt::DOWNLOAD); + msg.add_payload(arg); + } + +-void DownloadHandler::res_handler(Msg &msg) { +- std::string path = arg; ++void InstallHandler::res_handler(Msg &msg) { ++ if (msg.get_opt() == Opt::RESPONSE_ERROR) { ++ std::cout << "download failed, because " << msg.payload(0) <<": " << this->arg.c_str() << '\n'; ++ return; ++ } ++ std::string path = this->arg; + std::string url = msg.payload(0); +- download(url, path); ++ if (!download(url, path)) { ++ std::cout << "download failed, please check url or your network.\n"; ++ return; ++ } + std::string command = "rpm -ivh " + path; + std::string rm = "rm -f " + path; + system(command.c_str()); + system(rm.c_str()); + } +- +-void print_help() { +- printf("oeAware-client [options]...\n" +- " options\n" +- " -l|--load [plugin] load plugin and need plugin type.\n" +- " -t|--type [plugin_type] assign plugin type.\n" +- " -r|--remove [plugin] remove plugin from system.\n" +- " -e|--enable [instance] enable the plugin instance.\n" +- " -d|--disable [instance] disable the plugin instance.\n" +- " -q query all plugins information.\n" +- " --query [plugin] query the plugin information.\n" +- " -Q query all instances dependencies.\n" +- " --query-dep [instance] query the instance dependency.\n" +- " --list the list of supported plugins.\n" +- " --download [plugin] download plugin from the list.\n" +- ); +-} +\ No newline at end of file +diff --git a/src/client/cmd_handler.h b/src/client/cmd_handler.h +index 4afae4c..ab21944 100644 +--- a/src/client/cmd_handler.h ++++ b/src/client/cmd_handler.h +@@ -11,72 +11,72 @@ + ******************************************************************************/ + #ifndef CLIENT_CMD_HANDLER_H + #define CLIENT_CMD_HANDLER_H +- + #include "message_protocol.h" ++#include "arg_parse.h" ++#include + #include + #include + +-static std::string type; +-static std::string arg; +- + class CmdHandler { + public: +- virtual void handler(Msg &msg) = 0; ++ virtual void handler(const ArgParse &arg_parse, Msg &msg) = 0; + virtual void res_handler(Msg &msg) = 0; ++private: + }; + + class LoadHandler : public CmdHandler { + public: +- void handler(Msg &msg) override; ++ void handler(const ArgParse &arg_parse, Msg &msg) override; + void res_handler(Msg &msg) override; ++private: ++ static std::unordered_set types; + }; + + class QueryHandler : public CmdHandler { + public: +- void handler(Msg &msg) override; ++ void handler(const ArgParse &arg_parse, Msg &msg) override; + void res_handler(Msg &msg) override; ++ void print_format(); + }; + + class RemoveHandler : public CmdHandler { + public: +- void handler(Msg &msg) override; ++ void handler(const ArgParse &arg_parse, Msg &msg) override; + void res_handler(Msg &msg) override; + }; + + + class QueryTopHandler : public CmdHandler { + public: +- void handler(Msg &msg) override; ++ void handler(const ArgParse &arg_parse, Msg &msg) override; + void res_handler(Msg &msg) override; + }; + + class EnabledHandler : public CmdHandler { + public: +- void handler(Msg &msg) override; ++ void handler(const ArgParse &arg_parse, Msg &msg) override; + void res_handler(Msg &msg) override; + }; + + class DisabledHandler : public CmdHandler { + public: +- void handler(Msg &msg) override; ++ void handler(const ArgParse &arg_parse, Msg &msg) override; + void res_handler(Msg &msg) override; + }; + + class ListHandler : public CmdHandler { + public: +- void handler(Msg &msg) override; ++ void handler(const ArgParse &arg_parse, Msg &msg) override; + void res_handler(Msg &msg) override; + }; + +-class DownloadHandler : public CmdHandler { ++class InstallHandler : public CmdHandler { + public: +- void handler(Msg &msg) override; ++ InstallHandler(const std::string &arg) : arg(arg) { } ++ void handler(const ArgParse &arg_parse, Msg &msg) override; + void res_handler(Msg &msg) override; ++private: ++ std::string arg; + }; + +-CmdHandler* get_cmd_handler(int cmd); +-void set_type(char* _type); +-void set_arg(char* _arg); +-void print_help(); +- + #endif // !CLIENT_CMD_HANDLER_H +diff --git a/src/client/main.cpp b/src/client/main.cpp +index 89aa268..62b7ca5 100644 +--- a/src/client/main.cpp ++++ b/src/client/main.cpp +@@ -12,15 +12,11 @@ + #include "client.h" + + int main(int argc, char *argv[]) { +- int cmd; + Client client; +- if ((cmd = client.arg_parse(argc, argv)) < 0) { ++ if (!client.init(argc, argv)) { + exit(EXIT_FAILURE); + } +- if (!client.init()) { +- exit(EXIT_FAILURE); +- } +- client.run_cmd(cmd); ++ client.run_cmd(); + client.close(); + return 0; +-} +\ No newline at end of file ++} +diff --git a/src/common/utils.cpp b/src/common/utils.cpp +index 8830c50..9435a5b 100644 +--- a/src/common/utils.cpp ++++ b/src/common/utils.cpp +@@ -12,33 +12,39 @@ + #include "utils.h" + #include + +-static size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *stream) { +- size_t written = fwrite(ptr, size, nmemb, (FILE*)stream); +- return written; ++static size_t write_data(void *ptr, size_t size, size_t nmemb, FILE *file) { ++ return fwrite(ptr, size, nmemb, file); + } + ++// set curl options ++static void curl_set_opt(CURL *curl, const std::string &url, FILE *file) { ++ curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); ++ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); ++ curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); ++ ++} ++// Downloads file from the specified url to the path. + bool download(const std::string &url, const std::string &path) { + CURL *curl = nullptr; + CURLcode res; ++ bool ok = true; + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + if (curl) { +- FILE *fp = fopen(path.c_str(), "wb"); +- if (fp == nullptr) { ++ FILE *file = fopen(path.c_str(), "wb"); ++ if (file == nullptr) { + return false; + } +- curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); +- curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); +- curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); ++ curl_set_opt(curl, url, file); + res = curl_easy_perform(curl); +- curl_easy_cleanup(curl); +- fclose(fp); +- if (res == CURLE_OK) { +- return true; +- } else { +- return false; +- } ++ fclose(file); ++ if (res != CURLE_OK) { ++ ok = false; ++ } ++ } else { ++ ok = false; + } + curl_global_cleanup(); +- return false; ++ curl_easy_cleanup(curl); ++ return ok; + } +\ No newline at end of file +diff --git a/src/plugin_mgr/config.cpp b/src/plugin_mgr/config.cpp +index b997b8f..1de5a34 100644 +--- a/src/plugin_mgr/config.cpp ++++ b/src/plugin_mgr/config.cpp +@@ -14,10 +14,20 @@ + #include + #include + +-void create_dir(std::string path) { +- if (access(path.c_str(), F_OK) == -1) { +- mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IROTH); +- } ++bool create_dir(const std::string &path) { ++ size_t pos = 0; ++ do { ++ pos = path.find_first_of("/", pos + 1); ++ std::string sub_path = path.substr(0, pos); ++ struct stat buffer; ++ if (stat(sub_path.c_str(), &buffer) == 0) { ++ continue; ++ } ++ if (mkdir(sub_path.c_str(), S_IRWXU | S_IRWXG) != 0) { ++ return false; ++ } ++ } while (pos != std::string::npos); ++ return true; + } + + bool Config::load(const std::string path) { +@@ -42,7 +52,16 @@ bool Config::load(const std::string path) { + std::string name = plugin_list[i]["name"].as(); + std::string description = plugin_list[i]["description"].as(); + std::string url = plugin_list[i]["url"].as(); +- this->plugin_list.emplace_back(PluginInfo(name, description, url)); ++ PluginInfo info(name, description, url); ++ if (name.empty()) { ++ std::cerr << "Warn: " << name << " url is empty.\n"; ++ continue; ++ } ++ if (this->plugin_list.count(name)) { ++ std::cerr << "Warn: duplicate " << name << " in plugin_list.\n"; ++ continue; ++ } ++ this->plugin_list.insert(std::make_pair(name, info)); + } + } else { + std::cerr << "Error: 'plugin_list' is not a sequence" << '\n'; +diff --git a/src/plugin_mgr/config.h b/src/plugin_mgr/config.h +index 2592fbe..16c7871 100644 +--- a/src/plugin_mgr/config.h ++++ b/src/plugin_mgr/config.h +@@ -14,6 +14,7 @@ + + #include "plugin.h" + #include ++#include + #include + #include + +@@ -31,12 +32,24 @@ public: + std::string get_url() const { + return this->url; + } ++ bool operator ==(const PluginInfo &other) const { ++ return name == other.get_name(); ++ } + private: + std::string name; + std::string description; + std::string url; + }; + ++namespace std { ++ template <> ++ struct hash { ++ size_t operator ()(const PluginInfo &obj) const { ++ return hash()(obj.get_name()); ++ } ++ }; ++} ++ + class EnableItem { + public: + EnableItem(std::string name) : name(name) { } +@@ -79,12 +92,18 @@ public: + std::string get_log_path() const { + return this->log_path; + } +- PluginInfo get_plugin_list(int i) const { +- return this->plugin_list[i]; ++ PluginInfo get_plugin_info(const std::string &name) const { ++ return this->plugin_list.at(name); ++ } ++ std::unordered_map get_plugin_list() const { ++ return this->plugin_list; + } + size_t get_plugin_list_size() const { + return this->plugin_list.size(); + } ++ bool is_plugin_info_exist(const std::string &name) { ++ return this->plugin_list.count(name); ++ } + EnableItem get_enable_list(int i) const { + return this->enable_list[i]; + } +@@ -96,11 +115,11 @@ private: + int schedule_cycle; + std::string log_path; + std::string log_type; +- std::vector plugin_list; ++ std::unordered_map plugin_list; + std::vector enable_list; + }; + + std::string get_path(PluginType type); +-void create_dir(std::string path); ++bool create_dir(const std::string &path); + + #endif +\ No newline at end of file +diff --git a/src/plugin_mgr/error_code.cpp b/src/plugin_mgr/error_code.cpp +index 252e4c2..6e09cb0 100644 +--- a/src/plugin_mgr/error_code.cpp ++++ b/src/plugin_mgr/error_code.cpp +@@ -11,6 +11,7 @@ const std::unordered_map ErrorText::error_codes = { + {ErrorCode::REMOVE_INSTANCE_IS_RUNNING, "instance is running"}, + {ErrorCode::REMOVE_INSTANCE_HAVE_DEP, "instance with pre-dependency"}, + {ErrorCode::LOAD_PLUGIN_FILE_NOT_EXIST, "plugin file does not exist"}, ++ {ErrorCode::LOAD_PLUGIN_FILE_IS_NOT_SO, "file is not a plugin file"}, + {ErrorCode::LOAD_PLUGIN_FILE_PERMISSION_DEFINED, "plugin file permission defined"}, + {ErrorCode::LOAD_PLUGIN_EXIST, "plugin already loaded"}, + {ErrorCode::LOAD_PLUGIN_DLOPEN_FAILED, "plugin dlopen failed"}, +diff --git a/src/plugin_mgr/error_code.h b/src/plugin_mgr/error_code.h +index f58d5ed..7c06054 100644 +--- a/src/plugin_mgr/error_code.h ++++ b/src/plugin_mgr/error_code.h +@@ -15,6 +15,7 @@ enum class ErrorCode { + REMOVE_INSTANCE_HAVE_DEP, + LOAD_PLUGIN_FILE_NOT_EXIST, + LOAD_PLUGIN_FILE_PERMISSION_DEFINED, ++ LOAD_PLUGIN_FILE_IS_NOT_SO, + LOAD_PLUGIN_EXIST, + LOAD_PLUGIN_DLOPEN_FAILED, + LOAD_PLUGIN_DLSYM_FAILED, +diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp +index e7e32bf..c9981ef 100644 +--- a/src/plugin_mgr/plugin_manager.cpp ++++ b/src/plugin_mgr/plugin_manager.cpp +@@ -173,11 +173,14 @@ void PluginManager::update_instance_state() { + } + } + +-ErrorCode PluginManager::load_plugin(const std::string name, PluginType type) { ++ErrorCode PluginManager::load_plugin(const std::string &name, PluginType type) { + std::string plugin_path = get_path(type) + "/" + name; + if (!file_exist(plugin_path)) { + return ErrorCode::LOAD_PLUGIN_FILE_NOT_EXIST; + } ++ if (!end_with(name, ".so")) { ++ return ErrorCode::LOAD_PLUGIN_FILE_IS_NOT_SO; ++ } + if (!check_permission(plugin_path, S_IRUSR | S_IRGRP)) { + return ErrorCode::LOAD_PLUGIN_FILE_PERMISSION_DEFINED; + } +@@ -285,7 +288,7 @@ ErrorCode PluginManager::instance_disabled(std::string name) { + return ErrorCode::OK; + } + +-static bool end_with(const std::string &s, const std::string &ending) { ++bool PluginManager::end_with(const std::string &s, const std::string &ending) { + if (s.length() >= ending.length()) { + return (s.compare(s.length() - ending.length(), ending.length(), ending) == 0); + } else { +@@ -293,7 +296,7 @@ static bool end_with(const std::string &s, const std::string &ending) { + } + } + +-static std::string get_plugin_in_dir(const std::string &path) { ++std::string PluginManager::get_plugin_in_dir(const std::string &path) { + std::string res; + struct stat s = {}; + lstat(path.c_str(), &s); +@@ -314,10 +317,10 @@ static std::string get_plugin_in_dir(const std::string &path) { + } + + ErrorCode PluginManager::add_list(std::string &res) { +- res += "Download Packages:\n"; +- for (int i = 0; i < config.get_plugin_list_size(); ++i) { +- PluginInfo info = config.get_plugin_list(i); +- res += info.get_name() + "\n"; ++ auto plugin_list = config.get_plugin_list(); ++ res += "Supported Packages:\n"; ++ for (auto &p : plugin_list) { ++ res += p.first + "\n"; + } + res += "Installed Plugins:\n"; + res += get_plugin_in_dir(DEFAULT_COLLECTOR_PATH); +@@ -326,20 +329,11 @@ ErrorCode PluginManager::add_list(std::string &res) { + return ErrorCode::OK; + } + +-ErrorCode PluginManager::download(const std::string &name, std::string &res) { +- std::string url; +- std::string type; +- for (int i = 0; i < config.get_plugin_list_size(); ++i) { +- PluginInfo info = config.get_plugin_list(i); +- if (info.get_name() == name) { +- url = info.get_url(); +- break; +- } +- } +- if (url.empty()) { ++ErrorCode PluginManager::download(const std::string &name, std::string &res) { ++ if (!config.is_plugin_info_exist(name)) { + return ErrorCode::DOWNLOAD_NOT_FOUND; + } +- res += url; ++ res += config.get_plugin_info(name).get_url(); + return ErrorCode::OK; + } + +@@ -451,7 +445,6 @@ int PluginManager::run() { + case Opt::LOAD: { + std::string plugin_name = msg.get_payload(0); + PluginType type = plugin_types[msg.get_payload(1)]; +- if (!end_with(plugin_name, ".so")) break; + ErrorCode ret_code = load_plugin(plugin_name, type); + if(ret_code == ErrorCode::OK) { + INFO("[PluginManager] " << plugin_name << "plugin loaded."); +diff --git a/src/plugin_mgr/plugin_manager.h b/src/plugin_mgr/plugin_manager.h +index 8d240cc..709d42e 100644 +--- a/src/plugin_mgr/plugin_manager.h ++++ b/src/plugin_mgr/plugin_manager.h +@@ -36,7 +36,7 @@ public: + void* get_data_buffer(std::string name); + private: + void pre_load_plugin(PluginType type); +- ErrorCode load_plugin(const std::string path, PluginType type); ++ ErrorCode load_plugin(const std::string &path, PluginType type); + ErrorCode remove(const std::string &name); + ErrorCode query_all_plugins(std::string &res); + ErrorCode query_plugin(const std::string &name, std::string &res); +@@ -55,6 +55,8 @@ private: + void batch_load(); + void batch_remove(); + void update_instance_state(); ++ bool end_with(const std::string &s, const std::string &ending); ++ std::string get_plugin_in_dir(const std::string &path); + private: + std::unique_ptr instance_run_handler; + Config &config; +-- +2.33.0 + diff --git a/0004-fix-auto-enable-error-and-check-plugin-list-config.patch b/0004-fix-auto-enable-error-and-check-plugin-list-config.patch new file mode 100644 index 0000000..fa22264 --- /dev/null +++ b/0004-fix-auto-enable-error-and-check-plugin-list-config.patch @@ -0,0 +1,200 @@ +From 7ff05329ac299727fc2be5d7f1a92a4e3b0bdd43 Mon Sep 17 00:00:00 2001 +From: fly_1997 +Date: Mon, 29 Apr 2024 17:31:44 +0800 +Subject: [PATCH 4/4] fix auto enable error and check plugin list config + +--- + oeaware.service | 2 +- + src/client/arg_parse.cpp | 7 ++++--- + src/common/utils.cpp | 34 ++++++++++++++++++------------- + src/plugin_mgr/config.cpp | 21 ++++++++++++++----- + src/plugin_mgr/config.h | 3 +++ + src/plugin_mgr/plugin_manager.cpp | 11 +++++++++- + 6 files changed, 54 insertions(+), 24 deletions(-) + +diff --git a/oeaware.service b/oeaware.service +index 3ab4b69..b321530 100644 +--- a/oeaware.service ++++ b/oeaware.service +@@ -5,7 +5,7 @@ After=network.target + [Service] + Type=simple + ExecStart=/usr/bin/oeaware /etc/oeAware/config.yaml +-ExecStop=kill -9 $MAINPID ++ExecStop=kill $MAINPID && sleep 5 && kill -9 $MAINPID + Restart=on-failure + RestartSec=1 + RemainAfterExit=yes +diff --git a/src/client/arg_parse.cpp b/src/client/arg_parse.cpp +index cbf0b8e..70fcd4a 100644 +--- a/src/client/arg_parse.cpp ++++ b/src/client/arg_parse.cpp +@@ -30,6 +30,7 @@ const struct option ArgParse::long_options[] = { + + void ArgParse::arg_error(const std::string &msg) { + std::cerr << "oeawarectl: " << msg << "\n"; ++ print_help(); + exit(EXIT_FAILURE); + } + +@@ -42,7 +43,7 @@ void ArgParse::set_arg(char *_arg) { + } + + void ArgParse::print_help() { +- std::cout << "oeawarectl [options]...\n" ++ std::cout << "usage: oeawarectl [options]...\n" + " options\n" + " -l|--load [plugin] load plugin and need plugin type.\n" + " -t|--type [plugin_type] assign plugin type. there are three types:\n" +@@ -76,12 +77,12 @@ int ArgParse::init(int argc, char *argv[]) { + help = true; + break; + case '?': +- arg_error("unknown option. See --help."); ++ arg_error("unknown option."); + return -1; + default: { + if (opt == 'l' || opt == 'r' || opt == 'q' || opt == 'Q' || opt == 'e' || opt == 'd' || opt == 'L' || opt == 'i') { + if (cmd != -1) { +- arg_error("invalid option. See --help.\n"); ++ arg_error("invalid option."); + return -1; + } + cmd = opt; +diff --git a/src/common/utils.cpp b/src/common/utils.cpp +index 9435a5b..f2c277d 100644 +--- a/src/common/utils.cpp ++++ b/src/common/utils.cpp +@@ -23,28 +23,34 @@ static void curl_set_opt(CURL *curl, const std::string &url, FILE *file) { + curl_easy_setopt(curl, CURLOPT_WRITEDATA, file); + + } ++static bool curl_handle(CURL *curl, const std::string &url, const std::string &path) { ++ FILE *file = fopen(path.c_str(), "wb"); ++ if (file == nullptr) { ++ return false; ++ } ++ curl_set_opt(curl, url, file); ++ CURLcode res = curl_easy_perform(curl); ++ long http_code = 0; ++ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); ++ fclose(file); ++ if (res == CURLE_OK && http_code >= 200 && http_code < 300) { ++ return true; ++ } ++ return false; ++} ++ + // Downloads file from the specified url to the path. + bool download(const std::string &url, const std::string &path) { + CURL *curl = nullptr; +- CURLcode res; +- bool ok = true; ++ bool ret = true; + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + if (curl) { +- FILE *file = fopen(path.c_str(), "wb"); +- if (file == nullptr) { +- return false; +- } +- curl_set_opt(curl, url, file); +- res = curl_easy_perform(curl); +- fclose(file); +- if (res != CURLE_OK) { +- ok = false; +- } ++ if (!curl_handle(curl, url, path)) ret = false; + } else { +- ok = false; ++ ret = false; + } + curl_global_cleanup(); + curl_easy_cleanup(curl); +- return ok; ++ return ret; + } +\ No newline at end of file +diff --git a/src/plugin_mgr/config.cpp b/src/plugin_mgr/config.cpp +index 1de5a34..3c76e8e 100644 +--- a/src/plugin_mgr/config.cpp ++++ b/src/plugin_mgr/config.cpp +@@ -30,6 +30,18 @@ bool create_dir(const std::string &path) { + return true; + } + ++bool check_plugin_list(YAML::Node plugin_list_item) { ++ if (plugin_list_item["name"].IsNull()) { ++ std::cerr << "Warn: null name in plugin_list.\n"; ++ return false; ++ } ++ if (plugin_list_item["url"].IsNull()) { ++ std::cerr << "Warn: null url in plugin_list.\n"; ++ return false; ++ } ++ return true; ++} ++ + bool Config::load(const std::string path) { + YAML::Node node; + struct stat buffer; +@@ -49,16 +61,15 @@ bool Config::load(const std::string path) { + YAML::Node plugin_list = node["plugin_list"]; + if (plugin_list.IsSequence()) { + for (int i = 0; i < plugin_list.size(); ++i) { ++ if (!check_plugin_list(plugin_list[i])){ ++ continue; ++ } + std::string name = plugin_list[i]["name"].as(); + std::string description = plugin_list[i]["description"].as(); + std::string url = plugin_list[i]["url"].as(); + PluginInfo info(name, description, url); +- if (name.empty()) { +- std::cerr << "Warn: " << name << " url is empty.\n"; +- continue; +- } + if (this->plugin_list.count(name)) { +- std::cerr << "Warn: duplicate " << name << " in plugin_list.\n"; ++ std::cerr << "Warn: duplicate \"" << name << "\" in plugin_list.\n"; + continue; + } + this->plugin_list.insert(std::make_pair(name, info)); +diff --git a/src/plugin_mgr/config.h b/src/plugin_mgr/config.h +index 16c7871..5ab7672 100644 +--- a/src/plugin_mgr/config.h ++++ b/src/plugin_mgr/config.h +@@ -65,6 +65,9 @@ public: + size_t get_instance_size() const { + return this->instance.size(); + } ++ std::string get_instance_name(int i) { ++ return this->instance[i]; ++ } + std::string get_name() const { + return this->name; + } +diff --git a/src/plugin_mgr/plugin_manager.cpp b/src/plugin_mgr/plugin_manager.cpp +index c9981ef..0826a60 100644 +--- a/src/plugin_mgr/plugin_manager.cpp ++++ b/src/plugin_mgr/plugin_manager.cpp +@@ -348,7 +348,16 @@ void PluginManager::pre_enable() { + } + std::shared_ptr plugin = memory_store.get_plugin(name); + for (int j = 0; j < plugin->get_instance_len(); ++j) { +- instance_enabled(plugin->get_instance(i)->get_name()); ++ instance_enabled(plugin->get_instance(j)->get_name()); ++ } ++ } else { ++ for (int j = 0; j < item.get_instance_size(); ++j) { ++ std::string name = item.get_instance_name(j); ++ if (!memory_store.is_instance_exist(name)) { ++ WARN("[PluginManager] instance " << name << " cannot be enabled, because it does not exist."); ++ continue; ++ } ++ instance_enabled(name); + } + } + } +-- +2.33.0 + diff --git a/oeAware-manager.spec b/oeAware-manager.spec index 91d9ef2..b4e91b2 100644 --- a/oeAware-manager.spec +++ b/oeAware-manager.spec @@ -1,10 +1,14 @@ Name: oeAware-manager Version: v1.0.0 -Release: 2 +Release: 3 Summary: OeAware server and client License: MulanPSL2 URL: https://gitee.com/openeuler/%{name} Source0: %{name}-%{version}.tar.gz +Patch1: 0001-fix-remove-plugin-bug-and-refactor.patch +Patch2: 0002-add-error-code-and-replace-raw-poniters-with-smart-p.patch +Patch3: 0003-add-client-error-description-extract-class-and-fix-b.patch +Patch4: 0004-fix-auto-enable-error-and-check-plugin-list-config.patch BuildRequires: cmake make gcc-c++ BuildRequires: boost-devel @@ -30,21 +34,23 @@ cmake .. make %{?_smp_mflags} %install -install -D -m 0770 build/src/plugin_mgr/oeAware %{buildroot}%{_bindir}/oeaware -install -D -m 0770 build/src/client/oeawarectl %{buildroot}%{_bindir}/oeawarectl +install -D -m 0750 build/src/plugin_mgr/oeaware %{buildroot}%{_bindir}/oeaware +install -D -m 0750 build/src/client/oeawarectl %{buildroot}%{_bindir}/oeawarectl install -D -m 0640 config.yaml %{buildroot}%{_sysconfdir}/oeAware/config.yaml -install -D -p -m 0644 oeAware.service %{buildroot}%{_unitdir}/oeAware.service +install -D -p -m 0644 oeaware.service %{buildroot}%{_unitdir}/oeaware.service %files -%attr(0770, root, root) %{_bindir}/oeaware -%attr(0770, root, root) %{_bindir}/oeawarectl +%attr(0750, root, root) %{_bindir}/oeaware +%attr(0750, root, root) %{_bindir}/oeawarectl %attr(0640, root, root) %{_sysconfdir}/oeAware/config.yaml -%attr(0644, root, root) %{_unitdir}/oeAware.service +%attr(0644, root, root) %{_unitdir}/oeaware.service %changelog +* Mon Apr 29 2024 fly_1997 -v1.0.0-3 +- add error description, refactor, and fix bugs + * Sun Apr 28 2024 huangwenhua -v1.0.0-2 - Add Requires:graphviz * Thu Apr 18 2024 fly_1997 -v1.0.0-1 - Package init -