]>
Commit | Line | Data |
---|---|---|
3c016b8b BP |
1 | /* Copyright (c) 2015 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 <getopt.h> | |
19 | ||
20 | #include "command-line.h" | |
21 | #include "daemon.h" | |
22 | #include "fatal-signal.h" | |
23 | #include "openvswitch/vlog.h" | |
24 | #include "ovstest.h" | |
25 | #include "poll-loop.h" | |
26 | #include "unixctl.h" | |
27 | #include "util.h" | |
28 | ||
29 | VLOG_DEFINE_THIS_MODULE(test_unixctl); | |
30 | ||
31 | static void parse_options(int *argc, char **argvp[], char **unixctl_pathp); | |
32 | OVS_NO_RETURN static void usage(void); | |
33 | ||
34 | static void | |
35 | test_unixctl_exit(struct unixctl_conn *conn, int argc OVS_UNUSED, | |
36 | const char *argv[] OVS_UNUSED, void *exiting_) | |
37 | { | |
38 | bool *exiting = exiting_; | |
39 | *exiting = true; | |
40 | unixctl_command_reply(conn, NULL); | |
41 | } | |
42 | ||
43 | static void | |
44 | test_unixctl_echo(struct unixctl_conn *conn, int argc OVS_UNUSED, | |
45 | const char *argv[], void *aux OVS_UNUSED) | |
46 | { | |
47 | unixctl_command_reply(conn, argv[1]); | |
48 | } | |
49 | ||
50 | static void | |
51 | test_unixctl_echo_error(struct unixctl_conn *conn, int argc OVS_UNUSED, | |
52 | const char *argv[], void *aux OVS_UNUSED) | |
53 | { | |
54 | unixctl_command_reply_error(conn, argv[1]); | |
55 | } | |
56 | ||
57 | static void | |
58 | test_unixctl_log(struct unixctl_conn *conn, int argc OVS_UNUSED, | |
59 | const char *argv[], void *aux OVS_UNUSED) | |
60 | { | |
61 | VLOG_INFO("%s", argv[1]); | |
62 | unixctl_command_reply(conn, NULL); | |
63 | } | |
64 | ||
65 | static void | |
66 | test_unixctl_block(struct unixctl_conn *conn OVS_UNUSED, int argc OVS_UNUSED, | |
67 | const char *argv[] OVS_UNUSED, void *aux OVS_UNUSED) | |
68 | { | |
69 | VLOG_INFO("%s", argv[1]); | |
70 | unixctl_command_reply(conn, NULL); | |
71 | } | |
72 | ||
73 | static int | |
74 | test_unixctl_main(int argc, char *argv[]) | |
75 | { | |
76 | char *unixctl_path = NULL; | |
77 | struct unixctl_server *unixctl; | |
78 | bool exiting = false; | |
79 | ||
80 | ovs_cmdl_proctitle_init(argc, argv); | |
81 | set_program_name(argv[0]); | |
82 | service_start(&argc, &argv); | |
83 | fatal_ignore_sigpipe(); | |
84 | parse_options(&argc, &argv, &unixctl_path); | |
85 | ||
86 | daemonize_start(false); | |
87 | int retval = unixctl_server_create(unixctl_path, &unixctl); | |
88 | if (retval) { | |
89 | exit(EXIT_FAILURE); | |
90 | } | |
91 | unixctl_command_register("exit", "", 0, 0, test_unixctl_exit, &exiting); | |
92 | unixctl_command_register("echo", "ARG", 1, 1, test_unixctl_echo, NULL); | |
93 | unixctl_command_register("echo_error", "ARG", 1, 1, | |
94 | test_unixctl_echo_error, NULL); | |
95 | unixctl_command_register("log", "ARG", 1, 1, test_unixctl_log, NULL); | |
96 | unixctl_command_register("block", "", 0, 0, test_unixctl_block, NULL); | |
97 | daemonize_complete(); | |
98 | ||
99 | VLOG_INFO("Entering run loop."); | |
100 | while (!exiting) { | |
101 | unixctl_server_run(unixctl); | |
102 | unixctl_server_wait(unixctl); | |
103 | if (exiting) { | |
104 | poll_immediate_wake(); | |
105 | } | |
106 | poll_block(); | |
107 | } | |
108 | unixctl_server_destroy(unixctl); | |
109 | ||
110 | service_stop(); | |
111 | return 0; | |
112 | } | |
113 | ||
114 | static void | |
115 | parse_options(int *argcp, char **argvp[], char **unixctl_pathp) | |
116 | { | |
117 | enum { | |
118 | OPT_REMOTE = UCHAR_MAX + 1, | |
119 | OPT_UNIXCTL, | |
120 | VLOG_OPTION_ENUMS, | |
121 | DAEMON_OPTION_ENUMS | |
122 | }; | |
123 | static const struct option long_options[] = { | |
124 | {"unixctl", required_argument, NULL, OPT_UNIXCTL}, | |
125 | {"help", no_argument, NULL, 'h'}, | |
126 | {"version", no_argument, NULL, 'V'}, | |
127 | DAEMON_LONG_OPTIONS, | |
128 | VLOG_LONG_OPTIONS, | |
129 | {NULL, 0, NULL, 0}, | |
130 | }; | |
131 | char *short_options = ovs_cmdl_long_options_to_short_options(long_options); | |
132 | int argc = *argcp; | |
133 | char **argv = *argvp; | |
134 | ||
135 | for (;;) { | |
136 | int c; | |
137 | ||
138 | c = getopt_long(argc, argv, short_options, long_options, NULL); | |
139 | if (c == -1) { | |
140 | break; | |
141 | } | |
142 | ||
143 | switch (c) { | |
144 | case OPT_UNIXCTL: | |
145 | *unixctl_pathp = optarg; | |
146 | break; | |
147 | ||
148 | case 'h': | |
149 | usage(); | |
150 | ||
151 | case 'V': | |
152 | ovs_print_version(0, 0); | |
153 | exit(EXIT_SUCCESS); | |
154 | ||
155 | VLOG_OPTION_HANDLERS | |
156 | DAEMON_OPTION_HANDLERS | |
157 | ||
158 | case '?': | |
159 | exit(EXIT_FAILURE); | |
160 | ||
161 | default: | |
162 | abort(); | |
163 | } | |
164 | } | |
165 | free(short_options); | |
166 | ||
167 | *argcp -= optind; | |
168 | *argvp += optind; | |
169 | } | |
170 | ||
171 | static void | |
172 | usage(void) | |
173 | { | |
174 | printf("%s: Open vSwitch unixctl test program\n" | |
175 | "usage: %s [OPTIONS]\n", | |
176 | program_name, program_name); | |
177 | daemon_usage(); | |
178 | vlog_usage(); | |
179 | printf("\nOther options:\n" | |
180 | " --unixctl=SOCKET override default control socket name\n" | |
181 | " -h, --help display this help message\n" | |
182 | " -V, --version display version information\n"); | |
183 | exit(EXIT_SUCCESS); | |
184 | } | |
185 | ||
186 | OVSTEST_REGISTER("test-unixctl", test_unixctl_main); |