The user is required to expose the_idl and the_idl_txn global variables,
so that memory can be cleaned up on fatal errors. This patch changes to
ask user to supply an exit function via ctl_init(). What user needs to
do on exit can now remain private.

Signed-off-by: Andy Zhou <az...@nicira.com>
---
 lib/db-ctl-base.c     | 24 +++++++++++++-----------
 lib/db-ctl-base.h     | 11 ++---------
 utilities/ovs-vsctl.c | 29 +++++++++++++++++++++++++++--
 vtep/vtep-ctl.c       | 32 ++++++++++++++++++++++++++++----
 4 files changed, 70 insertions(+), 26 deletions(-)

diff --git a/lib/db-ctl-base.c b/lib/db-ctl-base.c
index e3ba0c5..a137af6 100644
--- a/lib/db-ctl-base.c
+++ b/lib/db-ctl-base.c
@@ -40,12 +40,6 @@
 
 VLOG_DEFINE_THIS_MODULE(db_ctl_base);
 
-/* The IDL we're using and the current transaction, if any.
- * This is for use by ctl_exit() only, to allow it to clean up.
- * Other code should use its context arguments. */
-struct ovsdb_idl *the_idl;
-struct ovsdb_idl_txn *the_idl_txn;
-
 /* This array defines the 'show' command output format.  User can check the
  * definition in utilities/ovs-vsctl.c as reference.
  *
@@ -59,6 +53,14 @@ struct ovsdb_idl_txn *the_idl_txn;
  * */
 static const struct cmd_show_table *cmd_show_tables;
 
+/* ctl_exit() is called by ctl_fatal(). User can optionally supply an exit
+ * function ctl_exit_func() via ctl_init. If supplied, this function will
+ * be called by ctl_exit()
+ */
+static void (*ctl_exit_func)(int status) = NULL;
+OVS_NO_RETURN static void ctl_exit(int status);
+
+
 /* Represents all tables in the schema.  User must define 'tables'
  * in implementation and supply via clt_init().  The definition must end
  * with an all-NULL entry. */
@@ -1956,11 +1958,9 @@ ctl_fatal(const char *format, ...)
 void
 ctl_exit(int status)
 {
-    if (the_idl_txn) {
-        ovsdb_idl_txn_abort(the_idl_txn);
-        ovsdb_idl_txn_destroy(the_idl_txn);
+    if (ctl_exit_func) {
+        ctl_exit_func(status);
     }
-    ovsdb_idl_destroy(the_idl);
     exit(status);
 }
 
@@ -2007,10 +2007,12 @@ ctl_register_commands(const struct ctl_command_syntax 
*commands)
 /* Registers the 'db_ctl_commands' to 'all_commands'. */
 void
 ctl_init(const struct ctl_table_class tables_[],
-         const struct cmd_show_table cmd_show_tables_[])
+         const struct cmd_show_table cmd_show_tables_[],
+         void (*ctl_exit_func_)(int status))
 {
     tables = tables_;
     cmd_show_tables = cmd_show_tables_;
+    ctl_exit_func = ctl_exit_func_;
     ctl_register_commands(db_ctl_commands);
 }
 
diff --git a/lib/db-ctl-base.h b/lib/db-ctl-base.h
index e750599..034f29d 100644
--- a/lib/db-ctl-base.h
+++ b/lib/db-ctl-base.h
@@ -33,8 +33,6 @@ struct table;
  * (structs, commands and functions).  To utilize this module, user must
  * define the following:
  *
- * - the 'the_idl' and 'the_idl_txn'.
- *
  * - the command syntaxes for each command.  (See 'struct ctl_command_syntax'
  *   for more info)  and regiters them using ctl_register_commands().
  *
@@ -46,17 +44,12 @@ struct table;
 /* ctl_fatal() also logs the error, so it is preferred in this file. */
 #define ovs_fatal please_use_ctl_fatal_instead_of_ovs_fatal
 
-/* idl and idl transaction to be used for the *ctl command execution.
- * User must provide them.  */
-extern struct ovsdb_idl *the_idl;
-extern struct ovsdb_idl_txn *the_idl_txn;
-
 struct ctl_table_class;
 struct cmd_show_table;
 void ctl_init(const struct ctl_table_class *tables,
-              const struct cmd_show_table *cmd_show_tables);
+              const struct cmd_show_table *cmd_show_tables,
+             void (*ctl_exit_func)(int status));
 char *ctl_default_db(void);
-OVS_NO_RETURN void ctl_exit(int status);
 OVS_NO_RETURN void ctl_fatal(const char *, ...) OVS_PRINTF_FORMAT(1, 2);
 
 /* *ctl command syntax structure, to be defined by each command implementation.
diff --git a/utilities/ovs-vsctl.c b/utilities/ovs-vsctl.c
index 7794106..ccb9270 100644
--- a/utilities/ovs-vsctl.c
+++ b/utilities/ovs-vsctl.c
@@ -84,6 +84,14 @@ static bool retry;
 static struct table_style table_style = TABLE_STYLE_DEFAULT;
 
 static void vsctl_cmd_init(void);
+
+/* The IDL we're using and the current transaction, if any.
+ * This is for use by vsctl_exit() only, to allow it to clean up.
+ * Other code should use its context arguments. */
+static struct ovsdb_idl *the_idl;
+static struct ovsdb_idl_txn *the_idl_txn;
+OVS_NO_RETURN static void vsctl_exit(int status);
+
 OVS_NO_RETURN static void usage(void);
 static void parse_options(int argc, char *argv[], struct shash *local_options);
 static void run_prerequisites(struct ctl_command[], size_t n_commands,
@@ -1343,7 +1351,7 @@ cmd_br_exists(struct ctl_context *ctx)
 
     vsctl_context_populate_cache(ctx);
     if (!find_bridge(vsctl_ctx, ctx->argv[1], false)) {
-        ctl_exit(2);
+        vsctl_exit(2);
     }
 }
 
@@ -2648,6 +2656,23 @@ try_again:
     free(error);
 }
 
+/* Frees the current transaction and the underlying IDL and then calls
+ * exit(status).
+ *
+ * Freeing the transaction and the IDL is not strictly necessary, but it makes
+ * for a clean memory leak report from valgrind in the normal case.  That makes
+ * it easier to notice real memory leaks. */
+static void
+vsctl_exit(int status)
+{
+    if (the_idl_txn) {
+        ovsdb_idl_txn_abort(the_idl_txn);
+        ovsdb_idl_txn_destroy(the_idl_txn);
+    }
+    ovsdb_idl_destroy(the_idl);
+    exit(status);
+}
+
 /*
  * Developers who add new commands to the 'struct ctl_command_syntax' must
  * define the 'arguments' member of the struct.  The following keywords are
@@ -2749,6 +2774,6 @@ static const struct ctl_command_syntax vsctl_commands[] = 
{
 static void
 vsctl_cmd_init(void)
 {
-    ctl_init(tables, cmd_show_tables);
+    ctl_init(tables, cmd_show_tables, vsctl_exit);
     ctl_register_commands(vsctl_commands);
 }
diff --git a/vtep/vtep-ctl.c b/vtep/vtep-ctl.c
index d9c4b26..d3e042e 100644
--- a/vtep/vtep-ctl.c
+++ b/vtep/vtep-ctl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2010, 2011, 2012, 2014 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2014, 2015 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -70,6 +70,13 @@ static int timeout;
 /* Format for table output. */
 static struct table_style table_style = TABLE_STYLE_DEFAULT;
 
+/* The IDL we're using and the current transaction, if any.
+ * This is for use by vtep_ctl_exit() only, to allow it to clean up.
+ * Other code should use its context arguments. */
+static struct ovsdb_idl *the_idl;
+static struct ovsdb_idl_txn *the_idl_txn;
+
+OVS_NO_RETURN static void vtep_ctl_exit(int status);
 static void vtep_ctl_cmd_init(void);
 OVS_NO_RETURN static void usage(void);
 static void parse_options(int argc, char *argv[], struct shash *local_options);
@@ -270,6 +277,23 @@ parse_options(int argc, char *argv[], struct shash 
*local_options)
     free(options);
 }
 
+/* Frees the current transaction and the underlying IDL and then calls
+ * exit(status).
+ *
+ * Freeing the transaction and the IDL is not strictly necessary, but it makes
+ * for a clean memory leak report from valgrind in the normal case.  That makes
+ * it easier to notice real memory leaks. */
+static void
+vtep_ctl_exit(int status)
+{
+    if (the_idl_txn) {
+        ovsdb_idl_txn_abort(the_idl_txn);
+        ovsdb_idl_txn_destroy(the_idl_txn);
+    }
+    ovsdb_idl_destroy(the_idl);
+    exit(status);
+}
+
 static void
 usage(void)
 {
@@ -1194,7 +1218,7 @@ cmd_ps_exists(struct ctl_context *ctx)
 
     vtep_ctl_context_populate_cache(ctx);
     if (!find_pswitch(vtepctl_ctx, ctx->argv[1], false)) {
-        ctl_exit(2);
+        vtep_ctl_exit(2);
     }
 }
 
@@ -1368,7 +1392,7 @@ cmd_ls_exists(struct ctl_context *ctx)
 
     vtep_ctl_context_populate_cache(ctx);
     if (!find_lswitch(vtepctl_ctx, ctx->argv[1], false)) {
-        ctl_exit(2);
+        vtep_ctl_exit(2);
     }
 }
 
@@ -2310,6 +2334,6 @@ static const struct ctl_command_syntax vtep_commands[] = {
 static void
 vtep_ctl_cmd_init(void)
 {
-    ctl_init(tables, cmd_show_tables);
+    ctl_init(tables, cmd_show_tables, vtep_ctl_exit);
     ctl_register_commands(vtep_commands);
 }
-- 
1.9.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to