ovsdb: Add replication support and refactor files in terms of replication.
[sliver-openvswitch.git] / ovsdb / ovsdb-tool.c
1 /*
2  * Copyright (c) 2009 Nicira Networks.
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 "command-line.h"
26 #include "compiler.h"
27 #include "file.h"
28 #include "log.h"
29 #include "json.h"
30 #include "ovsdb.h"
31 #include "ovsdb-error.h"
32 #include "table.h"
33 #include "timeval.h"
34 #include "util.h"
35
36 #include "vlog.h"
37 #define THIS_MODULE VLM_ovsdb_tool
38
39 static const struct command all_commands[];
40
41 static void usage(void) NO_RETURN;
42 static void parse_options(int argc, char *argv[]);
43
44 int
45 main(int argc, char *argv[])
46 {
47     set_program_name(argv[0]);
48     time_init();
49     vlog_init();
50     parse_options(argc, argv);
51     signal(SIGPIPE, SIG_IGN);
52     run_command(argc - optind, argv + optind, all_commands);
53     return 0;
54 }
55
56 static void
57 parse_options(int argc, char *argv[])
58 {
59     static struct option long_options[] = {
60         {"verbose", optional_argument, 0, 'v'},
61         {"help", no_argument, 0, 'h'},
62         {"version", no_argument, 0, 'V'},
63         {0, 0, 0, 0},
64     };
65     char *short_options = long_options_to_short_options(long_options);
66
67     for (;;) {
68         int c;
69
70         c = getopt_long(argc, argv, short_options, long_options, NULL);
71         if (c == -1) {
72             break;
73         }
74
75         switch (c) {
76         case 'h':
77             usage();
78
79         case 'V':
80             OVS_PRINT_VERSION(0, 0);
81             exit(EXIT_SUCCESS);
82
83         case 'v':
84             vlog_set_verbosity(optarg);
85             break;
86
87         case '?':
88             exit(EXIT_FAILURE);
89
90         default:
91             abort();
92         }
93     }
94     free(short_options);
95 }
96
97 static void
98 usage(void)
99 {
100     printf("%s: Open vSwitch database management utility\n"
101            "usage: %s [OPTIONS] COMMAND [ARG...]\n"
102            "  create DB SCHEMA   create DB with the given SCHEMA\n"
103            "  compact DB [DST]   compact DB in-place (or to DST)\n"
104            "  extract-schema DB  print DB's schema on stdout\n"
105            "  query DB TRNS      execute read-only transaction on DB\n"
106            "  transact DB TRNS   execute read/write transaction on DB\n",
107            program_name, program_name);
108     vlog_usage();
109     printf("\nOther options:\n"
110            "  -h, --help                  display this help message\n"
111            "  -V, --version               display version information\n");
112     exit(EXIT_SUCCESS);
113 }
114 \f
115 static struct json *
116 parse_json(const char *s)
117 {
118     struct json *json = json_from_string(s);
119     if (json->type == JSON_STRING) {
120         ovs_fatal(0, "\"%s\": %s", s, json->u.string);
121     }
122     return json;
123 }
124
125 static void
126 print_and_free_json(struct json *json)
127 {
128     char *string = json_to_string(json, JSSF_SORT);
129     json_destroy(json);
130     puts(string);
131     free(string);
132 }
133
134 static void
135 check_ovsdb_error(struct ovsdb_error *error)
136 {
137     if (error) {
138         ovs_fatal(0, "%s", ovsdb_error_to_string(error));
139     }
140 }
141 \f
142 static void
143 do_create(int argc UNUSED, char *argv[])
144 {
145     const char *db_file_name = argv[1];
146     const char *schema_file_name = argv[2];
147     struct ovsdb_schema *schema;
148     struct ovsdb_log *log;
149     struct json *json;
150
151     /* Read schema from file and convert to JSON. */
152     check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema));
153     json = ovsdb_schema_to_json(schema);
154
155     /* Create database file. */
156     check_ovsdb_error(ovsdb_log_open(db_file_name, O_RDWR | O_CREAT | O_EXCL,
157                                      &log));
158     check_ovsdb_error(ovsdb_log_write(log, json));
159     check_ovsdb_error(ovsdb_log_commit(log));
160     ovsdb_log_close(log);
161
162     json_destroy(json);
163 }
164
165 static void
166 transact(bool read_only, const char *db_file_name, const char *transaction)
167 {
168     struct json *request, *result;
169     struct ovsdb *db;
170
171     check_ovsdb_error(ovsdb_file_open(db_file_name, read_only, &db));
172
173     request = parse_json(transaction);
174     result = ovsdb_execute(db, request, 0, NULL);
175     json_destroy(request);
176
177     print_and_free_json(result);
178     ovsdb_destroy(db);
179 }
180
181 static void
182 do_query(int argc UNUSED, char *argv[])
183 {
184     transact(true, argv[1], argv[2]);
185 }
186
187 static void
188 do_transact(int argc UNUSED, char *argv[])
189 {
190     transact(false, argv[1], argv[2]);
191 }
192
193 static void
194 do_help(int argc UNUSED, char *argv[] UNUSED)
195 {
196     usage();
197 }
198
199 static const struct command all_commands[] = {
200     { "create", 2, 2, do_create },
201     { "query", 2, 2, do_query },
202     { "transact", 2, 2, do_transact },
203     { "help", 0, INT_MAX, do_help },
204     { NULL, 0, 0, NULL },
205 };