[Xorp-hackers] [PATCH 5/8] xorp: rtrmgr: Enable usage of %get functions
igorm at etf.rs
igorm at etf.rs
Tue Mar 20 10:02:44 PDT 2012
From: Igor Maravic <igorm at etf.rs>
%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 <igorm at etf.rs>
---
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
More information about the Xorp-hackers
mailing list