xref: /dpdk/app/test/test_eal_flags.c (revision bb85a78d)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation.
3  * Copyright(c) 2014 6WIND S.A.
4  */
5 
6 #include <stdio.h>
7 
8 #include "test.h"
9 
10 #include <string.h>
11 #include <stdarg.h>
12 #include <libgen.h>
13 #include <stdlib.h>
14 #include <errno.h>
15 #include <unistd.h>
16 #include <dirent.h>
17 #include <sys/file.h>
18 #include <sys/stat.h>
19 #include <sys/wait.h>
20 #include <limits.h>
21 #include <fcntl.h>
22 
23 #include <rte_lcore.h>
24 #include <rte_debug.h>
25 #include <rte_string_fns.h>
26 
27 #include "process.h"
28 
29 #define DEFAULT_MEM_SIZE "18"
30 #define mp_flag "--proc-type=secondary"
31 #define no_hpet "--no-hpet"
32 #define no_huge "--no-huge"
33 #define no_shconf "--no-shconf"
34 #define allow "--allow"
35 #define vdev "--vdev"
36 #define memtest "memtest"
37 #define memtest1 "memtest1"
38 #define memtest2 "memtest2"
39 #define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 20)
40 #define launch_proc(ARGV) process_dup(ARGV, RTE_DIM(ARGV), __func__)
41 
42 enum hugepage_action {
43 	HUGEPAGE_CHECK_EXISTS = 0,
44 	HUGEPAGE_CHECK_LOCKED,
45 	HUGEPAGE_DELETE,
46 	HUGEPAGE_INVALID
47 };
48 
49 /* if string contains a hugepage path */
50 static int
51 get_hugepage_path(char * src, int src_len, char * dst, int dst_len)
52 {
53 #define NUM_TOKENS 4
54 	char *tokens[NUM_TOKENS];
55 
56 	/* if we couldn't properly split the string */
57 	if (rte_strsplit(src, src_len, tokens, NUM_TOKENS, ' ') < NUM_TOKENS)
58 		return 0;
59 
60 	if (strncmp(tokens[2], "hugetlbfs", sizeof("hugetlbfs")) == 0) {
61 		strlcpy(dst, tokens[1], dst_len);
62 		return 1;
63 	}
64 	return 0;
65 }
66 
67 /*
68  * Cycles through hugepage directories and looks for hugepage
69  * files associated with a given prefix. Depending on value of
70  * action, the hugepages are checked if they exist, checked if
71  * they can be locked, or are simply deleted.
72  *
73  * Returns 1 if it finds at least one hugepage matching the action
74  * Returns 0 if no matching hugepages were found
75  * Returns -1 if it encounters an error
76  */
77 static int
78 process_hugefiles(const char * prefix, enum hugepage_action action)
79 {
80 	FILE * hugedir_handle = NULL;
81 	DIR * hugepage_dir = NULL;
82 	struct dirent *dirent = NULL;
83 
84 	char hugefile_prefix[PATH_MAX] = {0};
85 	char hugedir[PATH_MAX] = {0};
86 	char line[PATH_MAX] = {0};
87 
88 	int fd, lck_result, result = 0;
89 
90 	const int prefix_len = snprintf(hugefile_prefix,
91 			sizeof(hugefile_prefix), "%smap_", prefix);
92 	if (prefix_len <= 0 || prefix_len >= (int)sizeof(hugefile_prefix)
93 			|| prefix_len >= (int)sizeof(dirent->d_name)) {
94 		printf("Error creating hugefile filename prefix\n");
95 		return -1;
96 	}
97 
98 	/* get hugetlbfs mountpoints from /proc/mounts */
99 	hugedir_handle = fopen("/proc/mounts", "r");
100 
101 	if (hugedir_handle == NULL) {
102 		printf("Error parsing /proc/mounts!\n");
103 		return -1;
104 	}
105 
106 	/* read and parse script output */
107 	while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
108 
109 		/* check if we have a hugepage filesystem path */
110 		if (!get_hugepage_path(line, sizeof(line), hugedir, sizeof(hugedir)))
111 			continue;
112 
113 		/* check if directory exists */
114 		if ((hugepage_dir = opendir(hugedir)) == NULL) {
115 			fclose(hugedir_handle);
116 			printf("Error reading %s: %s\n", hugedir, strerror(errno));
117 			return -1;
118 		}
119 
120 		while ((dirent = readdir(hugepage_dir)) != NULL) {
121 			if (memcmp(dirent->d_name, hugefile_prefix, prefix_len) != 0)
122 				continue;
123 
124 			switch (action) {
125 			case HUGEPAGE_CHECK_EXISTS:
126 				{
127 					/* file exists, return */
128 					closedir(hugepage_dir);
129 					result = 1;
130 					goto end;
131 				}
132 				break;
133 			case HUGEPAGE_DELETE:
134 				{
135 					char file_path[PATH_MAX] = {0};
136 
137 					snprintf(file_path, sizeof(file_path),
138 						"%s/%s", hugedir, dirent->d_name);
139 
140 					/* remove file */
141 					if (remove(file_path) < 0) {
142 						printf("Error deleting %s - %s!\n",
143 								dirent->d_name, strerror(errno));
144 						closedir(hugepage_dir);
145 						result = -1;
146 						goto end;
147 					}
148 					result = 1;
149 				}
150 				break;
151 			case HUGEPAGE_CHECK_LOCKED:
152 				{
153 					/* try and lock the file */
154 					fd = openat(dirfd(hugepage_dir), dirent->d_name, O_RDONLY);
155 
156 					/* this shouldn't happen */
157 					if (fd == -1) {
158 						printf("Error opening %s - %s!\n",
159 								dirent->d_name, strerror(errno));
160 						closedir(hugepage_dir);
161 						result = -1;
162 						goto end;
163 					}
164 
165 					/* non-blocking lock */
166 					lck_result = flock(fd, LOCK_EX | LOCK_NB);
167 
168 					/* if lock succeeds, there's something wrong */
169 					if (lck_result != -1) {
170 						result = 0;
171 
172 						/* unlock the resulting lock */
173 						flock(fd, LOCK_UN);
174 						close(fd);
175 						closedir(hugepage_dir);
176 						goto end;
177 					}
178 					result = 1;
179 					close(fd);
180 				}
181 				break;
182 				/* shouldn't happen */
183 			default:
184 				goto end;
185 			} /* switch */
186 
187 		} /* read hugepage directory */
188 		closedir(hugepage_dir);
189 	} /* read /proc/mounts */
190 end:
191 	fclose(hugedir_handle);
192 	return result;
193 }
194 
195 #ifdef RTE_EXEC_ENV_LINUX
196 /*
197  * count the number of "node*" files in /sys/devices/system/node/
198  */
199 static int
200 get_number_of_sockets(void)
201 {
202 	struct dirent *dirent = NULL;
203 	const char * nodedir = "/sys/devices/system/node/";
204 	DIR * dir = NULL;
205 	int result = 0;
206 
207 	/* check if directory exists */
208 	if ((dir = opendir(nodedir)) == NULL) {
209 		/* if errno==ENOENT this means we don't have NUMA support */
210 		if (errno == ENOENT) {
211 			printf("No NUMA nodes detected: assuming 1 available socket\n");
212 			return 1;
213 		}
214 		printf("Error opening %s: %s\n", nodedir, strerror(errno));
215 		return -1;
216 	}
217 
218 	while ((dirent = readdir(dir)) != NULL)
219 		if (strncmp(dirent->d_name, "node", sizeof("node") - 1) == 0)
220 			result++;
221 
222 	closedir(dir);
223 	return result;
224 }
225 #endif
226 
227 /*
228  * Test that the app doesn't run with invalid allow option.
229  * Final tests ensures it does run with valid options as sanity check (one
230  * test for with Domain+BDF, second for just with BDF)
231  */
232 static int
233 test_allow_flag(void)
234 {
235 	unsigned i;
236 #ifdef RTE_EXEC_ENV_FREEBSD
237 	/* BSD target doesn't support prefixes at this point */
238 	const char * prefix = "";
239 #else
240 	char prefix[PATH_MAX], tmp[PATH_MAX];
241 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
242 		printf("Error - unable to get current prefix!\n");
243 		return -1;
244 	}
245 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
246 #endif
247 
248 	const char *wlinval[][7] = {
249 		{prgname, prefix, mp_flag,
250 				allow, "error", "", ""},
251 		{prgname, prefix, mp_flag,
252 				allow, "0:0:0", "", ""},
253 		{prgname, prefix, mp_flag,
254 				allow, "0:error:0.1", "", ""},
255 		{prgname, prefix, mp_flag,
256 				allow, "0:0:0.1error", "", ""},
257 		{prgname, prefix, mp_flag,
258 				allow, "error0:0:0.1", "", ""},
259 		{prgname, prefix, mp_flag,
260 				allow, "0:0:0.1.2", "", ""},
261 	};
262 	/* Test with valid allow option */
263 	const char *wlval1[] = {prgname, prefix, mp_flag,
264 			allow, "00FF:09:0B.3"};
265 	const char *wlval2[] = {prgname, prefix, mp_flag,
266 			allow, "09:0B.3", allow, "0a:0b.1"};
267 	const char *wlval3[] = {prgname, prefix, mp_flag,
268 			allow, "09:0B.3,type=test",
269 			allow, "08:00.1,type=normal",
270 	};
271 
272 	for (i = 0; i < RTE_DIM(wlinval); i++) {
273 		if (launch_proc(wlinval[i]) == 0) {
274 			printf("Error - process did run ok with invalid "
275 			    "allow parameter\n");
276 			return -1;
277 		}
278 	}
279 	if (launch_proc(wlval1) != 0 ) {
280 		printf("Error - process did not run ok with valid allow\n");
281 		return -1;
282 	}
283 	if (launch_proc(wlval2) != 0 ) {
284 		printf("Error - process did not run ok with valid allow value set\n");
285 		return -1;
286 	}
287 	if (launch_proc(wlval3) != 0 ) {
288 		printf("Error - process did not run ok with valid allow + args\n");
289 		return -1;
290 	}
291 
292 	return 0;
293 }
294 
295 /*
296  * Test that the app doesn't run with invalid blocklist option.
297  * Final test ensures it does run with valid options as sanity check
298  */
299 static int
300 test_invalid_b_flag(void)
301 {
302 #ifdef RTE_EXEC_ENV_FREEBSD
303 	/* BSD target doesn't support prefixes at this point */
304 	const char * prefix = "";
305 #else
306 	char prefix[PATH_MAX], tmp[PATH_MAX];
307 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
308 		printf("Error - unable to get current prefix!\n");
309 		return -1;
310 	}
311 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
312 #endif
313 
314 	const char *blinval[][5] = {
315 		{prgname, prefix, mp_flag, "-b", "error"},
316 		{prgname, prefix, mp_flag, "-b", "0:0:0"},
317 		{prgname, prefix, mp_flag, "-b", "0:error:0.1"},
318 		{prgname, prefix, mp_flag, "-b", "0:0:0.1error"},
319 		{prgname, prefix, mp_flag, "-b", "error0:0:0.1"},
320 		{prgname, prefix, mp_flag, "-b", "0:0:0.1.2"},
321 	};
322 	/* Test with valid blocklist option */
323 	const char *blval[] = {prgname, prefix, mp_flag,
324 			       "-b", "FF:09:0B.3"};
325 
326 	int i;
327 
328 	for (i = 0; i != RTE_DIM(blinval); i++) {
329 		if (launch_proc(blinval[i]) == 0) {
330 			printf("Error - process did run ok with invalid "
331 			    "blocklist parameter\n");
332 			return -1;
333 		}
334 	}
335 	if (launch_proc(blval) != 0) {
336 		printf("Error - process did not run ok with valid blocklist value\n");
337 		return -1;
338 	}
339 	return 0;
340 }
341 
342 /*
343  *  Test that the app doesn't run with invalid vdev option.
344  *  Final test ensures it does run with valid options as sanity check
345  */
346 static int
347 test_invalid_vdev_flag(void)
348 {
349 #ifdef RTE_NET_RING
350 #ifdef RTE_EXEC_ENV_FREEBSD
351 	/* BSD target doesn't support prefixes at this point, and we also need to
352 	 * run another primary process here */
353 	const char * prefix = no_shconf;
354 #else
355 	const char * prefix = "--file-prefix=vdev";
356 #endif
357 
358 	/* Test with invalid vdev option */
359 	const char *vdevinval[] = {prgname, prefix, no_huge,
360 				vdev, "eth_dummy"};
361 
362 	/* Test with valid vdev option */
363 	const char *vdevval1[] = {prgname, prefix, no_huge,
364 	vdev, "net_ring0"};
365 
366 	const char *vdevval2[] = {prgname, prefix, no_huge,
367 	vdev, "net_ring0,args=test"};
368 
369 	const char *vdevval3[] = {prgname, prefix, no_huge,
370 	vdev, "net_ring0,nodeaction=r1:0:CREATE"};
371 
372 	if (launch_proc(vdevinval) == 0) {
373 		printf("Error - process did run ok with invalid "
374 			"vdev parameter\n");
375 		return -1;
376 	}
377 
378 	if (launch_proc(vdevval1) != 0) {
379 		printf("Error - process did not run ok with valid vdev value\n");
380 		return -1;
381 	}
382 
383 	if (launch_proc(vdevval2) != 0) {
384 		printf("Error - process did not run ok with valid vdev value,"
385 			"with dummy args\n");
386 		return -1;
387 	}
388 
389 	if (launch_proc(vdevval3) != 0) {
390 		printf("Error - process did not run ok with valid vdev value,"
391 			"with valid args\n");
392 		return -1;
393 	}
394 	return 0;
395 #else
396 	return TEST_SKIPPED;
397 #endif
398 }
399 
400 /*
401  * Test that the app doesn't run with invalid -r option.
402  */
403 static int
404 test_invalid_r_flag(void)
405 {
406 #ifdef RTE_EXEC_ENV_FREEBSD
407 	/* BSD target doesn't support prefixes at this point */
408 	const char * prefix = "";
409 #else
410 	char prefix[PATH_MAX], tmp[PATH_MAX];
411 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
412 		printf("Error - unable to get current prefix!\n");
413 		return -1;
414 	}
415 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
416 #endif
417 
418 	const char *rinval[][5] = {
419 			{prgname, prefix, mp_flag, "-r", "error"},
420 			{prgname, prefix, mp_flag, "-r", "0"},
421 			{prgname, prefix, mp_flag, "-r", "-1"},
422 			{prgname, prefix, mp_flag, "-r", "17"},
423 	};
424 	/* Test with valid blocklist option */
425 	const char *rval[] = {prgname, prefix, mp_flag, "-r", "16"};
426 
427 	int i;
428 
429 	for (i = 0; i != RTE_DIM(rinval); i++) {
430 		if (launch_proc(rinval[i]) == 0) {
431 			printf("Error - process did run ok with invalid "
432 			    "-r (rank) parameter\n");
433 			return -1;
434 		}
435 	}
436 	if (launch_proc(rval) != 0) {
437 		printf("Error - process did not run ok with valid -r (rank) value\n");
438 		return -1;
439 	}
440 	return 0;
441 }
442 
443 /*
444  * Test that the app doesn't run without the coremask/corelist flags. In all cases
445  * should give an error and fail to run
446  */
447 static int
448 test_missing_c_flag(void)
449 {
450 #ifdef RTE_EXEC_ENV_FREEBSD
451 	/* BSD target doesn't support prefixes at this point */
452 	const char * prefix = "";
453 #else
454 	char prefix[PATH_MAX], tmp[PATH_MAX];
455 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
456 		printf("Error - unable to get current prefix!\n");
457 		return -1;
458 	}
459 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
460 #endif
461 
462 	/* -c flag but no coremask value */
463 	const char *argv1[] = { prgname, prefix, mp_flag, "-c"};
464 	/* No -c, -l or --lcores flag at all */
465 	const char *argv2[] = { prgname, prefix, mp_flag};
466 	/* bad coremask value */
467 	const char *argv3[] = { prgname, prefix, mp_flag,
468 				"-c", "error" };
469 	/* sanity check of tests - valid coremask value */
470 	const char *argv4[] = { prgname, prefix, mp_flag,
471 				"-c", "1" };
472 	/* -l flag but no corelist value */
473 	const char *argv5[] = { prgname, prefix, mp_flag,
474 				"-l"};
475 	const char *argv6[] = { prgname, prefix, mp_flag,
476 				"-l", " " };
477 	/* bad corelist values */
478 	const char *argv7[] = { prgname, prefix, mp_flag,
479 				"-l", "error" };
480 	const char *argv8[] = { prgname, prefix, mp_flag,
481 				"-l", "1-" };
482 	const char *argv9[] = { prgname, prefix, mp_flag,
483 				"-l", "1," };
484 	const char *argv10[] = { prgname, prefix, mp_flag,
485 				 "-l", "1#2" };
486 	/* core number is negative value */
487 	const char * const argv11[] = { prgname, prefix, mp_flag,
488 				"-l", "-5" };
489 	const char * const argv12[] = { prgname, prefix, mp_flag,
490 				"-l", "-5-7" };
491 	/* core number is maximum value */
492 	const char * const argv13[] = { prgname, prefix, mp_flag,
493 				"-l", RTE_STR(RTE_MAX_LCORE) };
494 	const char * const argv14[] = { prgname, prefix, mp_flag,
495 				"-l", "1-"RTE_STR(RTE_MAX_LCORE) };
496 	/* sanity check test - valid corelist value */
497 	const char * const argv15[] = { prgname, prefix, mp_flag,
498 				 "-l", "1-2,3" };
499 
500 	/* --lcores flag but no lcores value */
501 	const char * const argv16[] = { prgname, prefix, mp_flag,
502 				 "--lcores" };
503 	const char * const argv17[] = { prgname, prefix, mp_flag,
504 				 "--lcores", " " };
505 	/* bad lcores value */
506 	const char * const argv18[] = { prgname, prefix, mp_flag,
507 				 "--lcores", "1-3-5" };
508 	const char * const argv19[] = { prgname, prefix, mp_flag,
509 				 "--lcores", "0-1,,2" };
510 	const char * const argv20[] = { prgname, prefix, mp_flag,
511 				 "--lcores", "0-,1" };
512 	const char * const argv21[] = { prgname, prefix, mp_flag,
513 				 "--lcores", "(0-,2-4)" };
514 	const char * const argv22[] = { prgname, prefix, mp_flag,
515 				 "--lcores", "(-1,2)" };
516 	const char * const argv23[] = { prgname, prefix, mp_flag,
517 				 "--lcores", "(2-4)@(2-4-6)" };
518 	const char * const argv24[] = { prgname, prefix, mp_flag,
519 				 "--lcores", "(a,2)" };
520 	const char * const argv25[] = { prgname, prefix, mp_flag,
521 				 "--lcores", "1-3@(1,3)" };
522 	const char * const argv26[] = { prgname, prefix, mp_flag,
523 				 "--lcores", "3@((1,3)" };
524 	const char * const argv27[] = { prgname, prefix, mp_flag,
525 				 "--lcores", "(4-7)=(1,3)" };
526 	const char * const argv28[] = { prgname, prefix, mp_flag,
527 				 "--lcores", "[4-7]@(1,3)" };
528 	/* sanity check of tests - valid lcores value */
529 	const char * const argv29[] = { prgname, prefix, mp_flag,
530 				 "--lcores",
531 				 "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
532 	/* check an invalid cpu value >= CPU_SETSIZE */
533 	const char * const argv30[] = { prgname, prefix, mp_flag,
534 				 "--lcores", "3@" RTE_STR(CPU_SETSIZE) };
535 
536 	if (launch_proc(argv2) != 0) {
537 		printf("Error - "
538 		       "process did not run ok when missing -c flag\n");
539 		return -1;
540 	}
541 
542 	if (launch_proc(argv1) == 0
543 			|| launch_proc(argv3) == 0) {
544 		printf("Error - "
545 		       "process ran without error with invalid -c flag\n");
546 		return -1;
547 	}
548 	if (launch_proc(argv4) != 0) {
549 		printf("Error - "
550 		       "process did not run ok with valid coremask value\n");
551 		return -1;
552 	}
553 
554 	/* start -l test */
555 	if (launch_proc(argv5) == 0
556 			|| launch_proc(argv6) == 0
557 			|| launch_proc(argv7) == 0
558 			|| launch_proc(argv8) == 0
559 			|| launch_proc(argv9) == 0
560 			|| launch_proc(argv10) == 0
561 			|| launch_proc(argv11) == 0
562 			|| launch_proc(argv12) == 0
563 			|| launch_proc(argv13) == 0
564 			|| launch_proc(argv14) == 0) {
565 		printf("Error - "
566 		       "process ran without error with invalid -l flag\n");
567 		return -1;
568 	}
569 	if (rte_lcore_is_enabled(0) && rte_lcore_is_enabled(1) &&
570 	    rte_lcore_is_enabled(2) && rte_lcore_is_enabled(3) &&
571 	    launch_proc(argv15) != 0) {
572 		printf("Error - "
573 		       "process did not run ok with valid corelist value\n");
574 		return -1;
575 	}
576 
577 	/* start --lcores tests */
578 	if (launch_proc(argv16) == 0 || launch_proc(argv17) == 0 ||
579 	    launch_proc(argv18) == 0 || launch_proc(argv19) == 0 ||
580 	    launch_proc(argv20) == 0 || launch_proc(argv21) == 0 ||
581 	    launch_proc(argv22) == 0 || launch_proc(argv23) == 0 ||
582 	    launch_proc(argv24) == 0 || launch_proc(argv25) == 0 ||
583 	    launch_proc(argv26) == 0 || launch_proc(argv27) == 0 ||
584 	    launch_proc(argv28) == 0 || launch_proc(argv30) == 0) {
585 		printf("Error - "
586 		       "process ran without error with invalid --lcore flag\n");
587 		return -1;
588 	}
589 
590 	if (rte_lcore_is_enabled(0) && rte_lcore_is_enabled(1) &&
591 	    rte_lcore_is_enabled(2) && rte_lcore_is_enabled(3) &&
592 	    rte_lcore_is_enabled(3) && rte_lcore_is_enabled(5) &&
593 	    rte_lcore_is_enabled(4) && rte_lcore_is_enabled(7) &&
594 	    launch_proc(argv29) != 0) {
595 		printf("Error - "
596 		       "process did not run ok with valid corelist value\n");
597 		return -1;
598 	}
599 
600 	return 0;
601 }
602 
603 /*
604  * Test --main-lcore option with matching coremask
605  */
606 static int
607 test_main_lcore_flag(void)
608 {
609 #ifdef RTE_EXEC_ENV_FREEBSD
610 	/* BSD target doesn't support prefixes at this point */
611 	const char *prefix = "";
612 #else
613 	char prefix[PATH_MAX], tmp[PATH_MAX];
614 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
615 		printf("Error - unable to get current prefix!\n");
616 		return -1;
617 	}
618 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
619 #endif
620 
621 	if (!rte_lcore_is_enabled(0) || !rte_lcore_is_enabled(1))
622 		return TEST_SKIPPED;
623 
624 	/* --main-lcore flag but no value */
625 	const char *argv1[] = { prgname, prefix, mp_flag,
626 				"-c", "3", "--main-lcore"};
627 	/* --main-lcore flag with invalid value */
628 	const char *argv2[] = { prgname, prefix, mp_flag,
629 				"-c", "3", "--main-lcore", "-1"};
630 	const char *argv3[] = { prgname, prefix, mp_flag,
631 				"-c", "3", "--main-lcore", "X"};
632 	/* main lcore not in coremask */
633 	const char *argv4[] = { prgname, prefix, mp_flag,
634 				"-c", "3", "--main-lcore", "2"};
635 	/* valid value */
636 	const char *argv5[] = { prgname, prefix, mp_flag,
637 				"-c", "3", "--main-lcore", "1"};
638 	/* valid value set before coremask */
639 	const char *argv6[] = { prgname, prefix, mp_flag,
640 				"--main-lcore", "1", "-c", "3"};
641 
642 	if (launch_proc(argv1) == 0
643 			|| launch_proc(argv2) == 0
644 			|| launch_proc(argv3) == 0
645 			|| launch_proc(argv4) == 0) {
646 		printf("Error - process ran without error with wrong --main-lcore\n");
647 		return -1;
648 	}
649 	if (launch_proc(argv5) != 0
650 			|| launch_proc(argv6) != 0) {
651 		printf("Error - process did not run ok with valid --main-lcore\n");
652 		return -1;
653 	}
654 	return 0;
655 }
656 
657 /*
658  * Test that the app doesn't run with invalid -n flag option.
659  * Final test ensures it does run with valid options as sanity check
660  * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf
661  * flags.
662  */
663 static int
664 test_invalid_n_flag(void)
665 {
666 #ifdef RTE_EXEC_ENV_FREEBSD
667 	/* BSD target doesn't support prefixes at this point */
668 	const char * prefix = "";
669 #else
670 	char prefix[PATH_MAX], tmp[PATH_MAX];
671 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
672 		printf("Error - unable to get current prefix!\n");
673 		return -1;
674 	}
675 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
676 #endif
677 
678 	/* -n flag but no value */
679 	const char *argv1[] = { prgname, prefix, no_huge, no_shconf,
680 				"-n"};
681 	/* bad numeric value */
682 	const char *argv2[] = { prgname, prefix, no_huge, no_shconf,
683 				"-n", "e" };
684 	/* zero is invalid */
685 	const char *argv3[] = { prgname, prefix, no_huge, no_shconf,
686 				"-n", "0" };
687 	/* sanity test - check with good value */
688 	const char *argv4[] = { prgname, prefix, no_huge, no_shconf,
689 				"-n", "2" };
690 	/* sanity test - check with no -n flag */
691 	const char *argv5[] = { prgname, prefix, no_huge, no_shconf};
692 
693 	if (launch_proc(argv1) == 0
694 			|| launch_proc(argv2) == 0
695 			|| launch_proc(argv3) == 0) {
696 		printf("Error - process ran without error when"
697 		       "invalid -n flag\n");
698 		return -1;
699 	}
700 	if (launch_proc(argv4) != 0) {
701 		printf("Error - process did not run ok with valid num-channel value\n");
702 		return -1;
703 	}
704 	if (launch_proc(argv5) != 0) {
705 		printf("Error - process did not run ok without -n flag\n");
706 		return -1;
707 	}
708 
709 	return 0;
710 }
711 
712 /*
713  * Test that the app runs with HPET, and without HPET
714  */
715 static int
716 test_no_hpet_flag(void)
717 {
718 	char prefix[PATH_MAX] = "";
719 
720 #ifdef RTE_EXEC_ENV_FREEBSD
721 	return 0;
722 #else
723 	char tmp[PATH_MAX];
724 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
725 		printf("Error - unable to get current prefix!\n");
726 		return -1;
727 	}
728 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
729 #endif
730 
731 	/* With --no-hpet */
732 	const char *argv1[] = {prgname, prefix, mp_flag, no_hpet};
733 	/* Without --no-hpet */
734 	const char *argv2[] = {prgname, prefix, mp_flag};
735 
736 	if (launch_proc(argv1) != 0) {
737 		printf("Error - process did not run ok with --no-hpet flag\n");
738 		return -1;
739 	}
740 	if (launch_proc(argv2) != 0) {
741 		printf("Error - process did not run ok without --no-hpet flag\n");
742 		return -1;
743 	}
744 	return 0;
745 }
746 
747 /*
748  * Test that the app runs with --no-huge and doesn't run when --socket-mem are
749  * specified with --no-huge.
750  */
751 static int
752 test_no_huge_flag(void)
753 {
754 #ifdef RTE_EXEC_ENV_FREEBSD
755 	/* BSD target doesn't support prefixes at this point, and we also need to
756 	 * run another primary process here */
757 	const char * prefix = no_shconf;
758 #else
759 	const char * prefix = "--file-prefix=nohuge";
760 #endif
761 
762 	/* With --no-huge */
763 	const char *argv1[] = {prgname, prefix, no_huge};
764 	/* With --no-huge and -m */
765 	const char *argv2[] = {prgname, prefix, no_huge,
766 			"-m", DEFAULT_MEM_SIZE};
767 
768 	/* With --no-huge and --socket-mem */
769 	const char *argv3[] = {prgname, prefix, no_huge,
770 			"--socket-mem=" DEFAULT_MEM_SIZE};
771 	/* With --no-huge, -m and --socket-mem */
772 	const char *argv4[] = {prgname, prefix, no_huge,
773 			"-m", DEFAULT_MEM_SIZE, "--socket-mem=" DEFAULT_MEM_SIZE};
774 	if (launch_proc(argv1) != 0) {
775 		printf("Error - process did not run ok with --no-huge flag\n");
776 		return -1;
777 	}
778 	if (launch_proc(argv2) != 0) {
779 		printf("Error - process did not run ok with --no-huge and -m flags\n");
780 		return -1;
781 	}
782 #ifdef RTE_EXEC_ENV_FREEBSD
783 	/* BSD target does not support NUMA, hence no --socket-mem tests */
784 	return 0;
785 #endif
786 
787 	if (launch_proc(argv3) == 0) {
788 		printf("Error - process run ok with --no-huge and --socket-mem "
789 				"flags\n");
790 		return -1;
791 	}
792 	if (launch_proc(argv4) == 0) {
793 		printf("Error - process run ok with --no-huge, -m and "
794 				"--socket-mem flags\n");
795 		return -1;
796 	}
797 	return 0;
798 }
799 
800 static int
801 test_misc_flags(void)
802 {
803 	char hugepath[PATH_MAX] = {0};
804 	char hugepath_dir[PATH_MAX] = {0};
805 	char hugepath_dir2[PATH_MAX] = {0};
806 	char hugepath_dir3[PATH_MAX] = {0};
807 #ifdef RTE_EXEC_ENV_FREEBSD
808 	/* BSD target doesn't support prefixes at this point */
809 	const char * prefix = "";
810 	const char * nosh_prefix = "";
811 #else
812 	char prefix[PATH_MAX], tmp[PATH_MAX];
813 	const char * nosh_prefix = "--file-prefix=noshconf";
814 	FILE * hugedir_handle = NULL;
815 	char line[PATH_MAX] = {0};
816 	unsigned i, isempty = 1;
817 
818 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
819 		printf("Error - unable to get current prefix!\n");
820 		return -1;
821 	}
822 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
823 
824 	/*
825 	 * get first valid hugepage path
826 	 */
827 
828 	/* get hugetlbfs mountpoints from /proc/mounts */
829 	hugedir_handle = fopen("/proc/mounts", "r");
830 
831 	if (hugedir_handle == NULL) {
832 		printf("Error opening /proc/mounts!\n");
833 		return -1;
834 	}
835 
836 	/* read /proc/mounts */
837 	while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
838 
839 		/* find first valid hugepath */
840 		if (get_hugepage_path(line, sizeof(line), hugepath, sizeof(hugepath)))
841 			break;
842 	}
843 
844 	fclose(hugedir_handle);
845 
846 	/* check if path is not empty */
847 	for (i = 0; i < sizeof(hugepath); i++)
848 		if (hugepath[i] != '\0')
849 			isempty = 0;
850 
851 	if (isempty) {
852 		printf("No mounted hugepage dir found!\n");
853 		return -1;
854 	}
855 #endif
856 
857 	snprintf(hugepath_dir, sizeof(hugepath_dir), "%s/dpdk.missing", hugepath);
858 	snprintf(hugepath_dir2, sizeof(hugepath_dir2), "%s/dpdk.dir", hugepath);
859 
860 	if (mkdir(hugepath_dir2, 0700) != 0 && errno != EEXIST) {
861 		printf("Error - failed to mkdir(%s)\n", hugepath_dir2);
862 		return -1;
863 	}
864 
865 	snprintf(hugepath_dir3, sizeof(hugepath_dir3), "%s/dpdk.dir/sub", hugepath);
866 
867 	if (mkdir(hugepath_dir3, 0700) != 0 && errno != EEXIST) {
868 		printf("Error - failed to mkdir(%s)\n", hugepath_dir3);
869 		goto fail;
870 	}
871 
872 	/* check that some general flags don't prevent things from working.
873 	 * All cases, apart from the first, app should run.
874 	 * No further testing of output done.
875 	 */
876 	/* sanity check - failure with invalid option */
877 	const char *argv0[] = {prgname, prefix, mp_flag, "--invalid-opt"};
878 
879 	/* With --no-pci */
880 	const char *argv1[] = {prgname, prefix, mp_flag, "--no-pci"};
881 	/* With -v */
882 	const char *argv2[] = {prgname, prefix, mp_flag, "-v"};
883 	/* With valid --syslog */
884 	const char *argv3[] = {prgname, prefix, mp_flag,
885 			"--syslog", "syslog"};
886 	/* With empty --syslog (should fail) */
887 	const char *argv4[] = {prgname, prefix, mp_flag, "--syslog"};
888 	/* With invalid --syslog */
889 	const char *argv5[] = {prgname, prefix, mp_flag, "--syslog", "error"};
890 	/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */
891 	const char *argv6[] = {prgname, "-m", DEFAULT_MEM_SIZE,
892 			no_shconf, nosh_prefix, no_huge};
893 
894 	/* With --huge-dir */
895 	const char *argv7[] = {prgname, "-m", DEFAULT_MEM_SIZE,
896 			"--file-prefix=hugedir", "--huge-dir", hugepath};
897 	/* With empty --huge-dir (should fail) */
898 	const char *argv8[] = {prgname, "-m", DEFAULT_MEM_SIZE,
899 			"--file-prefix=hugedir", "--huge-dir"};
900 	/* With invalid --huge-dir */
901 	const char *argv9[] = {prgname, "-m", DEFAULT_MEM_SIZE,
902 			"--file-prefix=hugedir", "--huge-dir", "invalid"};
903 	/* With invalid --huge-dir sub-directory */
904 	const char *argv10[] = {prgname, "-m", DEFAULT_MEM_SIZE,
905 			"--file-prefix=hugedir", "--huge-dir", hugepath_dir};
906 	/* With valid --huge-dir sub-directory */
907 	const char *argv11[] = {prgname, "-m", DEFAULT_MEM_SIZE,
908 			"--file-prefix=hugedir", "--huge-dir", hugepath_dir2};
909 	/* Secondary process with invalid --huge-dir (should run as flag has no
910 	 * effect on secondary processes) */
911 	const char *argv12[] = {prgname, prefix, mp_flag,
912 			"--huge-dir", "invalid"};
913 
914 	/* try running with base-virtaddr param */
915 	const char *argv13[] = {prgname, "--file-prefix=virtaddr",
916 			"--base-virtaddr=0x12345678"};
917 
918 	/* try running with --vfio-intr INTx flag */
919 	const char *argv14[] = {prgname, "--file-prefix=intr",
920 			"--vfio-intr=legacy"};
921 
922 	/* try running with --vfio-intr MSI flag */
923 	const char *argv15[] = {prgname, "--file-prefix=intr",
924 			"--vfio-intr=msi"};
925 
926 	/* try running with --vfio-intr MSI-X flag */
927 	const char *argv16[] = {prgname, "--file-prefix=intr",
928 			"--vfio-intr=msix"};
929 
930 	/* try running with --vfio-intr invalid flag */
931 	const char *argv17[] = {prgname, "--file-prefix=intr",
932 			"--vfio-intr=invalid"};
933 
934 	/* With process type as auto-detect */
935 	const char * const argv18[] = {prgname, "--file-prefix=auto",
936 			"--proc-type=auto"};
937 
938 	/* With process type as auto-detect with no-shconf */
939 	const char * const argv19[] = {prgname, "--proc-type=auto",
940 			no_shconf, nosh_prefix, no_huge};
941 
942 	/* With process type as --create-uio-dev flag */
943 	const char * const argv20[] = {prgname, "--file-prefix=uiodev",
944 			"--create-uio-dev"};
945 
946 	/* run all tests also applicable to FreeBSD first */
947 
948 	if (launch_proc(argv0) == 0) {
949 		printf("Error - process ran ok with invalid flag\n");
950 		goto fail;
951 	}
952 	if (launch_proc(argv1) != 0) {
953 		printf("Error - process did not run ok with --no-pci flag\n");
954 		goto fail;
955 	}
956 	if (launch_proc(argv2) != 0) {
957 		printf("Error - process did not run ok with -v flag\n");
958 		goto fail;
959 	}
960 	if (launch_proc(argv6) != 0) {
961 		printf("Error - process did not run ok with --no-shconf flag\n");
962 		goto fail;
963 	}
964 
965 #ifdef RTE_EXEC_ENV_FREEBSD
966 	/* no more tests to be done on FreeBSD */
967 	return 0;
968 #endif
969 
970 	if (launch_proc(argv3) != 0) {
971 		printf("Error - process did not run ok with --syslog flag\n");
972 		goto fail;
973 	}
974 	if (launch_proc(argv4) == 0) {
975 		printf("Error - process run ok with empty --syslog flag\n");
976 		goto fail;
977 	}
978 	if (launch_proc(argv5) == 0) {
979 		printf("Error - process run ok with invalid --syslog flag\n");
980 		goto fail;
981 	}
982 	if (launch_proc(argv7) != 0) {
983 		printf("Error - process did not run ok with --huge-dir flag\n");
984 		goto fail;
985 	}
986 	if (launch_proc(argv8) == 0) {
987 		printf("Error - process run ok with empty --huge-dir flag\n");
988 		goto fail;
989 	}
990 	if (launch_proc(argv9) == 0) {
991 		printf("Error - process run ok with invalid --huge-dir flag\n");
992 		goto fail;
993 	}
994 	if (launch_proc(argv10) == 0) {
995 		printf("Error - process run ok with invalid --huge-dir sub-dir flag\n");
996 		goto fail;
997 	}
998 	if (launch_proc(argv11) != 0) {
999 		printf("Error - process did not run ok with --huge-dir subdir flag\n");
1000 		goto fail;
1001 	}
1002 	if (launch_proc(argv12) != 0) {
1003 		printf("Error - secondary process did not run ok with invalid --huge-dir flag\n");
1004 		goto fail;
1005 	}
1006 	if (launch_proc(argv13) != 0) {
1007 		printf("Error - process did not run ok with --base-virtaddr parameter\n");
1008 		goto fail;
1009 	}
1010 	if (launch_proc(argv14) != 0) {
1011 		printf("Error - process did not run ok with "
1012 				"--vfio-intr INTx parameter\n");
1013 		goto fail;
1014 	}
1015 	if (launch_proc(argv15) != 0) {
1016 		printf("Error - process did not run ok with "
1017 				"--vfio-intr MSI parameter\n");
1018 		goto fail;
1019 	}
1020 	if (launch_proc(argv16) != 0) {
1021 		printf("Error - process did not run ok with "
1022 				"--vfio-intr MSI-X parameter\n");
1023 		goto fail;
1024 	}
1025 	if (launch_proc(argv17) == 0) {
1026 		printf("Error - process run ok with "
1027 				"--vfio-intr invalid parameter\n");
1028 		goto fail;
1029 	}
1030 	if (launch_proc(argv18) != 0) {
1031 		printf("Error - process did not run ok with "
1032 				"--proc-type as auto parameter\n");
1033 		goto fail;
1034 	}
1035 	if (launch_proc(argv19) != 0) {
1036 		printf("Error - process did not run ok with "
1037 				"--proc-type and --no-shconf parameter\n");
1038 		goto fail;
1039 	}
1040 	if (launch_proc(argv20) != 0) {
1041 		printf("Error - process did not run ok with "
1042 				"--create-uio-dev parameter\n");
1043 		goto fail;
1044 	}
1045 
1046 	rmdir(hugepath_dir3);
1047 	rmdir(hugepath_dir2);
1048 	return 0;
1049 
1050 fail:
1051 	rmdir(hugepath_dir3);
1052 	rmdir(hugepath_dir2);
1053 	return -1;
1054 }
1055 
1056 static int
1057 test_file_prefix(void)
1058 {
1059 	/*
1060 	 * 1. check if current process hugefiles are locked
1061 	 * 2. try to run secondary process without a corresponding primary process
1062 	 * (while failing to run, it will also remove any unused hugepage files)
1063 	 * 3. check if current process hugefiles are still in place and are locked
1064 	 * 4. run a primary process with memtest1 prefix in default and legacy
1065 	 *    mem mode
1066 	 * 5. check if memtest1 hugefiles are created in case of legacy mem
1067 	 *    mode, and deleted in case of default mem mode
1068 	 * 6. run a primary process with memtest2 prefix in default and legacy
1069 	 *    mem modes
1070 	 * 7. check that memtest2 hugefiles are present in the hugedir after a
1071 	 *    run in legacy mode, and not present at all after run in default
1072 	 *    mem mode
1073 	 */
1074 	char prefix[PATH_MAX] = "";
1075 
1076 #ifdef RTE_EXEC_ENV_FREEBSD
1077 	return 0;
1078 #else
1079 	if (get_current_prefix(prefix, sizeof(prefix)) == NULL) {
1080 		printf("Error - unable to get current prefix!\n");
1081 		return -1;
1082 	}
1083 #endif
1084 
1085 	/* this should fail unless the test itself is run with "memtest" prefix */
1086 	const char *argv0[] = {prgname, mp_flag, "-m",
1087 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest };
1088 
1089 	/* primary process with memtest1 and default mem mode */
1090 	const char *argv1[] = {prgname, "-m",
1091 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest1 };
1092 
1093 	/* primary process with memtest1 and legacy mem mode */
1094 	const char *argv2[] = {prgname, "-m",
1095 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest1,
1096 			"--legacy-mem" };
1097 
1098 	/* primary process with memtest2 and legacy mem mode */
1099 	const char *argv3[] = {prgname, "-m",
1100 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest2,
1101 			"--legacy-mem" };
1102 
1103 	/* primary process with memtest2 and default mem mode */
1104 	const char *argv4[] = {prgname, "-m",
1105 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest2 };
1106 
1107 	/* primary process with --in-memory mode */
1108 	const char * const argv5[] = {prgname, "-m",
1109 		DEFAULT_MEM_SIZE, "--in-memory" };
1110 
1111 	/* primary process with memtest1 and --in-memory mode */
1112 	const char * const argv6[] = {prgname, "-m",
1113 		DEFAULT_MEM_SIZE, "--in-memory",
1114 		"--file-prefix=" memtest1 };
1115 
1116 	/* primary process with parent file-prefix and --in-memory mode */
1117 	const char * const argv7[] = {prgname, "-m",
1118 		DEFAULT_MEM_SIZE, "--in-memory", "--file-prefix", prefix };
1119 
1120 	/* primary process with memtest1 and --single-file-segments mode */
1121 	const char * const argv8[] = {prgname, "-m",
1122 		DEFAULT_MEM_SIZE, "--single-file-segments",
1123 		"--file-prefix=" memtest1 };
1124 
1125 	/* check if files for current prefix are present */
1126 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
1127 		printf("Error - hugepage files for %s were not created!\n", prefix);
1128 		return -1;
1129 	}
1130 
1131 	/* checks if files for current prefix are locked */
1132 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
1133 		printf("Error - hugepages for current process aren't locked!\n");
1134 		return -1;
1135 	}
1136 
1137 	/* check if files for secondary process are present */
1138 	if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) {
1139 		/* check if they are not locked */
1140 		if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) {
1141 			printf("Error - hugepages for current process are locked!\n");
1142 			return -1;
1143 		}
1144 		/* they aren't locked, delete them */
1145 		else {
1146 			if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) {
1147 				printf("Error - deleting hugepages failed!\n");
1148 				return -1;
1149 			}
1150 		}
1151 	}
1152 
1153 	if (launch_proc(argv0) == 0) {
1154 		printf("Error - secondary process ran ok without primary process\n");
1155 		return -1;
1156 	}
1157 
1158 	/* check if files for current prefix are present */
1159 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
1160 		printf("Error - hugepage files for %s were not created!\n", prefix);
1161 		return -1;
1162 	}
1163 
1164 	/* checks if files for current prefix are locked */
1165 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
1166 		printf("Error - hugepages for current process aren't locked!\n");
1167 		return -1;
1168 	}
1169 
1170 	/* we're running this process in default memory mode, which means it
1171 	 * should clean up after itself on exit and leave no hugepages behind.
1172 	 */
1173 	if (launch_proc(argv1) != 0) {
1174 		printf("Error - failed to run with --file-prefix=%s\n",
1175 				memtest1);
1176 		return -1;
1177 	}
1178 
1179 	/* check if memtest1_map0 is present */
1180 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1181 		printf("Error - hugepage files for %s were not deleted!\n",
1182 				memtest1);
1183 		return -1;
1184 	}
1185 
1186 	/* now, we're running a process under the same prefix, but with legacy
1187 	 * mem mode - this should leave behind hugepage files.
1188 	 */
1189 	if (launch_proc(argv2) != 0) {
1190 		printf("Error - failed to run with --file-prefix=%s\n",
1191 				memtest1);
1192 		return -1;
1193 	}
1194 
1195 	/* check if memtest1_map0 is present */
1196 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) {
1197 		printf("Error - hugepage files for %s were not created!\n",
1198 				memtest1);
1199 		return -1;
1200 	}
1201 
1202 	if (launch_proc(argv3) != 0) {
1203 		printf("Error - failed to run with --file-prefix=%s\n",
1204 				memtest2);
1205 		return -1;
1206 	}
1207 
1208 	/* check if hugefiles for memtest2 are present */
1209 	if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) {
1210 		printf("Error - hugepage files for %s were not created!\n",
1211 				memtest2);
1212 		return -1;
1213 	}
1214 
1215 	/* check if hugefiles for memtest1 are present */
1216 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1217 		printf("Error - hugepage files for %s were not deleted!\n",
1218 				memtest1);
1219 		return -1;
1220 	}
1221 
1222 	/* this process will run in default mem mode, so it should not leave any
1223 	 * hugepage files behind.
1224 	 */
1225 	if (launch_proc(argv4) != 0) {
1226 		printf("Error - failed to run with --file-prefix=%s\n",
1227 				memtest2);
1228 		return -1;
1229 	}
1230 
1231 	/* check if hugefiles for memtest2 are present */
1232 	if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 0) {
1233 		printf("Error - hugepage files for %s were not deleted!\n",
1234 				memtest2);
1235 		return -1;
1236 	}
1237 
1238 	/* check if hugefiles for memtest1 are present */
1239 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1240 		printf("Error - hugepage files for %s were not deleted!\n",
1241 				memtest1);
1242 		return -1;
1243 	}
1244 
1245 	/* this process will run in --in-memory mode, so it should not leave any
1246 	 * hugepage files behind.
1247 	 */
1248 
1249 	/* test case to check eal-options with --in-memory mode */
1250 	if (launch_proc(argv5) != 0) {
1251 		printf("Error - failed to run with --in-memory mode\n");
1252 		return -1;
1253 	}
1254 
1255 	/*test case to check eal-options with --in-memory mode with
1256 	 * custom file-prefix.
1257 	 */
1258 	if (launch_proc(argv6) != 0) {
1259 		printf("Error - failed to run with --in-memory mode\n");
1260 		return -1;
1261 	}
1262 
1263 	/* check if hugefiles for memtest1 are present */
1264 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1265 		printf("Error - hugepage files for %s were created and not deleted!\n",
1266 				memtest1);
1267 		return -1;
1268 	}
1269 
1270 	/* test case to check eal-options with --in-memory mode with
1271 	 * parent file-prefix.
1272 	 */
1273 	if (launch_proc(argv7) != 0) {
1274 		printf("Error - failed to run with --file-prefix=%s\n", prefix);
1275 		return -1;
1276 	}
1277 
1278 	/* this process will run in --single-file-segments mode,
1279 	 * so it should not leave any hugepage files behind.
1280 	 */
1281 	if (launch_proc(argv8) != 0) {
1282 		printf("Error - failed to run with --single-file-segments mode\n");
1283 		return -1;
1284 	}
1285 
1286 	/* check if hugefiles for memtest1 are present */
1287 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1288 		printf("Error - hugepage files for %s were not deleted!\n",
1289 				memtest1);
1290 		return -1;
1291 	}
1292 
1293 	return 0;
1294 }
1295 
1296 /* This function writes in passed buf pointer a valid --socket-mem= option
1297  * for num_sockets then concatenates the provided suffix string.
1298  *
1299  * Example for num_sockets 4, mem "2", suffix "plop"
1300  * --socket-mem=2,2,2,2plop
1301  */
1302 static void
1303 populate_socket_mem_param(int num_sockets, const char *mem,
1304 		const char *suffix, char *buf, size_t buf_size)
1305 {
1306 	unsigned int offset = 0;
1307 	int written;
1308 	int i;
1309 
1310 	written = snprintf(&buf[offset], buf_size - offset, "--socket-mem=");
1311 	if (written < 0 || written + offset >= buf_size)
1312 		return;
1313 	offset += written;
1314 
1315 	for (i = 0; i < num_sockets - 1; i++) {
1316 		written = snprintf(&buf[offset], buf_size - offset,
1317 			"%s,", mem);
1318 		if (written < 0 || written + offset >= buf_size)
1319 			return;
1320 		offset += written;
1321 	}
1322 
1323 	written = snprintf(&buf[offset], buf_size - offset, "%s%s", mem,
1324 		suffix);
1325 	if (written < 0 || written + offset >= buf_size)
1326 		return;
1327 	offset += written;
1328 }
1329 
1330 /*
1331  * Tests for correct handling of -m and --socket-mem flags
1332  */
1333 static int
1334 test_memory_flags(void)
1335 {
1336 #ifdef RTE_EXEC_ENV_FREEBSD
1337 	/* BSD target doesn't support prefixes at this point */
1338 	const char * prefix = "";
1339 #else
1340 	char prefix[PATH_MAX], tmp[PATH_MAX];
1341 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
1342 		printf("Error - unable to get current prefix!\n");
1343 		return -1;
1344 	}
1345 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
1346 #endif
1347 
1348 	/* valid -m flag and mp flag */
1349 	const char *argv0[] = {prgname, prefix, mp_flag,
1350 			"-m", DEFAULT_MEM_SIZE};
1351 
1352 	/* valid -m flag */
1353 	const char *argv1[] = {prgname,
1354 			"--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE};
1355 
1356 	/* valid (zero) --socket-mem flag */
1357 	char arg2_socket_mem[SOCKET_MEM_STRLEN];
1358 	const char *argv2[] = {prgname,
1359 			"--file-prefix=" memtest, arg2_socket_mem};
1360 
1361 	/* invalid (incomplete) --socket-mem flag */
1362 	char arg3_socket_mem[SOCKET_MEM_STRLEN];
1363 	const char *argv3[] = {prgname,
1364 			"--file-prefix=" memtest, arg3_socket_mem};
1365 
1366 	/* invalid (mixed with invalid data) --socket-mem flag */
1367 	char arg4_socket_mem[SOCKET_MEM_STRLEN];
1368 	const char *argv4[] = {prgname,
1369 			"--file-prefix=" memtest, arg4_socket_mem};
1370 
1371 	/* invalid (with numeric value as last character) --socket-mem flag */
1372 	char arg5_socket_mem[SOCKET_MEM_STRLEN];
1373 	const char *argv5[] = {prgname,
1374 			"--file-prefix=" memtest, arg5_socket_mem};
1375 
1376 	/* invalid (with empty socket) --socket-mem flag */
1377 	char arg6_socket_mem[SOCKET_MEM_STRLEN];
1378 	const char *argv6[] = {prgname,
1379 			"--file-prefix=" memtest, arg6_socket_mem};
1380 
1381 	/* invalid (null) --socket-mem flag */
1382 	const char *argv7[] = {prgname,
1383 			"--file-prefix=" memtest, "--socket-mem="};
1384 
1385 	/* valid --socket-mem specified together with -m flag */
1386 	char arg8_socket_mem[SOCKET_MEM_STRLEN];
1387 	const char *argv8[] = {prgname,
1388 			"--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE,
1389 			arg8_socket_mem};
1390 
1391 #ifdef RTE_EXEC_ENV_FREEBSD
1392 	int num_sockets = 1;
1393 #else
1394 	int num_sockets = RTE_MIN(get_number_of_sockets(),
1395 			RTE_MAX_NUMA_NODES);
1396 #endif
1397 
1398 	if (num_sockets <= 0) {
1399 		printf("Error - cannot get number of sockets!\n");
1400 		return -1;
1401 	}
1402 
1403 	/* invalid --socket-mem flag (with extra socket) */
1404 	char invalid_socket_mem[SOCKET_MEM_STRLEN];
1405 	const char *argv9[] = {prgname,
1406 			"--file-prefix=" memtest, invalid_socket_mem};
1407 
1408 	/* valid --socket-mem flag */
1409 	char valid_socket_mem[SOCKET_MEM_STRLEN];
1410 	const char *argv10[] = {prgname,
1411 			"--file-prefix=" memtest, valid_socket_mem};
1412 
1413 	if (launch_proc(argv0) != 0) {
1414 		printf("Error - secondary process failed with valid -m flag !\n");
1415 		return -1;
1416 	}
1417 
1418 #ifdef RTE_EXEC_ENV_FREEBSD
1419 	/* no other tests are applicable to BSD */
1420 	return 0;
1421 #endif
1422 
1423 	if (launch_proc(argv1) != 0) {
1424 		printf("Error - process failed with valid -m flag!\n");
1425 		return -1;
1426 	}
1427 
1428 	populate_socket_mem_param(num_sockets, "0", "",
1429 		arg2_socket_mem, sizeof(arg2_socket_mem));
1430 	if (launch_proc(argv2) != 0) {
1431 		printf("Error - process failed with valid (zero) --socket-mem!\n");
1432 		return -1;
1433 	}
1434 
1435 	if (num_sockets > 1) {
1436 		populate_socket_mem_param(num_sockets - 1, "2", ",",
1437 			arg3_socket_mem, sizeof(arg3_socket_mem));
1438 		if (launch_proc(argv3) == 0) {
1439 			printf("Error - process run ok with invalid "
1440 				"(incomplete) --socket-mem!\n");
1441 			return -1;
1442 		}
1443 
1444 		populate_socket_mem_param(num_sockets - 1, "2", ",Fred",
1445 			arg4_socket_mem, sizeof(arg4_socket_mem));
1446 		if (launch_proc(argv4) == 0) {
1447 			printf("Error - process run ok with invalid "
1448 				"(mixed with invalid input) --socket-mem!\n");
1449 			return -1;
1450 		}
1451 
1452 		populate_socket_mem_param(num_sockets - 1, "2", ",Fred0",
1453 			arg5_socket_mem, sizeof(arg5_socket_mem));
1454 		if (launch_proc(argv5) == 0) {
1455 			printf("Error - process run ok with invalid "
1456 				"(mixed with invalid input with a numeric value as "
1457 				"last character) --socket-mem!\n");
1458 			return -1;
1459 		}
1460 	}
1461 
1462 	if (num_sockets > 2) {
1463 		populate_socket_mem_param(num_sockets - 2, "2", ",,2",
1464 			arg6_socket_mem, sizeof(arg6_socket_mem));
1465 		if (launch_proc(argv6) == 0) {
1466 			printf("Error - process run ok with invalid "
1467 				"(with empty socket) --socket-mem!\n");
1468 			return -1;
1469 		}
1470 	}
1471 
1472 	if (launch_proc(argv7) == 0) {
1473 		printf("Error - process run ok with invalid (null) --socket-mem!\n");
1474 		return -1;
1475 	}
1476 
1477 	populate_socket_mem_param(num_sockets, "2", "",
1478 		arg8_socket_mem, sizeof(arg8_socket_mem));
1479 	if (launch_proc(argv8) == 0) {
1480 		printf("Error - process run ok with --socket-mem and -m specified!\n");
1481 		return -1;
1482 	}
1483 
1484 	populate_socket_mem_param(num_sockets + 1, "2", "",
1485 		invalid_socket_mem, sizeof(invalid_socket_mem));
1486 	if (launch_proc(argv9) == 0) {
1487 		printf("Error - process run ok with extra socket in --socket-mem!\n");
1488 		return -1;
1489 	}
1490 
1491 	populate_socket_mem_param(num_sockets, "2", "",
1492 		valid_socket_mem, sizeof(valid_socket_mem));
1493 	if (launch_proc(argv10) != 0) {
1494 		printf("Error - process failed with valid --socket-mem!\n");
1495 		return -1;
1496 	}
1497 
1498 	return 0;
1499 }
1500 
1501 static int
1502 test_eal_flags(void)
1503 {
1504 	int ret = 0;
1505 
1506 	ret = test_missing_c_flag();
1507 	if (ret < 0) {
1508 		printf("Error in test_missing_c_flag()\n");
1509 		return ret;
1510 	}
1511 
1512 	ret = test_main_lcore_flag();
1513 	if (ret < 0) {
1514 		printf("Error in test_main_lcore_flag()\n");
1515 		return ret;
1516 	}
1517 
1518 	ret = test_invalid_n_flag();
1519 	if (ret < 0) {
1520 		printf("Error in test_invalid_n_flag()\n");
1521 		return ret;
1522 	}
1523 
1524 	ret = test_no_hpet_flag();
1525 	if (ret < 0) {
1526 		printf("Error in test_no_hpet_flag()\n");
1527 		return ret;
1528 	}
1529 
1530 	ret = test_no_huge_flag();
1531 	if (ret < 0) {
1532 		printf("Error in test_no_huge_flag()\n");
1533 		return ret;
1534 	}
1535 
1536 	ret = test_allow_flag();
1537 	if (ret < 0) {
1538 		printf("Error in test_allow_flag()\n");
1539 		return ret;
1540 	}
1541 
1542 	ret = test_invalid_b_flag();
1543 	if (ret < 0) {
1544 		printf("Error in test_invalid_b_flag()\n");
1545 		return ret;
1546 	}
1547 
1548 #ifdef RTE_NET_RING
1549 	ret = test_invalid_vdev_flag();
1550 	if (ret < 0) {
1551 		printf("Error in test_invalid_vdev_flag()\n");
1552 		return ret;
1553 	}
1554 #endif
1555 	ret = test_invalid_r_flag();
1556 	if (ret < 0) {
1557 		printf("Error in test_invalid_r_flag()\n");
1558 		return ret;
1559 	}
1560 
1561 	ret = test_memory_flags();
1562 	if (ret < 0) {
1563 		printf("Error in test_memory_flags()\n");
1564 		return ret;
1565 	}
1566 
1567 	ret = test_file_prefix();
1568 	if (ret < 0) {
1569 		printf("Error in test_file_prefix()\n");
1570 		return ret;
1571 	}
1572 
1573 	ret = test_misc_flags();
1574 	if (ret < 0) {
1575 		printf("Error in test_misc_flags()");
1576 		return ret;
1577 	}
1578 
1579 	return ret;
1580 }
1581 
1582 REGISTER_TEST_COMMAND(eal_flags_autotest, test_eal_flags);
1583 
1584 /* subtests used in meson for CI */
1585 REGISTER_TEST_COMMAND(eal_flags_c_opt_autotest, test_missing_c_flag);
1586 REGISTER_TEST_COMMAND(eal_flags_main_opt_autotest, test_main_lcore_flag);
1587 REGISTER_TEST_COMMAND(eal_flags_n_opt_autotest, test_invalid_n_flag);
1588 REGISTER_TEST_COMMAND(eal_flags_hpet_autotest, test_no_hpet_flag);
1589 REGISTER_TEST_COMMAND(eal_flags_no_huge_autotest, test_no_huge_flag);
1590 REGISTER_TEST_COMMAND(eal_flags_a_opt_autotest, test_allow_flag);
1591 REGISTER_TEST_COMMAND(eal_flags_b_opt_autotest, test_invalid_b_flag);
1592 REGISTER_TEST_COMMAND(eal_flags_vdev_opt_autotest, test_invalid_vdev_flag);
1593 REGISTER_TEST_COMMAND(eal_flags_r_opt_autotest, test_invalid_r_flag);
1594 REGISTER_TEST_COMMAND(eal_flags_mem_autotest, test_memory_flags);
1595 REGISTER_TEST_COMMAND(eal_flags_file_prefix_autotest, test_file_prefix);
1596 REGISTER_TEST_COMMAND(eal_flags_misc_autotest, test_misc_flags);
1597