replace snprintf with strlcpy without adding extra include
[dpdk.git] / app / test / test_eal_flags.c
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                 strlcpy(dst, tokens[1], dst_len);
62                 return 1;
63         }
64         return 0;
65 }
66
67 /*
68  * Cycles through hugepage directories and looks for hugepage
69  * files associated with a given prefix. Depending on value of
70  * action, the hugepages are checked if they exist, checked if
71  * they can be locked, or are simply deleted.
72  *
73  * Returns 1 if it finds at least one hugepage matching the action
74  * Returns 0 if no matching hugepages were found
75  * Returns -1 if it encounters an error
76  */
77 static int
78 process_hugefiles(const char * prefix, enum hugepage_action action)
79 {
80         FILE * hugedir_handle = NULL;
81         DIR * hugepage_dir = NULL;
82         struct dirent *dirent = NULL;
83
84         char hugefile_prefix[PATH_MAX] = {0};
85         char hugedir[PATH_MAX] = {0};
86         char line[PATH_MAX] = {0};
87
88         int fd, lck_result, result = 0;
89
90         const int prefix_len = snprintf(hugefile_prefix,
91                         sizeof(hugefile_prefix), "%smap_", prefix);
92         if (prefix_len <= 0 || prefix_len >= (int)sizeof(hugefile_prefix)
93                         || prefix_len >= (int)sizeof(dirent->d_name)) {
94                 printf("Error creating hugefile filename prefix\n");
95                 return -1;
96         }
97
98         /* get hugetlbfs mountpoints from /proc/mounts */
99         hugedir_handle = fopen("/proc/mounts", "r");
100
101         if (hugedir_handle == NULL) {
102                 printf("Error parsing /proc/mounts!\n");
103                 return -1;
104         }
105
106         /* read and parse script output */
107         while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
108
109                 /* check if we have a hugepage filesystem path */
110                 if (!get_hugepage_path(line, sizeof(line), hugedir, sizeof(hugedir)))
111                         continue;
112
113                 /* check if directory exists */
114                 if ((hugepage_dir = opendir(hugedir)) == NULL) {
115                         fclose(hugedir_handle);
116                         printf("Error reading %s: %s\n", hugedir, strerror(errno));
117                         return -1;
118                 }
119
120                 while ((dirent = readdir(hugepage_dir)) != NULL) {
121                         if (memcmp(dirent->d_name, hugefile_prefix, prefix_len) != 0)
122                                 continue;
123
124                         switch (action) {
125                         case HUGEPAGE_CHECK_EXISTS:
126                                 {
127                                         /* file exists, return */
128                                         result = 1;
129                                         goto end;
130                                 }
131                                 break;
132                         case HUGEPAGE_DELETE:
133                                 {
134                                         char file_path[PATH_MAX] = {0};
135
136                                         snprintf(file_path, sizeof(file_path),
137                                                 "%s/%s", hugedir, dirent->d_name);
138
139                                         /* remove file */
140                                         if (remove(file_path) < 0) {
141                                                 printf("Error deleting %s - %s!\n",
142                                                                 dirent->d_name, strerror(errno));
143                                                 closedir(hugepage_dir);
144                                                 result = -1;
145                                                 goto end;
146                                         }
147                                         result = 1;
148                                 }
149                                 break;
150                         case HUGEPAGE_CHECK_LOCKED:
151                                 {
152                                         /* try and lock the file */
153                                         fd = openat(dirfd(hugepage_dir), dirent->d_name, O_RDONLY);
154
155                                         /* this shouldn't happen */
156                                         if (fd == -1) {
157                                                 printf("Error opening %s - %s!\n",
158                                                                 dirent->d_name, strerror(errno));
159                                                 closedir(hugepage_dir);
160                                                 result = -1;
161                                                 goto end;
162                                         }
163
164                                         /* non-blocking lock */
165                                         lck_result = flock(fd, LOCK_EX | LOCK_NB);
166
167                                         /* if lock succeeds, there's something wrong */
168                                         if (lck_result != -1) {
169                                                 result = 0;
170
171                                                 /* unlock the resulting lock */
172                                                 flock(fd, LOCK_UN);
173                                                 close(fd);
174                                                 closedir(hugepage_dir);
175                                                 goto end;
176                                         }
177                                         result = 1;
178                                         close(fd);
179                                 }
180                                 break;
181                                 /* shouldn't happen */
182                         default:
183                                 goto end;
184                         } /* switch */
185
186                 } /* read hugepage directory */
187                 closedir(hugepage_dir);
188         } /* read /proc/mounts */
189 end:
190         fclose(hugedir_handle);
191         return result;
192 }
193
194 #ifdef RTE_EXEC_ENV_LINUX
195 /*
196  * count the number of "node*" files in /sys/devices/system/node/
197  */
198 static int
199 get_number_of_sockets(void)
200 {
201         struct dirent *dirent = NULL;
202         const char * nodedir = "/sys/devices/system/node/";
203         DIR * dir = NULL;
204         int result = 0;
205
206         /* check if directory exists */
207         if ((dir = opendir(nodedir)) == NULL) {
208                 /* if errno==ENOENT this means we don't have NUMA support */
209                 if (errno == ENOENT) {
210                         printf("No NUMA nodes detected: assuming 1 available socket\n");
211                         return 1;
212                 }
213                 printf("Error opening %s: %s\n", nodedir, strerror(errno));
214                 return -1;
215         }
216
217         while ((dirent = readdir(dir)) != NULL)
218                 if (strncmp(dirent->d_name, "node", sizeof("node") - 1) == 0)
219                         result++;
220
221         closedir(dir);
222         return result;
223 }
224 #endif
225
226 /*
227  * Test that the app doesn't run with invalid whitelist option.
228  * Final tests ensures it does run with valid options as sanity check (one
229  * test for with Domain+BDF, second for just with BDF)
230  */
231 static int
232 test_whitelist_flag(void)
233 {
234         unsigned i;
235 #ifdef RTE_EXEC_ENV_FREEBSD
236         /* BSD target doesn't support prefixes at this point */
237         const char * prefix = "";
238 #else
239         char prefix[PATH_MAX], tmp[PATH_MAX];
240         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
241                 printf("Error - unable to get current prefix!\n");
242                 return -1;
243         }
244         snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
245 #endif
246
247         const char *wlinval[][11] = {
248                 {prgname, prefix, mp_flag, "-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);