]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib: avoid expensive operations when editing a candidate config
authorRenato Westphal <renato@opensourcerouting.org>
Sun, 6 Oct 2019 04:16:47 +0000 (01:16 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Sat, 12 Oct 2019 00:18:36 +0000 (21:18 -0300)
nb_candidate_edit() was calling both the lyd_schema_sort() and
lyd_validate() functions whenever a new node was added to the
candidate configuration. This was done to ensure the candidate
is always ready to be displayed correctly (libyang only creates
default child nodes during the validation process, and data nodes
aren't guaranteed to be ordered by default).

The problem is that the two aforementioned functions are too
expensive to be called in the northbound hot path. Instead, it makes
more sense to call them only before displaying the configuration
(in which case a recursive sort needs to be done). Introduce the
nb_cli_show_config_prepare() to achieve that purpose.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
lib/command.c
lib/northbound.c
lib/northbound_cli.c
lib/northbound_cli.h

index 04f2bd95a08177e4789f0a32869181f35e1fb8ae..32e877280daaf6d989d39d60751050ce3093d3f3 100644 (file)
@@ -1709,6 +1709,8 @@ static int vty_write_config(struct vty *vty)
        if (host.noconfig)
                return CMD_SUCCESS;
 
+       nb_cli_show_config_prepare(running_config, false);
+
        if (vty->type == VTY_TERM) {
                vty_out(vty, "\nCurrent configuration:\n");
                vty_out(vty, "!\n");
index 1b332fb1e8bd692c59ebb7255afc96999a5ea99b..2f14b287d9cc49633ec314ee4169d2e29d836f05 100644 (file)
@@ -516,17 +516,6 @@ int nb_candidate_edit(struct nb_config *candidate,
                                  __func__);
                        return NB_ERR;
                }
-
-               /*
-                * If a new node was created, call lyd_validate() only to create
-                * default child nodes.
-                */
-               if (dnode) {
-                       lyd_schema_sort(dnode, 0);
-                       lyd_validate(&dnode,
-                                    LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL,
-                                    ly_native_ctx);
-               }
                break;
        case NB_OP_DESTROY:
                dnode = yang_dnode_get(candidate->dnode, xpath_edit);
index a215d8b759da1c4a17f2fcbf591b5525ff486cc5..07e8c9dff9d747a11201a2dd40911142ef0203b2 100644 (file)
@@ -421,6 +421,23 @@ static struct lyd_node *ly_iter_next_up(const struct lyd_node *elem)
        return elem->parent;
 }
 
+/* Prepare the configuration for display. */
+void nb_cli_show_config_prepare(struct nb_config *config, bool with_defaults)
+{
+       lyd_schema_sort(config->dnode, 1);
+
+       /*
+        * When "with-defaults" is used, call lyd_validate() only to create
+        * default child nodes, ignoring any possible validation error. This
+        * doesn't need to be done when displaying the running configuration
+        * since it's always fully validated.
+        */
+       if (with_defaults && config != running_config)
+               (void)lyd_validate(&config->dnode,
+                                  LYD_OPT_CONFIG | LYD_OPT_WHENAUTODEL,
+                                  ly_native_ctx);
+}
+
 void nb_cli_show_dnode_cmds(struct vty *vty, struct lyd_node *root,
                            bool with_defaults)
 {
@@ -513,6 +530,8 @@ static int nb_cli_show_config(struct vty *vty, struct nb_config *config,
                              struct yang_translator *translator,
                              bool with_defaults)
 {
+       nb_cli_show_config_prepare(config, with_defaults);
+
        switch (format) {
        case NB_CFG_FMT_CMDS:
                nb_cli_show_config_cmds(vty, config, with_defaults);
index 209239ca6318d6ba39256aa6ca6a85159a3876a5..b2d8c8f0353f4f2d38046fd0e2d6423315cd3b42 100644 (file)
@@ -109,6 +109,8 @@ extern void nb_cli_show_dnode_cmds(struct vty *vty, struct lyd_node *dnode,
                                   bool show_defaults);
 
 /* Prototypes of internal functions. */
+extern void nb_cli_show_config_prepare(struct nb_config *config,
+                                      bool with_defaults);
 extern void nb_cli_confirmed_commit_clean(struct vty *vty);
 extern int nb_cli_confirmed_commit_rollback(struct vty *vty);
 extern void nb_cli_install_default(int node);