Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #define ALLOW_INTERNAL_API
6 : :
7 : : #include <errno.h> /* errno */
8 : : #include <limits.h> /* PATH_MAX */
9 : : #ifndef RTE_EXEC_ENV_WINDOWS
10 : : #include <sys/wait.h>
11 : : #endif
12 : : #include <stdlib.h> /* NULL */
13 : : #include <string.h> /* strerror */
14 : : #include <unistd.h>
15 : : #include <dirent.h>
16 : :
17 : : #include <rte_string_fns.h> /* strlcpy */
18 : : #include <rte_devargs.h>
19 : : #include <rte_eal.h>
20 : :
21 : : #ifdef RTE_LIB_PDUMP
22 : : #ifdef RTE_NET_RING
23 : : #include <rte_thread.h>
24 : : #include "test_pdump.h"
25 : : #endif
26 : : #endif
27 : :
28 : : #include "test.h"
29 : : #include "process.h"
30 : :
31 : : #define PREFIX_ALLOW "--allow="
32 : : #define PREFIX_DRIVER_PATH "--driver-path="
33 : :
34 : : static int
35 : 0 : add_parameter_allow(char **argv, int max_capacity)
36 : : {
37 : : struct rte_devargs *devargs;
38 : : int count = 0;
39 : :
40 [ # # ]: 0 : RTE_EAL_DEVARGS_FOREACH(NULL, devargs) {
41 [ # # ]: 0 : if (strlen(devargs->name) == 0)
42 : 0 : continue;
43 : :
44 [ # # # # ]: 0 : if (devargs->data == NULL || strlen(devargs->data) == 0) {
45 [ # # ]: 0 : if (asprintf(&argv[count], PREFIX_ALLOW"%s", devargs->name) < 0)
46 : : break;
47 : : } else {
48 [ # # ]: 0 : if (asprintf(&argv[count], PREFIX_ALLOW"%s,%s",
49 : 0 : devargs->name, devargs->data) < 0)
50 : : break;
51 : : }
52 : :
53 [ # # ]: 0 : if (++count == max_capacity)
54 : : break;
55 : : }
56 : :
57 : 0 : return count;
58 : : }
59 : :
60 : : static int
61 : 0 : add_parameter_driver_path(char **argv, int max_capacity)
62 : : {
63 : : const char *driver_path;
64 : : int count = 0;
65 : :
66 [ # # ]: 0 : RTE_EAL_DRIVER_PATH_FOREACH(driver_path, true) {
67 [ # # ]: 0 : if (asprintf(&argv[count], PREFIX_DRIVER_PATH"%s", driver_path) < 0)
68 : : break;
69 : :
70 [ # # ]: 0 : if (++count == max_capacity)
71 : : break;
72 : : }
73 : :
74 : 0 : return count;
75 : : }
76 : :
77 : : int
78 : 151 : process_dup(const char *const argv[], int numargs, const char *env_value)
79 : : {
80 : : int num = 0;
81 : : char **argv_cpy;
82 : : int allow_num;
83 : : int driver_path_num;
84 : : int argv_num;
85 : : int i, status;
86 : : #ifdef RTE_LIB_PDUMP
87 : : #ifdef RTE_NET_RING
88 : : rte_thread_t thread;
89 : : int rc;
90 : : #endif
91 : : #endif
92 : :
93 : 151 : pid_t pid = fork();
94 [ + - ]: 151 : if (pid < 0)
95 : : return -1;
96 [ - + ]: 151 : else if (pid == 0) {
97 : 0 : allow_num = rte_devargs_type_count(RTE_DEVTYPE_ALLOWED);
98 : 0 : driver_path_num = rte_eal_driver_path_count(true);
99 : 0 : argv_num = numargs + allow_num + driver_path_num + 1;
100 : 0 : argv_cpy = calloc(argv_num, sizeof(char *));
101 [ # # ]: 0 : if (!argv_cpy)
102 : 0 : rte_panic("Memory allocation failed\n");
103 : :
104 : : /* make a copy of the arguments to be passed to exec */
105 [ # # ]: 0 : for (i = 0; i < numargs; i++) {
106 : 0 : argv_cpy[i] = strdup(argv[i]);
107 [ # # ]: 0 : if (argv_cpy[i] == NULL)
108 : 0 : rte_panic("Error dup args\n");
109 : : }
110 [ # # ]: 0 : if (allow_num > 0)
111 : 0 : num = add_parameter_allow(&argv_cpy[i], allow_num);
112 : 0 : num += numargs;
113 : :
114 [ # # ]: 0 : if (driver_path_num > 0) {
115 : 0 : int added = add_parameter_driver_path(&argv_cpy[num], driver_path_num);
116 : 0 : num += added;
117 : : }
118 : :
119 : : #ifdef RTE_EXEC_ENV_LINUX
120 : : {
121 : : const char *procdir = "/proc/self/fd/";
122 : : struct dirent *dirent;
123 : : char *endptr;
124 : : int fd, fdir;
125 : : DIR *dir;
126 : :
127 : : /* close all open file descriptors, check /proc/self/fd
128 : : * to only call close on open fds. Exclude fds 0, 1 and
129 : : * 2
130 : : */
131 : 0 : dir = opendir(procdir);
132 [ # # ]: 0 : if (dir == NULL) {
133 : 0 : rte_panic("Error opening %s: %s\n", procdir,
134 : : strerror(errno));
135 : : }
136 : :
137 : 0 : fdir = dirfd(dir);
138 [ # # ]: 0 : if (fdir < 0) {
139 : 0 : status = errno;
140 : 0 : closedir(dir);
141 : 0 : rte_panic("Error %d obtaining fd for dir %s: %s\n",
142 : : fdir, procdir,
143 : : strerror(status));
144 : : }
145 : :
146 [ # # ]: 0 : while ((dirent = readdir(dir)) != NULL) {
147 : :
148 [ # # ]: 0 : if (strcmp(dirent->d_name, ".") == 0 ||
149 [ # # ]: 0 : strcmp(dirent->d_name, "..") == 0)
150 : 0 : continue;
151 : :
152 : 0 : errno = 0;
153 : 0 : fd = strtol(dirent->d_name, &endptr, 10);
154 [ # # # # ]: 0 : if (errno != 0 || endptr[0] != '\0') {
155 : : printf("Error converting name fd %d %s:\n",
156 : : fd, dirent->d_name);
157 : 0 : continue;
158 : : }
159 : :
160 [ # # ]: 0 : if (fd == fdir || fd <= 2)
161 : 0 : continue;
162 : :
163 : 0 : close(fd);
164 : : }
165 : 0 : closedir(dir);
166 : : }
167 : : #endif
168 : : printf("Running binary with argv[]:");
169 [ # # ]: 0 : for (i = 0; i < num; i++)
170 : 0 : printf("'%s' ", argv_cpy[i]);
171 : : printf("\n");
172 : 0 : fflush(stdout);
173 : :
174 : : /* set the environment variable */
175 [ # # ]: 0 : if (setenv(RECURSIVE_ENV_VAR, env_value, 1) != 0)
176 : 0 : rte_panic("Cannot export environment variable\n");
177 [ # # ]: 0 : if (execv(argv_cpy[0], argv_cpy) < 0)
178 : 0 : rte_panic("Cannot exec: %s\n", strerror(errno));
179 : : }
180 : : /* parent process does a wait */
181 : : #ifdef RTE_LIB_PDUMP
182 : : #ifdef RTE_NET_RING
183 [ + + ]: 151 : if ((strcmp(env_value, "run_pdump_server_tests") == 0)) {
184 : 1 : rc = rte_thread_create(&thread, NULL, send_pkts, NULL);
185 [ - + ]: 1 : if (rc != 0) {
186 : 0 : rte_panic("Cannot start send pkts thread: %s\n",
187 : : strerror(rc));
188 : : }
189 : : }
190 : : #endif
191 : : #endif
192 : :
193 [ - + ]: 151 : while (wait(&status) != pid)
194 : : ;
195 : : #ifdef RTE_LIB_PDUMP
196 : : #ifdef RTE_NET_RING
197 [ + + ]: 151 : if ((strcmp(env_value, "run_pdump_server_tests") == 0)) {
198 : 1 : flag_for_send_pkts = 0;
199 : 1 : rte_thread_join(thread, NULL);
200 : : }
201 : : #endif
202 : : #endif
203 : 151 : return status;
204 : : }
205 : :
206 : : #ifndef RTE_EXEC_ENV_LINUX
207 : : const char *
208 : : file_prefix_arg(void)
209 : : {
210 : : return "";
211 : : }
212 : : #else /* RTE_EXEC_ENV_LINUX */
213 : : char *
214 : 1 : get_current_prefix(char *prefix, int size)
215 : : {
216 : 12 : rte_basename(rte_eal_get_runtime_dir(), prefix, size);
217 : 1 : return prefix;
218 : : }
219 : :
220 : : /* Return a --file-prefix=XXXX argument */
221 : : const char *
222 : 11 : file_prefix_arg(void)
223 : : {
224 : : static char prefix[NAME_MAX + sizeof("--file-prefix=")];
225 : : char tmp[NAME_MAX];
226 : :
227 : : snprintf(prefix, sizeof(prefix), "--file-prefix=%s",
228 : : get_current_prefix(tmp, sizeof(tmp)));
229 : 11 : return prefix;
230 : : }
231 : : #endif /* RTE_EXEC_ENV_LINUX */
|