]>
git.proxmox.com Git - mirror_ovs.git/blob - ovsdb/ovsdb-tool.c
2 * Copyright (c) 2009, 2010 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 #define THIS_MODULE VLM_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]);
55 parse_options(argc
, argv
);
56 signal(SIGPIPE
, SIG_IGN
);
57 run_command(argc
- optind
, argv
+ optind
, all_commands
);
62 parse_options(int argc
, char *argv
[])
64 static struct option long_options
[] = {
65 {"more", no_argument
, 0, 'm'},
66 {"verbose", optional_argument
, 0, 'v'},
67 {"help", no_argument
, 0, 'h'},
68 {"version", no_argument
, 0, 'V'},
71 char *short_options
= long_options_to_short_options(long_options
);
76 c
= getopt_long(argc
, argv
, short_options
, long_options
, NULL
);
90 OVS_PRINT_VERSION(0, 0);
94 vlog_set_verbosity(optarg
);
110 printf("%s: Open vSwitch database management utility\n"
111 "usage: %s [OPTIONS] COMMAND [ARG...]\n"
112 " create DB SCHEMA create DB with the given SCHEMA\n"
113 " compact DB [DST] compact DB in-place (or to DST)\n"
114 " convert DB SCHEMA [DST] convert DB to SCHEMA (to DST)\n"
115 " extract-schema DB print DB's schema on stdout\n"
116 " query DB TRNS execute read-only transaction on DB\n"
117 " transact DB TRNS execute read/write transaction on DB\n"
118 " show-log DB prints information about DB's log entries\n",
119 program_name
, program_name
);
121 printf("\nOther options:\n"
122 " -m, --more increase show-log verbosity\n"
123 " -h, --help display this help message\n"
124 " -V, --version display version information\n");
129 parse_json(const char *s
)
131 struct json
*json
= json_from_string(s
);
132 if (json
->type
== JSON_STRING
) {
133 ovs_fatal(0, "\"%s\": %s", s
, json
->u
.string
);
139 print_and_free_json(struct json
*json
)
141 char *string
= json_to_string(json
, JSSF_SORT
);
148 check_ovsdb_error(struct ovsdb_error
*error
)
151 ovs_fatal(0, "%s", ovsdb_error_to_string(error
));
156 do_create(int argc OVS_UNUSED
, char *argv
[])
158 const char *db_file_name
= argv
[1];
159 const char *schema_file_name
= argv
[2];
160 struct ovsdb_schema
*schema
;
161 struct ovsdb_log
*log
;
164 /* Read schema from file and convert to JSON. */
165 check_ovsdb_error(ovsdb_schema_from_file(schema_file_name
, &schema
));
166 json
= ovsdb_schema_to_json(schema
);
167 ovsdb_schema_destroy(schema
);
169 /* Create database file. */
170 check_ovsdb_error(ovsdb_log_open(db_file_name
, OVSDB_LOG_CREATE
,
172 check_ovsdb_error(ovsdb_log_write(log
, json
));
173 check_ovsdb_error(ovsdb_log_commit(log
));
174 ovsdb_log_close(log
);
180 compact_or_convert(const char *src_name
, const char *dst_name
,
181 const struct ovsdb_schema
*new_schema
,
184 struct lockfile
*src_lock
;
185 struct lockfile
*dst_lock
;
186 bool in_place
= dst_name
== NULL
;
190 /* Lock the source, if we will be replacing it. */
192 retval
= lockfile_lock(src_name
, 0, &src_lock
);
194 ovs_fatal(retval
, "%s: failed to lock lockfile", src_name
);
198 /* Get (temporary) destination and lock it. */
200 dst_name
= xasprintf("%s.tmp", src_name
);
202 retval
= lockfile_lock(dst_name
, 0, &dst_lock
);
204 ovs_fatal(retval
, "%s: failed to lock lockfile", dst_name
);
208 check_ovsdb_error(new_schema
209 ? ovsdb_file_open_as_schema(src_name
, new_schema
, &db
)
210 : ovsdb_file_open(src_name
, true, &db
, NULL
));
211 check_ovsdb_error(ovsdb_file_save_copy(dst_name
, false, comment
, db
));
214 /* Replace source. */
216 if (rename(dst_name
, src_name
)) {
217 ovs_fatal(errno
, "failed to rename \"%s\" to \"%s\"",
220 fsync_parent_dir(dst_name
);
221 lockfile_unlock(src_lock
);
224 lockfile_unlock(dst_lock
);
228 do_compact(int argc OVS_UNUSED
, char *argv
[])
230 compact_or_convert(argv
[1], argv
[2], NULL
, "compacted by ovsdb-tool");
234 do_convert(int argc OVS_UNUSED
, char *argv
[])
236 const char *schema_file_name
= argv
[2];
237 struct ovsdb_schema
*new_schema
;
239 check_ovsdb_error(ovsdb_schema_from_file(schema_file_name
, &new_schema
));
240 compact_or_convert(argv
[1], argv
[3], new_schema
,
241 "converted by ovsdb-tool");
242 ovsdb_schema_destroy(new_schema
);
246 transact(bool read_only
, const char *db_file_name
, const char *transaction
)
248 struct json
*request
, *result
;
251 check_ovsdb_error(ovsdb_file_open(db_file_name
, read_only
, &db
, NULL
));
253 request
= parse_json(transaction
);
254 result
= ovsdb_execute(db
, request
, 0, NULL
);
255 json_destroy(request
);
257 print_and_free_json(result
);
262 do_query(int argc OVS_UNUSED
, char *argv
[])
264 transact(true, argv
[1], argv
[2]);
268 do_transact(int argc OVS_UNUSED
, char *argv
[])
270 transact(false, argv
[1], argv
[2]);
274 print_db_changes(struct shash
*tables
, struct shash
*names
)
276 struct shash_node
*n1
;
278 SHASH_FOR_EACH (n1
, tables
) {
279 const char *table
= n1
->name
;
280 struct json
*rows
= n1
->data
;
281 struct shash_node
*n2
;
283 if (n1
->name
[0] == '_' || rows
->type
!= JSON_OBJECT
) {
287 SHASH_FOR_EACH (n2
, json_object(rows
)) {
288 const char *row_uuid
= n2
->name
;
289 struct json
*columns
= n2
->data
;
290 struct shash_node
*n3
;
291 char *old_name
, *new_name
;
292 bool free_new_name
= false;
294 old_name
= new_name
= shash_find_data(names
, row_uuid
);
295 if (columns
->type
== JSON_OBJECT
) {
296 struct json
*new_name_json
;
298 new_name_json
= shash_find_data(json_object(columns
), "name");
300 new_name
= json_to_string(new_name_json
, JSSF_SORT
);
301 free_new_name
= true;
305 printf("\ttable %s", table
);
309 printf(" insert row %s:\n", new_name
);
311 printf(" insert row %.8s:\n", row_uuid
);
314 printf(" row %s:\n", old_name
);
317 if (columns
->type
== JSON_OBJECT
) {
318 if (show_log_verbosity
> 1) {
319 SHASH_FOR_EACH (n3
, json_object(columns
)) {
320 const char *column
= n3
->name
;
321 struct json
*value
= n3
->data
;
324 value_string
= json_to_string(value
, JSSF_SORT
);
325 printf("\t\t%s=%s\n", column
, value_string
);
330 || (new_name
!= old_name
&& strcmp(old_name
, new_name
))) {
332 shash_delete(names
, shash_find(names
, row_uuid
));
335 shash_add(names
, row_uuid
, (new_name
337 : xmemdup0(row_uuid
, 8)));
339 } else if (columns
->type
== JSON_NULL
) {
340 struct shash_node
*node
;
342 printf("\t\tdelete row\n");
343 node
= shash_find(names
, row_uuid
);
345 shash_delete(names
, node
);
358 do_show_log(int argc OVS_UNUSED
, char *argv
[])
360 const char *db_file_name
= argv
[1];
362 struct ovsdb_log
*log
;
365 check_ovsdb_error(ovsdb_log_open(db_file_name
, OVSDB_LOG_READ_ONLY
,
371 check_ovsdb_error(ovsdb_log_read(log
, &json
));
376 printf("record %u:", i
);
377 if (json
->type
== JSON_OBJECT
) {
378 struct json
*date
, *comment
;
380 date
= shash_find_data(json_object(json
), "_date");
381 if (date
&& date
->type
== JSON_INTEGER
) {
382 time_t t
= json_integer(date
);
385 strftime(s
, sizeof s
, "%Y-%m-%d %H:%M:%S", localtime(&t
));
389 comment
= shash_find_data(json_object(json
), "_comment");
390 if (comment
&& comment
->type
== JSON_STRING
) {
391 printf(" \"%s\"", json_string(comment
));
394 if (i
> 0 && show_log_verbosity
> 0) {
396 print_db_changes(json_object(json
), &names
);
403 /* XXX free 'names'. */
407 do_help(int argc OVS_UNUSED
, char *argv
[] OVS_UNUSED
)
412 static const struct command all_commands
[] = {
413 { "create", 2, 2, do_create
},
414 { "compact", 1, 2, do_compact
},
415 { "convert", 2, 3, do_convert
},
416 { "query", 2, 2, do_query
},
417 { "transact", 2, 2, do_transact
},
418 { "show-log", 1, 1, do_show_log
},
419 { "help", 0, INT_MAX
, do_help
},
420 { NULL
, 0, 0, NULL
},