xref: /dpdk/app/test/test_eal_flags.c (revision 089e5ed727a15da2729cfee9b63533dd120bd04c)
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[][7] = {
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[][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 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[][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 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 	/* With process type as auto-detect */
907 	const char * const argv16[] = {prgname, "--file-prefix=auto",
908 			"--proc-type=auto"};
909 
910 	/* With process type as auto-detect with no-shconf */
911 	const char * const argv17[] = {prgname, "--proc-type=auto",
912 			no_shconf, nosh_prefix, no_huge};
913 
914 	/* With process type as --create-uio-dev flag */
915 	const char * const argv18[] = {prgname, "--file-prefix=uiodev",
916 			"--create-uio-dev"};
917 
918 	/* run all tests also applicable to FreeBSD first */
919 
920 	if (launch_proc(argv0) == 0) {
921 		printf("Error - process ran ok with invalid flag\n");
922 		return -1;
923 	}
924 	if (launch_proc(argv1) != 0) {
925 		printf("Error - process did not run ok with --no-pci flag\n");
926 		return -1;
927 	}
928 	if (launch_proc(argv2) != 0) {
929 		printf("Error - process did not run ok with -v flag\n");
930 		return -1;
931 	}
932 	if (launch_proc(argv6) != 0) {
933 		printf("Error - process did not run ok with --no-shconf flag\n");
934 		return -1;
935 	}
936 
937 #ifdef RTE_EXEC_ENV_FREEBSD
938 	/* no more tests to be done on FreeBSD */
939 	return 0;
940 #endif
941 
942 	if (launch_proc(argv3) != 0) {
943 		printf("Error - process did not run ok with --syslog flag\n");
944 		return -1;
945 	}
946 	if (launch_proc(argv4) == 0) {
947 		printf("Error - process run ok with empty --syslog flag\n");
948 		return -1;
949 	}
950 	if (launch_proc(argv5) == 0) {
951 		printf("Error - process run ok with invalid --syslog flag\n");
952 		return -1;
953 	}
954 	if (launch_proc(argv7) != 0) {
955 		printf("Error - process did not run ok with --huge-dir flag\n");
956 		return -1;
957 	}
958 	if (launch_proc(argv8) == 0) {
959 		printf("Error - process run ok with empty --huge-dir flag\n");
960 		return -1;
961 	}
962 	if (launch_proc(argv9) == 0) {
963 		printf("Error - process run ok with invalid --huge-dir flag\n");
964 		return -1;
965 	}
966 	if (launch_proc(argv10) != 0) {
967 		printf("Error - secondary process did not run ok with invalid --huge-dir flag\n");
968 		return -1;
969 	}
970 	if (launch_proc(argv11) != 0) {
971 		printf("Error - process did not run ok with --base-virtaddr parameter\n");
972 		return -1;
973 	}
974 	if (launch_proc(argv12) != 0) {
975 		printf("Error - process did not run ok with "
976 				"--vfio-intr INTx parameter\n");
977 		return -1;
978 	}
979 	if (launch_proc(argv13) != 0) {
980 		printf("Error - process did not run ok with "
981 				"--vfio-intr MSI parameter\n");
982 		return -1;
983 	}
984 	if (launch_proc(argv14) != 0) {
985 		printf("Error - process did not run ok with "
986 				"--vfio-intr MSI-X parameter\n");
987 		return -1;
988 	}
989 	if (launch_proc(argv15) == 0) {
990 		printf("Error - process run ok with "
991 				"--vfio-intr invalid parameter\n");
992 		return -1;
993 	}
994 	if (launch_proc(argv16) != 0) {
995 		printf("Error - process did not run ok with "
996 				"--proc-type as auto parameter\n");
997 		return -1;
998 	}
999 	if (launch_proc(argv17) != 0) {
1000 		printf("Error - process did not run ok with "
1001 				"--proc-type and --no-shconf parameter\n");
1002 		return -1;
1003 	}
1004 	if (launch_proc(argv18) != 0) {
1005 		printf("Error - process did not run ok with "
1006 				"--create-uio-dev parameter\n");
1007 		return -1;
1008 	}
1009 
1010 	return 0;
1011 }
1012 
1013 static int
1014 test_file_prefix(void)
1015 {
1016 	/*
1017 	 * 1. check if current process hugefiles are locked
1018 	 * 2. try to run secondary process without a corresponding primary process
1019 	 * (while failing to run, it will also remove any unused hugepage files)
1020 	 * 3. check if current process hugefiles are still in place and are locked
1021 	 * 4. run a primary process with memtest1 prefix in default and legacy
1022 	 *    mem mode
1023 	 * 5. check if memtest1 hugefiles are created in case of legacy mem
1024 	 *    mode, and deleted in case of default mem mode
1025 	 * 6. run a primary process with memtest2 prefix in default and legacy
1026 	 *    mem modes
1027 	 * 7. check that memtest2 hugefiles are present in the hugedir after a
1028 	 *    run in legacy mode, and not present at all after run in default
1029 	 *    mem mode
1030 	 */
1031 	char prefix[PATH_MAX] = "";
1032 
1033 #ifdef RTE_EXEC_ENV_FREEBSD
1034 	return 0;
1035 #else
1036 	if (get_current_prefix(prefix, sizeof(prefix)) == NULL) {
1037 		printf("Error - unable to get current prefix!\n");
1038 		return -1;
1039 	}
1040 #endif
1041 
1042 	/* this should fail unless the test itself is run with "memtest" prefix */
1043 	const char *argv0[] = {prgname, mp_flag, "-m",
1044 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest };
1045 
1046 	/* primary process with memtest1 and default mem mode */
1047 	const char *argv1[] = {prgname, "-m",
1048 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest1 };
1049 
1050 	/* primary process with memtest1 and legacy mem mode */
1051 	const char *argv2[] = {prgname, "-m",
1052 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest1,
1053 			"--legacy-mem" };
1054 
1055 	/* primary process with memtest2 and legacy mem mode */
1056 	const char *argv3[] = {prgname, "-m",
1057 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest2,
1058 			"--legacy-mem" };
1059 
1060 	/* primary process with memtest2 and default mem mode */
1061 	const char *argv4[] = {prgname, "-m",
1062 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest2 };
1063 
1064 	/* primary process with --in-memory mode */
1065 	const char * const argv5[] = {prgname, "-m",
1066 		DEFAULT_MEM_SIZE, "--in-memory" };
1067 
1068 	/* primary process with memtest1 and --in-memory mode */
1069 	const char * const argv6[] = {prgname, "-m",
1070 		DEFAULT_MEM_SIZE, "--in-memory",
1071 		"--file-prefix=" memtest1 };
1072 
1073 	/* primary process with parent file-prefix and --in-memory mode */
1074 	const char * const argv7[] = {prgname, "-m",
1075 		DEFAULT_MEM_SIZE, "--in-memory", "--file-prefix", prefix };
1076 
1077 	/* primary process with memtest1 and --single-file-segments mode */
1078 	const char * const argv8[] = {prgname, "-m",
1079 		DEFAULT_MEM_SIZE, "--single-file-segments",
1080 		"--file-prefix=" memtest1 };
1081 
1082 	/* check if files for current prefix are present */
1083 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
1084 		printf("Error - hugepage files for %s were not created!\n", prefix);
1085 		return -1;
1086 	}
1087 
1088 	/* checks if files for current prefix are locked */
1089 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
1090 		printf("Error - hugepages for current process aren't locked!\n");
1091 		return -1;
1092 	}
1093 
1094 	/* check if files for secondary process are present */
1095 	if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) {
1096 		/* check if they are not locked */
1097 		if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) {
1098 			printf("Error - hugepages for current process are locked!\n");
1099 			return -1;
1100 		}
1101 		/* they aren't locked, delete them */
1102 		else {
1103 			if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) {
1104 				printf("Error - deleting hugepages failed!\n");
1105 				return -1;
1106 			}
1107 		}
1108 	}
1109 
1110 	if (launch_proc(argv0) == 0) {
1111 		printf("Error - secondary process ran ok without primary process\n");
1112 		return -1;
1113 	}
1114 
1115 	/* check if files for current prefix are present */
1116 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
1117 		printf("Error - hugepage files for %s were not created!\n", prefix);
1118 		return -1;
1119 	}
1120 
1121 	/* checks if files for current prefix are locked */
1122 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
1123 		printf("Error - hugepages for current process aren't locked!\n");
1124 		return -1;
1125 	}
1126 
1127 	/* we're running this process in default memory mode, which means it
1128 	 * should clean up after itself on exit and leave no hugepages behind.
1129 	 */
1130 	if (launch_proc(argv1) != 0) {
1131 		printf("Error - failed to run with --file-prefix=%s\n",
1132 				memtest1);
1133 		return -1;
1134 	}
1135 
1136 	/* check if memtest1_map0 is present */
1137 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1138 		printf("Error - hugepage files for %s were not deleted!\n",
1139 				memtest1);
1140 		return -1;
1141 	}
1142 
1143 	/* now, we're running a process under the same prefix, but with legacy
1144 	 * mem mode - this should leave behind hugepage files.
1145 	 */
1146 	if (launch_proc(argv2) != 0) {
1147 		printf("Error - failed to run with --file-prefix=%s\n",
1148 				memtest1);
1149 		return -1;
1150 	}
1151 
1152 	/* check if memtest1_map0 is present */
1153 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) {
1154 		printf("Error - hugepage files for %s were not created!\n",
1155 				memtest1);
1156 		return -1;
1157 	}
1158 
1159 	if (launch_proc(argv3) != 0) {
1160 		printf("Error - failed to run with --file-prefix=%s\n",
1161 				memtest2);
1162 		return -1;
1163 	}
1164 
1165 	/* check if hugefiles for memtest2 are present */
1166 	if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) {
1167 		printf("Error - hugepage files for %s were not created!\n",
1168 				memtest2);
1169 		return -1;
1170 	}
1171 
1172 	/* check if hugefiles for memtest1 are present */
1173 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1174 		printf("Error - hugepage files for %s were not deleted!\n",
1175 				memtest1);
1176 		return -1;
1177 	}
1178 
1179 	/* this process will run in default mem mode, so it should not leave any
1180 	 * hugepage files behind.
1181 	 */
1182 	if (launch_proc(argv4) != 0) {
1183 		printf("Error - failed to run with --file-prefix=%s\n",
1184 				memtest2);
1185 		return -1;
1186 	}
1187 
1188 	/* check if hugefiles for memtest2 are present */
1189 	if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 0) {
1190 		printf("Error - hugepage files for %s were not deleted!\n",
1191 				memtest2);
1192 		return -1;
1193 	}
1194 
1195 	/* check if hugefiles for memtest1 are present */
1196 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1197 		printf("Error - hugepage files for %s were not deleted!\n",
1198 				memtest1);
1199 		return -1;
1200 	}
1201 
1202 	/* this process will run in --in-memory mode, so it should not leave any
1203 	 * hugepage files behind.
1204 	 */
1205 
1206 	/* test case to check eal-options with --in-memory mode */
1207 	if (launch_proc(argv5) != 0) {
1208 		printf("Error - failed to run with --in-memory mode\n");
1209 		return -1;
1210 	}
1211 
1212 	/*test case to check eal-options with --in-memory mode with
1213 	 * custom file-prefix.
1214 	 */
1215 	if (launch_proc(argv6) != 0) {
1216 		printf("Error - failed to run with --in-memory mode\n");
1217 		return -1;
1218 	}
1219 
1220 	/* check if hugefiles for memtest1 are present */
1221 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1222 		printf("Error - hugepage files for %s were created and not deleted!\n",
1223 				memtest1);
1224 		return -1;
1225 	}
1226 
1227 	/* test case to check eal-options with --in-memory mode with
1228 	 * parent file-prefix.
1229 	 */
1230 	if (launch_proc(argv7) != 0) {
1231 		printf("Error - failed to run with --file-prefix=%s\n", prefix);
1232 		return -1;
1233 	}
1234 
1235 	/* this process will run in --single-file-segments mode,
1236 	 * so it should not leave any hugepage files behind.
1237 	 */
1238 	if (launch_proc(argv8) != 0) {
1239 		printf("Error - failed to run with --single-file-segments mode\n");
1240 		return -1;
1241 	}
1242 
1243 	/* check if hugefiles for memtest1 are present */
1244 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1245 		printf("Error - hugepage files for %s were not deleted!\n",
1246 				memtest1);
1247 		return -1;
1248 	}
1249 
1250 	return 0;
1251 }
1252 
1253 /* This function writes in passed buf pointer a valid --socket-mem= option
1254  * for num_sockets then concatenates the provided suffix string.
1255  *
1256  * Example for num_sockets 4, mem "2", suffix "plop"
1257  * --socket-mem=2,2,2,2plop
1258  */
1259 static void
1260 populate_socket_mem_param(int num_sockets, const char *mem,
1261 		const char *suffix, char *buf, size_t buf_size)
1262 {
1263 	unsigned int offset = 0;
1264 	int written;
1265 	int i;
1266 
1267 	written = snprintf(&buf[offset], buf_size - offset, "--socket-mem=");
1268 	if (written < 0 || written + offset >= buf_size)
1269 		return;
1270 	offset += written;
1271 
1272 	for (i = 0; i < num_sockets - 1; i++) {
1273 		written = snprintf(&buf[offset], buf_size - offset,
1274 			"%s,", mem);
1275 		if (written < 0 || written + offset >= buf_size)
1276 			return;
1277 		offset += written;
1278 	}
1279 
1280 	written = snprintf(&buf[offset], buf_size - offset, "%s%s", mem,
1281 		suffix);
1282 	if (written < 0 || written + offset >= buf_size)
1283 		return;
1284 	offset += written;
1285 }
1286 
1287 /*
1288  * Tests for correct handling of -m and --socket-mem flags
1289  */
1290 static int
1291 test_memory_flags(void)
1292 {
1293 #ifdef RTE_EXEC_ENV_FREEBSD
1294 	/* BSD target doesn't support prefixes at this point */
1295 	const char * prefix = "";
1296 #else
1297 	char prefix[PATH_MAX], tmp[PATH_MAX];
1298 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
1299 		printf("Error - unable to get current prefix!\n");
1300 		return -1;
1301 	}
1302 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
1303 #endif
1304 
1305 	/* valid -m flag and mp flag */
1306 	const char *argv0[] = {prgname, prefix, mp_flag,
1307 			"-m", DEFAULT_MEM_SIZE};
1308 
1309 	/* valid -m flag */
1310 	const char *argv1[] = {prgname,
1311 			"--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE};
1312 
1313 	/* valid (zero) --socket-mem flag */
1314 	char arg2_socket_mem[SOCKET_MEM_STRLEN];
1315 	const char *argv2[] = {prgname,
1316 			"--file-prefix=" memtest, arg2_socket_mem};
1317 
1318 	/* invalid (incomplete) --socket-mem flag */
1319 	char arg3_socket_mem[SOCKET_MEM_STRLEN];
1320 	const char *argv3[] = {prgname,
1321 			"--file-prefix=" memtest, arg3_socket_mem};
1322 
1323 	/* invalid (mixed with invalid data) --socket-mem flag */
1324 	char arg4_socket_mem[SOCKET_MEM_STRLEN];
1325 	const char *argv4[] = {prgname,
1326 			"--file-prefix=" memtest, arg4_socket_mem};
1327 
1328 	/* invalid (with numeric value as last character) --socket-mem flag */
1329 	char arg5_socket_mem[SOCKET_MEM_STRLEN];
1330 	const char *argv5[] = {prgname,
1331 			"--file-prefix=" memtest, arg5_socket_mem};
1332 
1333 	/* invalid (with empty socket) --socket-mem flag */
1334 	char arg6_socket_mem[SOCKET_MEM_STRLEN];
1335 	const char *argv6[] = {prgname,
1336 			"--file-prefix=" memtest, arg6_socket_mem};
1337 
1338 	/* invalid (null) --socket-mem flag */
1339 	const char *argv7[] = {prgname,
1340 			"--file-prefix=" memtest, "--socket-mem="};
1341 
1342 	/* valid --socket-mem specified together with -m flag */
1343 	char arg8_socket_mem[SOCKET_MEM_STRLEN];
1344 	const char *argv8[] = {prgname,
1345 			"--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE,
1346 			arg8_socket_mem};
1347 
1348 #ifdef RTE_EXEC_ENV_FREEBSD
1349 	int num_sockets = 1;
1350 #else
1351 	int num_sockets = RTE_MIN(get_number_of_sockets(),
1352 			RTE_MAX_NUMA_NODES);
1353 #endif
1354 
1355 	if (num_sockets <= 0) {
1356 		printf("Error - cannot get number of sockets!\n");
1357 		return -1;
1358 	}
1359 
1360 	/* invalid --socket-mem flag (with extra socket) */
1361 	char invalid_socket_mem[SOCKET_MEM_STRLEN];
1362 	const char *argv9[] = {prgname,
1363 			"--file-prefix=" memtest, invalid_socket_mem};
1364 
1365 	/* valid --socket-mem flag */
1366 	char valid_socket_mem[SOCKET_MEM_STRLEN];
1367 	const char *argv10[] = {prgname,
1368 			"--file-prefix=" memtest, valid_socket_mem};
1369 
1370 	if (launch_proc(argv0) != 0) {
1371 		printf("Error - secondary process failed with valid -m flag !\n");
1372 		return -1;
1373 	}
1374 
1375 #ifdef RTE_EXEC_ENV_FREEBSD
1376 	/* no other tests are applicable to BSD */
1377 	return 0;
1378 #endif
1379 
1380 	if (launch_proc(argv1) != 0) {
1381 		printf("Error - process failed with valid -m flag!\n");
1382 		return -1;
1383 	}
1384 
1385 	populate_socket_mem_param(num_sockets, "0", "",
1386 		arg2_socket_mem, sizeof(arg2_socket_mem));
1387 	if (launch_proc(argv2) != 0) {
1388 		printf("Error - process failed with valid (zero) --socket-mem!\n");
1389 		return -1;
1390 	}
1391 
1392 	if (num_sockets > 1) {
1393 		populate_socket_mem_param(num_sockets - 1, "2", ",",
1394 			arg3_socket_mem, sizeof(arg3_socket_mem));
1395 		if (launch_proc(argv3) == 0) {
1396 			printf("Error - process run ok with invalid "
1397 				"(incomplete) --socket-mem!\n");
1398 			return -1;
1399 		}
1400 
1401 		populate_socket_mem_param(num_sockets - 1, "2", ",Fred",
1402 			arg4_socket_mem, sizeof(arg4_socket_mem));
1403 		if (launch_proc(argv4) == 0) {
1404 			printf("Error - process run ok with invalid "
1405 				"(mixed with invalid input) --socket-mem!\n");
1406 			return -1;
1407 		}
1408 
1409 		populate_socket_mem_param(num_sockets - 1, "2", ",Fred0",
1410 			arg5_socket_mem, sizeof(arg5_socket_mem));
1411 		if (launch_proc(argv5) == 0) {
1412 			printf("Error - process run ok with invalid "
1413 				"(mixed with invalid input with a numeric value as "
1414 				"last character) --socket-mem!\n");
1415 			return -1;
1416 		}
1417 	}
1418 
1419 	if (num_sockets > 2) {
1420 		populate_socket_mem_param(num_sockets - 2, "2", ",,2",
1421 			arg6_socket_mem, sizeof(arg6_socket_mem));
1422 		if (launch_proc(argv6) == 0) {
1423 			printf("Error - process run ok with invalid "
1424 				"(with empty socket) --socket-mem!\n");
1425 			return -1;
1426 		}
1427 	}
1428 
1429 	if (launch_proc(argv7) == 0) {
1430 		printf("Error - process run ok with invalid (null) --socket-mem!\n");
1431 		return -1;
1432 	}
1433 
1434 	populate_socket_mem_param(num_sockets, "2", "",
1435 		arg8_socket_mem, sizeof(arg8_socket_mem));
1436 	if (launch_proc(argv8) == 0) {
1437 		printf("Error - process run ok with --socket-mem and -m specified!\n");
1438 		return -1;
1439 	}
1440 
1441 	populate_socket_mem_param(num_sockets + 1, "2", "",
1442 		invalid_socket_mem, sizeof(invalid_socket_mem));
1443 	if (launch_proc(argv9) == 0) {
1444 		printf("Error - process run ok with extra socket in --socket-mem!\n");
1445 		return -1;
1446 	}
1447 
1448 	populate_socket_mem_param(num_sockets, "2", "",
1449 		valid_socket_mem, sizeof(valid_socket_mem));
1450 	if (launch_proc(argv10) != 0) {
1451 		printf("Error - process failed with valid --socket-mem!\n");
1452 		return -1;
1453 	}
1454 
1455 	return 0;
1456 }
1457 
1458 static int
1459 test_eal_flags(void)
1460 {
1461 	int ret = 0;
1462 
1463 	ret = test_missing_c_flag();
1464 	if (ret < 0) {
1465 		printf("Error in test_missing_c_flag()\n");
1466 		return ret;
1467 	}
1468 
1469 	ret = test_master_lcore_flag();
1470 	if (ret < 0) {
1471 		printf("Error in test_master_lcore_flag()\n");
1472 		return ret;
1473 	}
1474 
1475 	ret = test_invalid_n_flag();
1476 	if (ret < 0) {
1477 		printf("Error in test_invalid_n_flag()\n");
1478 		return ret;
1479 	}
1480 
1481 	ret = test_no_hpet_flag();
1482 	if (ret < 0) {
1483 		printf("Error in test_no_hpet_flag()\n");
1484 		return ret;
1485 	}
1486 
1487 	ret = test_no_huge_flag();
1488 	if (ret < 0) {
1489 		printf("Error in test_no_huge_flag()\n");
1490 		return ret;
1491 	}
1492 
1493 	ret = test_whitelist_flag();
1494 	if (ret < 0) {
1495 		printf("Error in test_invalid_whitelist_flag()\n");
1496 		return ret;
1497 	}
1498 
1499 	ret = test_invalid_b_flag();
1500 	if (ret < 0) {
1501 		printf("Error in test_invalid_b_flag()\n");
1502 		return ret;
1503 	}
1504 
1505 #ifdef RTE_LIBRTE_PMD_RING
1506 	ret = test_invalid_vdev_flag();
1507 	if (ret < 0) {
1508 		printf("Error in test_invalid_vdev_flag()\n");
1509 		return ret;
1510 	}
1511 #endif
1512 	ret = test_invalid_r_flag();
1513 	if (ret < 0) {
1514 		printf("Error in test_invalid_r_flag()\n");
1515 		return ret;
1516 	}
1517 
1518 	ret = test_memory_flags();
1519 	if (ret < 0) {
1520 		printf("Error in test_memory_flags()\n");
1521 		return ret;
1522 	}
1523 
1524 	ret = test_file_prefix();
1525 	if (ret < 0) {
1526 		printf("Error in test_file_prefix()\n");
1527 		return ret;
1528 	}
1529 
1530 	ret = test_misc_flags();
1531 	if (ret < 0) {
1532 		printf("Error in test_misc_flags()");
1533 		return ret;
1534 	}
1535 
1536 	return ret;
1537 }
1538 
1539 REGISTER_TEST_COMMAND(eal_flags_autotest, test_eal_flags);
1540 
1541 /* subtests used in meson for CI */
1542 REGISTER_TEST_COMMAND(eal_flags_c_opt_autotest, test_missing_c_flag);
1543 REGISTER_TEST_COMMAND(eal_flags_master_opt_autotest, test_master_lcore_flag);
1544 REGISTER_TEST_COMMAND(eal_flags_n_opt_autotest, test_invalid_n_flag);
1545 REGISTER_TEST_COMMAND(eal_flags_hpet_autotest, test_no_hpet_flag);
1546 REGISTER_TEST_COMMAND(eal_flags_no_huge_autotest, test_no_huge_flag);
1547 REGISTER_TEST_COMMAND(eal_flags_w_opt_autotest, test_whitelist_flag);
1548 REGISTER_TEST_COMMAND(eal_flags_b_opt_autotest, test_invalid_b_flag);
1549 REGISTER_TEST_COMMAND(eal_flags_vdev_opt_autotest, test_invalid_vdev_flag);
1550 REGISTER_TEST_COMMAND(eal_flags_r_opt_autotest, test_invalid_r_flag);
1551 REGISTER_TEST_COMMAND(eal_flags_mem_autotest, test_memory_flags);
1552 REGISTER_TEST_COMMAND(eal_flags_file_prefix_autotest, test_file_prefix);
1553 REGISTER_TEST_COMMAND(eal_flags_misc_autotest, test_misc_flags);
1554