2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-19 14:37:21 +00:00
Files
openvswitch/lib/db-ctl-base.h
Ben Pfaff 3f5b5f7b41 db-ctl-base: Always support all tables in schema.
When one adds a new table to a database schema, it's easy to forget to
add the table to the list of tables in the *ctl.c program.  When this
happens, the database commands for that program don't work on that table
at all, even for commands like "list" and "create" that don't need any
special help.  This patch fixes that problem, by making sure that
db-ctl-base always has the complete list of tables.

Previously, each ctl_table_class pointed directly to the corresponding
ovsdb_idl_table_class.  With this patch, there are instead two parallel
arrays, one of ovsdb_idl_table_classes and the other of ctl_table_classes.
This change accounts for the bulk of the change to the db-ctl-base code.

Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Lance Richardson <lrichard@redhat.com>
2017-01-13 13:14:59 -08:00

255 lines
9.3 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2015, 2017 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DB_CTL_BASE_H
#define DB_CTL_BASE_H 1
#include "compiler.h"
#include "openvswitch/dynamic-string.h"
#include "openvswitch/shash.h"
struct ctl_context;
struct option;
struct ovsdb_idl;
struct ovsdb_idl_row;
struct ovsdb_idl_txn;
struct ovsdb_symbol_table;
struct table;
/* This library module contains the common parts for ovsdb manipulation
* (structs, commands and functions). To utilize this module, user must
* define the following:
*
* - the command syntaxes for each command. (See 'struct ctl_command_syntax'
* for more info) and regiters them using ctl_register_commands().
*
* - the *ctl command context by inheriting the 'struct ctl_context' for
* additional commands implemented by user. (See 'struct ctl_context' for
* more info)
*/
/* ctl_fatal() also logs the error, so it is preferred in this file. */
#define ovs_fatal please_use_ctl_fatal_instead_of_ovs_fatal
struct ctl_table_class;
struct ovsdb_idl_class;
struct ovsdb_idl_table_class;
struct cmd_show_table;
/* ctl_init() figures out the number of tables on its own and flags an error if
* 'ctl_classes' was defined with the wrong number of elements. */
#define ctl_init(idl_classes, ctl_classes, cmd_show_table, ctl_exit_func) \
(BUILD_ASSERT(ARRAY_SIZE(idl_classes) == ARRAY_SIZE(ctl_classes)), \
ctl_init__(idl_classes, ctl_classes, ARRAY_SIZE(idl_classes), \
cmd_show_table, ctl_exit_func))
void ctl_init__(const struct ovsdb_idl_table_class *idl_classes,
const struct ctl_table_class *ctl_classes,
size_t n_classes,
const struct cmd_show_table *cmd_show_tables,
void (*ctl_exit_func)(int status));
char *ctl_default_db(void);
OVS_NO_RETURN void ctl_fatal(const char *, ...) OVS_PRINTF_FORMAT(1, 2);
/* *ctl command syntax structure, to be defined by each command implementation.
*
* Execution Path
* ==============
*
* Three stylized functions accompany each of these data structures:
*
* "pre-run" "run" "post-run"
* --------------- ------------ -----------------
* *ctl ->prerequisites ->run ->postprocess
*
* Any *ctl command implementation should go through the following execution
* path:
*
* 1. parses user command-line input and finds the corresponding syntax
* structures.
*
* 2. calls prerequisites() for getting the columns or tables used by each
* command.
*
* 3. calls run() to execute each command and to generate output.
*
* 4. calls postprocess() after output has been committed. (Only needed
* by 'create' command sofar)
*
* Execution Context
* =================
*
* Each of the stylized functions requires the 'struct ctl_context' as input
* to provide context e.g. command-line arguments, table to be modified. User
* may define more specific context (by inheriting 'struct ctl_context') and
* write stylized functions that use it. In that case, CONTAINER_OF() can
* be used to cast the generic context to the specific one.
*
* */
struct ctl_command_syntax {
const char *name; /* e.g. "add-br" */
int min_args; /* Min number of arguments following name. */
int max_args; /* Max number of arguments following name. */
/* Names that roughly describe the arguments that the command
* uses. These should be similar to the names displayed in the
* man page or in the help output. */
const char *arguments;
/* If nonnull, calls ovsdb_idl_add_column() or ovsdb_idl_add_table() for
* each column or table in ctx->idl that it uses. */
void (*prerequisites)(struct ctl_context *ctx);
/* Does the actual work of the command and puts the command's output, if
* any, in ctx->output or ctx->table.
*
* Alternatively, if some prerequisite of the command is not met and the
* caller should wait for something to change and then retry, it may set
* ctx->try_again to true. (Only the "wait-until" command currently does
* this.) */
void (*run)(struct ctl_context *ctx);
/* If nonnull, called after the transaction has been successfully
* committed. ctx->output is the output from the "run" function, which
* this function may modify and otherwise postprocess as needed. (Only the
* "create" command currently does any postprocessing.) */
void (*postprocess)(struct ctl_context *ctx);
/* A comma-separated list of supported options, e.g. "--a,--b", or the
* empty string if the command does not support any options. */
const char *options;
enum { RO, RW } mode; /* Does this command modify the database? */
};
/* A command extracted from command-line input plus the structs for
* output generation. */
struct ctl_command {
/* Data that remains constant after initialization. */
const struct ctl_command_syntax *syntax;
int argc;
char **argv;
struct shash options;
/* Data modified by commands. */
struct ds output;
struct table *table;
};
bool ctl_might_write_to_db(char **argv);
const char *ctl_get_db_cmd_usage(void);
void ctl_print_commands(void);
void ctl_print_options(const struct option *);
void ctl_add_cmd_options(struct option **, size_t *n_options_p,
size_t *allocated_options_p, int opt_val);
void ctl_register_commands(const struct ctl_command_syntax *);
struct ctl_command *ctl_parse_commands(int argc, char *argv[],
struct shash *local_options,
size_t *n_commandsp);
/* Sometimes, it is desirable to print the table with weak reference to
* rows in a 'cmd_show_table' table. In that case, the 'weak_ref_table'
* should be used and user must define all variables. */
struct weak_ref_table {
const struct ovsdb_idl_table_class *table;
const struct ovsdb_idl_column *name_column;
/* This colum must be a weak reference to the owning
* 'struct cmd_show_table''s table row. */
const struct ovsdb_idl_column *wref_column;
};
/* This struct is for organizing the 'show' command output where:
*
* - 'table' is the table to show.
*
* - if 'name_column' is not null, it is used as the name for each row
* in 'table'.
*
* - 'columns[]' allows user to specify the print of additional columns
* in 'table'.
*
* - if 'wref_table' is populated, print 'wref_table.name_column' for
* each row in table 'wref_table.table' that has a reference to 'table'
* in 'wref_table.wref_column'. Every field must be populated.
*
* */
struct cmd_show_table {
const struct ovsdb_idl_table_class *table;
const struct ovsdb_idl_column *name_column;
const struct ovsdb_idl_column *columns[3]; /* Seems like a good number. */
const struct weak_ref_table wref_table;
};
/* The base context struct for conducting the common database
* operations (commands listed in 'db_ctl_commands'). User should
* define the per-schema context by inheriting this struct as base.
*
* Database Caches
* ===============
*
* User may implement caches for contents of the database to facilitate
* specific commands. In that case, the common commands defined in
* 'db_ctl_commands' that may invalidate the cache must call the
* invalidate_cache().
*
**/
struct ctl_context {
/* Read-only. */
int argc;
char **argv;
struct shash options;
/* Modifiable state. */
struct ds output;
struct table *table;
struct ovsdb_idl *idl;
struct ovsdb_idl_txn *txn;
struct ovsdb_symbol_table *symtab;
/* For implementation with a cache of the contents of the database,
* this function will be called when the database is changed and the
* change makes the cache no longer valid. */
void (*invalidate_cache)(struct ctl_context *);
/* A command may set this member to true if some prerequisite is not met
* and the caller should wait for something to change and then retry. */
bool try_again;
};
void ctl_context_init_command(struct ctl_context *, struct ctl_command *);
void ctl_context_init(struct ctl_context *, struct ctl_command *,
struct ovsdb_idl *, struct ovsdb_idl_txn *,
struct ovsdb_symbol_table *,
void (*invalidate_cache)(struct ctl_context *));
void ctl_context_done_command(struct ctl_context *, struct ctl_command *);
void ctl_context_done(struct ctl_context *, struct ctl_command *);
struct ctl_row_id {
const struct ovsdb_idl_table_class *table;
const struct ovsdb_idl_column *name_column;
const struct ovsdb_idl_column *uuid_column;
};
struct ctl_table_class {
struct ctl_row_id row_ids[2];
};
void ctl_set_column(const char *table_name,
const struct ovsdb_idl_row *, const char *arg,
struct ovsdb_symbol_table *);
#endif /* db-ctl-base.h */