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