diff options
author | Ben Pfaff <blp@ovn.org> | 2017-01-13 11:28:54 -0800 |
---|---|---|
committer | Ben Pfaff <blp@ovn.org> | 2017-01-31 14:50:27 -0800 |
commit | e32494f976cd4ac1eed94aca5eae0bd836f2bbdd (patch) | |
tree | 7f342628641adfd3dd63b096c3616ac4c8c73bc1 | |
parent | fa3cc9b9f9f361a458549beb671f3a10e6508872 (diff) | |
download | openvswitch-e32494f976cd4ac1eed94aca5eae0bd836f2bbdd.tar.gz |
ovn-trace: Fix memory leaks.
Suggested-by: Justin Pettit <jpettit@ovn.org>
Signed-off-by: Ben Pfaff <blp@ovn.org>
-rw-r--r-- | ovn/utilities/ovn-trace.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/ovn/utilities/ovn-trace.c b/ovn/utilities/ovn-trace.c index b894442b8..e9d4a71d2 100644 --- a/ovn/utilities/ovn-trace.c +++ b/ovn/utilities/ovn-trace.c @@ -905,11 +905,13 @@ struct ovntrace_node { struct ovs_list node; /* In parent. */ enum ovntrace_node_type type; - const char *name; + char *name; bool always_indent; struct ovs_list subs; /* List of children. */ }; +static void ovntrace_node_destroy(struct ovntrace_node *); + static struct ovntrace_node * OVS_PRINTF_FORMAT(3, 4) ovntrace_node_append(struct ovs_list *super, enum ovntrace_node_type type, const char *format, ...) @@ -942,6 +944,29 @@ ovntrace_node_clone(const struct ovs_list *old, struct ovs_list *new) } static void +ovntrace_node_list_destroy(struct ovs_list *list) +{ + if (list) { + struct ovntrace_node *node, *next; + + LIST_FOR_EACH_SAFE (node, next, node, list) { + ovs_list_remove(&node->node); + ovntrace_node_destroy(node); + } + } +} + +static void +ovntrace_node_destroy(struct ovntrace_node *node) +{ + if (node) { + ovntrace_node_list_destroy(&node->subs); + free(node->name); + free(node); + } +} + +static void ovntrace_node_print_details(struct ds *output, const struct ovs_list *nodes, int level) { @@ -977,8 +1002,10 @@ ovntrace_node_prune_summary(struct ovs_list *nodes) ovntrace_node_prune_summary(&sub->subs); if (sub->type == OVNTRACE_NODE_MODIFY || sub->type == OVNTRACE_NODE_TABLE) { + /* Replace 'sub' by its children, if any, */ ovs_list_remove(&sub->node); ovs_list_splice(&next->node, sub->subs.next, &sub->subs); + ovntrace_node_destroy(sub); } } } @@ -1019,8 +1046,10 @@ ovntrace_node_prune_hard(struct ovs_list *nodes) sub->type == OVNTRACE_NODE_PIPELINE || sub->type == OVNTRACE_NODE_TABLE || sub->type == OVNTRACE_NODE_OUTPUT) { + /* Replace 'sub' by its children, if any, */ ovs_list_remove(&sub->node); ovs_list_splice(&next->node, sub->subs.next, &sub->subs); + ovntrace_node_destroy(sub); } } } @@ -1676,6 +1705,7 @@ trace(const char *dp_s, const char *flow_s) ovntrace_node_clone(&root, &clone); ovntrace_node_prune_summary(&clone); ovntrace_node_print_summary(&output, &clone, 0); + ovntrace_node_list_destroy(&clone); } if (minimal) { @@ -1686,6 +1716,8 @@ trace(const char *dp_s, const char *flow_s) ovntrace_node_print_summary(&output, &root, 0); } + ovntrace_node_list_destroy(&root); + vconn_close(vconn); return ds_steal_cstr(&output); |