]> git.proxmox.com Git - mirror_ovs.git/blame - ovn/ovn-nbd.c
ovn-nbd: Add skeleton for northbound daemon.
[mirror_ovs.git] / ovn / ovn-nbd.c
CommitLineData
ac0630a2
RB
1/*
2 * Licensed under the Apache License, Version 2.0 (the "License");
3 * you may not use this file except in compliance with the License.
4 * You may obtain a copy of the License at:
5 *
6 * http://www.apache.org/licenses/LICENSE-2.0
7 *
8 * Unless required by applicable law or agreed to in writing, software
9 * distributed under the License is distributed on an "AS IS" BASIS,
10 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 * See the License for the specific language governing permissions and
12 * limitations under the License.
13 */
14
15#include <config.h>
16
17#include <getopt.h>
18#include <stdlib.h>
19#include <stdio.h>
20
21#include "command-line.h"
22#include "dirs.h"
23#include "fatal-signal.h"
24#include "ovn/ovn-idl.h"
25#include "ovn/ovn-nb-idl.h"
26#include "poll-loop.h"
27#include "stream.h"
28#include "stream-ssl.h"
29#include "util.h"
30#include "openvswitch/vlog.h"
31
32VLOG_DEFINE_THIS_MODULE(ovn_nbd);
33
34static const char *ovnnb_db;
35static const char *ovn_db;
36
37static const char *default_db(void);
38
39static void
40usage(void)
41{
42 printf("\
43%s: OVN northbound management daemon\n\
44usage: %s [OPTIONS]\n\
45\n\
46Options:\n\
47 --ovnnb-db=DATABASE connect to ovn-nb database at DATABASE\n\
48 (default: %s)\n\
49 --ovn-db=DATABASE connect to ovn database at DATABASE\n\
50 (default: %s)\n\
51 -h, --help display this help message\n\
52 -o, --options list available options\n\
53 -V, --version display version information\n\
54", program_name, program_name, default_db(), default_db());
55 vlog_usage();
56 stream_usage("database", true, true, false);
57}
58\f
59static void
60ovnnb_db_changed(struct ovsdb_idl *idl OVS_UNUSED)
61{
62 /* XXX */
63 printf("ovn-nbd: ovn-nb db contents have changed.\n");
64}
65
66static void
67ovn_db_changed(struct ovsdb_idl *idl OVS_UNUSED)
68{
69 /* XXX */
70 printf("ovn-nbd: ovn db contents have changed.\n");
71}
72\f
73static const char *
74default_db(void)
75{
76 static char *def;
77 if (!def) {
78 def = xasprintf("unix:%s/db.sock", ovs_rundir());
79 }
80 return def;
81}
82
83static void
84parse_options(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
85{
86 enum {
87 VLOG_OPTION_ENUMS,
88 };
89 static const struct option long_options[] = {
90 {"ovn-db", required_argument, NULL, 'd'},
91 {"ovnnb-db", required_argument, NULL, 'D'},
92 {"help", no_argument, NULL, 'h'},
93 {"options", no_argument, NULL, 'o'},
94 {"version", no_argument, NULL, 'V'},
95 VLOG_LONG_OPTIONS,
96 STREAM_SSL_LONG_OPTIONS,
97 {NULL, 0, NULL, 0},
98 };
99 char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
100
101 for (;;) {
102 int c;
103
104 c = getopt_long(argc, argv, short_options, long_options, NULL);
105 if (c == -1) {
106 break;
107 }
108
109 switch (c) {
110 VLOG_OPTION_HANDLERS;
111 STREAM_SSL_OPTION_HANDLERS;
112
113 case 'd':
114 ovn_db = optarg;
115 break;
116
117 case 'D':
118 ovnnb_db = optarg;
119 break;
120
121 case 'h':
122 usage();
123 exit(EXIT_SUCCESS);
124
125 case 'o':
126 ovs_cmdl_print_options(long_options);
127 exit(EXIT_SUCCESS);
128
129 case 'V':
130 ovs_print_version(0, 0);
131 exit(EXIT_SUCCESS);
132
133 default:
134 break;
135 }
136 }
137
138 if (!ovn_db) {
139 ovn_db = default_db();
140 }
141
142 if (!ovnnb_db) {
143 ovnnb_db = default_db();
144 }
145
146 free(short_options);
147}
148
149int
150main(int argc, char *argv[])
151{
152 extern struct vlog_module VLM_reconnect;
153 struct ovsdb_idl *ovnnb_idl, *ovn_idl;
154 unsigned int ovnnb_seqno, ovn_seqno;
155 int res = EXIT_SUCCESS;
156
157 fatal_ignore_sigpipe();
158 set_program_name(argv[0]);
159 vlog_set_levels(NULL, VLF_CONSOLE, VLL_WARN);
160 vlog_set_levels(&VLM_reconnect, VLF_ANY_DESTINATION, VLL_WARN);
161 parse_options(argc, argv);
162 nbrec_init();
163 ovnrec_init();
164
165 /* We want to detect all changes to the ovn-nb db. */
166 ovnnb_idl = ovsdb_idl_create(ovnnb_db, &nbrec_idl_class, true, true);
167
168 /* There is only a small subset of changes to the ovn db that ovn-nbd has to
169 * care about, so we'll enable monitoring those directly. */
170 ovn_idl = ovsdb_idl_create(ovn_db, &ovnrec_idl_class, false, true);
171 ovsdb_idl_add_column(ovn_idl, &ovnrec_bindings_col_chassis);
172
173 /*
174 * The loop here just runs the IDL in a loop waiting for the seqno to
175 * change, which indicates that the contents of the db have changed.
176 *
177 * If the contents of the ovn-nb db change, the mappings to the ovn db must
178 * be recalculated.
179 *
180 * If the contents of the ovn db change, it means the 'up' state of a port
181 * may have changed, as that's the only type of change ovn-nbd is watching
182 * for.
183 */
184
185 ovnnb_seqno = ovsdb_idl_get_seqno(ovnnb_idl);
186 ovn_seqno = ovsdb_idl_get_seqno(ovn_idl);
187 for (;;) {
188 ovsdb_idl_run(ovnnb_idl);
189 ovsdb_idl_run(ovn_idl);
190
191 if (!ovsdb_idl_is_alive(ovnnb_idl)) {
192 int retval = ovsdb_idl_get_last_error(ovnnb_idl);
193 VLOG_ERR("%s: database connection failed (%s)",
194 ovnnb_db, ovs_retval_to_string(retval));
195 res = EXIT_FAILURE;
196 break;
197 }
198
199 if (!ovsdb_idl_is_alive(ovn_idl)) {
200 int retval = ovsdb_idl_get_last_error(ovn_idl);
201 VLOG_ERR("%s: database connection failed (%s)",
202 ovn_db, ovs_retval_to_string(retval));
203 res = EXIT_FAILURE;
204 break;
205 }
206
207 if (ovnnb_seqno != ovsdb_idl_get_seqno(ovnnb_idl)) {
208 ovnnb_seqno = ovsdb_idl_get_seqno(ovnnb_idl);
209 ovnnb_db_changed(ovnnb_idl);
210 }
211
212 if (ovn_seqno != ovsdb_idl_get_seqno(ovn_idl)) {
213 ovn_seqno = ovsdb_idl_get_seqno(ovn_idl);
214 ovn_db_changed(ovn_idl);
215 }
216
217 if (ovnnb_seqno == ovsdb_idl_get_seqno(ovnnb_idl) &&
218 ovn_seqno == ovsdb_idl_get_seqno(ovn_idl)) {
219 ovsdb_idl_wait(ovnnb_idl);
220 ovsdb_idl_wait(ovn_idl);
221 poll_block();
222 }
223 }
224
225 ovsdb_idl_destroy(ovnnb_idl);
226
227 exit(res);
228}