xref: /dpdk/app/graph/main.c (revision 6f1407a19532991ac49054116ca30692bc274f80)
15b21ffb2SSunil Kumar Kori /* SPDX-License-Identifier: BSD-3-Clause
25b21ffb2SSunil Kumar Kori  * Copyright(c) 2023 Marvell.
35b21ffb2SSunil Kumar Kori  */
45b21ffb2SSunil Kumar Kori 
53f90eda5SSunil Kumar Kori #include <errno.h>
65b21ffb2SSunil Kumar Kori #include <fcntl.h>
75b21ffb2SSunil Kumar Kori #include <getopt.h>
85b21ffb2SSunil Kumar Kori #include <signal.h>
95b21ffb2SSunil Kumar Kori #include <stdio.h>
105b21ffb2SSunil Kumar Kori #include <stdlib.h>
115b21ffb2SSunil Kumar Kori #include <string.h>
125b21ffb2SSunil Kumar Kori #include <sys/select.h>
135b21ffb2SSunil Kumar Kori #include <unistd.h>
145b21ffb2SSunil Kumar Kori 
153f90eda5SSunil Kumar Kori #include <rte_cycles.h>
165b21ffb2SSunil Kumar Kori #include <rte_eal.h>
175b21ffb2SSunil Kumar Kori #include <rte_launch.h>
185b21ffb2SSunil Kumar Kori 
195b21ffb2SSunil Kumar Kori #include "module_api.h"
205b21ffb2SSunil Kumar Kori 
215b21ffb2SSunil Kumar Kori volatile bool force_quit;
223f90eda5SSunil Kumar Kori struct conn *conn;
235b21ffb2SSunil Kumar Kori 
24*6f1407a1SSunil Kumar Kori static const char usage[] = "%s EAL_ARGS -- -s SCRIPT [-h HOST] [-p PORT] [--enable-graph-stats] "
255b21ffb2SSunil Kumar Kori 			    "[--help]\n";
265b21ffb2SSunil Kumar Kori 
275b21ffb2SSunil Kumar Kori static struct app_params {
283f90eda5SSunil Kumar Kori 	struct conn_params conn;
295b21ffb2SSunil Kumar Kori 	char *script_name;
30*6f1407a1SSunil Kumar Kori 	bool enable_graph_stats;
315b21ffb2SSunil Kumar Kori } app = {
323f90eda5SSunil Kumar Kori 	.conn = {
333f90eda5SSunil Kumar Kori 		.welcome = "\nWelcome!\n\n",
343f90eda5SSunil Kumar Kori 		.prompt = "graph> ",
353f90eda5SSunil Kumar Kori 		.addr = "0.0.0.0",
363f90eda5SSunil Kumar Kori 		.port = 8086,
373f90eda5SSunil Kumar Kori 		.buf_size = 1024 * 1024,
383f90eda5SSunil Kumar Kori 		.msg_in_len_max = 1024,
393f90eda5SSunil Kumar Kori 		.msg_out_len_max = 1024 * 1024,
403f90eda5SSunil Kumar Kori 		.msg_handle = cli_process,
413f90eda5SSunil Kumar Kori 		.msg_handle_arg = NULL, /* set later. */
423f90eda5SSunil Kumar Kori 	},
435b21ffb2SSunil Kumar Kori 	.script_name = NULL,
44*6f1407a1SSunil Kumar Kori 	.enable_graph_stats = false,
455b21ffb2SSunil Kumar Kori };
465b21ffb2SSunil Kumar Kori 
475b21ffb2SSunil Kumar Kori static void
signal_handler(int signum)485b21ffb2SSunil Kumar Kori signal_handler(int signum)
495b21ffb2SSunil Kumar Kori {
505b21ffb2SSunil Kumar Kori 	if (signum == SIGINT || signum == SIGTERM) {
515b21ffb2SSunil Kumar Kori 		printf("\n\nSignal %d received, preparing to exit...\n", signum);
525b21ffb2SSunil Kumar Kori 		force_quit = true;
535b21ffb2SSunil Kumar Kori 	}
545b21ffb2SSunil Kumar Kori }
555b21ffb2SSunil Kumar Kori 
565b21ffb2SSunil Kumar Kori static int
app_args_parse(int argc,char ** argv)575b21ffb2SSunil Kumar Kori app_args_parse(int argc, char **argv)
585b21ffb2SSunil Kumar Kori {
595b21ffb2SSunil Kumar Kori 	struct option lgopts[] = {
605b21ffb2SSunil Kumar Kori 		{"help", 0, 0, 'H'},
61*6f1407a1SSunil Kumar Kori 		{"enable-graph-stats", 0, 0, 'g'},
625b21ffb2SSunil Kumar Kori 	};
633f90eda5SSunil Kumar Kori 	int h_present, p_present, s_present, n_args, i;
645b21ffb2SSunil Kumar Kori 	char *app_name = argv[0];
655b21ffb2SSunil Kumar Kori 	int opt, option_index;
665b21ffb2SSunil Kumar Kori 
675b21ffb2SSunil Kumar Kori 	/* Skip EAL input args */
685b21ffb2SSunil Kumar Kori 	n_args = argc;
695b21ffb2SSunil Kumar Kori 	for (i = 0; i < n_args; i++)
705b21ffb2SSunil Kumar Kori 		if (strcmp(argv[i], "--") == 0) {
715b21ffb2SSunil Kumar Kori 			argc -= i;
725b21ffb2SSunil Kumar Kori 			argv += i;
735b21ffb2SSunil Kumar Kori 			break;
745b21ffb2SSunil Kumar Kori 		}
755b21ffb2SSunil Kumar Kori 
765b21ffb2SSunil Kumar Kori 	if (i == n_args)
775b21ffb2SSunil Kumar Kori 		return 0;
785b21ffb2SSunil Kumar Kori 
795b21ffb2SSunil Kumar Kori 	/* Parse args */
803f90eda5SSunil Kumar Kori 	h_present = 0;
813f90eda5SSunil Kumar Kori 	p_present = 0;
825b21ffb2SSunil Kumar Kori 	s_present = 0;
835b21ffb2SSunil Kumar Kori 
843f90eda5SSunil Kumar Kori 	while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index)) != EOF) {
855b21ffb2SSunil Kumar Kori 		switch (opt) {
863f90eda5SSunil Kumar Kori 		case 'h':
873f90eda5SSunil Kumar Kori 			if (h_present) {
883f90eda5SSunil Kumar Kori 				printf("Error: Multiple -h arguments\n");
893f90eda5SSunil Kumar Kori 				return -1;
903f90eda5SSunil Kumar Kori 			}
913f90eda5SSunil Kumar Kori 			h_present = 1;
923f90eda5SSunil Kumar Kori 
933f90eda5SSunil Kumar Kori 			if (!strlen(optarg)) {
943f90eda5SSunil Kumar Kori 				printf("Error: Argument for -h not provided\n");
953f90eda5SSunil Kumar Kori 				return -1;
963f90eda5SSunil Kumar Kori 			}
973f90eda5SSunil Kumar Kori 
983f90eda5SSunil Kumar Kori 			app.conn.addr = strdup(optarg);
993f90eda5SSunil Kumar Kori 			if (app.conn.addr == NULL) {
1003f90eda5SSunil Kumar Kori 				printf("Error: Not enough memory\n");
1013f90eda5SSunil Kumar Kori 				return -1;
1023f90eda5SSunil Kumar Kori 			}
1033f90eda5SSunil Kumar Kori 			break;
1043f90eda5SSunil Kumar Kori 
1053f90eda5SSunil Kumar Kori 		case 'p':
1063f90eda5SSunil Kumar Kori 			if (p_present) {
1073f90eda5SSunil Kumar Kori 				printf("Error: Multiple -p arguments\n");
1083f90eda5SSunil Kumar Kori 				return -1;
1093f90eda5SSunil Kumar Kori 			}
1103f90eda5SSunil Kumar Kori 			p_present = 1;
1113f90eda5SSunil Kumar Kori 
1123f90eda5SSunil Kumar Kori 			if (!strlen(optarg)) {
1133f90eda5SSunil Kumar Kori 				printf("Error: Argument for -p not provided\n");
1143f90eda5SSunil Kumar Kori 				return -1;
1153f90eda5SSunil Kumar Kori 			}
1163f90eda5SSunil Kumar Kori 
1173f90eda5SSunil Kumar Kori 			app.conn.port = (uint16_t)strtoul(optarg, NULL, 10);
1183f90eda5SSunil Kumar Kori 			break;
1193f90eda5SSunil Kumar Kori 
1205b21ffb2SSunil Kumar Kori 		case 's':
1215b21ffb2SSunil Kumar Kori 			if (s_present) {
1225b21ffb2SSunil Kumar Kori 				printf("Error: Multiple -s arguments\n");
1235b21ffb2SSunil Kumar Kori 				return -1;
1245b21ffb2SSunil Kumar Kori 			}
1255b21ffb2SSunil Kumar Kori 			s_present = 1;
1265b21ffb2SSunil Kumar Kori 
1275b21ffb2SSunil Kumar Kori 			if (!strlen(optarg)) {
1285b21ffb2SSunil Kumar Kori 				printf("Error: Argument for -s not provided\n");
1295b21ffb2SSunil Kumar Kori 				return -1;
1305b21ffb2SSunil Kumar Kori 			}
1315b21ffb2SSunil Kumar Kori 
1325b21ffb2SSunil Kumar Kori 			app.script_name = strdup(optarg);
1335b21ffb2SSunil Kumar Kori 			if (app.script_name == NULL) {
1345b21ffb2SSunil Kumar Kori 				printf("Error: Not enough memory\n");
1355b21ffb2SSunil Kumar Kori 				return -1;
1365b21ffb2SSunil Kumar Kori 			}
1375b21ffb2SSunil Kumar Kori 			break;
1385b21ffb2SSunil Kumar Kori 
139*6f1407a1SSunil Kumar Kori 		case 'g':
140*6f1407a1SSunil Kumar Kori 			app.enable_graph_stats = true;
141*6f1407a1SSunil Kumar Kori 			printf("WARNING! Telnet session can not be accessed with"
142*6f1407a1SSunil Kumar Kori 			       "--enable-graph-stats");
143*6f1407a1SSunil Kumar Kori 			break;
144*6f1407a1SSunil Kumar Kori 
1455b21ffb2SSunil Kumar Kori 		case 'H':
1465b21ffb2SSunil Kumar Kori 		default:
1475b21ffb2SSunil Kumar Kori 			printf(usage, app_name);
1485b21ffb2SSunil Kumar Kori 			return -1;
1495b21ffb2SSunil Kumar Kori 		}
1505b21ffb2SSunil Kumar Kori 	}
1515b21ffb2SSunil Kumar Kori 	optind = 1; /* reset getopt lib */
1525b21ffb2SSunil Kumar Kori 
1535b21ffb2SSunil Kumar Kori 	return 0;
1545b21ffb2SSunil Kumar Kori }
1555b21ffb2SSunil Kumar Kori 
1563f90eda5SSunil Kumar Kori bool
app_graph_stats_enabled(void)157*6f1407a1SSunil Kumar Kori app_graph_stats_enabled(void)
158*6f1407a1SSunil Kumar Kori {
159*6f1407a1SSunil Kumar Kori 	return app.enable_graph_stats;
160*6f1407a1SSunil Kumar Kori }
161*6f1407a1SSunil Kumar Kori 
162*6f1407a1SSunil Kumar Kori bool
app_graph_exit(void)1633f90eda5SSunil Kumar Kori app_graph_exit(void)
1643f90eda5SSunil Kumar Kori {
1653f90eda5SSunil Kumar Kori 	struct timeval tv;
1663f90eda5SSunil Kumar Kori 	fd_set fds;
1673f90eda5SSunil Kumar Kori 	int ret;
1683f90eda5SSunil Kumar Kori 	char c;
1693f90eda5SSunil Kumar Kori 
1703f90eda5SSunil Kumar Kori 	FD_ZERO(&fds);
1713f90eda5SSunil Kumar Kori 	FD_SET(0, &fds);
1723f90eda5SSunil Kumar Kori 	tv.tv_sec = 0;
1733f90eda5SSunil Kumar Kori 	tv.tv_usec = 100;
1743f90eda5SSunil Kumar Kori 	ret = select(1, &fds, NULL, NULL, &tv);
1753f90eda5SSunil Kumar Kori 	if ((ret < 0 && errno == EINTR) || (ret == 1 && read(0, &c, 1) > 0))
1763f90eda5SSunil Kumar Kori 		return true;
1773f90eda5SSunil Kumar Kori 	else
1783f90eda5SSunil Kumar Kori 		return false;
1793f90eda5SSunil Kumar Kori 
1803f90eda5SSunil Kumar Kori }
1813f90eda5SSunil Kumar Kori 
1825b21ffb2SSunil Kumar Kori int
main(int argc,char ** argv)1835b21ffb2SSunil Kumar Kori main(int argc, char **argv)
1845b21ffb2SSunil Kumar Kori {
1855b21ffb2SSunil Kumar Kori 	int rc;
1865b21ffb2SSunil Kumar Kori 
1875b21ffb2SSunil Kumar Kori 	/* Parse application arguments */
1885b21ffb2SSunil Kumar Kori 	rc = app_args_parse(argc, argv);
1895b21ffb2SSunil Kumar Kori 	if (rc < 0)
1905b21ffb2SSunil Kumar Kori 		return rc;
1915b21ffb2SSunil Kumar Kori 
1925b21ffb2SSunil Kumar Kori 	/* EAL */
1935b21ffb2SSunil Kumar Kori 	rc = rte_eal_init(argc, argv);
1945b21ffb2SSunil Kumar Kori 	if (rc < 0) {
1955b21ffb2SSunil Kumar Kori 		printf("Error: EAL initialization failed (%d)\n", rc);
1965b21ffb2SSunil Kumar Kori 		return rc;
1975b21ffb2SSunil Kumar Kori 	};
1985b21ffb2SSunil Kumar Kori 
1995b21ffb2SSunil Kumar Kori 	force_quit = false;
2005b21ffb2SSunil Kumar Kori 	signal(SIGINT, signal_handler);
2015b21ffb2SSunil Kumar Kori 	signal(SIGTERM, signal_handler);
2025b21ffb2SSunil Kumar Kori 
2035b21ffb2SSunil Kumar Kori 	cli_init();
2045b21ffb2SSunil Kumar Kori 
2055b21ffb2SSunil Kumar Kori 	/* Script */
2065b21ffb2SSunil Kumar Kori 	if (app.script_name) {
2073f90eda5SSunil Kumar Kori 		cli_script_process(app.script_name, app.conn.msg_in_len_max,
2083f90eda5SSunil Kumar Kori 			app.conn.msg_out_len_max, NULL);
2095b21ffb2SSunil Kumar Kori 	}
2105b21ffb2SSunil Kumar Kori 
2113f90eda5SSunil Kumar Kori 	/* Connectivity */
2123f90eda5SSunil Kumar Kori 	app.conn.msg_handle_arg = NULL;
2133f90eda5SSunil Kumar Kori 	conn = conn_init(&app.conn);
2143f90eda5SSunil Kumar Kori 	if (!conn) {
2153f90eda5SSunil Kumar Kori 		printf("Error: Connectivity initialization failed\n");
2163f90eda5SSunil Kumar Kori 		goto exit;
2173f90eda5SSunil Kumar Kori 	};
2183f90eda5SSunil Kumar Kori 
2193f90eda5SSunil Kumar Kori 	rte_delay_ms(1);
2203f90eda5SSunil Kumar Kori 	printf("Press enter to exit\n");
2213f90eda5SSunil Kumar Kori 
2223f90eda5SSunil Kumar Kori 	/* Dispatch loop */
2233f90eda5SSunil Kumar Kori 	while (!force_quit) {
2243f90eda5SSunil Kumar Kori 		conn_req_poll(conn);
2253f90eda5SSunil Kumar Kori 
2263f90eda5SSunil Kumar Kori 		conn_msg_poll(conn);
2273f90eda5SSunil Kumar Kori 		if (app_graph_exit())
2283f90eda5SSunil Kumar Kori 			force_quit = true;
2293f90eda5SSunil Kumar Kori 	}
2303f90eda5SSunil Kumar Kori 
2313f90eda5SSunil Kumar Kori exit:
2323f90eda5SSunil Kumar Kori 	conn_free(conn);
2333850cb06SSunil Kumar Kori 	ethdev_stop();
2345b21ffb2SSunil Kumar Kori 	cli_exit();
2355b21ffb2SSunil Kumar Kori 	rte_eal_cleanup();
2365b21ffb2SSunil Kumar Kori 	return 0;
2375b21ffb2SSunil Kumar Kori }
238