]>
git.proxmox.com Git - ovs.git/blob - ovsdb/ovsdb-tool.c
2 * Copyright (c) 2009, 2010, 2011 Nicira Networks.
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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
25 #include "command-line.h"
32 #include "ovsdb-error.h"
33 #include "socket-util.h"
39 VLOG_DEFINE_THIS_MODULE(ovsdb_tool
);
41 /* -m, --more: Verbosity level for "show-log" command output. */
42 static int show_log_verbosity
;
44 static const struct command all_commands
[];
46 static void usage(void) NO_RETURN
;
47 static void parse_options(int argc
, char *argv
[]);
50 main(int argc
, char *argv
[])
52 set_program_name(argv
[0]);
53 parse_options(argc
, argv
);
54 signal(SIGPIPE
, SIG_IGN
);
55 run_command(argc
- optind
, argv
+ optind
, all_commands
);
60 parse_options(int argc
, char *argv
[])
62 static struct option long_options
[] = {
63 {"more", no_argument
, NULL
, 'm'},
64 {"verbose", optional_argument
, NULL
, 'v'},
65 {"help", no_argument
, NULL
, 'h'},
66 {"version", no_argument
, NULL
, 'V'},
69 char *short_options
= long_options_to_short_options(long_options
);
74 c
= getopt_long(argc
, argv
, short_options
, long_options
, NULL
);
88 OVS_PRINT_VERSION(0, 0);
92 vlog_set_verbosity(optarg
);
108 printf("%s: Open vSwitch database management utility\n"
109 "usage: %s [OPTIONS] COMMAND [ARG...]\n"
110 " create DB SCHEMA create DB with the given SCHEMA\n"
111 " compact DB [DST] compact DB in-place (or to DST)\n"
112 " convert DB SCHEMA [DST] convert DB to SCHEMA (to DST)\n"
113 " db-version DB report version of schema used by DB\n"
114 " db-cksum DB report checksum of schema used by DB\n"
115 " schema-version SCHEMA report SCHEMA's schema version\n"
116 " schema-cksum SCHEMA report SCHEMA's checksum\n"
117 " query DB TRNS execute read-only transaction on DB\n"
118 " transact DB TRNS execute read/write transaction on DB\n"
119 " show-log DB prints information about DB's log entries\n",
120 program_name
, program_name
);
122 printf("\nOther options:\n"
123 " -m, --more increase show-log verbosity\n"
124 " -h, --help display this help message\n"
125 " -V, --version display version information\n");
130 parse_json(const char *s
)
132 struct json
*json
= json_from_string(s
);
133 if (json
->type
== JSON_STRING
) {
134 ovs_fatal(0, "\"%s\": %s", s
, json
->u
.string
);
140 print_and_free_json(struct json
*json
)
142 char *string
= json_to_string(json
, JSSF_SORT
);
149 check_ovsdb_error(struct ovsdb_error
*error
)
152 ovs_fatal(0, "%s", ovsdb_error_to_string(error
));
157 do_create(int argc OVS_UNUSED
, char *argv
[])
159 const char *db_file_name
= argv
[1];
160 const char *schema_file_name
= argv
[2];
161 struct ovsdb_schema
*schema
;
162 struct ovsdb_log
*log
;
165 /* Read schema from file and convert to JSON. */
166 check_ovsdb_error(ovsdb_schema_from_file(schema_file_name
, &schema
));
167 json
= ovsdb_schema_to_json(schema
);
168 ovsdb_schema_destroy(schema
);
170 /* Create database file. */
171 check_ovsdb_error(ovsdb_log_open(db_file_name
, OVSDB_LOG_CREATE
,
173 check_ovsdb_error(ovsdb_log_write(log
, json
));
174 check_ovsdb_error(ovsdb_log_commit(log
));
175 ovsdb_log_close(log
);
181 compact_or_convert(const char *src_name
, const char *dst_name
,
182 const struct ovsdb_schema
*new_schema
,
185 struct lockfile
*src_lock
;
186 struct lockfile
*dst_lock
;
187 bool in_place
= dst_name
== NULL
;
191 /* Lock the source, if we will be replacing it. */
193 retval
= lockfile_lock(src_name
, 0, &src_lock
);
195 ovs_fatal(retval
, "%s: failed to lock lockfile", src_name
);
199 /* Get (temporary) destination and lock it. */
201 dst_name
= xasprintf("%s.tmp", src_name
);
203 retval
= lockfile_lock(dst_name
, 0, &dst_lock
);
205 ovs_fatal(retval
, "%s: failed to lock lockfile", dst_name
);
209 check_ovsdb_error(new_schema
210 ? ovsdb_file_open_as_schema(src_name
, new_schema
, &db
)
211 : ovsdb_file_open(src_name
, true, &db
, NULL
));
212 check_ovsdb_error(ovsdb_file_save_copy(dst_name
, false, comment
, db
));
215 /* Replace source. */
217 if (rename(dst_name
, src_name
)) {
218 ovs_fatal(errno
, "failed to rename \"%s\" to \"%s\"",
221 fsync_parent_dir(dst_name
);
222 lockfile_unlock(src_lock
);
225 lockfile_unlock(dst_lock
);
229 do_compact(int argc OVS_UNUSED
, char *argv
[])
231 compact_or_convert(argv
[1], argv
[2], NULL
, "compacted by ovsdb-tool");
235 do_convert(int argc OVS_UNUSED
, char *argv
[])
237 const char *schema_file_name
= argv
[2];
238 struct ovsdb_schema
*new_schema
;
240 check_ovsdb_error(ovsdb_schema_from_file(schema_file_name
, &new_schema
));
241 compact_or_convert(argv
[1], argv
[3], new_schema
,
242 "converted by ovsdb-tool");
243 ovsdb_schema_destroy(new_schema
);
247 do_needs_conversion(int argc OVS_UNUSED
, char *argv
[])
249 const char *db_file_name
= argv
[1];
250 const char *schema_file_name
= argv
[2];
251 struct ovsdb_schema
*schema1
, *schema2
;
253 check_ovsdb_error(ovsdb_file_read_schema(db_file_name
, &schema1
));
254 check_ovsdb_error(ovsdb_schema_from_file(schema_file_name
, &schema2
));
255 puts(ovsdb_schema_equal(schema1
, schema2
) ? "no" : "yes");
256 ovsdb_schema_destroy(schema1
);
257 ovsdb_schema_destroy(schema2
);
261 do_db_version(int argc OVS_UNUSED
, char *argv
[])
263 const char *db_file_name
= argv
[1];
264 struct ovsdb_schema
*schema
;
266 check_ovsdb_error(ovsdb_file_read_schema(db_file_name
, &schema
));
267 puts(schema
->version
);
268 ovsdb_schema_destroy(schema
);
272 do_db_cksum(int argc OVS_UNUSED
, char *argv
[])
274 const char *db_file_name
= argv
[1];
275 struct ovsdb_schema
*schema
;
277 check_ovsdb_error(ovsdb_file_read_schema(db_file_name
, &schema
));
279 ovsdb_schema_destroy(schema
);
283 do_schema_version(int argc OVS_UNUSED
, char *argv
[])
285 const char *schema_file_name
= argv
[1];
286 struct ovsdb_schema
*schema
;
288 check_ovsdb_error(ovsdb_schema_from_file(schema_file_name
, &schema
));
289 puts(schema
->version
);
290 ovsdb_schema_destroy(schema
);
294 do_schema_cksum(int argc OVS_UNUSED
, char *argv
[])
296 const char *schema_file_name
= argv
[1];
297 struct ovsdb_schema
*schema
;
299 check_ovsdb_error(ovsdb_schema_from_file(schema_file_name
, &schema
));
301 ovsdb_schema_destroy(schema
);
305 transact(bool read_only
, const char *db_file_name
, const char *transaction
)
307 struct json
*request
, *result
;
310 check_ovsdb_error(ovsdb_file_open(db_file_name
, read_only
, &db
, NULL
));
312 request
= parse_json(transaction
);
313 result
= ovsdb_execute(db
, request
, 0, NULL
);
314 json_destroy(request
);
316 print_and_free_json(result
);
321 do_query(int argc OVS_UNUSED
, char *argv
[])
323 transact(true, argv
[1], argv
[2]);
327 do_transact(int argc OVS_UNUSED
, char *argv
[])
329 transact(false, argv
[1], argv
[2]);
333 print_db_changes(struct shash
*tables
, struct shash
*names
)
335 struct shash_node
*n1
;
337 SHASH_FOR_EACH (n1
, tables
) {
338 const char *table
= n1
->name
;
339 struct json
*rows
= n1
->data
;
340 struct shash_node
*n2
;
342 if (n1
->name
[0] == '_' || rows
->type
!= JSON_OBJECT
) {
346 SHASH_FOR_EACH (n2
, json_object(rows
)) {
347 const char *row_uuid
= n2
->name
;
348 struct json
*columns
= n2
->data
;
349 struct shash_node
*n3
;
350 char *old_name
, *new_name
;
351 bool free_new_name
= false;
353 old_name
= new_name
= shash_find_data(names
, row_uuid
);
354 if (columns
->type
== JSON_OBJECT
) {
355 struct json
*new_name_json
;
357 new_name_json
= shash_find_data(json_object(columns
), "name");
359 new_name
= json_to_string(new_name_json
, JSSF_SORT
);
360 free_new_name
= true;
364 printf("\ttable %s", table
);
368 printf(" insert row %s:\n", new_name
);
370 printf(" insert row %.8s:\n", row_uuid
);
373 printf(" row %s:\n", old_name
);
376 if (columns
->type
== JSON_OBJECT
) {
377 if (show_log_verbosity
> 1) {
378 SHASH_FOR_EACH (n3
, json_object(columns
)) {
379 const char *column
= n3
->name
;
380 struct json
*value
= n3
->data
;
383 value_string
= json_to_string(value
, JSSF_SORT
);
384 printf("\t\t%s=%s\n", column
, value_string
);
389 || (new_name
!= old_name
&& strcmp(old_name
, new_name
))) {
391 shash_delete(names
, shash_find(names
, row_uuid
));
394 shash_add(names
, row_uuid
, (new_name
396 : xmemdup0(row_uuid
, 8)));
398 } else if (columns
->type
== JSON_NULL
) {
399 struct shash_node
*node
;
401 printf("\t\tdelete row\n");
402 node
= shash_find(names
, row_uuid
);
404 shash_delete(names
, node
);
417 do_show_log(int argc OVS_UNUSED
, char *argv
[])
419 const char *db_file_name
= argv
[1];
421 struct ovsdb_log
*log
;
424 check_ovsdb_error(ovsdb_log_open(db_file_name
, OVSDB_LOG_READ_ONLY
,
430 check_ovsdb_error(ovsdb_log_read(log
, &json
));
435 printf("record %u:", i
);
436 if (json
->type
== JSON_OBJECT
) {
437 struct json
*date
, *comment
;
439 date
= shash_find_data(json_object(json
), "_date");
440 if (date
&& date
->type
== JSON_INTEGER
) {
441 time_t t
= json_integer(date
);
444 strftime(s
, sizeof s
, "%Y-%m-%d %H:%M:%S", localtime(&t
));
448 comment
= shash_find_data(json_object(json
), "_comment");
449 if (comment
&& comment
->type
== JSON_STRING
) {
450 printf(" \"%s\"", json_string(comment
));
453 if (i
> 0 && show_log_verbosity
> 0) {
455 print_db_changes(json_object(json
), &names
);
462 ovsdb_log_close(log
);
463 /* XXX free 'names'. */
467 do_help(int argc OVS_UNUSED
, char *argv
[] OVS_UNUSED
)
472 static const struct command all_commands
[] = {
473 { "create", 2, 2, do_create
},
474 { "compact", 1, 2, do_compact
},
475 { "convert", 2, 3, do_convert
},
476 { "needs-conversion", 2, 2, do_needs_conversion
},
477 { "db-version", 1, 1, do_db_version
},
478 { "db-cksum", 1, 1, do_db_cksum
},
479 { "schema-version", 1, 1, do_schema_version
},
480 { "schema-cksum", 1, 1, do_schema_cksum
},
481 { "query", 2, 2, do_query
},
482 { "transact", 2, 2, do_transact
},
483 { "show-log", 1, 1, do_show_log
},
484 { "help", 0, INT_MAX
, do_help
},
485 { NULL
, 0, 0, NULL
},