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.
+ *
+ * Particularly, if an element in 'columns[]' represents a reference to
+ * another table, the referred table must also be defined as an entry in
+ * in 'cmd_show_tables[]'.
+ *
+ * The definition must end with an all-NULL entry. It is initalized once
+ * when ctl_init() is called.
+ *
+ * */
+extern 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
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);
}
/* Registers the 'db_ctl_commands' to 'all_commands'. */
void
-ctl_init(const struct ctl_table_class tables_[])
+ctl_init(const struct ctl_table_class tables_[],
+ void (*ctl_exit_func_)(int status))
{
tables = tables_;
+ ctl_exit_func = ctl_exit_func_;
ctl_register_commands(db_ctl_commands);
}
* (structs, commands and functions). To utilize this module, user must
* define the following:
*
- * - the 'the_idl' and 'the_idl_txn'.
- *
* - the 'cmd_show_tables'. (See 'struct cmd_show_table' for more info).
*
* - the command syntaxes for each command. (See 'struct ctl_command_syntax'
/* 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;
-void ctl_init(const struct ctl_table_class *tables);
+void ctl_init(const struct ctl_table_class *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.
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,
vsctl_context_populate_cache(ctx);
if (!find_bridge(vsctl_ctx, ctx->argv[1], false)) {
- ctl_exit(2);
+ vsctl_exit(2);
}
}
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
static void
vsctl_cmd_init(void)
{
- ctl_init(tables);
+ ctl_init(tables, vsctl_exit);
ctl_register_commands(vsctl_commands);
}
/*
- * 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.
/* 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);
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)
{
vtep_ctl_context_populate_cache(ctx);
if (!find_pswitch(vtepctl_ctx, ctx->argv[1], false)) {
- ctl_exit(2);
+ vtep_ctl_exit(2);
}
}
vtep_ctl_context_populate_cache(ctx);
if (!find_lswitch(vtepctl_ctx, ctx->argv[1], false)) {
- ctl_exit(2);
+ vtep_ctl_exit(2);
}
}
static void
vtep_ctl_cmd_init(void)
{
- ctl_init(tables);
+ ctl_init(tables, vtep_ctl_exit);
ctl_register_commands(vtep_commands);
}