]>
Commit | Line | Data |
---|---|---|
07ff77cc | 1 | /* |
3f5b5f7b | 2 | * Copyright (c) 2015, 2017 Nicira, Inc. |
07ff77cc AW |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at: | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | #ifndef DB_CTL_BASE_H | |
18 | #define DB_CTL_BASE_H 1 | |
19 | ||
20 | #include "compiler.h" | |
3e8a2ad1 | 21 | #include "openvswitch/dynamic-string.h" |
ee89ea7b | 22 | #include "openvswitch/shash.h" |
07ff77cc AW |
23 | |
24 | struct ctl_context; | |
25 | struct option; | |
26 | struct ovsdb_idl; | |
27 | struct ovsdb_idl_row; | |
28 | struct ovsdb_idl_txn; | |
29 | struct ovsdb_symbol_table; | |
30 | struct table; | |
31 | ||
32 | /* This library module contains the common parts for ovsdb manipulation | |
33 | * (structs, commands and functions). To utilize this module, user must | |
34 | * define the following: | |
35 | * | |
07ff77cc AW |
36 | * - the command syntaxes for each command. (See 'struct ctl_command_syntax' |
37 | * for more info) and regiters them using ctl_register_commands(). | |
38 | * | |
39 | * - the *ctl command context by inheriting the 'struct ctl_context' for | |
40 | * additional commands implemented by user. (See 'struct ctl_context' for | |
41 | * more info) | |
07ff77cc AW |
42 | */ |
43 | ||
44 | /* ctl_fatal() also logs the error, so it is preferred in this file. */ | |
45 | #define ovs_fatal please_use_ctl_fatal_instead_of_ovs_fatal | |
46 | ||
802cb46e | 47 | struct ctl_table_class; |
3f5b5f7b BP |
48 | struct ovsdb_idl_class; |
49 | struct ovsdb_idl_table_class; | |
d33340a5 | 50 | struct cmd_show_table; |
3f5b5f7b BP |
51 | |
52 | /* ctl_init() figures out the number of tables on its own and flags an error if | |
53 | * 'ctl_classes' was defined with the wrong number of elements. */ | |
54 | #define ctl_init(idl_classes, ctl_classes, cmd_show_table, ctl_exit_func) \ | |
55 | (BUILD_ASSERT(ARRAY_SIZE(idl_classes) == ARRAY_SIZE(ctl_classes)), \ | |
56 | ctl_init__(idl_classes, ctl_classes, ARRAY_SIZE(idl_classes), \ | |
57 | cmd_show_table, ctl_exit_func)) | |
58 | void ctl_init__(const struct ovsdb_idl_table_class *idl_classes, | |
59 | const struct ctl_table_class *ctl_classes, | |
60 | size_t n_classes, | |
61 | const struct cmd_show_table *cmd_show_tables, | |
62 | void (*ctl_exit_func)(int status)); | |
51a73ff0 | 63 | char *ctl_default_db(void); |
07ff77cc AW |
64 | OVS_NO_RETURN void ctl_fatal(const char *, ...) OVS_PRINTF_FORMAT(1, 2); |
65 | ||
943f394e | 66 | /* *ctl command syntax structure, to be defined by each command implementation. |
07ff77cc AW |
67 | * |
68 | * Execution Path | |
69 | * ============== | |
70 | * | |
71 | * Three stylized functions accompany each of these data structures: | |
72 | * | |
73 | * "pre-run" "run" "post-run" | |
74 | * --------------- ------------ ----------------- | |
75 | * *ctl ->prerequisites ->run ->postprocess | |
76 | * | |
943f394e | 77 | * Any *ctl command implementation should go through the following execution |
07ff77cc AW |
78 | * path: |
79 | * | |
80 | * 1. parses user command-line input and finds the corresponding syntax | |
81 | * structures. | |
82 | * | |
83 | * 2. calls prerequisites() for getting the columns or tables used by each | |
84 | * command. | |
85 | * | |
86 | * 3. calls run() to execute each command and to generate output. | |
87 | * | |
88 | * 4. calls postprocess() after output has been committed. (Only needed | |
89 | * by 'create' command sofar) | |
90 | * | |
91 | * Execution Context | |
92 | * ================= | |
93 | * | |
94 | * Each of the stylized functions requires the 'struct ctl_context' as input | |
95 | * to provide context e.g. command-line arguments, table to be modified. User | |
96 | * may define more specific context (by inheriting 'struct ctl_context') and | |
97 | * write stylized functions that use it. In that case, CONTAINER_OF() can | |
98 | * be used to cast the generic context to the specific one. | |
99 | * | |
100 | * */ | |
101 | struct ctl_command_syntax { | |
102 | const char *name; /* e.g. "add-br" */ | |
103 | int min_args; /* Min number of arguments following name. */ | |
104 | int max_args; /* Max number of arguments following name. */ | |
105 | ||
106 | /* Names that roughly describe the arguments that the command | |
107 | * uses. These should be similar to the names displayed in the | |
108 | * man page or in the help output. */ | |
109 | const char *arguments; | |
110 | ||
111 | /* If nonnull, calls ovsdb_idl_add_column() or ovsdb_idl_add_table() for | |
112 | * each column or table in ctx->idl that it uses. */ | |
113 | void (*prerequisites)(struct ctl_context *ctx); | |
114 | ||
115 | /* Does the actual work of the command and puts the command's output, if | |
116 | * any, in ctx->output or ctx->table. | |
117 | * | |
118 | * Alternatively, if some prerequisite of the command is not met and the | |
119 | * caller should wait for something to change and then retry, it may set | |
120 | * ctx->try_again to true. (Only the "wait-until" command currently does | |
121 | * this.) */ | |
122 | void (*run)(struct ctl_context *ctx); | |
123 | ||
124 | /* If nonnull, called after the transaction has been successfully | |
125 | * committed. ctx->output is the output from the "run" function, which | |
126 | * this function may modify and otherwise postprocess as needed. (Only the | |
127 | * "create" command currently does any postprocessing.) */ | |
128 | void (*postprocess)(struct ctl_context *ctx); | |
129 | ||
130 | /* A comma-separated list of supported options, e.g. "--a,--b", or the | |
c2f4c39b BP |
131 | * empty string if the command does not support any options. |
132 | * | |
133 | * Arguments are determined by appending special characters to option | |
134 | * names: | |
135 | * | |
136 | * - Append "=" (e.g. "--id=") for a required argument. | |
137 | * | |
138 | * - Append "?" (e.g. "--ovs?") for an optional argument. | |
139 | * | |
140 | * - Otherwise an option does not accept an argument. */ | |
07ff77cc AW |
141 | const char *options; |
142 | ||
1f4a7252 | 143 | enum { RO, RW } mode; /* Does this command modify the database? */ |
07ff77cc AW |
144 | }; |
145 | ||
146 | /* A command extracted from command-line input plus the structs for | |
147 | * output generation. */ | |
148 | struct ctl_command { | |
149 | /* Data that remains constant after initialization. */ | |
150 | const struct ctl_command_syntax *syntax; | |
151 | int argc; | |
152 | char **argv; | |
153 | struct shash options; | |
154 | ||
155 | /* Data modified by commands. */ | |
156 | struct ds output; | |
157 | struct table *table; | |
158 | }; | |
159 | ||
160 | bool ctl_might_write_to_db(char **argv); | |
161 | const char *ctl_get_db_cmd_usage(void); | |
51a73ff0 AW |
162 | void ctl_print_commands(void); |
163 | void ctl_print_options(const struct option *); | |
164 | void ctl_add_cmd_options(struct option **, size_t *n_options_p, | |
165 | size_t *allocated_options_p, int opt_val); | |
07ff77cc | 166 | void ctl_register_commands(const struct ctl_command_syntax *); |
07ff77cc AW |
167 | struct ctl_command *ctl_parse_commands(int argc, char *argv[], |
168 | struct shash *local_options, | |
169 | size_t *n_commandsp); | |
af046a16 | 170 | |
016e4684 AW |
171 | /* Sometimes, it is desirable to print the table with weak reference to |
172 | * rows in a 'cmd_show_table' table. In that case, the 'weak_ref_table' | |
173 | * should be used and user must define all variables. */ | |
174 | struct weak_ref_table { | |
175 | const struct ovsdb_idl_table_class *table; | |
176 | const struct ovsdb_idl_column *name_column; | |
177 | /* This colum must be a weak reference to the owning | |
178 | * 'struct cmd_show_table''s table row. */ | |
179 | const struct ovsdb_idl_column *wref_column; | |
180 | }; | |
181 | ||
af046a16 AW |
182 | /* This struct is for organizing the 'show' command output where: |
183 | * | |
184 | * - 'table' is the table to show. | |
185 | * | |
186 | * - if 'name_column' is not null, it is used as the name for each row | |
187 | * in 'table'. | |
188 | * | |
189 | * - 'columns[]' allows user to specify the print of additional columns | |
190 | * in 'table'. | |
016e4684 AW |
191 | * |
192 | * - if 'wref_table' is populated, print 'wref_table.name_column' for | |
193 | * each row in table 'wref_table.table' that has a reference to 'table' | |
194 | * in 'wref_table.wref_column'. Every field must be populated. | |
195 | * | |
af046a16 AW |
196 | * */ |
197 | struct cmd_show_table { | |
198 | const struct ovsdb_idl_table_class *table; | |
199 | const struct ovsdb_idl_column *name_column; | |
200 | const struct ovsdb_idl_column *columns[3]; /* Seems like a good number. */ | |
016e4684 | 201 | const struct weak_ref_table wref_table; |
af046a16 AW |
202 | }; |
203 | ||
07ff77cc AW |
204 | \f |
205 | /* The base context struct for conducting the common database | |
206 | * operations (commands listed in 'db_ctl_commands'). User should | |
207 | * define the per-schema context by inheriting this struct as base. | |
208 | * | |
209 | * Database Caches | |
210 | * =============== | |
211 | * | |
212 | * User may implement caches for contents of the database to facilitate | |
213 | * specific commands. In that case, the common commands defined in | |
214 | * 'db_ctl_commands' that may invalidate the cache must call the | |
215 | * invalidate_cache(). | |
216 | * | |
217 | **/ | |
218 | struct ctl_context { | |
219 | /* Read-only. */ | |
220 | int argc; | |
221 | char **argv; | |
222 | struct shash options; | |
223 | ||
224 | /* Modifiable state. */ | |
225 | struct ds output; | |
226 | struct table *table; | |
227 | struct ovsdb_idl *idl; | |
228 | struct ovsdb_idl_txn *txn; | |
229 | struct ovsdb_symbol_table *symtab; | |
230 | ||
231 | /* For implementation with a cache of the contents of the database, | |
232 | * this function will be called when the database is changed and the | |
233 | * change makes the cache no longer valid. */ | |
234 | void (*invalidate_cache)(struct ctl_context *); | |
235 | ||
236 | /* A command may set this member to true if some prerequisite is not met | |
237 | * and the caller should wait for something to change and then retry. */ | |
238 | bool try_again; | |
239 | }; | |
240 | ||
241 | void ctl_context_init_command(struct ctl_context *, struct ctl_command *); | |
242 | void ctl_context_init(struct ctl_context *, struct ctl_command *, | |
243 | struct ovsdb_idl *, struct ovsdb_idl_txn *, | |
244 | struct ovsdb_symbol_table *, | |
245 | void (*invalidate_cache)(struct ctl_context *)); | |
246 | void ctl_context_done_command(struct ctl_context *, struct ctl_command *); | |
247 | void ctl_context_done(struct ctl_context *, struct ctl_command *); | |
248 | ||
a0b02897 BP |
249 | /* A way to identify a particular row in the database based on a user-provided |
250 | * string. If all fields are NULL, the struct is ignored. Otherwise, | |
251 | * 'name_column' designates a column whose table is searched for rows that | |
15931827 BP |
252 | * match with the user string. If 'key' is NULL, then 'name_column' should be |
253 | * a string or integer-valued column; otherwise it should be a map from a | |
254 | * string to one of those types and the value corresponding to 'key' is what is | |
255 | * matched. If a matching row is found, then: | |
a0b02897 BP |
256 | * |
257 | * - If 'uuid_column' is NULL, the matching row is the final row. | |
258 | * | |
259 | * - Otherwise 'uuid_column' must designate a UUID-typed column whose value | |
260 | * refers to exactly one row, which is the final row. | |
261 | */ | |
07ff77cc | 262 | struct ctl_row_id { |
07ff77cc | 263 | const struct ovsdb_idl_column *name_column; |
15931827 | 264 | const char *key; |
07ff77cc AW |
265 | const struct ovsdb_idl_column *uuid_column; |
266 | }; | |
267 | ||
268 | struct ctl_table_class { | |
d81af5eb | 269 | struct ctl_row_id row_ids[4]; |
07ff77cc AW |
270 | }; |
271 | ||
bed7aef9 BP |
272 | const struct ovsdb_idl_row *ctl_get_row(struct ctl_context *, |
273 | const struct ovsdb_idl_table_class *, | |
274 | const char *record_id, | |
275 | bool must_exist); | |
276 | ||
15ffc202 AZ |
277 | void ctl_set_column(const char *table_name, |
278 | const struct ovsdb_idl_row *, const char *arg, | |
279 | struct ovsdb_symbol_table *); | |
07ff77cc AW |
280 | |
281 | #endif /* db-ctl-base.h */ |