]> git.proxmox.com Git - mirror_ovs.git/blob - vswitchd/ovs-vswitchd.c
Configurable Link State Change (LSC) detection mode
[mirror_ovs.git] / vswitchd / ovs-vswitchd.c
1 /* Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <config.h>
17
18 #include <errno.h>
19 #include <getopt.h>
20 #include <limits.h>
21 #include <signal.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #ifdef HAVE_MLOCKALL
25 #include <sys/mman.h>
26 #endif
27
28 #include "bridge.h"
29 #include "command-line.h"
30 #include "compiler.h"
31 #include "daemon.h"
32 #include "dirs.h"
33 #include "dpif.h"
34 #include "dummy.h"
35 #include "fatal-signal.h"
36 #include "memory.h"
37 #include "netdev.h"
38 #include "openflow/openflow.h"
39 #include "ovsdb-idl.h"
40 #include "ovs-rcu.h"
41 #include "ovs-router.h"
42 #include "openvswitch/poll-loop.h"
43 #include "simap.h"
44 #include "stream-ssl.h"
45 #include "stream.h"
46 #include "svec.h"
47 #include "timeval.h"
48 #include "unixctl.h"
49 #include "util.h"
50 #include "openvswitch/vconn.h"
51 #include "openvswitch/vlog.h"
52 #include "lib/vswitch-idl.h"
53
54 VLOG_DEFINE_THIS_MODULE(vswitchd);
55
56 /* --mlockall: If set, locks all process memory into physical RAM, preventing
57 * the kernel from paging any of its memory to disk. */
58 static bool want_mlockall;
59
60 static unixctl_cb_func ovs_vswitchd_exit;
61
62 static char *parse_options(int argc, char *argv[], char **unixctl_path);
63 OVS_NO_RETURN static void usage(void);
64
65 struct ovs_vswitchd_exit_args {
66 bool *exiting;
67 bool *cleanup;
68 };
69
70 int
71 main(int argc, char *argv[])
72 {
73 char *unixctl_path = NULL;
74 struct unixctl_server *unixctl;
75 char *remote;
76 bool exiting, cleanup;
77 struct ovs_vswitchd_exit_args exit_args = {&exiting, &cleanup};
78 int retval;
79
80 set_program_name(argv[0]);
81
82 ovs_cmdl_proctitle_init(argc, argv);
83 service_start(&argc, &argv);
84 remote = parse_options(argc, argv, &unixctl_path);
85 fatal_ignore_sigpipe();
86
87 daemonize_start(true);
88
89 if (want_mlockall) {
90 #ifdef HAVE_MLOCKALL
91 if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
92 VLOG_ERR("mlockall failed: %s", ovs_strerror(errno));
93 }
94 #else
95 VLOG_ERR("mlockall not supported on this system");
96 #endif
97 }
98
99 retval = unixctl_server_create(unixctl_path, &unixctl);
100 if (retval) {
101 exit(EXIT_FAILURE);
102 }
103 unixctl_command_register("exit", "[--cleanup]", 0, 1,
104 ovs_vswitchd_exit, &exit_args);
105
106 bridge_init(remote);
107 free(remote);
108
109 exiting = false;
110 cleanup = false;
111 while (!exiting) {
112 memory_run();
113 if (memory_should_report()) {
114 struct simap usage;
115
116 simap_init(&usage);
117 bridge_get_memory_usage(&usage);
118 memory_report(&usage);
119 simap_destroy(&usage);
120 }
121 bridge_run();
122 unixctl_server_run(unixctl);
123 netdev_run();
124
125 memory_wait();
126 bridge_wait();
127 unixctl_server_wait(unixctl);
128 netdev_wait();
129 if (exiting) {
130 poll_immediate_wake();
131 }
132 poll_block();
133 if (should_service_stop()) {
134 exiting = true;
135 }
136 }
137 bridge_exit(cleanup);
138 unixctl_server_destroy(unixctl);
139 service_stop();
140 vlog_disable_async();
141 ovsrcu_exit();
142
143 return 0;
144 }
145
146 static char *
147 parse_options(int argc, char *argv[], char **unixctl_pathp)
148 {
149 enum {
150 OPT_PEER_CA_CERT = UCHAR_MAX + 1,
151 OPT_MLOCKALL,
152 OPT_UNIXCTL,
153 VLOG_OPTION_ENUMS,
154 OPT_BOOTSTRAP_CA_CERT,
155 OPT_ENABLE_DUMMY,
156 OPT_DISABLE_SYSTEM,
157 DAEMON_OPTION_ENUMS,
158 OPT_DPDK,
159 SSL_OPTION_ENUMS,
160 OPT_DUMMY_NUMA,
161 };
162 static const struct option long_options[] = {
163 {"help", no_argument, NULL, 'h'},
164 {"version", no_argument, NULL, 'V'},
165 {"mlockall", no_argument, NULL, OPT_MLOCKALL},
166 {"unixctl", required_argument, NULL, OPT_UNIXCTL},
167 DAEMON_LONG_OPTIONS,
168 VLOG_LONG_OPTIONS,
169 STREAM_SSL_LONG_OPTIONS,
170 {"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
171 {"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT},
172 {"enable-dummy", optional_argument, NULL, OPT_ENABLE_DUMMY},
173 {"disable-system", no_argument, NULL, OPT_DISABLE_SYSTEM},
174 {"dpdk", optional_argument, NULL, OPT_DPDK},
175 {"dummy-numa", required_argument, NULL, OPT_DUMMY_NUMA},
176 {NULL, 0, NULL, 0},
177 };
178 char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
179
180 for (;;) {
181 int c;
182
183 c = getopt_long(argc, argv, short_options, long_options, NULL);
184 if (c == -1) {
185 break;
186 }
187
188 switch (c) {
189 case 'h':
190 usage();
191
192 case 'V':
193 ovs_print_version(0, 0);
194 print_dpdk_version();
195 exit(EXIT_SUCCESS);
196
197 case OPT_MLOCKALL:
198 want_mlockall = true;
199 break;
200
201 case OPT_UNIXCTL:
202 *unixctl_pathp = optarg;
203 break;
204
205 VLOG_OPTION_HANDLERS
206 DAEMON_OPTION_HANDLERS
207 STREAM_SSL_OPTION_HANDLERS
208
209 case OPT_PEER_CA_CERT:
210 stream_ssl_set_peer_ca_cert_file(optarg);
211 break;
212
213 case OPT_BOOTSTRAP_CA_CERT:
214 stream_ssl_set_ca_cert_file(optarg, true);
215 break;
216
217 case OPT_ENABLE_DUMMY:
218 dummy_enable(optarg);
219 break;
220
221 case OPT_DISABLE_SYSTEM:
222 dp_blacklist_provider("system");
223 ovs_router_disable_system_routing_table();
224 break;
225
226 case '?':
227 exit(EXIT_FAILURE);
228
229 case OPT_DPDK:
230 ovs_fatal(0, "Using --dpdk to configure DPDK is not supported.");
231 break;
232
233 case OPT_DUMMY_NUMA:
234 ovs_numa_set_dummy(optarg);
235 break;
236
237 default:
238 abort();
239 }
240 }
241 free(short_options);
242
243 argc -= optind;
244 argv += optind;
245
246 switch (argc) {
247 case 0:
248 return xasprintf("unix:%s/db.sock", ovs_rundir());
249
250 case 1:
251 return xstrdup(argv[0]);
252
253 default:
254 VLOG_FATAL("at most one non-option argument accepted; "
255 "use --help for usage");
256 }
257 }
258
259 static void
260 usage(void)
261 {
262 printf("%s: Open vSwitch daemon\n"
263 "usage: %s [OPTIONS] [DATABASE]\n"
264 "where DATABASE is a socket on which ovsdb-server is listening\n"
265 " (default: \"unix:%s/db.sock\").\n",
266 program_name, program_name, ovs_rundir());
267 stream_usage("DATABASE", true, false, true);
268 daemon_usage();
269 vlog_usage();
270 printf("\nDPDK options:\n"
271 "Configuration of DPDK via command-line is removed from this\n"
272 "version of Open vSwitch. DPDK is configured through ovsdb.\n"
273 );
274 printf("\nOther options:\n"
275 " --unixctl=SOCKET override default control socket name\n"
276 " -h, --help display this help message\n"
277 " -V, --version display version information\n");
278 exit(EXIT_SUCCESS);
279 }
280
281 static void
282 ovs_vswitchd_exit(struct unixctl_conn *conn, int argc,
283 const char *argv[], void *exit_args_)
284 {
285 struct ovs_vswitchd_exit_args *exit_args = exit_args_;
286 *exit_args->exiting = true;
287 *exit_args->cleanup = argc == 2 && !strcmp(argv[1], "--cleanup");
288 unixctl_command_reply(conn, NULL);
289 }