From: Igor Maravic <[email protected]> %get functions are very important, so our CLI DB would be synchronized with kernel DB.
So, in this patch I am looking for existing %get functions of affected modules. They are stashed in map for latter calling. After we finish all changes in our module, that means after end_commit function is called, all stashed %get functions are called. Signed-off-by: Igor Maravic <[email protected]> --- xorp/rtrmgr/cli.cc | 1 + xorp/rtrmgr/conf_tree_node.cc | 17 ++++++ xorp/rtrmgr/conf_tree_node.hh | 1 + xorp/rtrmgr/master_conf_tree_node.cc | 94 ++++++++++++++++++++++++++++++++++ xorp/rtrmgr/master_conf_tree_node.hh | 10 ++++ 5 files changed, 123 insertions(+), 0 deletions(-) diff --git a/xorp/rtrmgr/cli.cc b/xorp/rtrmgr/cli.cc index edb5a95..adcb019 100644 --- a/xorp/rtrmgr/cli.cc +++ b/xorp/rtrmgr/cli.cc @@ -1476,6 +1476,7 @@ RouterCLI::add_delete_subtree() cmds.push_back("%create"); cmds.push_back("%activate"); cmds.push_back("%update"); + cmds.push_back("%get"); cmds.push_back("%set"); cmds.push_back("%delete"); SlaveConfigTreeNode *current_config_node = config_tree()->find_node(_path); diff --git a/xorp/rtrmgr/conf_tree_node.cc b/xorp/rtrmgr/conf_tree_node.cc index c26d2a9..7050ffa 100644 --- a/xorp/rtrmgr/conf_tree_node.cc +++ b/xorp/rtrmgr/conf_tree_node.cc @@ -893,6 +893,23 @@ ConfigTreeNode::undelete_subtree() } } +ConfigTreeNode* +ConfigTreeNode::module_root_node() +{ + /** + * Module root node is the node that have modinfo commands defined + * + * If we are not the module root node, + * we recursively check our parent node. + */ + if (_template_tree_node->const_command("%modinfo")) + return this; + + XLOG_ASSERT(_parent); + + return _parent->module_root_node(); +} + string ConfigTreeNode::show_subtree(bool show_top, int depth, int indent, bool do_indent, bool numbered, bool annotate, diff --git a/xorp/rtrmgr/conf_tree_node.hh b/xorp/rtrmgr/conf_tree_node.hh index 4bff458..ebd8fe9 100644 --- a/xorp/rtrmgr/conf_tree_node.hh +++ b/xorp/rtrmgr/conf_tree_node.hh @@ -139,6 +139,7 @@ public: void set_parent(ConfigTreeNode* parent) { _parent = parent; } ConfigTreeNode* parent() { return _parent; } const ConfigTreeNode* const_parent() const { return _parent; } + ConfigTreeNode* module_root_node(); list<ConfigTreeNode*>& children() { return _children; } const list<ConfigTreeNode*>& const_children() const { return _children; } string show_subtree(bool show_top, int depth, int indent, bool do_indent, diff --git a/xorp/rtrmgr/master_conf_tree_node.cc b/xorp/rtrmgr/master_conf_tree_node.cc index 170b5f2..4251177 100644 --- a/xorp/rtrmgr/master_conf_tree_node.cc +++ b/xorp/rtrmgr/master_conf_tree_node.cc @@ -174,6 +174,15 @@ MasterConfigTreeNode::find_changed_modules(set<string>& changed_modules) const for (iter = modules.begin(); iter != modules.end(); ++iter) changed_modules.insert(*iter); } + + base_cmd = _template_tree_node->const_command("%get"); + if (base_cmd != NULL) { + cmd = reinterpret_cast<const Command*>(base_cmd); + modules = cmd->affected_modules(); + for (iter = modules.begin(); iter != modules.end(); ++iter) + changed_modules.insert(*iter); + } + base_cmd = _template_tree_node->const_command("%update"); if (base_cmd != NULL) { cmd = reinterpret_cast<const Command*>(base_cmd); @@ -246,6 +255,14 @@ MasterConfigTreeNode::find_active_modules(set<string>& active_modules) const for (iter = modules.begin(); iter != modules.end(); ++iter) active_modules.insert(*iter); } + + base_cmd = _template_tree_node->const_command("%get"); + if (base_cmd != NULL) { + cmd = reinterpret_cast<const Command*>(base_cmd); + modules = cmd->affected_modules(); + for (iter = modules.begin(); iter != modules.end(); ++iter) + active_modules.insert(*iter); + } } // @@ -301,6 +318,15 @@ MasterConfigTreeNode::find_all_modules(set<string>& all_modules) const for (iter = modules.begin(); iter != modules.end(); ++iter) all_modules.insert(*iter); } + + base_cmd = _template_tree_node->const_command("%get"); + if (base_cmd != NULL) { + cmd = reinterpret_cast<const Command*>(base_cmd); + modules = cmd->affected_modules(); + for (iter = modules.begin(); iter != modules.end(); ++iter) + all_modules.insert(*iter); + } + base_cmd = _template_tree_node->const_command("%set"); if (base_cmd != NULL) { cmd = reinterpret_cast<const Command*>(base_cmd); @@ -322,6 +348,7 @@ MasterConfigTreeNode::initialize_commit() _actions_pending = 0; _actions_succeeded = true; _cmd_that_failed = NULL; + _sync_cmds.clear(); list<ConfigTreeNode *>::iterator iter; for (iter = _children.begin(); iter != _children.end(); ++iter) { @@ -570,6 +597,18 @@ MasterConfigTreeNode::commit_changes(TaskManager& task_manager, if (_template_tree_node == NULL) break; + // The %get command + if (_value_committed == false) { + base_cmd = _template_tree_node->const_command("%get"); + if (base_cmd) { + debug_msg("found commands: %s. Adding it to sync map\n", cmd->str().c_str()); + MasterConfigTreeNode* module_root = dynamic_cast<MasterConfigTreeNode*>(this->module_root_node()); + XLOG_ASSERT(module_root); + + module_root->add_sync_cmd(this, reinterpret_cast<const Command*>(base_cmd)); + } + } + // The %activate command if (needs_activate || (_existence_committed == false)) { base_cmd = _template_tree_node->const_command("%activate"); @@ -633,6 +672,14 @@ MasterConfigTreeNode::commit_changes(TaskManager& task_manager, return false; } } + + /** + * Sync CLI DB, with module parameters + */ + bool result = this->sync(task_manager); + + if (!result) + return false; } } @@ -715,6 +762,7 @@ MasterConfigTreeNode::finalize_commit() XLOG_ASSERT(_actions_pending == 0); XLOG_ASSERT(_actions_succeeded); + XLOG_ASSERT(_sync_cmds.empty()); _existence_committed = true; _value_committed = true; _deleted = false; @@ -738,4 +786,50 @@ MasterConfigTreeNode::finalize_commit() } } +void +MasterConfigTreeNode::increment_actions_pending(const int increment = 1) +{ + XLOG_ASSERT(increment >= 0); + _actions_pending += increment; +} + + +void +MasterConfigTreeNode::add_sync_cmd(MasterConfigTreeNode* node, const Command* cmd) +{ + /** + * Synchronization should be done ONLY from module root node + */ + XLOG_ASSERT(this == module_root_node()); + + if (_sync_cmds.find(this) != _sync_cmds.end()) + XLOG_UNREACHABLE(); + + _sync_cmds[node] = cmd; +} + +bool +MasterConfigTreeNode::sync(TaskManager& task_manager) +{ + XLOG_ASSERT(this == module_root_node()); + map<MasterConfigTreeNode*, const Command*>::iterator iter; + + for (iter = _sync_cmds.begin(); iter != _sync_cmds.end(); ++iter) { + int ret = iter->second->execute(*(iter->first), task_manager); + if (ret < 0) { + string error_msg; + error_msg = c_format("Parameter error for \"%s\"\n", + iter->first->path().c_str()); + error_msg += "Correct this error and try again.\n"; + XLOG_WARNING("%s\n", error_msg.c_str()); + _sync_cmds.clear(); + return false; + } + iter->first->increment_actions_pending(ret); + } + + _sync_cmds.clear(); + return true; +} + diff --git a/xorp/rtrmgr/master_conf_tree_node.hh b/xorp/rtrmgr/master_conf_tree_node.hh index 0d37dc3..5c2bfad 100644 --- a/xorp/rtrmgr/master_conf_tree_node.hh +++ b/xorp/rtrmgr/master_conf_tree_node.hh @@ -58,6 +58,9 @@ public: void find_active_modules(set<string>& active_modules) const; void find_all_modules(set<string>& all_modules) const; + void add_sync_cmd(MasterConfigTreeNode* node, const Command* cmd); + bool sync(TaskManager& task_manager); + void initialize_commit(); bool children_changed(); bool commit_changes(TaskManager& task_manager, bool do_commit, @@ -66,6 +69,8 @@ public: bool check_commit_status(string& error_msg) const; void finalize_commit(); + void increment_actions_pending(const int increment); + protected: @@ -74,6 +79,11 @@ protected: bool _actions_succeeded; // Did any action fail during the commit? const Command* _cmd_that_failed; + map<MasterConfigTreeNode*, const Command*> _sync_cmds; //In this map we store MasterConfigTreeNodes + //that have been changed, and that have %get + //functions which we use for synchronization. + //This map should have elements only for module root node + private: }; -- 1.7.5.4 _______________________________________________ Xorp-hackers mailing list [email protected] http://mailman.ICSI.Berkeley.EDU/mailman/listinfo/xorp-hackers
