xref: /dpdk/app/test/test_eal_flags.c (revision cfe3aeb1)
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 pci_whitelist "--pci-whitelist"
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, \
40 		sizeof(ARGV)/(sizeof(ARGV[0])), __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 					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 whitelist 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_whitelist_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[][11] = {
248 		{prgname, prefix, mp_flag,
249 				pci_whitelist, "error", "", ""},
250 		{prgname, prefix, mp_flag,
251 				pci_whitelist, "0:0:0", "", ""},
252 		{prgname, prefix, mp_flag,
253 				pci_whitelist, "0:error:0.1", "", ""},
254 		{prgname, prefix, mp_flag,
255 				pci_whitelist, "0:0:0.1error", "", ""},
256 		{prgname, prefix, mp_flag,
257 				pci_whitelist, "error0:0:0.1", "", ""},
258 		{prgname, prefix, mp_flag,
259 				pci_whitelist, "0:0:0.1.2", "", ""},
260 	};
261 	/* Test with valid whitelist option */
262 	const char *wlval1[] = {prgname, prefix, mp_flag,
263 			pci_whitelist, "00FF:09:0B.3"};
264 	const char *wlval2[] = {prgname, prefix, mp_flag,
265 			pci_whitelist, "09:0B.3", pci_whitelist, "0a:0b.1"};
266 	const char *wlval3[] = {prgname, prefix, mp_flag,
267 			pci_whitelist, "09:0B.3,type=test",
268 			pci_whitelist, "08:00.1,type=normal",
269 	};
270 
271 	for (i = 0; i < sizeof(wlinval) / sizeof(wlinval[0]); i++) {
272 		if (launch_proc(wlinval[i]) == 0) {
273 			printf("Error - process did run ok with invalid "
274 			    "whitelist parameter\n");
275 			return -1;
276 		}
277 	}
278 	if (launch_proc(wlval1) != 0 ) {
279 		printf("Error - process did not run ok with valid whitelist\n");
280 		return -1;
281 	}
282 	if (launch_proc(wlval2) != 0 ) {
283 		printf("Error - process did not run ok with valid whitelist value set\n");
284 		return -1;
285 	}
286 	if (launch_proc(wlval3) != 0 ) {
287 		printf("Error - process did not run ok with valid whitelist + args\n");
288 		return -1;
289 	}
290 
291 	return 0;
292 }
293 
294 /*
295  * Test that the app doesn't run with invalid blacklist 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[][9] = {
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 blacklist 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 != sizeof (blinval) / sizeof (blinval[0]); i++) {
328 		if (launch_proc(blinval[i]) == 0) {
329 			printf("Error - process did run ok with invalid "
330 			    "blacklist parameter\n");
331 			return -1;
332 		}
333 	}
334 	if (launch_proc(blval) != 0) {
335 		printf("Error - process did not run ok with valid blacklist 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_LIBRTE_PMD_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[][9] = {
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 blacklist option */
424 	const char *rval[] = {prgname, prefix, mp_flag, "-r", "16"};
425 
426 	int i;
427 
428 	for (i = 0; i != sizeof (rinval) / sizeof (rinval[0]); 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 
532 	if (launch_proc(argv2) != 0) {
533 		printf("Error - "
534 		       "process did not run ok when missing -c flag\n");
535 		return -1;
536 	}
537 
538 	if (launch_proc(argv1) == 0
539 			|| launch_proc(argv3) == 0) {
540 		printf("Error - "
541 		       "process ran without error with invalid -c flag\n");
542 		return -1;
543 	}
544 	if (launch_proc(argv4) != 0) {
545 		printf("Error - "
546 		       "process did not run ok with valid coremask value\n");
547 		return -1;
548 	}
549 
550 	/* start -l test */
551 	if (launch_proc(argv5) == 0
552 			|| launch_proc(argv6) == 0
553 			|| launch_proc(argv7) == 0
554 			|| launch_proc(argv8) == 0
555 			|| launch_proc(argv9) == 0
556 			|| launch_proc(argv10) == 0
557 			|| launch_proc(argv11) == 0
558 			|| launch_proc(argv12) == 0
559 			|| launch_proc(argv13) == 0
560 			|| launch_proc(argv14) == 0) {
561 		printf("Error - "
562 		       "process ran without error with invalid -l flag\n");
563 		return -1;
564 	}
565 	if (rte_lcore_is_enabled(0) && rte_lcore_is_enabled(1) &&
566 	    rte_lcore_is_enabled(2) && rte_lcore_is_enabled(3) &&
567 	    launch_proc(argv15) != 0) {
568 		printf("Error - "
569 		       "process did not run ok with valid corelist value\n");
570 		return -1;
571 	}
572 
573 	/* start --lcores tests */
574 	if (launch_proc(argv16) == 0 || launch_proc(argv17) == 0 ||
575 	    launch_proc(argv18) == 0 || launch_proc(argv19) == 0 ||
576 	    launch_proc(argv20) == 0 || launch_proc(argv21) == 0 ||
577 	    launch_proc(argv22) == 0 || launch_proc(argv23) == 0 ||
578 	    launch_proc(argv24) == 0 || launch_proc(argv25) == 0 ||
579 	    launch_proc(argv26) == 0 || launch_proc(argv27) == 0 ||
580 	    launch_proc(argv28) == 0) {
581 		printf("Error - "
582 		       "process ran without error with invalid --lcore flag\n");
583 		return -1;
584 	}
585 
586 	if (rte_lcore_is_enabled(0) && rte_lcore_is_enabled(1) &&
587 	    rte_lcore_is_enabled(2) && rte_lcore_is_enabled(3) &&
588 	    rte_lcore_is_enabled(3) && rte_lcore_is_enabled(5) &&
589 	    rte_lcore_is_enabled(4) && rte_lcore_is_enabled(7) &&
590 	    launch_proc(argv29) != 0) {
591 		printf("Error - "
592 		       "process did not run ok with valid corelist value\n");
593 		return -1;
594 	}
595 
596 	return 0;
597 }
598 
599 /*
600  * Test --master-lcore option with matching coremask
601  */
602 static int
603 test_master_lcore_flag(void)
604 {
605 #ifdef RTE_EXEC_ENV_FREEBSD
606 	/* BSD target doesn't support prefixes at this point */
607 	const char *prefix = "";
608 #else
609 	char prefix[PATH_MAX], tmp[PATH_MAX];
610 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
611 		printf("Error - unable to get current prefix!\n");
612 		return -1;
613 	}
614 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
615 #endif
616 
617 	if (!rte_lcore_is_enabled(0) || !rte_lcore_is_enabled(1))
618 		return TEST_SKIPPED;
619 
620 	/* --master-lcore flag but no value */
621 	const char *argv1[] = { prgname, prefix, mp_flag,
622 				"-c", "3", "--master-lcore"};
623 	/* --master-lcore flag with invalid value */
624 	const char *argv2[] = { prgname, prefix, mp_flag,
625 				"-c", "3", "--master-lcore", "-1"};
626 	const char *argv3[] = { prgname, prefix, mp_flag,
627 				"-c", "3", "--master-lcore", "X"};
628 	/* master lcore not in coremask */
629 	const char *argv4[] = { prgname, prefix, mp_flag,
630 				"-c", "3", "--master-lcore", "2"};
631 	/* valid value */
632 	const char *argv5[] = { prgname, prefix, mp_flag,
633 				"-c", "3", "--master-lcore", "1"};
634 	/* valid value set before coremask */
635 	const char *argv6[] = { prgname, prefix, mp_flag,
636 				"--master-lcore", "1", "-c", "3"};
637 
638 	if (launch_proc(argv1) == 0
639 			|| launch_proc(argv2) == 0
640 			|| launch_proc(argv3) == 0
641 			|| launch_proc(argv4) == 0) {
642 		printf("Error - process ran without error with wrong --master-lcore\n");
643 		return -1;
644 	}
645 	if (launch_proc(argv5) != 0
646 			|| launch_proc(argv6) != 0) {
647 		printf("Error - process did not run ok with valid --master-lcore\n");
648 		return -1;
649 	}
650 	return 0;
651 }
652 
653 /*
654  * Test that the app doesn't run with invalid -n flag option.
655  * Final test ensures it does run with valid options as sanity check
656  * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf
657  * flags.
658  */
659 static int
660 test_invalid_n_flag(void)
661 {
662 #ifdef RTE_EXEC_ENV_FREEBSD
663 	/* BSD target doesn't support prefixes at this point */
664 	const char * prefix = "";
665 #else
666 	char prefix[PATH_MAX], tmp[PATH_MAX];
667 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
668 		printf("Error - unable to get current prefix!\n");
669 		return -1;
670 	}
671 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
672 #endif
673 
674 	/* -n flag but no value */
675 	const char *argv1[] = { prgname, prefix, no_huge, no_shconf,
676 				"-n"};
677 	/* bad numeric value */
678 	const char *argv2[] = { prgname, prefix, no_huge, no_shconf,
679 				"-n", "e" };
680 	/* zero is invalid */
681 	const char *argv3[] = { prgname, prefix, no_huge, no_shconf,
682 				"-n", "0" };
683 	/* sanity test - check with good value */
684 	const char *argv4[] = { prgname, prefix, no_huge, no_shconf,
685 				"-n", "2" };
686 	/* sanity test - check with no -n flag */
687 	const char *argv5[] = { prgname, prefix, no_huge, no_shconf};
688 
689 	if (launch_proc(argv1) == 0
690 			|| launch_proc(argv2) == 0
691 			|| launch_proc(argv3) == 0) {
692 		printf("Error - process ran without error when"
693 		       "invalid -n flag\n");
694 		return -1;
695 	}
696 	if (launch_proc(argv4) != 0) {
697 		printf("Error - process did not run ok with valid num-channel value\n");
698 		return -1;
699 	}
700 	if (launch_proc(argv5) != 0) {
701 		printf("Error - process did not run ok without -n flag\n");
702 		return -1;
703 	}
704 
705 	return 0;
706 }
707 
708 /*
709  * Test that the app runs with HPET, and without HPET
710  */
711 static int
712 test_no_hpet_flag(void)
713 {
714 	char prefix[PATH_MAX] = "";
715 
716 #ifdef RTE_EXEC_ENV_FREEBSD
717 	return 0;
718 #else
719 	char tmp[PATH_MAX];
720 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
721 		printf("Error - unable to get current prefix!\n");
722 		return -1;
723 	}
724 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
725 #endif
726 
727 	/* With --no-hpet */
728 	const char *argv1[] = {prgname, prefix, mp_flag, no_hpet};
729 	/* Without --no-hpet */
730 	const char *argv2[] = {prgname, prefix, mp_flag};
731 
732 	if (launch_proc(argv1) != 0) {
733 		printf("Error - process did not run ok with --no-hpet flag\n");
734 		return -1;
735 	}
736 	if (launch_proc(argv2) != 0) {
737 		printf("Error - process did not run ok without --no-hpet flag\n");
738 		return -1;
739 	}
740 	return 0;
741 }
742 
743 /*
744  * Test that the app runs with --no-huge and doesn't run when --socket-mem are
745  * specified with --no-huge.
746  */
747 static int
748 test_no_huge_flag(void)
749 {
750 #ifdef RTE_EXEC_ENV_FREEBSD
751 	/* BSD target doesn't support prefixes at this point, and we also need to
752 	 * run another primary process here */
753 	const char * prefix = no_shconf;
754 #else
755 	const char * prefix = "--file-prefix=nohuge";
756 #endif
757 
758 	/* With --no-huge */
759 	const char *argv1[] = {prgname, prefix, no_huge};
760 	/* With --no-huge and -m */
761 	const char *argv2[] = {prgname, prefix, no_huge,
762 			"-m", DEFAULT_MEM_SIZE};
763 
764 	/* With --no-huge and --socket-mem */
765 	const char *argv3[] = {prgname, prefix, no_huge,
766 			"--socket-mem=" DEFAULT_MEM_SIZE};
767 	/* With --no-huge, -m and --socket-mem */
768 	const char *argv4[] = {prgname, prefix, no_huge,
769 			"-m", DEFAULT_MEM_SIZE, "--socket-mem=" DEFAULT_MEM_SIZE};
770 	if (launch_proc(argv1) != 0) {
771 		printf("Error - process did not run ok with --no-huge flag\n");
772 		return -1;
773 	}
774 	if (launch_proc(argv2) != 0) {
775 		printf("Error - process did not run ok with --no-huge and -m flags\n");
776 		return -1;
777 	}
778 #ifdef RTE_EXEC_ENV_FREEBSD
779 	/* BSD target does not support NUMA, hence no --socket-mem tests */
780 	return 0;
781 #endif
782 
783 	if (launch_proc(argv3) == 0) {
784 		printf("Error - process run ok with --no-huge and --socket-mem "
785 				"flags\n");
786 		return -1;
787 	}
788 	if (launch_proc(argv4) == 0) {
789 		printf("Error - process run ok with --no-huge, -m and "
790 				"--socket-mem flags\n");
791 		return -1;
792 	}
793 	return 0;
794 }
795 
796 static int
797 test_misc_flags(void)
798 {
799 	char hugepath[PATH_MAX] = {0};
800 #ifdef RTE_EXEC_ENV_FREEBSD
801 	/* BSD target doesn't support prefixes at this point */
802 	const char * prefix = "";
803 	const char * nosh_prefix = "";
804 #else
805 	char prefix[PATH_MAX], tmp[PATH_MAX];
806 	const char * nosh_prefix = "--file-prefix=noshconf";
807 	FILE * hugedir_handle = NULL;
808 	char line[PATH_MAX] = {0};
809 	unsigned i, isempty = 1;
810 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
811 		printf("Error - unable to get current prefix!\n");
812 		return -1;
813 	}
814 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
815 
816 	/*
817 	 * get first valid hugepage path
818 	 */
819 
820 	/* get hugetlbfs mountpoints from /proc/mounts */
821 	hugedir_handle = fopen("/proc/mounts", "r");
822 
823 	if (hugedir_handle == NULL) {
824 		printf("Error opening /proc/mounts!\n");
825 		return -1;
826 	}
827 
828 	/* read /proc/mounts */
829 	while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
830 
831 		/* find first valid hugepath */
832 		if (get_hugepage_path(line, sizeof(line), hugepath, sizeof(hugepath)))
833 			break;
834 	}
835 
836 	fclose(hugedir_handle);
837 
838 	/* check if path is not empty */
839 	for (i = 0; i < sizeof(hugepath); i++)
840 		if (hugepath[i] != '\0')
841 			isempty = 0;
842 
843 	if (isempty) {
844 		printf("No mounted hugepage dir found!\n");
845 		return -1;
846 	}
847 #endif
848 
849 
850 	/* check that some general flags don't prevent things from working.
851 	 * All cases, apart from the first, app should run.
852 	 * No further testing of output done.
853 	 */
854 	/* sanity check - failure with invalid option */
855 	const char *argv0[] = {prgname, prefix, mp_flag, "--invalid-opt"};
856 
857 	/* With --no-pci */
858 	const char *argv1[] = {prgname, prefix, mp_flag, "--no-pci"};
859 	/* With -v */
860 	const char *argv2[] = {prgname, prefix, mp_flag, "-v"};
861 	/* With valid --syslog */
862 	const char *argv3[] = {prgname, prefix, mp_flag,
863 			"--syslog", "syslog"};
864 	/* With empty --syslog (should fail) */
865 	const char *argv4[] = {prgname, prefix, mp_flag, "--syslog"};
866 	/* With invalid --syslog */
867 	const char *argv5[] = {prgname, prefix, mp_flag, "--syslog", "error"};
868 	/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */
869 	const char *argv6[] = {prgname, "-m", DEFAULT_MEM_SIZE,
870 			no_shconf, nosh_prefix, no_huge};
871 
872 	/* With --huge-dir */
873 	const char *argv7[] = {prgname, "-m", DEFAULT_MEM_SIZE,
874 			"--file-prefix=hugedir", "--huge-dir", hugepath};
875 	/* With empty --huge-dir (should fail) */
876 	const char *argv8[] = {prgname, "-m", DEFAULT_MEM_SIZE,
877 			"--file-prefix=hugedir", "--huge-dir"};
878 	/* With invalid --huge-dir */
879 	const char *argv9[] = {prgname, "-m", DEFAULT_MEM_SIZE,
880 			"--file-prefix=hugedir", "--huge-dir", "invalid"};
881 	/* Secondary process with invalid --huge-dir (should run as flag has no
882 	 * effect on secondary processes) */
883 	const char *argv10[] = {prgname, prefix, mp_flag,
884 			"--huge-dir", "invalid"};
885 
886 	/* try running with base-virtaddr param */
887 	const char *argv11[] = {prgname, "--file-prefix=virtaddr",
888 			"--base-virtaddr=0x12345678"};
889 
890 	/* try running with --vfio-intr INTx flag */
891 	const char *argv12[] = {prgname, "--file-prefix=intr",
892 			"--vfio-intr=legacy"};
893 
894 	/* try running with --vfio-intr MSI flag */
895 	const char *argv13[] = {prgname, "--file-prefix=intr",
896 			"--vfio-intr=msi"};
897 
898 	/* try running with --vfio-intr MSI-X flag */
899 	const char *argv14[] = {prgname, "--file-prefix=intr",
900 			"--vfio-intr=msix"};
901 
902 	/* try running with --vfio-intr invalid flag */
903 	const char *argv15[] = {prgname, "--file-prefix=intr",
904 			"--vfio-intr=invalid"};
905 
906 	/* run all tests also applicable to FreeBSD first */
907 
908 	if (launch_proc(argv0) == 0) {
909 		printf("Error - process ran ok with invalid flag\n");
910 		return -1;
911 	}
912 	if (launch_proc(argv1) != 0) {
913 		printf("Error - process did not run ok with --no-pci flag\n");
914 		return -1;
915 	}
916 	if (launch_proc(argv2) != 0) {
917 		printf("Error - process did not run ok with -v flag\n");
918 		return -1;
919 	}
920 	if (launch_proc(argv6) != 0) {
921 		printf("Error - process did not run ok with --no-shconf flag\n");
922 		return -1;
923 	}
924 
925 #ifdef RTE_EXEC_ENV_FREEBSD
926 	/* no more tests to be done on FreeBSD */
927 	return 0;
928 #endif
929 
930 	if (launch_proc(argv3) != 0) {
931 		printf("Error - process did not run ok with --syslog flag\n");
932 		return -1;
933 	}
934 	if (launch_proc(argv4) == 0) {
935 		printf("Error - process run ok with empty --syslog flag\n");
936 		return -1;
937 	}
938 	if (launch_proc(argv5) == 0) {
939 		printf("Error - process run ok with invalid --syslog flag\n");
940 		return -1;
941 	}
942 	if (launch_proc(argv7) != 0) {
943 		printf("Error - process did not run ok with --huge-dir flag\n");
944 		return -1;
945 	}
946 	if (launch_proc(argv8) == 0) {
947 		printf("Error - process run ok with empty --huge-dir flag\n");
948 		return -1;
949 	}
950 	if (launch_proc(argv9) == 0) {
951 		printf("Error - process run ok with invalid --huge-dir flag\n");
952 		return -1;
953 	}
954 	if (launch_proc(argv10) != 0) {
955 		printf("Error - secondary process did not run ok with invalid --huge-dir flag\n");
956 		return -1;
957 	}
958 	if (launch_proc(argv11) != 0) {
959 		printf("Error - process did not run ok with --base-virtaddr parameter\n");
960 		return -1;
961 	}
962 	if (launch_proc(argv12) != 0) {
963 		printf("Error - process did not run ok with "
964 				"--vfio-intr INTx parameter\n");
965 		return -1;
966 	}
967 	if (launch_proc(argv13) != 0) {
968 		printf("Error - process did not run ok with "
969 				"--vfio-intr MSI parameter\n");
970 		return -1;
971 	}
972 	if (launch_proc(argv14) != 0) {
973 		printf("Error - process did not run ok with "
974 				"--vfio-intr MSI-X parameter\n");
975 		return -1;
976 	}
977 	if (launch_proc(argv15) == 0) {
978 		printf("Error - process run ok with "
979 				"--vfio-intr invalid parameter\n");
980 		return -1;
981 	}
982 	return 0;
983 }
984 
985 static int
986 test_file_prefix(void)
987 {
988 	/*
989 	 * 1. check if current process hugefiles are locked
990 	 * 2. try to run secondary process without a corresponding primary process
991 	 * (while failing to run, it will also remove any unused hugepage files)
992 	 * 3. check if current process hugefiles are still in place and are locked
993 	 * 4. run a primary process with memtest1 prefix in default and legacy
994 	 *    mem mode
995 	 * 5. check if memtest1 hugefiles are created in case of legacy mem
996 	 *    mode, and deleted in case of default mem mode
997 	 * 6. run a primary process with memtest2 prefix in default and legacy
998 	 *    mem modes
999 	 * 7. check that memtest2 hugefiles are present in the hugedir after a
1000 	 *    run in legacy mode, and not present at all after run in default
1001 	 *    mem mode
1002 	 */
1003 	char prefix[PATH_MAX] = "";
1004 
1005 #ifdef RTE_EXEC_ENV_FREEBSD
1006 	return 0;
1007 #else
1008 	if (get_current_prefix(prefix, sizeof(prefix)) == NULL) {
1009 		printf("Error - unable to get current prefix!\n");
1010 		return -1;
1011 	}
1012 #endif
1013 
1014 	/* this should fail unless the test itself is run with "memtest" prefix */
1015 	const char *argv0[] = {prgname, mp_flag, "-m",
1016 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest };
1017 
1018 	/* primary process with memtest1 and default mem mode */
1019 	const char *argv1[] = {prgname, "-m",
1020 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest1 };
1021 
1022 	/* primary process with memtest1 and legacy mem mode */
1023 	const char *argv2[] = {prgname, "-m",
1024 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest1,
1025 			"--legacy-mem" };
1026 
1027 	/* primary process with memtest2 and legacy mem mode */
1028 	const char *argv3[] = {prgname, "-m",
1029 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest2,
1030 			"--legacy-mem" };
1031 
1032 	/* primary process with memtest2 and default mem mode */
1033 	const char *argv4[] = {prgname, "-m",
1034 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest2 };
1035 
1036 	/* check if files for current prefix are present */
1037 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
1038 		printf("Error - hugepage files for %s were not created!\n", prefix);
1039 		return -1;
1040 	}
1041 
1042 	/* checks if files for current prefix are locked */
1043 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
1044 		printf("Error - hugepages for current process aren't locked!\n");
1045 		return -1;
1046 	}
1047 
1048 	/* check if files for secondary process are present */
1049 	if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) {
1050 		/* check if they are not locked */
1051 		if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) {
1052 			printf("Error - hugepages for current process are locked!\n");
1053 			return -1;
1054 		}
1055 		/* they aren't locked, delete them */
1056 		else {
1057 			if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) {
1058 				printf("Error - deleting hugepages failed!\n");
1059 				return -1;
1060 			}
1061 		}
1062 	}
1063 
1064 	if (launch_proc(argv0) == 0) {
1065 		printf("Error - secondary process ran ok without primary process\n");
1066 		return -1;
1067 	}
1068 
1069 	/* check if files for current prefix are present */
1070 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
1071 		printf("Error - hugepage files for %s were not created!\n", prefix);
1072 		return -1;
1073 	}
1074 
1075 	/* checks if files for current prefix are locked */
1076 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
1077 		printf("Error - hugepages for current process aren't locked!\n");
1078 		return -1;
1079 	}
1080 
1081 	/* we're running this process in default memory mode, which means it
1082 	 * should clean up after itself on exit and leave no hugepages behind.
1083 	 */
1084 	if (launch_proc(argv1) != 0) {
1085 		printf("Error - failed to run with --file-prefix=%s\n",
1086 				memtest1);
1087 		return -1;
1088 	}
1089 
1090 	/* check if memtest1_map0 is present */
1091 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1092 		printf("Error - hugepage files for %s were not deleted!\n",
1093 				memtest1);
1094 		return -1;
1095 	}
1096 
1097 	/* now, we're running a process under the same prefix, but with legacy
1098 	 * mem mode - this should leave behind hugepage files.
1099 	 */
1100 	if (launch_proc(argv2) != 0) {
1101 		printf("Error - failed to run with --file-prefix=%s\n",
1102 				memtest1);
1103 		return -1;
1104 	}
1105 
1106 	/* check if memtest1_map0 is present */
1107 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) {
1108 		printf("Error - hugepage files for %s were not created!\n",
1109 				memtest1);
1110 		return -1;
1111 	}
1112 
1113 	if (launch_proc(argv3) != 0) {
1114 		printf("Error - failed to run with --file-prefix=%s\n",
1115 				memtest2);
1116 		return -1;
1117 	}
1118 
1119 	/* check if hugefiles for memtest2 are present */
1120 	if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) {
1121 		printf("Error - hugepage files for %s were not created!\n",
1122 				memtest2);
1123 		return -1;
1124 	}
1125 
1126 	/* check if hugefiles for memtest1 are present */
1127 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1128 		printf("Error - hugepage files for %s were not deleted!\n",
1129 				memtest1);
1130 		return -1;
1131 	}
1132 
1133 	/* this process will run in default mem mode, so it should not leave any
1134 	 * hugepage files behind.
1135 	 */
1136 	if (launch_proc(argv4) != 0) {
1137 		printf("Error - failed to run with --file-prefix=%s\n",
1138 				memtest2);
1139 		return -1;
1140 	}
1141 
1142 	/* check if hugefiles for memtest2 are present */
1143 	if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 0) {
1144 		printf("Error - hugepage files for %s were not deleted!\n",
1145 				memtest2);
1146 		return -1;
1147 	}
1148 
1149 	/* check if hugefiles for memtest1 are present */
1150 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1151 		printf("Error - hugepage files for %s were not deleted!\n",
1152 				memtest1);
1153 		return -1;
1154 	}
1155 
1156 	return 0;
1157 }
1158 
1159 /*
1160  * Tests for correct handling of -m and --socket-mem flags
1161  */
1162 static int
1163 test_memory_flags(void)
1164 {
1165 #ifdef RTE_EXEC_ENV_FREEBSD
1166 	/* BSD target doesn't support prefixes at this point */
1167 	const char * prefix = "";
1168 #else
1169 	char prefix[PATH_MAX], tmp[PATH_MAX];
1170 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
1171 		printf("Error - unable to get current prefix!\n");
1172 		return -1;
1173 	}
1174 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
1175 #endif
1176 
1177 	/* valid -m flag and mp flag */
1178 	const char *argv0[] = {prgname, prefix, mp_flag,
1179 			"-m", DEFAULT_MEM_SIZE};
1180 
1181 	/* valid -m flag */
1182 	const char *argv1[] = {prgname,
1183 			"--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE};
1184 
1185 	/* valid (zero) --socket-mem flag */
1186 	const char *argv2[] = {prgname,
1187 			"--file-prefix=" memtest, "--socket-mem=0,0,0,0"};
1188 
1189 	/* invalid (incomplete) --socket-mem flag */
1190 	const char *argv3[] = {prgname,
1191 			"--file-prefix=" memtest, "--socket-mem=2,2,"};
1192 
1193 	/* invalid (mixed with invalid data) --socket-mem flag */
1194 	const char *argv4[] = {prgname,
1195 			"--file-prefix=" memtest, "--socket-mem=2,2,Fred"};
1196 
1197 	/* invalid (with numeric value as last character) --socket-mem flag */
1198 	const char *argv5[] = {prgname,
1199 			"--file-prefix=" memtest, "--socket-mem=2,2,Fred0"};
1200 
1201 	/* invalid (with empty socket) --socket-mem flag */
1202 	const char *argv6[] = {prgname,
1203 			"--file-prefix=" memtest, "--socket-mem=2,,2"};
1204 
1205 	/* invalid (null) --socket-mem flag */
1206 	const char *argv7[] = {prgname,
1207 			"--file-prefix=" memtest, "--socket-mem="};
1208 
1209 	/* valid --socket-mem specified together with -m flag */
1210 	const char *argv8[] = {prgname,
1211 			"--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE, "--socket-mem=2,2"};
1212 
1213 	/* construct an invalid socket mask with 2 megs on each socket plus
1214 	 * extra 2 megs on socket that doesn't exist on current system */
1215 	char invalid_socket_mem[SOCKET_MEM_STRLEN];
1216 	char buf[SOCKET_MEM_STRLEN];	/* to avoid copying string onto itself */
1217 
1218 #ifdef RTE_EXEC_ENV_FREEBSD
1219 	int i, num_sockets = 1;
1220 #else
1221 	int i, num_sockets = RTE_MIN(get_number_of_sockets(),
1222 			RTE_MAX_NUMA_NODES);
1223 #endif
1224 
1225 	if (num_sockets <= 0) {
1226 		printf("Error - cannot get number of sockets!\n");
1227 		return -1;
1228 	}
1229 
1230 	snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "--socket-mem=");
1231 
1232 	/* add one extra socket */
1233 	for (i = 0; i < num_sockets + 1; i++) {
1234 		snprintf(buf, sizeof(buf), "%s%s", invalid_socket_mem, DEFAULT_MEM_SIZE);
1235 		strlcpy(invalid_socket_mem, buf, sizeof(invalid_socket_mem));
1236 
1237 		if (num_sockets + 1 - i > 1) {
1238 			snprintf(buf, sizeof(buf), "%s,", invalid_socket_mem);
1239 			strlcpy(invalid_socket_mem, buf,
1240 				sizeof(invalid_socket_mem));
1241 		}
1242 	}
1243 
1244 	/* construct a valid socket mask with 2 megs on each existing socket */
1245 	char valid_socket_mem[SOCKET_MEM_STRLEN];
1246 
1247 	snprintf(valid_socket_mem, sizeof(valid_socket_mem), "--socket-mem=");
1248 
1249 	/* add one extra socket */
1250 	for (i = 0; i < num_sockets; i++) {
1251 		snprintf(buf, sizeof(buf), "%s%s", valid_socket_mem, DEFAULT_MEM_SIZE);
1252 		strlcpy(valid_socket_mem, buf, sizeof(valid_socket_mem));
1253 
1254 		if (num_sockets - i > 1) {
1255 			snprintf(buf, sizeof(buf), "%s,", valid_socket_mem);
1256 			strlcpy(valid_socket_mem, buf,
1257 				sizeof(valid_socket_mem));
1258 		}
1259 	}
1260 
1261 	/* invalid --socket-mem flag (with extra socket) */
1262 	const char *argv9[] = {prgname,
1263 			"--file-prefix=" memtest, invalid_socket_mem};
1264 
1265 	/* valid --socket-mem flag */
1266 	const char *argv10[] = {prgname,
1267 			"--file-prefix=" memtest, valid_socket_mem};
1268 
1269 	if (launch_proc(argv0) != 0) {
1270 		printf("Error - secondary process failed with valid -m flag !\n");
1271 		return -1;
1272 	}
1273 
1274 #ifdef RTE_EXEC_ENV_FREEBSD
1275 	/* no other tests are applicable to BSD */
1276 	return 0;
1277 #endif
1278 
1279 	if (launch_proc(argv1) != 0) {
1280 		printf("Error - process failed with valid -m flag!\n");
1281 		return -1;
1282 	}
1283 	if (launch_proc(argv2) != 0) {
1284 		printf("Error - process failed with valid (zero) --socket-mem!\n");
1285 		return -1;
1286 	}
1287 
1288 	if (launch_proc(argv3) == 0) {
1289 		printf("Error - process run ok with invalid "
1290 				"(incomplete) --socket-mem!\n");
1291 		return -1;
1292 	}
1293 
1294 	if (launch_proc(argv4) == 0) {
1295 		printf("Error - process run ok with invalid "
1296 				"(mixed with invalid input) --socket-mem!\n");
1297 		return -1;
1298 	}
1299 
1300 	if (launch_proc(argv5) == 0) {
1301 		printf("Error - process run ok with invalid "
1302 				"(mixed with invalid input with a numeric value as "
1303 				"last character) --socket-mem!\n");
1304 		return -1;
1305 	}
1306 
1307 	if (launch_proc(argv6) == 0) {
1308 		printf("Error - process run ok with invalid "
1309 				"(with empty socket) --socket-mem!\n");
1310 		return -1;
1311 	}
1312 
1313 	if (launch_proc(argv7) == 0) {
1314 		printf("Error - process run ok with invalid (null) --socket-mem!\n");
1315 		return -1;
1316 	}
1317 
1318 	if (launch_proc(argv8) == 0) {
1319 		printf("Error - process run ok with --socket-mem and -m specified!\n");
1320 		return -1;
1321 	}
1322 
1323 	if (launch_proc(argv9) == 0) {
1324 		printf("Error - process run ok with extra socket in --socket-mem!\n");
1325 		return -1;
1326 	}
1327 
1328 	if (launch_proc(argv10) != 0) {
1329 		printf("Error - process failed with valid --socket-mem!\n");
1330 		return -1;
1331 	}
1332 
1333 	return 0;
1334 }
1335 
1336 static int
1337 test_eal_flags(void)
1338 {
1339 	int ret = 0;
1340 
1341 	ret = test_missing_c_flag();
1342 	if (ret < 0) {
1343 		printf("Error in test_missing_c_flag()\n");
1344 		return ret;
1345 	}
1346 
1347 	ret = test_master_lcore_flag();
1348 	if (ret < 0) {
1349 		printf("Error in test_master_lcore_flag()\n");
1350 		return ret;
1351 	}
1352 
1353 	ret = test_invalid_n_flag();
1354 	if (ret < 0) {
1355 		printf("Error in test_invalid_n_flag()\n");
1356 		return ret;
1357 	}
1358 
1359 	ret = test_no_hpet_flag();
1360 	if (ret < 0) {
1361 		printf("Error in test_no_hpet_flag()\n");
1362 		return ret;
1363 	}
1364 
1365 	ret = test_no_huge_flag();
1366 	if (ret < 0) {
1367 		printf("Error in test_no_huge_flag()\n");
1368 		return ret;
1369 	}
1370 
1371 	ret = test_whitelist_flag();
1372 	if (ret < 0) {
1373 		printf("Error in test_invalid_whitelist_flag()\n");
1374 		return ret;
1375 	}
1376 
1377 	ret = test_invalid_b_flag();
1378 	if (ret < 0) {
1379 		printf("Error in test_invalid_b_flag()\n");
1380 		return ret;
1381 	}
1382 
1383 #ifdef RTE_LIBRTE_PMD_RING
1384 	ret = test_invalid_vdev_flag();
1385 	if (ret < 0) {
1386 		printf("Error in test_invalid_vdev_flag()\n");
1387 		return ret;
1388 	}
1389 #endif
1390 	ret = test_invalid_r_flag();
1391 	if (ret < 0) {
1392 		printf("Error in test_invalid_r_flag()\n");
1393 		return ret;
1394 	}
1395 
1396 	ret = test_memory_flags();
1397 	if (ret < 0) {
1398 		printf("Error in test_memory_flags()\n");
1399 		return ret;
1400 	}
1401 
1402 	ret = test_file_prefix();
1403 	if (ret < 0) {
1404 		printf("Error in test_file_prefix()\n");
1405 		return ret;
1406 	}
1407 
1408 	ret = test_misc_flags();
1409 	if (ret < 0) {
1410 		printf("Error in test_misc_flags()");
1411 		return ret;
1412 	}
1413 
1414 	return ret;
1415 }
1416 
1417 REGISTER_TEST_COMMAND(eal_flags_autotest, test_eal_flags);
1418 
1419 /* subtests used in meson for CI */
1420 REGISTER_TEST_COMMAND(eal_flags_c_opt_autotest, test_missing_c_flag);
1421 REGISTER_TEST_COMMAND(eal_flags_master_opt_autotest, test_master_lcore_flag);
1422 REGISTER_TEST_COMMAND(eal_flags_n_opt_autotest, test_invalid_n_flag);
1423 REGISTER_TEST_COMMAND(eal_flags_hpet_autotest, test_no_hpet_flag);
1424 REGISTER_TEST_COMMAND(eal_flags_no_huge_autotest, test_no_huge_flag);
1425 REGISTER_TEST_COMMAND(eal_flags_w_opt_autotest, test_whitelist_flag);
1426 REGISTER_TEST_COMMAND(eal_flags_b_opt_autotest, test_invalid_b_flag);
1427 REGISTER_TEST_COMMAND(eal_flags_vdev_opt_autotest, test_invalid_vdev_flag);
1428 REGISTER_TEST_COMMAND(eal_flags_r_opt_autotest, test_invalid_r_flag);
1429 REGISTER_TEST_COMMAND(eal_flags_mem_autotest, test_memory_flags);
1430 REGISTER_TEST_COMMAND(eal_flags_file_prefix_autotest, test_file_prefix);
1431 REGISTER_TEST_COMMAND(eal_flags_misc_autotest, test_misc_flags);
1432