]> git.proxmox.com Git - mirror_ovs.git/blame - utilities/ovs-appctl.c
checkpatch: Fix regexp for if, while, etc inside macros.
[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;
9551e80b 131 unsigned int timeout = 0;
064af421 132
3fbe1d30
BP
133 target = NULL;
134 e_options = 0;
064af421
BP
135 for (;;) {
136 int option;
064af421 137
9664732f 138 option = getopt_long(argc, argv, short_options, long_options, NULL);
064af421
BP
139 if (option == -1) {
140 break;
141 }
064af421
BP
142 switch (option) {
143 case 't':
3fbe1d30
BP
144 if (target) {
145 ovs_fatal(0, "-t or --target may be specified only once");
064af421 146 }
3fbe1d30 147 target = optarg;
064af421
BP
148 break;
149
150 case 'e':
3fbe1d30
BP
151 /* We ignore -e for compatibility. Older versions specified the
152 * command as the argument to -e. Since the current version takes
153 * the command as non-option arguments and we say that -e has no
154 * arguments, this just works in the common case. */
155 if (e_options++) {
156 ovs_fatal(0, "-e or --execute may be speciifed only once");
064af421
BP
157 }
158 break;
159
160 case 'h':
3fbe1d30 161 usage();
064af421
BP
162 break;
163
66fa2c88 164 case 'o':
5f383751 165 ovs_cmdl_print_options(long_options);
66fa2c88
AW
166 exit(EXIT_SUCCESS);
167
f4ec6ff4 168 case 'T':
cbcf40a8
IM
169 if (!str_to_uint(optarg, 10, &timeout) || !timeout) {
170 ovs_fatal(0, "value %s on -T or --timeout is invalid", optarg);
cbcf40a8 171 }
f4ec6ff4
EJ
172 break;
173
064af421 174 case 'V':
55d5bb44 175 ovs_print_version(0, 0);
064af421
BP
176 exit(EXIT_SUCCESS);
177
9664732f
BP
178 VLOG_OPTION_HANDLERS
179
064af421
BP
180 case '?':
181 exit(EXIT_FAILURE);
182
183 default:
428b2edd 184 OVS_NOT_REACHED();
064af421
BP
185 }
186 }
9664732f
BP
187 free(short_options_);
188 free(short_options);
3fbe1d30 189
9551e80b
IM
190 ctl_timeout_setup(timeout);
191
3fbe1d30
BP
192 if (optind >= argc) {
193 ovs_fatal(0, "at least one non-option argument is required "
194 "(use --help for help)");
195 }
196
197 return target ? target : "ovs-vswitchd";
198}
199
bde9f75d 200static struct jsonrpc *
3fbe1d30
BP
201connect_to_target(const char *target)
202{
bde9f75d 203 struct jsonrpc *client;
3fbe1d30
BP
204 char *socket_name;
205 int error;
206
a085daef 207#ifndef _WIN32
3fbe1d30
BP
208 if (target[0] != '/') {
209 char *pidfile_name;
3fbe1d30
BP
210 pid_t pid;
211
b43c6fe2 212 pidfile_name = xasprintf("%s/%s.pid", ovs_rundir(), target);
3fbe1d30
BP
213 pid = read_pidfile(pidfile_name);
214 if (pid < 0) {
215 ovs_fatal(-pid, "cannot read pidfile \"%s\"", pidfile_name);
216 }
217 free(pidfile_name);
218 socket_name = xasprintf("%s/%s.%ld.ctl",
b43c6fe2 219 ovs_rundir(), target, (long int) pid);
a085daef
GS
220#else
221 /* On windows, if the 'target' contains ':', we make an assumption that
222 * it is an absolute path. */
223 if (!strchr(target, ':')) {
224 socket_name = xasprintf("%s/%s.ctl", ovs_rundir(), target);
225#endif
3fbe1d30
BP
226 } else {
227 socket_name = xstrdup(target);
228 }
229
230 error = unixctl_client_create(socket_name, &client);
231 if (error) {
232 ovs_fatal(error, "cannot connect to \"%s\"", socket_name);
064af421 233 }
3fbe1d30
BP
234 free(socket_name);
235
236 return client;
064af421 237}
3fbe1d30 238