netdev-dpdk: fix mbuf leaks
[cascardo/ovs.git] / tests / test-unixctl.c
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);