Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
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 : : #include <config.h>
18 : : #include <errno.h>
19 : : #include <fcntl.h>
20 : : #include <getopt.h>
21 : : #include <signal.h>
22 : : #include <stdlib.h>
23 : : #include <string.h>
24 : :
25 : : #include "column.h"
26 : : #include "command-line.h"
27 : : #include "compiler.h"
28 : : #include "dirs.h"
29 : : #include "openvswitch/dynamic-string.h"
30 : : #include "fatal-signal.h"
31 : : #include "file.h"
32 : : #include "lockfile.h"
33 : : #include "log.h"
34 : : #include "openvswitch/json.h"
35 : : #include "ovsdb.h"
36 : : #include "ovsdb-data.h"
37 : : #include "ovsdb-error.h"
38 : : #include "socket-util.h"
39 : : #include "table.h"
40 : : #include "timeval.h"
41 : : #include "util.h"
42 : : #include "openvswitch/vlog.h"
43 : :
44 : : /* -m, --more: Verbosity level for "show-log" command output. */
45 : : static int show_log_verbosity;
46 : :
47 : : static const struct ovs_cmdl_command *get_all_commands(void);
48 : :
49 : : OVS_NO_RETURN static void usage(void);
50 : : static void parse_options(int argc, char *argv[]);
51 : :
52 : : static const char *default_db(void);
53 : : static const char *default_schema(void);
54 : :
55 : : int
56 : 1514 : main(int argc, char *argv[])
57 : : {
58 : 1514 : struct ovs_cmdl_context ctx = { .argc = 0, };
59 : 1514 : set_program_name(argv[0]);
60 : 1514 : parse_options(argc, argv);
61 : 1512 : fatal_ignore_sigpipe();
62 : 1512 : ctx.argc = argc - optind;
63 : 1512 : ctx.argv = argv + optind;
64 : 1512 : ovs_cmdl_run_command(&ctx, get_all_commands());
65 : 1512 : return 0;
66 : : }
67 : :
68 : : static void
69 : 1514 : parse_options(int argc, char *argv[])
70 : : {
71 : : static const struct option long_options[] = {
72 : : {"more", no_argument, NULL, 'm'},
73 : : {"verbose", optional_argument, NULL, 'v'},
74 : : {"help", no_argument, NULL, 'h'},
75 : : {"option", no_argument, NULL, 'o'},
76 : : {"version", no_argument, NULL, 'V'},
77 : : {NULL, 0, NULL, 0},
78 : : };
79 : 1514 : char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
80 : :
81 : : for (;;) {
82 : : int c;
83 : :
84 : 1514 : c = getopt_long(argc, argv, short_options, long_options, NULL);
85 [ + + ]: 1514 : if (c == -1) {
86 : 1512 : break;
87 : : }
88 : :
89 [ - - + - : 2 : switch (c) {
- - - ]
90 : : case 'm':
91 : 0 : show_log_verbosity++;
92 : 0 : break;
93 : :
94 : : case 'h':
95 : 0 : usage();
96 : :
97 : : case 'o':
98 : 2 : ovs_cmdl_print_options(long_options);
99 : 2 : exit(EXIT_SUCCESS);
100 : :
101 : : case 'V':
102 : 0 : ovs_print_version(0, 0);
103 : 0 : exit(EXIT_SUCCESS);
104 : :
105 : : case 'v':
106 : 0 : vlog_set_verbosity(optarg);
107 : 0 : break;
108 : :
109 : : case '?':
110 : 0 : exit(EXIT_FAILURE);
111 : :
112 : : default:
113 : 0 : abort();
114 : : }
115 : 0 : }
116 : 1512 : free(short_options);
117 : 1512 : }
118 : :
119 : : static void
120 : 0 : usage(void)
121 : : {
122 : 0 : printf("%s: Open vSwitch database management utility\n"
123 : : "usage: %s [OPTIONS] COMMAND [ARG...]\n"
124 : : " create [DB [SCHEMA]] create DB with the given SCHEMA\n"
125 : : " compact [DB [DST]] compact DB in-place (or to DST)\n"
126 : : " convert [DB [SCHEMA [DST]]] convert DB to SCHEMA (to DST)\n"
127 : : " db-version [DB] report version of schema used by DB\n"
128 : : " db-cksum [DB] report checksum of schema used by DB\n"
129 : : " schema-version [SCHEMA] report SCHEMA's schema version\n"
130 : : " schema-cksum [SCHEMA] report SCHEMA's checksum\n"
131 : : " query [DB] TRNS execute read-only transaction on DB\n"
132 : : " transact [DB] TRNS execute read/write transaction on DB\n"
133 : : " [-m]... show-log [DB] print DB's log entries\n"
134 : : "The default DB is %s.\n"
135 : : "The default SCHEMA is %s.\n",
136 : : program_name, program_name, default_db(), default_schema());
137 : 0 : vlog_usage();
138 : 0 : printf("\nOther options:\n"
139 : : " -m, --more increase show-log verbosity\n"
140 : : " -h, --help display this help message\n"
141 : : " -V, --version display version information\n");
142 : 0 : exit(EXIT_SUCCESS);
143 : : }
144 : :
145 : : static const char *
146 : 0 : default_db(void)
147 : : {
148 : : static char *db;
149 [ # # ]: 0 : if (!db) {
150 : 0 : db = xasprintf("%s/conf.db", ovs_dbdir());
151 : : }
152 : 0 : return db;
153 : : }
154 : :
155 : : static const char *
156 : 0 : default_schema(void)
157 : : {
158 : : static char *schema;
159 [ # # ]: 0 : if (!schema) {
160 : 0 : schema = xasprintf("%s/vswitch.ovsschema", ovs_pkgdatadir());
161 : : }
162 : 0 : return schema;
163 : : }
164 : :
165 : : static struct json *
166 : 243 : parse_json(const char *s)
167 : : {
168 : 243 : struct json *json = json_from_string(s);
169 [ - + ]: 243 : if (json->type == JSON_STRING) {
170 : 0 : ovs_fatal(0, "\"%s\": %s", s, json->u.string);
171 : : }
172 : 243 : return json;
173 : : }
174 : :
175 : : static void
176 : 243 : print_and_free_json(struct json *json)
177 : : {
178 : 243 : char *string = json_to_string(json, JSSF_SORT);
179 : 243 : json_destroy(json);
180 : 243 : puts(string);
181 : 243 : free(string);
182 : 243 : }
183 : :
184 : : static void
185 : 5287 : check_ovsdb_error(struct ovsdb_error *error)
186 : : {
187 [ - + ]: 5287 : if (error) {
188 : 0 : ovs_fatal(0, "%s", ovsdb_error_to_string(error));
189 : : }
190 : 5287 : }
191 : :
192 : : static void
193 : 1257 : do_create(struct ovs_cmdl_context *ctx)
194 : : {
195 [ + - ]: 1257 : const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
196 [ + - ]: 1257 : const char *schema_file_name = ctx->argc >= 3 ? ctx->argv[2] : default_schema();
197 : : struct ovsdb_schema *schema;
198 : : struct ovsdb_log *log;
199 : : struct json *json;
200 : :
201 : : /* Read schema from file and convert to JSON. */
202 : 1257 : check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema));
203 : 1257 : json = ovsdb_schema_to_json(schema);
204 : 1257 : ovsdb_schema_destroy(schema);
205 : :
206 : : /* Create database file. */
207 : 1257 : check_ovsdb_error(ovsdb_log_open(db_file_name, OVSDB_LOG_CREATE,
208 : : -1, &log));
209 : 1257 : check_ovsdb_error(ovsdb_log_write(log, json));
210 : 1257 : check_ovsdb_error(ovsdb_log_commit(log));
211 : 1257 : ovsdb_log_close(log);
212 : :
213 : 1257 : json_destroy(json);
214 : 1257 : }
215 : :
216 : : static void
217 : 3 : compact_or_convert(const char *src_name_, const char *dst_name_,
218 : : const struct ovsdb_schema *new_schema,
219 : : const char *comment)
220 : : {
221 : : char *src_name, *dst_name;
222 : : struct lockfile *src_lock;
223 : : struct lockfile *dst_lock;
224 : 3 : bool in_place = dst_name_ == NULL;
225 : : struct ovsdb *db;
226 : : int retval;
227 : :
228 : : /* Dereference symlinks for source and destination names. In the in-place
229 : : * case this ensures that, if the source name is a symlink, we replace its
230 : : * target instead of replacing the symlink by a regular file. In the
231 : : * non-in-place, this has the same effect for the destination name. */
232 : 3 : src_name = follow_symlinks(src_name_);
233 : 3 : dst_name = (in_place
234 : : ? xasprintf("%s.tmp", src_name)
235 [ + - ]: 3 : : follow_symlinks(dst_name_));
236 : :
237 : : /* Lock the source, if we will be replacing it. */
238 [ + - ]: 3 : if (in_place) {
239 : 3 : retval = lockfile_lock(src_name, &src_lock);
240 [ - + ]: 3 : if (retval) {
241 : 0 : ovs_fatal(retval, "%s: failed to lock lockfile", src_name);
242 : : }
243 : : }
244 : :
245 : : /* Get (temporary) destination and lock it. */
246 : 3 : retval = lockfile_lock(dst_name, &dst_lock);
247 [ - + ]: 3 : if (retval) {
248 : 0 : ovs_fatal(retval, "%s: failed to lock lockfile", dst_name);
249 : : }
250 : :
251 : : /* Save a copy. */
252 [ + + ]: 3 : check_ovsdb_error(new_schema
253 : : ? ovsdb_file_open_as_schema(src_name, new_schema, &db)
254 : : : ovsdb_file_open(src_name, true, &db, NULL));
255 : 3 : check_ovsdb_error(ovsdb_file_save_copy(dst_name, false, comment, db));
256 : 3 : ovsdb_destroy(db);
257 : :
258 : : /* Replace source. */
259 [ + - ]: 3 : if (in_place) {
260 : : #ifdef _WIN32
261 : : unlink(src_name);
262 : : #endif
263 [ - + ]: 3 : if (rename(dst_name, src_name)) {
264 : 0 : ovs_fatal(errno, "failed to rename \"%s\" to \"%s\"",
265 : : dst_name, src_name);
266 : : }
267 : 3 : fsync_parent_dir(dst_name);
268 : 3 : lockfile_unlock(src_lock);
269 : : }
270 : :
271 : 3 : lockfile_unlock(dst_lock);
272 : :
273 : 3 : free(src_name);
274 : 3 : free(dst_name);
275 : 3 : }
276 : :
277 : : static void
278 : 1 : do_compact(struct ovs_cmdl_context *ctx)
279 : : {
280 [ + - ]: 1 : const char *db = ctx->argc >= 2 ? ctx->argv[1] : default_db();
281 [ - + ]: 1 : const char *target = ctx->argc >= 3 ? ctx->argv[2] : NULL;
282 : :
283 : 1 : compact_or_convert(db, target, NULL, "compacted by ovsdb-tool "VERSION);
284 : 1 : }
285 : :
286 : : static void
287 : 2 : do_convert(struct ovs_cmdl_context *ctx)
288 : : {
289 [ + - ]: 2 : const char *db = ctx->argc >= 2 ? ctx->argv[1] : default_db();
290 [ + - ]: 2 : const char *schema = ctx->argc >= 3 ? ctx->argv[2] : default_schema();
291 [ - + ]: 2 : const char *target = ctx->argc >= 4 ? ctx->argv[3] : NULL;
292 : : struct ovsdb_schema *new_schema;
293 : :
294 : 2 : check_ovsdb_error(ovsdb_schema_from_file(schema, &new_schema));
295 : 2 : compact_or_convert(db, target, new_schema,
296 : : "converted by ovsdb-tool "VERSION);
297 : 2 : ovsdb_schema_destroy(new_schema);
298 : 2 : }
299 : :
300 : : static void
301 : 2 : do_needs_conversion(struct ovs_cmdl_context *ctx)
302 : : {
303 [ + - ]: 2 : const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
304 [ + - ]: 2 : const char *schema_file_name = ctx->argc >= 3 ? ctx->argv[2] : default_schema();
305 : : struct ovsdb_schema *schema1, *schema2;
306 : :
307 : 2 : check_ovsdb_error(ovsdb_file_read_schema(db_file_name, &schema1));
308 : 2 : check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema2));
309 [ + + ]: 2 : puts(ovsdb_schema_equal(schema1, schema2) ? "no" : "yes");
310 : 2 : ovsdb_schema_destroy(schema1);
311 : 2 : ovsdb_schema_destroy(schema2);
312 : 2 : }
313 : :
314 : : static void
315 : 1 : do_db_version(struct ovs_cmdl_context *ctx)
316 : : {
317 [ + - ]: 1 : const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
318 : : struct ovsdb_schema *schema;
319 : :
320 : 1 : check_ovsdb_error(ovsdb_file_read_schema(db_file_name, &schema));
321 : 1 : puts(schema->version);
322 : 1 : ovsdb_schema_destroy(schema);
323 : 1 : }
324 : :
325 : : static void
326 : 1 : do_db_cksum(struct ovs_cmdl_context *ctx)
327 : : {
328 [ + - ]: 1 : const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
329 : : struct ovsdb_schema *schema;
330 : :
331 : 1 : check_ovsdb_error(ovsdb_file_read_schema(db_file_name, &schema));
332 : 1 : puts(schema->cksum);
333 : 1 : ovsdb_schema_destroy(schema);
334 : 1 : }
335 : :
336 : : static void
337 : 1 : do_schema_version(struct ovs_cmdl_context *ctx)
338 : : {
339 [ + - ]: 1 : const char *schema_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_schema();
340 : : struct ovsdb_schema *schema;
341 : :
342 : 1 : check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema));
343 : 1 : puts(schema->version);
344 : 1 : ovsdb_schema_destroy(schema);
345 : 1 : }
346 : :
347 : : static void
348 : 1 : do_schema_cksum(struct ovs_cmdl_context *ctx)
349 : : {
350 [ + - ]: 1 : const char *schema_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_schema();
351 : : struct ovsdb_schema *schema;
352 : :
353 : 1 : check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema));
354 : 1 : puts(schema->cksum);
355 : 1 : ovsdb_schema_destroy(schema);
356 : 1 : }
357 : :
358 : : static void
359 : 243 : transact(bool read_only, int argc, char *argv[])
360 : : {
361 [ + - ]: 243 : const char *db_file_name = argc >= 3 ? argv[1] : default_db();
362 : 243 : const char *transaction = argv[argc - 1];
363 : : struct json *request, *result;
364 : : struct ovsdb *db;
365 : :
366 : 243 : check_ovsdb_error(ovsdb_file_open(db_file_name, read_only, &db, NULL));
367 : :
368 : 243 : request = parse_json(transaction);
369 : 243 : result = ovsdb_execute(db, NULL, request, false, 0, NULL);
370 : 243 : json_destroy(request);
371 : :
372 : 243 : print_and_free_json(result);
373 : 243 : ovsdb_destroy(db);
374 : 243 : }
375 : :
376 : : static void
377 : 0 : do_query(struct ovs_cmdl_context *ctx)
378 : : {
379 : 0 : transact(true, ctx->argc, ctx->argv);
380 : 0 : }
381 : :
382 : : static void
383 : 243 : do_transact(struct ovs_cmdl_context *ctx)
384 : : {
385 : 243 : transact(false, ctx->argc, ctx->argv);
386 : 243 : }
387 : :
388 : : static void
389 : 0 : print_db_changes(struct shash *tables, struct shash *names,
390 : : const struct ovsdb_schema *schema)
391 : : {
392 : : struct shash_node *n1;
393 : :
394 [ # # ][ # # ]: 0 : SHASH_FOR_EACH (n1, tables) {
395 : 0 : const char *table = n1->name;
396 : : struct ovsdb_table_schema *table_schema;
397 : 0 : struct json *rows = n1->data;
398 : : struct shash_node *n2;
399 : :
400 [ # # ][ # # ]: 0 : if (n1->name[0] == '_' || rows->type != JSON_OBJECT) {
401 : 0 : continue;
402 : : }
403 : :
404 : 0 : table_schema = shash_find_data(&schema->tables, table);
405 [ # # ][ # # ]: 0 : SHASH_FOR_EACH (n2, json_object(rows)) {
406 : 0 : const char *row_uuid = n2->name;
407 : 0 : struct json *columns = n2->data;
408 : : struct shash_node *n3;
409 : : char *old_name, *new_name;
410 : 0 : bool free_new_name = false;
411 : :
412 : 0 : old_name = new_name = shash_find_data(names, row_uuid);
413 [ # # ]: 0 : if (columns->type == JSON_OBJECT) {
414 : : struct json *new_name_json;
415 : :
416 : 0 : new_name_json = shash_find_data(json_object(columns), "name");
417 [ # # ]: 0 : if (new_name_json) {
418 : 0 : new_name = json_to_string(new_name_json, JSSF_SORT);
419 : 0 : free_new_name = true;
420 : : }
421 : : }
422 : :
423 : 0 : printf("\ttable %s", table);
424 : :
425 [ # # ]: 0 : if (!old_name) {
426 [ # # ]: 0 : if (new_name) {
427 : 0 : printf(" insert row %s (%.8s):\n", new_name, row_uuid);
428 : : } else {
429 : 0 : printf(" insert row %.8s:\n", row_uuid);
430 : : }
431 : : } else {
432 : 0 : printf(" row %s (%.8s):\n", old_name, row_uuid);
433 : : }
434 : :
435 [ # # ]: 0 : if (columns->type == JSON_OBJECT) {
436 [ # # ]: 0 : if (show_log_verbosity > 1) {
437 [ # # ][ # # ]: 0 : SHASH_FOR_EACH (n3, json_object(columns)) {
438 : 0 : const char *column = n3->name;
439 : : const struct ovsdb_column *column_schema;
440 : 0 : struct json *value = n3->data;
441 : 0 : char *value_string = NULL;
442 : :
443 : 0 : column_schema =
444 : : (table_schema
445 : 0 : ? shash_find_data(&table_schema->columns, column)
446 [ # # ]: 0 : : NULL);
447 [ # # ]: 0 : if (column_schema) {
448 : : const struct ovsdb_type *type;
449 : : struct ovsdb_error *error;
450 : : struct ovsdb_datum datum;
451 : :
452 : 0 : type = &column_schema->type;
453 : 0 : error = ovsdb_datum_from_json(&datum, type,
454 : : value, NULL);
455 [ # # ]: 0 : if (!error) {
456 : : struct ds s;
457 : :
458 : 0 : ds_init(&s);
459 : 0 : ovsdb_datum_to_string(&datum, type, &s);
460 : 0 : value_string = ds_steal_cstr(&s);
461 : : } else {
462 : 0 : ovsdb_error_destroy(error);
463 : : }
464 : : }
465 [ # # ]: 0 : if (!value_string) {
466 : 0 : value_string = json_to_string(value, JSSF_SORT);
467 : : }
468 : 0 : printf("\t\t%s=%s\n", column, value_string);
469 : 0 : free(value_string);
470 : : }
471 : : }
472 [ # # ]: 0 : if (!old_name
473 [ # # ][ # # ]: 0 : || (new_name != old_name && strcmp(old_name, new_name))) {
474 [ # # ]: 0 : if (old_name) {
475 : 0 : shash_delete(names, shash_find(names, row_uuid));
476 : 0 : free(old_name);
477 : : }
478 [ # # ]: 0 : shash_add(names, row_uuid, (new_name
479 : : ? xstrdup(new_name)
480 : : : xmemdup0(row_uuid, 8)));
481 : : }
482 [ # # ]: 0 : } else if (columns->type == JSON_NULL) {
483 : : struct shash_node *node;
484 : :
485 : 0 : printf("\t\tdelete row\n");
486 : 0 : node = shash_find(names, row_uuid);
487 [ # # ]: 0 : if (node) {
488 : 0 : shash_delete(names, node);
489 : : }
490 : 0 : free(old_name);
491 : : }
492 : :
493 [ # # ]: 0 : if (free_new_name) {
494 : 0 : free(new_name);
495 : : }
496 : : }
497 : : }
498 : 0 : }
499 : :
500 : : static void
501 : 0 : do_show_log(struct ovs_cmdl_context *ctx)
502 : : {
503 [ # # ]: 0 : const char *db_file_name = ctx->argc >= 2 ? ctx->argv[1] : default_db();
504 : : struct shash names;
505 : : struct ovsdb_log *log;
506 : : struct ovsdb_schema *schema;
507 : : unsigned int i;
508 : :
509 : 0 : check_ovsdb_error(ovsdb_log_open(db_file_name, OVSDB_LOG_READ_ONLY,
510 : : -1, &log));
511 : 0 : shash_init(&names);
512 : 0 : schema = NULL;
513 : 0 : for (i = 0; ; i++) {
514 : : struct json *json;
515 : :
516 : 0 : check_ovsdb_error(ovsdb_log_read(log, &json));
517 [ # # ]: 0 : if (!json) {
518 : 0 : break;
519 : : }
520 : :
521 : 0 : printf("record %u:", i);
522 [ # # ]: 0 : if (i == 0) {
523 : 0 : check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
524 : 0 : printf(" \"%s\" schema, version=\"%s\", cksum=\"%s\"\n",
525 : 0 : schema->name, schema->version, schema->cksum);
526 [ # # ]: 0 : } else if (json->type == JSON_OBJECT) {
527 : : struct json *date, *comment;
528 : :
529 : 0 : date = shash_find_data(json_object(json), "_date");
530 [ # # ][ # # ]: 0 : if (date && date->type == JSON_INTEGER) {
531 : 0 : long long int t = json_integer(date);
532 : : char *s;
533 : :
534 [ # # ]: 0 : if (t < INT32_MAX) {
535 : : /* Older versions of ovsdb wrote timestamps in seconds. */
536 : 0 : t *= 1000;
537 : : }
538 : :
539 : 0 : s = xastrftime_msec(" %Y-%m-%d %H:%M:%S.###", t, true);
540 : 0 : fputs(s, stdout);
541 : 0 : free(s);
542 : : }
543 : :
544 : 0 : comment = shash_find_data(json_object(json), "_comment");
545 [ # # ][ # # ]: 0 : if (comment && comment->type == JSON_STRING) {
546 : 0 : printf(" \"%s\"", json_string(comment));
547 : : }
548 : :
549 [ # # ][ # # ]: 0 : if (i > 0 && show_log_verbosity > 0) {
550 : 0 : putchar('\n');
551 : 0 : print_db_changes(json_object(json), &names, schema);
552 : : }
553 : : }
554 : 0 : json_destroy(json);
555 : 0 : putchar('\n');
556 : 0 : }
557 : :
558 : 0 : ovsdb_log_close(log);
559 : 0 : ovsdb_schema_destroy(schema);
560 : : /* XXX free 'names'. */
561 : 0 : }
562 : :
563 : : static void
564 : 0 : do_help(struct ovs_cmdl_context *ctx OVS_UNUSED)
565 : : {
566 : 0 : usage();
567 : : }
568 : :
569 : : static void
570 : 3 : do_list_commands(struct ovs_cmdl_context *ctx OVS_UNUSED)
571 : : {
572 : 3 : ovs_cmdl_print_commands(get_all_commands());
573 : 3 : }
574 : :
575 : : static const struct ovs_cmdl_command all_commands[] = {
576 : : { "create", "[db [schema]]", 0, 2, do_create, OVS_RW },
577 : : { "compact", "[db [dst]]", 0, 2, do_compact, OVS_RW },
578 : : { "convert", "[db [schema [dst]]]", 0, 3, do_convert, OVS_RW },
579 : : { "needs-conversion", NULL, 0, 2, do_needs_conversion, OVS_RO },
580 : : { "db-version", "[db]", 0, 1, do_db_version, OVS_RO },
581 : : { "db-cksum", "[db]", 0, 1, do_db_cksum, OVS_RO },
582 : : { "schema-version", "[schema]", 0, 1, do_schema_version, OVS_RO },
583 : : { "schema-cksum", "[schema]", 0, 1, do_schema_cksum, OVS_RO },
584 : : { "query", "[db] trns", 1, 2, do_query, OVS_RO },
585 : : { "transact", "[db] trns", 1, 2, do_transact, OVS_RO },
586 : : { "show-log", "[db]", 0, 1, do_show_log, OVS_RO },
587 : : { "help", NULL, 0, INT_MAX, do_help, OVS_RO },
588 : : { "list-commands", NULL, 0, INT_MAX, do_list_commands, OVS_RO },
589 : : { NULL, NULL, 0, 0, NULL, OVS_RO },
590 : : };
591 : :
592 : 1515 : static const struct ovs_cmdl_command *get_all_commands(void)
593 : : {
594 : 1515 : return all_commands;
595 : : }
|