]> git.proxmox.com Git - mirror_ovs.git/blame - utilities/ovs-appctl.c
ovs-tcpundump: Fix incompatibilities with python3
[mirror_ovs.git] / utilities / ovs-appctl.c
CommitLineData
064af421 1/*
9664732f 2 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2014 Nicira, Inc.
064af421 3 *
a14bc59f
BP
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:
064af421 7 *
a14bc59f
BP
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.
064af421 15 */
3fbe1d30 16
064af421 17#include <config.h>
064af421 18
064af421
BP
19#include <errno.h>
20#include <getopt.h>
064af421
BP
21#include <stdio.h>
22#include <string.h>
23#include <stdlib.h>
24
25#include "command-line.h"
3fbe1d30
BP
26#include "daemon.h"
27#include "dirs.h"
3e8a2ad1 28#include "openvswitch/dynamic-string.h"
bde9f75d 29#include "jsonrpc.h"
0e15264f 30#include "process.h"
064af421
BP
31#include "timeval.h"
32#include "unixctl.h"
33#include "util.h"
e6211adc 34#include "openvswitch/vlog.h"
064af421 35
3fbe1d30
BP
36static void usage(void);
37static const char *parse_command_line(int argc, char *argv[]);
bde9f75d 38static struct jsonrpc *connect_to_target(const char *target);
064af421 39
3fbe1d30
BP
40int
41main(int argc, char *argv[])
064af421 42{
bde9f75d
EJ
43 char *cmd_result, *cmd_error;
44 struct jsonrpc *client;
45 char *cmd, **cmd_argv;
3fbe1d30 46 const char *target;
bde9f75d
EJ
47 int cmd_argc;
48 int error;
3fbe1d30
BP
49
50 set_program_name(argv[0]);
3fbe1d30
BP
51
52 /* Parse command line and connect to target. */
53 target = parse_command_line(argc, argv);
54 client = connect_to_target(target);
55
3fbe1d30 56 /* Transact request and process reply. */
bde9f75d
EJ
57 cmd = argv[optind++];
58 cmd_argc = argc - optind;
59 cmd_argv = cmd_argc ? argv + optind : NULL;
60 error = unixctl_client_transact(client, cmd, cmd_argc, cmd_argv,
61 &cmd_result, &cmd_error);
064af421 62 if (error) {
3fbe1d30
BP
63 ovs_fatal(error, "%s: transaction error", target);
64 }
bde9f75d
EJ
65
66 if (cmd_error) {
156f7a40 67 jsonrpc_close(client);
bde9f75d
EJ
68 fputs(cmd_error, stderr);
69 ovs_error(0, "%s: server returned an error", target);
3fbe1d30 70 exit(2);
bde9f75d
EJ
71 } else if (cmd_result) {
72 fputs(cmd_result, stdout);
73 } else {
428b2edd 74 OVS_NOT_REACHED();
064af421 75 }
65f92a50 76
bde9f75d
EJ
77 jsonrpc_close(client);
78 free(cmd_result);
79 free(cmd_error);
3fbe1d30 80 return 0;
064af421
BP
81}
82
83static void
3fbe1d30 84usage(void)
064af421 85{
c1a543a8
BP
86 printf("\
87%s, for querying and controlling Open vSwitch daemon\n\
88usage: %s [TARGET] COMMAND [ARG...]\n\
89Targets:\n\
90 -t, --target=TARGET pidfile or socket to contact\n\
91Common commands:\n\
91a11f5b 92 list-commands List commands supported by the target\n\
d5e1e5ed 93 version Print version of the target\n\
c1a543a8 94 vlog/list List current logging levels\n\
532e1463 95 vlog/list-pattern List logging patterns for each destination.\n\
2a3e30b2
BP
96 vlog/set [SPEC]\n\
97 Set log levels as detailed in SPEC, which may include:\n\
98 A valid module name (all modules, by default)\n\
d5460484 99 'syslog', 'console', 'file' (all destinations, by default))\n\
2a3e30b2 100 'off', 'emer', 'err', 'warn', 'info', or 'dbg' ('dbg', bydefault)\n\
c1a543a8
BP
101 vlog/reopen Make the program reopen its log file\n\
102Other options:\n\
f4ec6ff4 103 --timeout=SECS wait at most SECS seconds for a response\n\
c1a543a8 104 -h, --help Print this helpful information\n\
d5e1e5ed 105 -V, --version Display ovs-appctl version information\n",
3fbe1d30
BP
106 program_name, program_name);
107 exit(EXIT_SUCCESS);
064af421
BP
108}
109
3fbe1d30
BP
110static const char *
111parse_command_line(int argc, char *argv[])
064af421 112{
9664732f 113 enum {
66fa2c88 114 OPT_START = UCHAR_MAX + 1,
9664732f
BP
115 VLOG_OPTION_ENUMS
116 };
064af421 117 static const struct option long_options[] = {
064af421 118 {"target", required_argument, NULL, 't'},
3fbe1d30 119 {"execute", no_argument, NULL, 'e'},
064af421 120 {"help", no_argument, NULL, 'h'},
66fa2c88 121 {"option", no_argument, NULL, 'o'},
064af421 122 {"version", no_argument, NULL, 'V'},
f4ec6ff4 123 {"timeout", required_argument, NULL, 'T'},
9664732f 124 VLOG_LONG_OPTIONS,
e3c17733 125 {NULL, 0, NULL, 0},
064af421 126 };
5f383751 127 char *short_options_ = ovs_cmdl_long_options_to_short_options(long_options);
9664732f 128 char *short_options = xasprintf("+%s", short_options_);
3fbe1d30
BP
129 const char *target;
130 int e_options;
064af421 131
3fbe1d30
BP
132 target = NULL;
133 e_options = 0;
064af421
BP
134 for (;;) {
135 int option;
064af421 136
9664732f 137 option = getopt_long(argc, argv, short_options, long_options, NULL);
064af421
BP
138 if (option == -1) {
139 break;
140 }
064af421
BP
141 switch (option) {
142 case 't':
3fbe1d30
BP
143 if (target) {
144 ovs_fatal(0, "-t or --target may be specified only once");
064af421 145 }
3fbe1d30 146 target = optarg;
064af421
BP
147 break;
148
149 case 'e':
3fbe1d30
BP
150 /* We ignore -e for compatibility. Older versions specified the
151 * command as the argument to -e. Since the current version takes
152 * the command as non-option arguments and we say that -e has no
153 * arguments, this just works in the common case. */
154 if (e_options++) {
155 ovs_fatal(0, "-e or --execute may be speciifed only once");
064af421
BP
156 }
157 break;
158
159 case 'h':
3fbe1d30 160 usage();
064af421
BP
161 break;
162
66fa2c88 163 case 'o':
5f383751 164 ovs_cmdl_print_options(long_options);
66fa2c88
AW
165 exit(EXIT_SUCCESS);
166
f4ec6ff4
EJ
167 case 'T':
168 time_alarm(atoi(optarg));
169 break;
170
064af421 171 case 'V':
55d5bb44 172 ovs_print_version(0, 0);
064af421
BP
173 exit(EXIT_SUCCESS);
174
9664732f
BP
175 VLOG_OPTION_HANDLERS
176
064af421
BP
177 case '?':
178 exit(EXIT_FAILURE);
179
180 default:
428b2edd 181 OVS_NOT_REACHED();
064af421
BP
182 }
183 }
9664732f
BP
184 free(short_options_);
185 free(short_options);
3fbe1d30
BP
186
187 if (optind >= argc) {
188 ovs_fatal(0, "at least one non-option argument is required "
189 "(use --help for help)");
190 }
191
192 return target ? target : "ovs-vswitchd";
193}
194
bde9f75d 195static struct jsonrpc *
3fbe1d30
BP
196connect_to_target(const char *target)
197{
bde9f75d 198 struct jsonrpc *client;
3fbe1d30
BP
199 char *socket_name;
200 int error;
201
a085daef 202#ifndef _WIN32
3fbe1d30
BP
203 if (target[0] != '/') {
204 char *pidfile_name;
3fbe1d30
BP
205 pid_t pid;
206
b43c6fe2 207 pidfile_name = xasprintf("%s/%s.pid", ovs_rundir(), target);
3fbe1d30
BP
208 pid = read_pidfile(pidfile_name);
209 if (pid < 0) {
210 ovs_fatal(-pid, "cannot read pidfile \"%s\"", pidfile_name);
211 }
212 free(pidfile_name);
213 socket_name = xasprintf("%s/%s.%ld.ctl",
b43c6fe2 214 ovs_rundir(), target, (long int) pid);
a085daef
GS
215#else
216 /* On windows, if the 'target' contains ':', we make an assumption that
217 * it is an absolute path. */
218 if (!strchr(target, ':')) {
219 socket_name = xasprintf("%s/%s.ctl", ovs_rundir(), target);
220#endif
3fbe1d30
BP
221 } else {
222 socket_name = xstrdup(target);
223 }
224
225 error = unixctl_client_create(socket_name, &client);
226 if (error) {
227 ovs_fatal(error, "cannot connect to \"%s\"", socket_name);
064af421 228 }
3fbe1d30
BP
229 free(socket_name);
230
231 return client;
064af421 232}
3fbe1d30 233