Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2023 Marvell.
3 : : */
4 : :
5 : : #include <errno.h>
6 : : #include <fcntl.h>
7 : : #include <getopt.h>
8 : : #include <signal.h>
9 : : #include <stdio.h>
10 : : #include <stdlib.h>
11 : : #include <string.h>
12 : : #include <sys/select.h>
13 : : #include <unistd.h>
14 : :
15 : : #include <rte_cycles.h>
16 : : #include <rte_eal.h>
17 : : #include <rte_launch.h>
18 : :
19 : : #include "module_api.h"
20 : :
21 : : volatile bool force_quit;
22 : : struct conn *conn;
23 : :
24 : : static const char usage[] = "%s EAL_ARGS -- -s SCRIPT [-h HOST] [-p PORT] [--enable-graph-stats] "
25 : : "[--help]\n";
26 : :
27 : : static struct app_params {
28 : : struct conn_params conn;
29 : : char *script_name;
30 : : bool enable_graph_stats;
31 : : } app = {
32 : : .conn = {
33 : : .welcome = "\nWelcome!\n\n",
34 : : .prompt = "graph> ",
35 : : .addr = "0.0.0.0",
36 : : .port = 8086,
37 : : .buf_size = 1024 * 1024,
38 : : .msg_in_len_max = 1024,
39 : : .msg_out_len_max = 1024 * 1024,
40 : : .msg_handle = cli_process,
41 : : .msg_handle_arg = NULL, /* set later. */
42 : : },
43 : : .script_name = NULL,
44 : : .enable_graph_stats = false,
45 : : };
46 : :
47 : : static void
48 : 0 : signal_handler(int signum)
49 : : {
50 : 0 : if (signum == SIGINT || signum == SIGTERM) {
51 : : printf("\n\nSignal %d received, preparing to exit...\n", signum);
52 : 0 : force_quit = true;
53 : : }
54 : 0 : }
55 : :
56 : : static int
57 : 0 : app_args_parse(int argc, char **argv)
58 : : {
59 : 0 : struct option lgopts[] = {
60 : : {"help", 0, 0, 'H'},
61 : : {"enable-graph-stats", 0, 0, 'g'},
62 : : };
63 : : int h_present, p_present, s_present, n_args, i;
64 : 0 : char *app_name = argv[0];
65 : : int opt, option_index;
66 : :
67 : : /* Skip EAL input args */
68 : : n_args = argc;
69 : 0 : for (i = 0; i < n_args; i++)
70 : 0 : if (strcmp(argv[i], "--") == 0) {
71 : 0 : argc -= i;
72 : : argv += i;
73 : 0 : break;
74 : : }
75 : :
76 : 0 : if (i == n_args)
77 : : return 0;
78 : :
79 : : /* Parse args */
80 : : h_present = 0;
81 : : p_present = 0;
82 : : s_present = 0;
83 : :
84 : 0 : while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index)) != EOF) {
85 : 0 : switch (opt) {
86 : 0 : case 'h':
87 : 0 : if (h_present) {
88 : : printf("Error: Multiple -h arguments\n");
89 : 0 : return -1;
90 : : }
91 : : h_present = 1;
92 : :
93 : 0 : if (!strlen(optarg)) {
94 : : printf("Error: Argument for -h not provided\n");
95 : 0 : return -1;
96 : : }
97 : :
98 : 0 : app.conn.addr = strdup(optarg);
99 : 0 : if (app.conn.addr == NULL) {
100 : : printf("Error: Not enough memory\n");
101 : 0 : return -1;
102 : : }
103 : : break;
104 : :
105 : 0 : case 'p':
106 : 0 : if (p_present) {
107 : : printf("Error: Multiple -p arguments\n");
108 : 0 : return -1;
109 : : }
110 : : p_present = 1;
111 : :
112 : 0 : if (!strlen(optarg)) {
113 : : printf("Error: Argument for -p not provided\n");
114 : 0 : return -1;
115 : : }
116 : :
117 : 0 : app.conn.port = (uint16_t)strtoul(optarg, NULL, 10);
118 : 0 : break;
119 : :
120 : 0 : case 's':
121 : 0 : if (s_present) {
122 : : printf("Error: Multiple -s arguments\n");
123 : 0 : return -1;
124 : : }
125 : : s_present = 1;
126 : :
127 : 0 : if (!strlen(optarg)) {
128 : : printf("Error: Argument for -s not provided\n");
129 : 0 : return -1;
130 : : }
131 : :
132 : 0 : app.script_name = strdup(optarg);
133 : 0 : if (app.script_name == NULL) {
134 : : printf("Error: Not enough memory\n");
135 : 0 : return -1;
136 : : }
137 : : break;
138 : :
139 : 0 : case 'g':
140 : 0 : app.enable_graph_stats = true;
141 : : printf("WARNING! Telnet session can not be accessed with"
142 : : "--enable-graph-stats");
143 : : break;
144 : :
145 : : case 'H':
146 : : default:
147 : : printf(usage, app_name);
148 : 0 : return -1;
149 : : }
150 : : }
151 : 0 : optind = 1; /* reset getopt lib */
152 : :
153 : 0 : return 0;
154 : : }
155 : :
156 : : bool
157 : 0 : app_graph_stats_enabled(void)
158 : : {
159 : 0 : return app.enable_graph_stats;
160 : : }
161 : :
162 : : bool
163 : 0 : app_graph_exit(void)
164 : : {
165 : : struct timeval tv;
166 : : fd_set fds;
167 : : int ret;
168 : : char c;
169 : :
170 : 0 : FD_ZERO(&fds);
171 : 0 : FD_SET(0, &fds);
172 : 0 : tv.tv_sec = 0;
173 : 0 : tv.tv_usec = 100;
174 : 0 : ret = select(1, &fds, NULL, NULL, &tv);
175 : 0 : if ((ret < 0 && errno == EINTR) || (ret == 1 && read(0, &c, 1) > 0))
176 : 0 : return true;
177 : : else
178 : 0 : return false;
179 : :
180 : : }
181 : :
182 : : int
183 : 0 : main(int argc, char **argv)
184 : : {
185 : : int rc;
186 : :
187 : : /* Parse application arguments */
188 : 0 : rc = app_args_parse(argc, argv);
189 : 0 : if (rc < 0)
190 : : return rc;
191 : :
192 : : /* EAL */
193 : 0 : rc = rte_eal_init(argc, argv);
194 : 0 : if (rc < 0) {
195 : : printf("Error: EAL initialization failed (%d)\n", rc);
196 : 0 : return rc;
197 : : };
198 : :
199 : 0 : force_quit = false;
200 : 0 : signal(SIGINT, signal_handler);
201 : 0 : signal(SIGTERM, signal_handler);
202 : :
203 : 0 : cli_init();
204 : :
205 : : /* Script */
206 : 0 : if (app.script_name) {
207 : 0 : cli_script_process(app.script_name, app.conn.msg_in_len_max,
208 : : app.conn.msg_out_len_max, NULL);
209 : : }
210 : :
211 : : /* Connectivity */
212 : 0 : app.conn.msg_handle_arg = NULL;
213 : 0 : conn = conn_init(&app.conn);
214 : 0 : if (!conn) {
215 : : printf("Error: Connectivity initialization failed\n");
216 : 0 : goto exit;
217 : : };
218 : :
219 : : rte_delay_ms(1);
220 : : printf("Press enter to exit\n");
221 : :
222 : : /* Dispatch loop */
223 : 0 : while (!force_quit) {
224 : 0 : conn_req_poll(conn);
225 : :
226 : 0 : conn_msg_poll(conn);
227 : 0 : if (app_graph_exit())
228 : 0 : force_quit = true;
229 : : }
230 : :
231 : 0 : exit:
232 : 0 : conn_free(conn);
233 : 0 : ethdev_stop();
234 : 0 : cli_exit();
235 : 0 : rte_eal_cleanup();
236 : 0 : return 0;
237 : : }
|