[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