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

Reply via email to