xref: /dpdk/app/test/test_eal_flags.c (revision 2d0c29a37a9c080c1cccb1ad7941aba2ccf5437e)
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_per_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 		snprintf(dst, dst_len, "%s", tokens[1]);
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, "-n", "1", "-c", "1",
249 				pci_whitelist, "error", "", ""},
250 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
251 				pci_whitelist, "0:0:0", "", ""},
252 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
253 				pci_whitelist, "0:error:0.1", "", ""},
254 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
255 				pci_whitelist, "0:0:0.1error", "", ""},
256 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
257 				pci_whitelist, "error0:0:0.1", "", ""},
258 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
259 				pci_whitelist, "0:0:0.1.2", "", ""},
260 	};
261 	/* Test with valid whitelist option */
262 	const char *wlval1[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
263 			pci_whitelist, "00FF:09:0B.3"};
264 	const char *wlval2[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
265 			pci_whitelist, "09:0B.3", pci_whitelist, "0a:0b.1"};
266 	const char *wlval3[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
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, "-n", "1", "-c", "1", "-b", "error"},
315 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0"},
316 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:error:0.1"},
317 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1error"},
318 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error0:0:0.1"},
319 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1.2"},
320 	};
321 	/* Test with valid blacklist option */
322 	const char *blval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "FF:09:0B.3"};
323 
324 	int i;
325 
326 	for (i = 0; i != sizeof (blinval) / sizeof (blinval[0]); i++) {
327 		if (launch_proc(blinval[i]) == 0) {
328 			printf("Error - process did run ok with invalid "
329 			    "blacklist parameter\n");
330 			return -1;
331 		}
332 	}
333 	if (launch_proc(blval) != 0) {
334 		printf("Error - process did not run ok with valid blacklist value\n");
335 		return -1;
336 	}
337 	return 0;
338 }
339 
340 /*
341  *  Test that the app doesn't run with invalid vdev option.
342  *  Final test ensures it does run with valid options as sanity check
343  */
344 #ifdef RTE_LIBRTE_PMD_RING
345 static int
346 test_invalid_vdev_flag(void)
347 {
348 #ifdef RTE_EXEC_ENV_FREEBSD
349 	/* BSD target doesn't support prefixes at this point, and we also need to
350 	 * run another primary process here */
351 	const char * prefix = no_shconf;
352 #else
353 	const char * prefix = "--file-prefix=vdev";
354 #endif
355 
356 	/* Test with invalid vdev option */
357 	const char *vdevinval[] = {prgname, prefix, no_huge, "-n", "1",
358 				"-c", "1", vdev, "eth_dummy"};
359 
360 	/* Test with valid vdev option */
361 	const char *vdevval1[] = {prgname, prefix, no_huge, "-n", "1",
362 	"-c", "1", vdev, "net_ring0"};
363 
364 	const char *vdevval2[] = {prgname, prefix, no_huge, "-n", "1",
365 	"-c", "1", vdev, "net_ring0,args=test"};
366 
367 	const char *vdevval3[] = {prgname, prefix, no_huge, "-n", "1",
368 	"-c", "1", vdev, "net_ring0,nodeaction=r1:0:CREATE"};
369 
370 	if (launch_proc(vdevinval) == 0) {
371 		printf("Error - process did run ok with invalid "
372 			"vdev parameter\n");
373 		return -1;
374 	}
375 
376 	if (launch_proc(vdevval1) != 0) {
377 		printf("Error - process did not run ok with valid vdev value\n");
378 		return -1;
379 	}
380 
381 	if (launch_proc(vdevval2) != 0) {
382 		printf("Error - process did not run ok with valid vdev value,"
383 			"with dummy args\n");
384 		return -1;
385 	}
386 
387 	if (launch_proc(vdevval3) != 0) {
388 		printf("Error - process did not run ok with valid vdev value,"
389 			"with valid args\n");
390 		return -1;
391 	}
392 	return 0;
393 }
394 #endif
395 
396 /*
397  * Test that the app doesn't run with invalid -r option.
398  */
399 static int
400 test_invalid_r_flag(void)
401 {
402 #ifdef RTE_EXEC_ENV_FREEBSD
403 	/* BSD target doesn't support prefixes at this point */
404 	const char * prefix = "";
405 #else
406 	char prefix[PATH_MAX], tmp[PATH_MAX];
407 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
408 		printf("Error - unable to get current prefix!\n");
409 		return -1;
410 	}
411 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
412 #endif
413 
414 	const char *rinval[][9] = {
415 			{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "error"},
416 			{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "0"},
417 			{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "-1"},
418 			{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "17"},
419 	};
420 	/* Test with valid blacklist option */
421 	const char *rval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "16"};
422 
423 	int i;
424 
425 	for (i = 0; i != sizeof (rinval) / sizeof (rinval[0]); i++) {
426 		if (launch_proc(rinval[i]) == 0) {
427 			printf("Error - process did run ok with invalid "
428 			    "-r (rank) parameter\n");
429 			return -1;
430 		}
431 	}
432 	if (launch_proc(rval) != 0) {
433 		printf("Error - process did not run ok with valid -r (rank) value\n");
434 		return -1;
435 	}
436 	return 0;
437 }
438 
439 /*
440  * Test that the app doesn't run without the coremask/corelist flags. In all cases
441  * should give an error and fail to run
442  */
443 static int
444 test_missing_c_flag(void)
445 {
446 #ifdef RTE_EXEC_ENV_FREEBSD
447 	/* BSD target doesn't support prefixes at this point */
448 	const char * prefix = "";
449 #else
450 	char prefix[PATH_MAX], tmp[PATH_MAX];
451 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
452 		printf("Error - unable to get current prefix!\n");
453 		return -1;
454 	}
455 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
456 #endif
457 
458 	/* -c flag but no coremask value */
459 	const char *argv1[] = { prgname, prefix, mp_flag, "-n", "3", "-c"};
460 	/* No -c, -l or --lcores flag at all */
461 	const char *argv2[] = { prgname, prefix, mp_flag, "-n", "3"};
462 	/* bad coremask value */
463 	const char *argv3[] = { prgname, prefix, mp_flag,
464 				"-n", "3", "-c", "error" };
465 	/* sanity check of tests - valid coremask value */
466 	const char *argv4[] = { prgname, prefix, mp_flag,
467 				"-n", "3", "-c", "1" };
468 	/* -l flag but no corelist value */
469 	const char *argv5[] = { prgname, prefix, mp_flag,
470 				"-n", "3", "-l"};
471 	const char *argv6[] = { prgname, prefix, mp_flag,
472 				"-n", "3", "-l", " " };
473 	/* bad corelist values */
474 	const char *argv7[] = { prgname, prefix, mp_flag,
475 				"-n", "3", "-l", "error" };
476 	const char *argv8[] = { prgname, prefix, mp_flag,
477 				"-n", "3", "-l", "1-" };
478 	const char *argv9[] = { prgname, prefix, mp_flag,
479 				"-n", "3", "-l", "1," };
480 	const char *argv10[] = { prgname, prefix, mp_flag,
481 				 "-n", "3", "-l", "1#2" };
482 	/* core number is negative value */
483 	const char * const argv11[] = { prgname, prefix, mp_flag,
484 				"-n", "3", "-l", "-5" };
485 	const char * const argv12[] = { prgname, prefix, mp_flag,
486 				"-n", "3", "-l", "-5-7" };
487 	/* core number is maximum value */
488 	const char * const argv13[] = { prgname, prefix, mp_flag,
489 				"-n", "3", "-l", RTE_STR(RTE_MAX_LCORE) };
490 	const char * const argv14[] = { prgname, prefix, mp_flag,
491 				"-n", "3", "-l", "1-"RTE_STR(RTE_MAX_LCORE) };
492 	/* sanity check test - valid corelist value */
493 	const char * const argv15[] = { prgname, prefix, mp_flag,
494 				 "-n", "3", "-l", "1-2,3" };
495 
496 	/* --lcores flag but no lcores value */
497 	const char * const argv16[] = { prgname, prefix, mp_flag,
498 				 "-n", "3", "--lcores" };
499 	const char * const argv17[] = { prgname, prefix, mp_flag,
500 				 "-n", "3", "--lcores", " " };
501 	/* bad lcores value */
502 	const char * const argv18[] = { prgname, prefix, mp_flag,
503 				 "-n", "3", "--lcores", "1-3-5" };
504 	const char * const argv19[] = { prgname, prefix, mp_flag,
505 				 "-n", "3", "--lcores", "0-1,,2" };
506 	const char * const argv20[] = { prgname, prefix, mp_flag,
507 				 "-n", "3", "--lcores", "0-,1" };
508 	const char * const argv21[] = { prgname, prefix, mp_flag,
509 				 "-n", "3", "--lcores", "(0-,2-4)" };
510 	const char * const argv22[] = { prgname, prefix, mp_flag,
511 				 "-n", "3", "--lcores", "(-1,2)" };
512 	const char * const argv23[] = { prgname, prefix, mp_flag,
513 				 "-n", "3", "--lcores", "(2-4)@(2-4-6)" };
514 	const char * const argv24[] = { prgname, prefix, mp_flag,
515 				 "-n", "3", "--lcores", "(a,2)" };
516 	const char * const argv25[] = { prgname, prefix, mp_flag,
517 				 "-n", "3", "--lcores", "1-3@(1,3)" };
518 	const char * const argv26[] = { prgname, prefix, mp_flag,
519 				 "-n", "3", "--lcores", "3@((1,3)" };
520 	const char * const argv27[] = { prgname, prefix, mp_flag,
521 				 "-n", "3", "--lcores", "(4-7)=(1,3)" };
522 	const char * const argv28[] = { prgname, prefix, mp_flag,
523 				 "-n", "3", "--lcores", "[4-7]@(1,3)" };
524 	/* sanity check of tests - valid lcores value */
525 	const char * const argv29[] = { prgname, prefix, mp_flag,
526 				 "-n", "3", "--lcores",
527 				 "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"};
528 
529 	if (launch_proc(argv2) != 0) {
530 		printf("Error - "
531 		       "process did not run ok when missing -c flag\n");
532 		return -1;
533 	}
534 
535 	if (launch_proc(argv1) == 0
536 			|| launch_proc(argv3) == 0) {
537 		printf("Error - "
538 		       "process ran without error with invalid -c flag\n");
539 		return -1;
540 	}
541 	if (launch_proc(argv4) != 0) {
542 		printf("Error - "
543 		       "process did not run ok with valid coremask value\n");
544 		return -1;
545 	}
546 
547 	/* start -l test */
548 	if (launch_proc(argv5) == 0
549 			|| launch_proc(argv6) == 0
550 			|| launch_proc(argv7) == 0
551 			|| launch_proc(argv8) == 0
552 			|| launch_proc(argv9) == 0
553 			|| launch_proc(argv10) == 0
554 			|| launch_proc(argv11) == 0
555 			|| launch_proc(argv12) == 0
556 			|| launch_proc(argv13) == 0
557 			|| launch_proc(argv14) == 0) {
558 		printf("Error - "
559 		       "process ran without error with invalid -l flag\n");
560 		return -1;
561 	}
562 	if (launch_proc(argv15) != 0) {
563 		printf("Error - "
564 		       "process did not run ok with valid corelist value\n");
565 		return -1;
566 	}
567 
568 	/* start --lcores tests */
569 	if (launch_proc(argv16) == 0 || launch_proc(argv17) == 0 ||
570 	    launch_proc(argv18) == 0 || launch_proc(argv19) == 0 ||
571 	    launch_proc(argv20) == 0 || launch_proc(argv21) == 0 ||
572 	    launch_proc(argv22) == 0 || launch_proc(argv23) == 0 ||
573 	    launch_proc(argv24) == 0 || launch_proc(argv25) == 0 ||
574 	    launch_proc(argv26) == 0 || launch_proc(argv27) == 0 ||
575 	    launch_proc(argv28) == 0) {
576 		printf("Error - "
577 		       "process ran without error with invalid --lcore flag\n");
578 		return -1;
579 	}
580 
581 	if (launch_proc(argv29) != 0) {
582 		printf("Error - "
583 		       "process did not run ok with valid corelist value\n");
584 		return -1;
585 	}
586 
587 	return 0;
588 }
589 
590 /*
591  * Test --master-lcore option with matching coremask
592  */
593 static int
594 test_master_lcore_flag(void)
595 {
596 #ifdef RTE_EXEC_ENV_FREEBSD
597 	/* BSD target doesn't support prefixes at this point */
598 	const char *prefix = "";
599 #else
600 	char prefix[PATH_MAX], tmp[PATH_MAX];
601 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
602 		printf("Error - unable to get current prefix!\n");
603 		return -1;
604 	}
605 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
606 #endif
607 
608 	/* --master-lcore flag but no value */
609 	const char *argv1[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore"};
610 	/* --master-lcore flag with invalid value */
611 	const char *argv2[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "-1"};
612 	const char *argv3[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "X"};
613 	/* master lcore not in coremask */
614 	const char *argv4[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "2"};
615 	/* valid value */
616 	const char *argv5[] = { prgname, prefix, mp_flag, "-n", "1", "-c", "3", "--master-lcore", "1"};
617 	/* valid value set before coremask */
618 	const char *argv6[] = { prgname, prefix, mp_flag, "-n", "1", "--master-lcore", "1", "-c", "3"};
619 
620 	if (launch_proc(argv1) == 0
621 			|| launch_proc(argv2) == 0
622 			|| launch_proc(argv3) == 0
623 			|| launch_proc(argv4) == 0) {
624 		printf("Error - process ran without error with wrong --master-lcore\n");
625 		return -1;
626 	}
627 	if (launch_proc(argv5) != 0
628 			|| launch_proc(argv6) != 0) {
629 		printf("Error - process did not run ok with valid --master-lcore\n");
630 		return -1;
631 	}
632 	return 0;
633 }
634 
635 /*
636  * Test that the app doesn't run with invalid -n flag option.
637  * Final test ensures it does run with valid options as sanity check
638  * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf
639  * flags.
640  */
641 static int
642 test_invalid_n_flag(void)
643 {
644 #ifdef RTE_EXEC_ENV_FREEBSD
645 	/* BSD target doesn't support prefixes at this point */
646 	const char * prefix = "";
647 #else
648 	char prefix[PATH_MAX], tmp[PATH_MAX];
649 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
650 		printf("Error - unable to get current prefix!\n");
651 		return -1;
652 	}
653 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
654 #endif
655 
656 	/* -n flag but no value */
657 	const char *argv1[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n"};
658 	/* bad numeric value */
659 	const char *argv2[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "e" };
660 	/* zero is invalid */
661 	const char *argv3[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "0" };
662 	/* sanity test - check with good value */
663 	const char *argv4[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "2" };
664 	/* sanity test - check with no -n flag */
665 	const char *argv5[] = { prgname, prefix, no_huge, no_shconf, "-c", "1"};
666 
667 	if (launch_proc(argv1) == 0
668 			|| launch_proc(argv2) == 0
669 			|| launch_proc(argv3) == 0) {
670 		printf("Error - process ran without error when"
671 		       "invalid -n flag\n");
672 		return -1;
673 	}
674 	if (launch_proc(argv4) != 0) {
675 		printf("Error - process did not run ok with valid num-channel value\n");
676 		return -1;
677 	}
678 	if (launch_proc(argv5) != 0) {
679 		printf("Error - process did not run ok without -n flag\n");
680 		return -1;
681 	}
682 
683 	return 0;
684 }
685 
686 /*
687  * Test that the app runs with HPET, and without HPET
688  */
689 static int
690 test_no_hpet_flag(void)
691 {
692 	char prefix[PATH_MAX] = "";
693 
694 #ifdef RTE_EXEC_ENV_FREEBSD
695 	return 0;
696 #else
697 	char tmp[PATH_MAX];
698 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
699 		printf("Error - unable to get current prefix!\n");
700 		return -1;
701 	}
702 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
703 #endif
704 
705 	/* With --no-hpet */
706 	const char *argv1[] = {prgname, prefix, mp_flag, no_hpet, "-c", "1", "-n", "2"};
707 	/* Without --no-hpet */
708 	const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-n", "2"};
709 
710 	if (launch_proc(argv1) != 0) {
711 		printf("Error - process did not run ok with --no-hpet flag\n");
712 		return -1;
713 	}
714 	if (launch_proc(argv2) != 0) {
715 		printf("Error - process did not run ok without --no-hpet flag\n");
716 		return -1;
717 	}
718 	return 0;
719 }
720 
721 /*
722  * Test that the app runs with --no-huge and doesn't run when --socket-mem are
723  * specified with --no-huge.
724  */
725 static int
726 test_no_huge_flag(void)
727 {
728 #ifdef RTE_EXEC_ENV_FREEBSD
729 	/* BSD target doesn't support prefixes at this point, and we also need to
730 	 * run another primary process here */
731 	const char * prefix = no_shconf;
732 #else
733 	const char * prefix = "--file-prefix=nohuge";
734 #endif
735 
736 	/* With --no-huge */
737 	const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2"};
738 	/* With --no-huge and -m */
739 	const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
740 			"-m", DEFAULT_MEM_SIZE};
741 
742 	/* With --no-huge and --socket-mem */
743 	const char *argv3[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
744 			"--socket-mem=" DEFAULT_MEM_SIZE};
745 	/* With --no-huge, -m and --socket-mem */
746 	const char *argv4[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
747 			"-m", DEFAULT_MEM_SIZE, "--socket-mem=" DEFAULT_MEM_SIZE};
748 	if (launch_proc(argv1) != 0) {
749 		printf("Error - process did not run ok with --no-huge flag\n");
750 		return -1;
751 	}
752 	if (launch_proc(argv2) != 0) {
753 		printf("Error - process did not run ok with --no-huge and -m flags\n");
754 		return -1;
755 	}
756 #ifdef RTE_EXEC_ENV_FREEBSD
757 	/* BSD target does not support NUMA, hence no --socket-mem tests */
758 	return 0;
759 #endif
760 
761 	if (launch_proc(argv3) == 0) {
762 		printf("Error - process run ok with --no-huge and --socket-mem "
763 				"flags\n");
764 		return -1;
765 	}
766 	if (launch_proc(argv4) == 0) {
767 		printf("Error - process run ok with --no-huge, -m and "
768 				"--socket-mem flags\n");
769 		return -1;
770 	}
771 	return 0;
772 }
773 
774 static int
775 test_misc_flags(void)
776 {
777 	char hugepath[PATH_MAX] = {0};
778 #ifdef RTE_EXEC_ENV_FREEBSD
779 	/* BSD target doesn't support prefixes at this point */
780 	const char * prefix = "";
781 	const char * nosh_prefix = "";
782 #else
783 	char prefix[PATH_MAX], tmp[PATH_MAX];
784 	const char * nosh_prefix = "--file-prefix=noshconf";
785 	FILE * hugedir_handle = NULL;
786 	char line[PATH_MAX] = {0};
787 	unsigned i, isempty = 1;
788 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
789 		printf("Error - unable to get current prefix!\n");
790 		return -1;
791 	}
792 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
793 
794 	/*
795 	 * get first valid hugepage path
796 	 */
797 
798 	/* get hugetlbfs mountpoints from /proc/mounts */
799 	hugedir_handle = fopen("/proc/mounts", "r");
800 
801 	if (hugedir_handle == NULL) {
802 		printf("Error opening /proc/mounts!\n");
803 		return -1;
804 	}
805 
806 	/* read /proc/mounts */
807 	while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
808 
809 		/* find first valid hugepath */
810 		if (get_hugepage_path(line, sizeof(line), hugepath, sizeof(hugepath)))
811 			break;
812 	}
813 
814 	fclose(hugedir_handle);
815 
816 	/* check if path is not empty */
817 	for (i = 0; i < sizeof(hugepath); i++)
818 		if (hugepath[i] != '\0')
819 			isempty = 0;
820 
821 	if (isempty) {
822 		printf("No mounted hugepage dir found!\n");
823 		return -1;
824 	}
825 #endif
826 
827 
828 	/* check that some general flags don't prevent things from working.
829 	 * All cases, apart from the first, app should run.
830 	 * No further testing of output done.
831 	 */
832 	/* sanity check - failure with invalid option */
833 	const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"};
834 
835 	/* With --no-pci */
836 	const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"};
837 	/* With -v */
838 	const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"};
839 	/* With valid --syslog */
840 	const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1",
841 			"--syslog", "syslog"};
842 	/* With empty --syslog (should fail) */
843 	const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"};
844 	/* With invalid --syslog */
845 	const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
846 	/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */
847 	const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE,
848 			no_shconf, nosh_prefix, no_huge};
849 
850 	/* With --huge-dir */
851 	const char *argv7[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE,
852 			"--file-prefix=hugedir", "--huge-dir", hugepath};
853 	/* With empty --huge-dir (should fail) */
854 	const char *argv8[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE,
855 			"--file-prefix=hugedir", "--huge-dir"};
856 	/* With invalid --huge-dir */
857 	const char *argv9[] = {prgname, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE,
858 			"--file-prefix=hugedir", "--huge-dir", "invalid"};
859 	/* Secondary process with invalid --huge-dir (should run as flag has no
860 	 * effect on secondary processes) */
861 	const char *argv10[] = {prgname, prefix, mp_flag, "-c", "1", "--huge-dir", "invalid"};
862 
863 	/* try running with base-virtaddr param */
864 	const char *argv11[] = {prgname, "--file-prefix=virtaddr",
865 			"-c", "1", "-n", "2", "--base-virtaddr=0x12345678"};
866 
867 	/* try running with --vfio-intr INTx flag */
868 	const char *argv12[] = {prgname, "--file-prefix=intr",
869 			"-c", "1", "-n", "2", "--vfio-intr=legacy"};
870 
871 	/* try running with --vfio-intr MSI flag */
872 	const char *argv13[] = {prgname, "--file-prefix=intr",
873 			"-c", "1", "-n", "2", "--vfio-intr=msi"};
874 
875 	/* try running with --vfio-intr MSI-X flag */
876 	const char *argv14[] = {prgname, "--file-prefix=intr",
877 			"-c", "1", "-n", "2", "--vfio-intr=msix"};
878 
879 	/* try running with --vfio-intr invalid flag */
880 	const char *argv15[] = {prgname, "--file-prefix=intr",
881 			"-c", "1", "-n", "2", "--vfio-intr=invalid"};
882 
883 	/* run all tests also applicable to FreeBSD first */
884 
885 	if (launch_proc(argv0) == 0) {
886 		printf("Error - process ran ok with invalid flag\n");
887 		return -1;
888 	}
889 	if (launch_proc(argv1) != 0) {
890 		printf("Error - process did not run ok with --no-pci flag\n");
891 		return -1;
892 	}
893 	if (launch_proc(argv2) != 0) {
894 		printf("Error - process did not run ok with -v flag\n");
895 		return -1;
896 	}
897 	if (launch_proc(argv6) != 0) {
898 		printf("Error - process did not run ok with --no-shconf flag\n");
899 		return -1;
900 	}
901 
902 #ifdef RTE_EXEC_ENV_FREEBSD
903 	/* no more tests to be done on FreeBSD */
904 	return 0;
905 #endif
906 
907 	if (launch_proc(argv3) != 0) {
908 		printf("Error - process did not run ok with --syslog flag\n");
909 		return -1;
910 	}
911 	if (launch_proc(argv4) == 0) {
912 		printf("Error - process run ok with empty --syslog flag\n");
913 		return -1;
914 	}
915 	if (launch_proc(argv5) == 0) {
916 		printf("Error - process run ok with invalid --syslog flag\n");
917 		return -1;
918 	}
919 	if (launch_proc(argv7) != 0) {
920 		printf("Error - process did not run ok with --huge-dir flag\n");
921 		return -1;
922 	}
923 	if (launch_proc(argv8) == 0) {
924 		printf("Error - process run ok with empty --huge-dir flag\n");
925 		return -1;
926 	}
927 	if (launch_proc(argv9) == 0) {
928 		printf("Error - process run ok with invalid --huge-dir flag\n");
929 		return -1;
930 	}
931 	if (launch_proc(argv10) != 0) {
932 		printf("Error - secondary process did not run ok with invalid --huge-dir flag\n");
933 		return -1;
934 	}
935 	if (launch_proc(argv11) != 0) {
936 		printf("Error - process did not run ok with --base-virtaddr parameter\n");
937 		return -1;
938 	}
939 	if (launch_proc(argv12) != 0) {
940 		printf("Error - process did not run ok with "
941 				"--vfio-intr INTx parameter\n");
942 		return -1;
943 	}
944 	if (launch_proc(argv13) != 0) {
945 		printf("Error - process did not run ok with "
946 				"--vfio-intr MSI parameter\n");
947 		return -1;
948 	}
949 	if (launch_proc(argv14) != 0) {
950 		printf("Error - process did not run ok with "
951 				"--vfio-intr MSI-X parameter\n");
952 		return -1;
953 	}
954 	if (launch_proc(argv15) == 0) {
955 		printf("Error - process run ok with "
956 				"--vfio-intr invalid parameter\n");
957 		return -1;
958 	}
959 	return 0;
960 }
961 
962 static int
963 test_file_prefix(void)
964 {
965 	/*
966 	 * 1. check if current process hugefiles are locked
967 	 * 2. try to run secondary process without a corresponding primary process
968 	 * (while failing to run, it will also remove any unused hugepage files)
969 	 * 3. check if current process hugefiles are still in place and are locked
970 	 * 4. run a primary process with memtest1 prefix in default and legacy
971 	 *    mem mode
972 	 * 5. check if memtest1 hugefiles are created in case of legacy mem
973 	 *    mode, and deleted in case of default mem mode
974 	 * 6. run a primary process with memtest2 prefix in default and legacy
975 	 *    mem modes
976 	 * 7. check that memtest2 hugefiles are present in the hugedir after a
977 	 *    run in legacy mode, and not present at all after run in default
978 	 *    mem mode
979 	 */
980 	char prefix[PATH_MAX] = "";
981 
982 #ifdef RTE_EXEC_ENV_FREEBSD
983 	return 0;
984 #else
985 	if (get_current_prefix(prefix, sizeof(prefix)) == NULL) {
986 		printf("Error - unable to get current prefix!\n");
987 		return -1;
988 	}
989 #endif
990 
991 	/* this should fail unless the test itself is run with "memtest" prefix */
992 	const char *argv0[] = {prgname, mp_flag, "-c", "1", "-n", "2", "-m", DEFAULT_MEM_SIZE,
993 			"--file-prefix=" memtest };
994 
995 	/* primary process with memtest1 and default mem mode */
996 	const char *argv1[] = {prgname, "-c", "1", "-n", "2", "-m",
997 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest1 };
998 
999 	/* primary process with memtest1 and legacy mem mode */
1000 	const char *argv2[] = {prgname, "-c", "1", "-n", "2", "-m",
1001 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest1,
1002 			"--legacy-mem" };
1003 
1004 	/* primary process with memtest2 and legacy mem mode */
1005 	const char *argv3[] = {prgname, "-c", "1", "-n", "2", "-m",
1006 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest2,
1007 			"--legacy-mem" };
1008 
1009 	/* primary process with memtest2 and default mem mode */
1010 	const char *argv4[] = {prgname, "-c", "1", "-n", "2", "-m",
1011 			DEFAULT_MEM_SIZE, "--file-prefix=" memtest2 };
1012 
1013 	/* check if files for current prefix are present */
1014 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
1015 		printf("Error - hugepage files for %s were not created!\n", prefix);
1016 		return -1;
1017 	}
1018 
1019 	/* checks if files for current prefix are locked */
1020 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
1021 		printf("Error - hugepages for current process aren't locked!\n");
1022 		return -1;
1023 	}
1024 
1025 	/* check if files for secondary process are present */
1026 	if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) {
1027 		/* check if they are not locked */
1028 		if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) {
1029 			printf("Error - hugepages for current process are locked!\n");
1030 			return -1;
1031 		}
1032 		/* they aren't locked, delete them */
1033 		else {
1034 			if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) {
1035 				printf("Error - deleting hugepages failed!\n");
1036 				return -1;
1037 			}
1038 		}
1039 	}
1040 
1041 	if (launch_proc(argv0) == 0) {
1042 		printf("Error - secondary process ran ok without primary process\n");
1043 		return -1;
1044 	}
1045 
1046 	/* check if files for current prefix are present */
1047 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
1048 		printf("Error - hugepage files for %s were not created!\n", prefix);
1049 		return -1;
1050 	}
1051 
1052 	/* checks if files for current prefix are locked */
1053 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
1054 		printf("Error - hugepages for current process aren't locked!\n");
1055 		return -1;
1056 	}
1057 
1058 	/* we're running this process in default memory mode, which means it
1059 	 * should clean up after itself on exit and leave no hugepages behind.
1060 	 */
1061 	if (launch_proc(argv1) != 0) {
1062 		printf("Error - failed to run with --file-prefix=%s\n",
1063 				memtest1);
1064 		return -1;
1065 	}
1066 
1067 	/* check if memtest1_map0 is present */
1068 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1069 		printf("Error - hugepage files for %s were not deleted!\n",
1070 				memtest1);
1071 		return -1;
1072 	}
1073 
1074 	/* now, we're running a process under the same prefix, but with legacy
1075 	 * mem mode - this should leave behind hugepage files.
1076 	 */
1077 	if (launch_proc(argv2) != 0) {
1078 		printf("Error - failed to run with --file-prefix=%s\n",
1079 				memtest1);
1080 		return -1;
1081 	}
1082 
1083 	/* check if memtest1_map0 is present */
1084 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) {
1085 		printf("Error - hugepage files for %s were not created!\n",
1086 				memtest1);
1087 		return -1;
1088 	}
1089 
1090 	if (launch_proc(argv3) != 0) {
1091 		printf("Error - failed to run with --file-prefix=%s\n",
1092 				memtest2);
1093 		return -1;
1094 	}
1095 
1096 	/* check if hugefiles for memtest2 are present */
1097 	if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) {
1098 		printf("Error - hugepage files for %s were not created!\n",
1099 				memtest2);
1100 		return -1;
1101 	}
1102 
1103 	/* check if hugefiles for memtest1 are present */
1104 	if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
1105 		printf("Error - hugepage files for %s were not deleted!\n",
1106 				memtest1);
1107 		return -1;
1108 	}
1109 
1110 	/* this process will run in default mem mode, so it should not leave any
1111 	 * hugepage files behind.
1112 	 */
1113 	if (launch_proc(argv4) != 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) != 0) {
1121 		printf("Error - hugepage files for %s were not deleted!\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 	return 0;
1134 }
1135 
1136 /*
1137  * Tests for correct handling of -m and --socket-mem flags
1138  */
1139 static int
1140 test_memory_flags(void)
1141 {
1142 #ifdef RTE_EXEC_ENV_FREEBSD
1143 	/* BSD target doesn't support prefixes at this point */
1144 	const char * prefix = "";
1145 #else
1146 	char prefix[PATH_MAX], tmp[PATH_MAX];
1147 	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
1148 		printf("Error - unable to get current prefix!\n");
1149 		return -1;
1150 	}
1151 	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
1152 #endif
1153 
1154 	/* valid -m flag and mp flag */
1155 	const char *argv0[] = {prgname, prefix, mp_flag, "-c", "10",
1156 			"-n", "2", "-m", DEFAULT_MEM_SIZE};
1157 
1158 	/* valid -m flag */
1159 	const char *argv1[] = {prgname, "-c", "10", "-n", "2",
1160 			"--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE};
1161 
1162 	/* valid (zero) --socket-mem flag */
1163 	const char *argv2[] = {prgname, "-c", "10", "-n", "2",
1164 			"--file-prefix=" memtest, "--socket-mem=0,0,0,0"};
1165 
1166 	/* invalid (incomplete) --socket-mem flag */
1167 	const char *argv3[] = {prgname, "-c", "10", "-n", "2",
1168 			"--file-prefix=" memtest, "--socket-mem=2,2,"};
1169 
1170 	/* invalid (mixed with invalid data) --socket-mem flag */
1171 	const char *argv4[] = {prgname, "-c", "10", "-n", "2",
1172 			"--file-prefix=" memtest, "--socket-mem=2,2,Fred"};
1173 
1174 	/* invalid (with numeric value as last character) --socket-mem flag */
1175 	const char *argv5[] = {prgname, "-c", "10", "-n", "2",
1176 			"--file-prefix=" memtest, "--socket-mem=2,2,Fred0"};
1177 
1178 	/* invalid (with empty socket) --socket-mem flag */
1179 	const char *argv6[] = {prgname, "-c", "10", "-n", "2",
1180 			"--file-prefix=" memtest, "--socket-mem=2,,2"};
1181 
1182 	/* invalid (null) --socket-mem flag */
1183 	const char *argv7[] = {prgname, "-c", "10", "-n", "2",
1184 			"--file-prefix=" memtest, "--socket-mem="};
1185 
1186 	/* valid --socket-mem specified together with -m flag */
1187 	const char *argv8[] = {prgname, "-c", "10", "-n", "2",
1188 			"--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE, "--socket-mem=2,2"};
1189 
1190 	/* construct an invalid socket mask with 2 megs on each socket plus
1191 	 * extra 2 megs on socket that doesn't exist on current system */
1192 	char invalid_socket_mem[SOCKET_MEM_STRLEN];
1193 	char buf[SOCKET_MEM_STRLEN];	/* to avoid copying string onto itself */
1194 
1195 #ifdef RTE_EXEC_ENV_FREEBSD
1196 	int i, num_sockets = 1;
1197 #else
1198 	int i, num_sockets = RTE_MIN(get_number_of_sockets(),
1199 			RTE_MAX_NUMA_NODES);
1200 #endif
1201 
1202 	if (num_sockets <= 0) {
1203 		printf("Error - cannot get number of sockets!\n");
1204 		return -1;
1205 	}
1206 
1207 	snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "--socket-mem=");
1208 
1209 	/* add one extra socket */
1210 	for (i = 0; i < num_sockets + 1; i++) {
1211 		snprintf(buf, sizeof(buf), "%s%s", invalid_socket_mem, DEFAULT_MEM_SIZE);
1212 		strlcpy(invalid_socket_mem, buf, sizeof(invalid_socket_mem));
1213 
1214 		if (num_sockets + 1 - i > 1) {
1215 			snprintf(buf, sizeof(buf), "%s,", invalid_socket_mem);
1216 			strlcpy(invalid_socket_mem, buf,
1217 				sizeof(invalid_socket_mem));
1218 		}
1219 	}
1220 
1221 	/* construct a valid socket mask with 2 megs on each existing socket */
1222 	char valid_socket_mem[SOCKET_MEM_STRLEN];
1223 
1224 	snprintf(valid_socket_mem, sizeof(valid_socket_mem), "--socket-mem=");
1225 
1226 	/* add one extra socket */
1227 	for (i = 0; i < num_sockets; i++) {
1228 		snprintf(buf, sizeof(buf), "%s%s", valid_socket_mem, DEFAULT_MEM_SIZE);
1229 		strlcpy(valid_socket_mem, buf, sizeof(valid_socket_mem));
1230 
1231 		if (num_sockets - i > 1) {
1232 			snprintf(buf, sizeof(buf), "%s,", valid_socket_mem);
1233 			strlcpy(valid_socket_mem, buf,
1234 				sizeof(valid_socket_mem));
1235 		}
1236 	}
1237 
1238 	/* invalid --socket-mem flag (with extra socket) */
1239 	const char *argv9[] = {prgname, "-c", "10", "-n", "2",
1240 			"--file-prefix=" memtest, invalid_socket_mem};
1241 
1242 	/* valid --socket-mem flag */
1243 	const char *argv10[] = {prgname, "-c", "10", "-n", "2",
1244 			"--file-prefix=" memtest, valid_socket_mem};
1245 
1246 	if (launch_proc(argv0) != 0) {
1247 		printf("Error - secondary process failed with valid -m flag !\n");
1248 		return -1;
1249 	}
1250 
1251 #ifdef RTE_EXEC_ENV_FREEBSD
1252 	/* no other tests are applicable to BSD */
1253 	return 0;
1254 #endif
1255 
1256 	if (launch_proc(argv1) != 0) {
1257 		printf("Error - process failed with valid -m flag!\n");
1258 		return -1;
1259 	}
1260 	if (launch_proc(argv2) != 0) {
1261 		printf("Error - process failed with valid (zero) --socket-mem!\n");
1262 		return -1;
1263 	}
1264 
1265 	if (launch_proc(argv3) == 0) {
1266 		printf("Error - process run ok with invalid "
1267 				"(incomplete) --socket-mem!\n");
1268 		return -1;
1269 	}
1270 
1271 	if (launch_proc(argv4) == 0) {
1272 		printf("Error - process run ok with invalid "
1273 				"(mixed with invalid input) --socket-mem!\n");
1274 		return -1;
1275 	}
1276 
1277 	if (launch_proc(argv5) == 0) {
1278 		printf("Error - process run ok with invalid "
1279 				"(mixed with invalid input with a numeric value as "
1280 				"last character) --socket-mem!\n");
1281 		return -1;
1282 	}
1283 
1284 	if (launch_proc(argv6) == 0) {
1285 		printf("Error - process run ok with invalid "
1286 				"(with empty socket) --socket-mem!\n");
1287 		return -1;
1288 	}
1289 
1290 	if (launch_proc(argv7) == 0) {
1291 		printf("Error - process run ok with invalid (null) --socket-mem!\n");
1292 		return -1;
1293 	}
1294 
1295 	if (launch_proc(argv8) == 0) {
1296 		printf("Error - process run ok with --socket-mem and -m specified!\n");
1297 		return -1;
1298 	}
1299 
1300 	if (launch_proc(argv9) == 0) {
1301 		printf("Error - process run ok with extra socket in --socket-mem!\n");
1302 		return -1;
1303 	}
1304 
1305 	if (launch_proc(argv10) != 0) {
1306 		printf("Error - process failed with valid --socket-mem!\n");
1307 		return -1;
1308 	}
1309 
1310 	return 0;
1311 }
1312 
1313 static int
1314 test_eal_flags(void)
1315 {
1316 	int ret = 0;
1317 
1318 	ret = test_missing_c_flag();
1319 	if (ret < 0) {
1320 		printf("Error in test_missing_c_flag()\n");
1321 		return ret;
1322 	}
1323 
1324 	ret = test_master_lcore_flag();
1325 	if (ret < 0) {
1326 		printf("Error in test_master_lcore_flag()\n");
1327 		return ret;
1328 	}
1329 
1330 	ret = test_invalid_n_flag();
1331 	if (ret < 0) {
1332 		printf("Error in test_invalid_n_flag()\n");
1333 		return ret;
1334 	}
1335 
1336 	ret = test_no_hpet_flag();
1337 	if (ret < 0) {
1338 		printf("Error in test_no_hpet_flag()\n");
1339 		return ret;
1340 	}
1341 
1342 	ret = test_no_huge_flag();
1343 	if (ret < 0) {
1344 		printf("Error in test_no_huge_flag()\n");
1345 		return ret;
1346 	}
1347 
1348 	ret = test_whitelist_flag();
1349 	if (ret < 0) {
1350 		printf("Error in test_invalid_whitelist_flag()\n");
1351 		return ret;
1352 	}
1353 
1354 	ret = test_invalid_b_flag();
1355 	if (ret < 0) {
1356 		printf("Error in test_invalid_b_flag()\n");
1357 		return ret;
1358 	}
1359 
1360 #ifdef RTE_LIBRTE_PMD_RING
1361 	ret = test_invalid_vdev_flag();
1362 	if (ret < 0) {
1363 		printf("Error in test_invalid_vdev_flag()\n");
1364 		return ret;
1365 	}
1366 #endif
1367 	ret = test_invalid_r_flag();
1368 	if (ret < 0) {
1369 		printf("Error in test_invalid_r_flag()\n");
1370 		return ret;
1371 	}
1372 
1373 	ret = test_memory_flags();
1374 	if (ret < 0) {
1375 		printf("Error in test_memory_flags()\n");
1376 		return ret;
1377 	}
1378 
1379 	ret = test_file_prefix();
1380 	if (ret < 0) {
1381 		printf("Error in test_file_prefix()\n");
1382 		return ret;
1383 	}
1384 
1385 	ret = test_misc_flags();
1386 	if (ret < 0) {
1387 		printf("Error in test_misc_flags()");
1388 		return ret;
1389 	}
1390 
1391 	return ret;
1392 }
1393 
1394 REGISTER_TEST_COMMAND(eal_flags_autotest, test_eal_flags);
1395