add FreeBSD support
[dpdk.git] / app / test / test_eal_flags.c
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
5  *   All rights reserved.
6  * 
7  *   Redistribution and use in source and binary forms, with or without
8  *   modification, are permitted provided that the following conditions
9  *   are met:
10  * 
11  *     * Redistributions of source code must retain the above copyright
12  *       notice, this list of conditions and the following disclaimer.
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *     * Neither the name of Intel Corporation nor the names of its
18  *       contributors may be used to endorse or promote products derived
19  *       from this software without specific prior written permission.
20  * 
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 #include <stdio.h>
34
35 #include <cmdline_parse.h>
36
37 #include "test.h"
38
39 #ifndef RTE_EXEC_ENV_BAREMETAL
40 #include <string.h>
41 #include <stdarg.h>
42 #include <libgen.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <errno.h>
46 #include <unistd.h>
47 #include <dirent.h>
48 #include <sys/wait.h>
49 #include <sys/file.h>
50 #include <limits.h>
51
52 #include <rte_debug.h>
53 #include <rte_string_fns.h>
54
55 #include "process.h"
56
57 #define mp_flag "--proc-type=secondary"
58 #define no_hpet "--no-hpet"
59 #define no_huge "--no-huge"
60 #define no_shconf "--no-shconf"
61 #define use_device "--use-device"
62 #define memtest "memtest"
63 #define memtest1 "memtest1"
64 #define memtest2 "memtest2"
65 #define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 10)
66 #define launch_proc(ARGV) process_dup(ARGV, \
67                 sizeof(ARGV)/(sizeof(ARGV[0])), __func__)
68
69 enum hugepage_action {
70         HUGEPAGE_CHECK_EXISTS = 0,
71         HUGEPAGE_CHECK_LOCKED,
72         HUGEPAGE_DELETE,
73         HUGEPAGE_INVALID
74 };
75
76 /* if string contains a hugepage path */
77 static int
78 get_hugepage_path(char * src, int src_len, char * dst, int dst_len)
79 {
80 #define NUM_TOKENS 4
81         char *tokens[NUM_TOKENS];
82
83         /* if we couldn't properly split the string */
84         if (rte_strsplit(src, src_len, tokens, NUM_TOKENS, ' ') < NUM_TOKENS)
85                 return 0;
86
87         if (strncmp(tokens[2], "hugetlbfs", sizeof("hugetlbfs")) == 0) {
88                 rte_snprintf(dst, dst_len, "%s", tokens[1]);
89                 return 1;
90         }
91         return 0;
92 }
93
94 /*
95  * Cycles through hugepage directories and looks for hugepage
96  * files associated with a given prefix. Depending on value of
97  * action, the hugepages are checked if they exist, checked if
98  * they can be locked, or are simply deleted.
99  *
100  * Returns 1 if it finds at least one hugepage matching the action
101  * Returns 0 if no matching hugepages were found
102  * Returns -1 if it encounters an error
103  */
104 static int
105 process_hugefiles(const char * prefix, enum hugepage_action action)
106 {
107         FILE * hugedir_handle = NULL;
108         DIR * hugepage_dir = NULL;
109         struct dirent *dirent = NULL;
110
111         char hugefile_prefix[PATH_MAX] = {0};
112         char hugedir[PATH_MAX] = {0};
113         char line[PATH_MAX] = {0};
114
115         int fd, lck_result, result = 0;
116
117         const int prefix_len = rte_snprintf(hugefile_prefix,
118                         sizeof(hugefile_prefix), "%smap_", prefix);
119         if (prefix_len <= 0 || prefix_len >= (int)sizeof(hugefile_prefix)
120                         || prefix_len >= (int)sizeof(dirent->d_name)) {
121                 printf("Error creating hugefile filename prefix\n");
122                 return -1;
123         }
124
125         /* get hugetlbfs mountpoints from /proc/mounts */
126         hugedir_handle = fopen("/proc/mounts", "r");
127
128         if (hugedir_handle == NULL) {
129                 printf("Error parsing /proc/mounts!\n");
130                 return -1;
131         }
132
133         /* read and parse script output */
134         while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
135
136                 /* check if we have a hugepage filesystem path */
137                 if (!get_hugepage_path(line, sizeof(line), hugedir, sizeof(hugedir)))
138                         continue;
139
140                 /* check if directory exists */
141                 if ((hugepage_dir = opendir(hugedir)) == NULL) {
142                         fclose(hugedir_handle);
143                         printf("Error reading %s: %s\n", hugedir, strerror(errno));
144                         return -1;
145                 }
146
147                 while ((dirent = readdir(hugepage_dir)) != NULL) {
148                         if (memcmp(dirent->d_name, hugefile_prefix, prefix_len) != 0)
149                                 continue;
150
151                         switch (action) {
152                         case HUGEPAGE_CHECK_EXISTS:
153                                 {
154                                         /* file exists, return */
155                                         result = 1;
156                                         goto end;
157                                 }
158                                 break;
159                         case HUGEPAGE_DELETE:
160                                 {
161                                         char file_path[PATH_MAX] = {0};
162
163                                         rte_snprintf(file_path, sizeof(file_path),
164                                                 "%s/%s", hugedir, dirent->d_name);
165                                         
166                                         /* remove file */
167                                         if (remove(file_path) < 0) {
168                                                 printf("Error deleting %s - %s!\n",
169                                                                 dirent->d_name, strerror(errno));
170                                                 closedir(hugepage_dir);
171                                                 result = -1;
172                                                 goto end;
173                                         }
174                                         result = 1;
175                                 }
176                                 break;
177                         case HUGEPAGE_CHECK_LOCKED:
178                                 {
179                                         /* try and lock the file */
180                                         fd = openat(dirfd(hugepage_dir), dirent->d_name, O_RDONLY);
181
182                                         /* this shouldn't happen */
183                                         if (fd == -1) {
184                                                 printf("Error opening %s - %s!\n",
185                                                                 dirent->d_name, strerror(errno));
186                                                 closedir(hugepage_dir);
187                                                 result = -1;
188                                                 goto end;
189                                         }
190
191                                         /* non-blocking lock */
192                                         lck_result = flock(fd, LOCK_EX | LOCK_NB);
193
194                                         /* if lock succeeds, there's something wrong */
195                                         if (lck_result != -1) {
196                                                 result = 0;
197
198                                                 /* unlock the resulting lock */
199                                                 flock(fd, LOCK_UN);
200                                                 close(fd);
201                                                 closedir(hugepage_dir);
202                                                 goto end;
203                                         }
204                                         result = 1;
205                                         close(fd);
206                                 }
207                                 break;
208                                 /* shouldn't happen */
209                         default:
210                                 goto end;
211                         } /* switch */
212
213                 } /* read hugepage directory */
214                 closedir(hugepage_dir);
215         } /* read /proc/mounts */
216 end:
217         fclose(hugedir_handle);
218         return result;
219 }
220
221 #ifdef RTE_EXEC_ENV_LINUXAPP
222 /*
223  * count the number of "node*" files in /sys/devices/system/node/
224  */
225 static int
226 get_number_of_sockets(void)
227 {
228         struct dirent *dirent = NULL;
229         const char * nodedir = "/sys/devices/system/node/";
230         DIR * dir = NULL;
231         int result = 0;
232
233         /* check if directory exists */
234         if ((dir = opendir(nodedir)) == NULL) {
235                 /* if errno==ENOENT this means we don't have NUMA support */
236                 if (errno == ENOENT) {
237                         printf("No NUMA nodes detected: assuming 1 available socket\n");
238                         return 1;
239                 }
240                 printf("Error opening %s: %s\n", nodedir, strerror(errno));
241                 return -1;
242         }
243
244         while ((dirent = readdir(dir)) != NULL)
245                 if (strncmp(dirent->d_name, "node", sizeof("node") - 1) == 0)
246                         result++;
247
248         closedir(dir);
249         return result;
250 }
251 #endif
252
253 static char*
254 get_current_prefix(char * prefix, int size)
255 {
256         char path[PATH_MAX] = {0};
257         char buf[PATH_MAX] = {0};
258
259         /* get file for config (fd is always 3) */
260         rte_snprintf(path, sizeof(path), "/proc/self/fd/%d", 3);
261
262         /* return NULL on error */
263         if (readlink(path, buf, sizeof(buf)) == -1)
264                 return NULL;
265
266         /* get the basename */
267         rte_snprintf(buf, sizeof(buf), "%s", basename(buf));
268
269         /* copy string all the way from second char up to start of _config */
270         rte_snprintf(prefix, size, "%.*s",
271                         strnlen(buf, sizeof(buf)) - sizeof("_config"), &buf[1]);
272
273         return prefix;
274 }
275
276 /* extra function prototypes for internal eal function to test in whitelist 
277  * ICC 12 doesn't approve of this practice, so temporarily disable warnings for it */
278 #ifdef __INTEL_COMPILER
279 #pragma warning disable 1419
280 #endif
281 extern int eal_dev_whitelist_exists(void);
282 extern int eal_dev_whitelist_add_entry(const char *);
283 extern int eal_dev_whitelist_parse(void);
284 extern int eal_dev_is_whitelisted(const char *, const char **);
285 extern void eal_dev_whitelist_clear(void);
286 #ifdef __INTEL_COMPILER
287 #pragma warning enable 1419
288 #endif
289
290 /*
291  * Test that the app doesn't run with invalid whitelist option.
292  * Final tests ensures it does run with valid options as sanity check (one
293  * test for with Domain+BDF, second for just with BDF)
294  */
295 static int
296 test_whitelist_flag(void)
297 {
298         unsigned i;
299 #ifdef RTE_EXEC_ENV_BSDAPP
300         /* BSD target doesn't support prefixes at this point */
301         const char * prefix = "";
302 #else
303         char prefix[PATH_MAX], tmp[PATH_MAX];
304         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
305                 printf("Error - unable to get current prefix!\n");
306                 return -1;
307         }
308         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
309 #endif
310
311         const char *wlinval[][11] = {
312                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
313                                 use_device, "error", "", ""},
314                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
315                                 use_device, "0:0:0", "", ""},
316                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
317                                 use_device, "0:error:0.1", "", ""},
318                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
319                                 use_device, "0:0:0.1error", "", ""},
320                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
321                                 use_device, "error0:0:0.1", "", ""},
322                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
323                                 use_device, "0:0:0.1.2", "", ""},
324                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
325                                 use_device, "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x",
326                                 use_device, "y,z,1,2,3,4,5,6,7,8,9,0"},
327         };
328         /* Test with valid whitelist option */
329         const char *wlval1[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
330                         use_device, "00FF:09:0B.3"};
331         const char *wlval2[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
332                         use_device, "09:0B.3,0a:0b.1"};
333         const char *wlval3[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
334                         use_device, "09:0B.3;type=test,08:00.1;type=normal"};
335
336         for (i = 0; i < sizeof(wlinval) / sizeof(wlinval[0]); i++) {
337                 if (launch_proc(wlinval[i]) == 0) {
338                         printf("Error - process did run ok with invalid "
339                             "whitelist parameter\n");
340                         return -1;
341                 }
342         }
343         if (launch_proc(wlval1) != 0 ) {
344                 printf("Error - process did not run ok with valid whitelist\n");
345                 return -1;
346         }
347         if (launch_proc(wlval2) != 0 ) {
348                 printf("Error - process did not run ok with valid whitelist value set\n");
349                 return -1;
350         }
351         if (launch_proc(wlval3) != 0 ) {
352                 printf("Error - process did not run ok with valid whitelist + args\n");
353                 return -1;
354         }
355
356         /* extra-sanity checks of whitelists - to be run only if no whitelist */
357         if (eal_dev_whitelist_exists())
358                 return 0;
359
360         /* check that whitelist_parse returns error without whitelist */
361         if (eal_dev_whitelist_parse() != -1) {
362                 printf("ERROR: calling whitelist parse without a whitelist doesn't "
363                                 "return an error\n");
364                 return -1;
365         }
366         if (eal_dev_is_whitelisted("adevice", NULL)) {
367                 printf("Whitelist lookup does not return false if no whitelist\n");
368                 return -1;
369         }
370         eal_dev_whitelist_add_entry("0000:00:00.0");
371         eal_dev_whitelist_parse();
372         if (eal_dev_is_whitelisted("adevice", NULL)) {
373                 printf("Whitelist lookup does not return false for unlisted dev\n");
374                 return -1;
375         }
376         if (!eal_dev_is_whitelisted("0000:00:00.0", NULL)) {
377                 printf("Whitelist lookup does not return true for whitelisted dev\n");
378                 return -1;
379         }
380         eal_dev_whitelist_clear();
381
382         return 0;
383 }
384
385 /*
386  * Test that the app doesn't run with invalid blacklist option.
387  * Final test ensures it does run with valid options as sanity check
388  */
389 static int
390 test_invalid_b_flag(void)
391 {
392 #ifdef RTE_EXEC_ENV_BSDAPP
393         /* BSD target doesn't support prefixes at this point */
394         const char * prefix = "";
395 #else
396         char prefix[PATH_MAX], tmp[PATH_MAX];
397         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
398                 printf("Error - unable to get current prefix!\n");
399                 return -1;
400         }
401         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
402 #endif
403
404         const char *blinval[][9] = {
405                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error"},
406                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0"},
407                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:error:0.1"},
408                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1error"},
409                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error0:0:0.1"},
410                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1.2"},
411         };
412         /* Test with valid blacklist option */
413         const char *blval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "FF:09:0B.3"};
414
415         int i;
416
417         for (i = 0; i != sizeof (blinval) / sizeof (blinval[0]); i++) {
418                 if (launch_proc(blinval[i]) == 0) {
419                         printf("Error - process did run ok with invalid "
420                             "blacklist parameter\n");
421                         return -1;
422                 }
423         }
424         if (launch_proc(blval) != 0) {
425                 printf("Error - process did not run ok with valid blacklist value\n");
426                 return -1;
427         }
428         return 0;
429 }
430
431
432 /*
433  * Test that the app doesn't run with invalid -r option.
434  */
435 static int
436 test_invalid_r_flag(void)
437 {
438 #ifdef RTE_EXEC_ENV_BSDAPP
439         /* BSD target doesn't support prefixes at this point */
440         const char * prefix = "";
441 #else
442         char prefix[PATH_MAX], tmp[PATH_MAX];
443         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
444                 printf("Error - unable to get current prefix!\n");
445                 return -1;
446         }
447         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
448 #endif
449
450         const char *rinval[][9] = {
451                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "error"},
452                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "0"},
453                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "-1"},
454                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "17"},
455         };
456         /* Test with valid blacklist option */
457         const char *rval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "16"};
458
459         int i;
460
461         for (i = 0; i != sizeof (rinval) / sizeof (rinval[0]); i++) {
462                 if (launch_proc(rinval[i]) == 0) {
463                         printf("Error - process did run ok with invalid "
464                             "-r (rank) parameter\n");
465                         return -1;
466                 }
467         }
468         if (launch_proc(rval) != 0) {
469                 printf("Error - process did not run ok with valid -r (rank) value\n");
470                 return -1;
471         }
472         return 0;
473 }
474
475 /*
476  * Test that the app doesn't run without the coremask flag. In all cases
477  * should give an error and fail to run
478  */
479 static int
480 test_missing_c_flag(void)
481 {
482 #ifdef RTE_EXEC_ENV_BSDAPP
483         /* BSD target doesn't support prefixes at this point */
484         const char * prefix = "";
485 #else
486         char prefix[PATH_MAX], tmp[PATH_MAX];
487         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
488                 printf("Error - unable to get current prefix!\n");
489                 return -1;
490         }
491         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
492 #endif
493
494         /* -c flag but no coremask value */
495         const char *argv1[] = { prgname, prefix, mp_flag, "-n", "3", "-c"};
496         /* No -c flag at all */
497         const char *argv2[] = { prgname, prefix, mp_flag, "-n", "3"};
498         /* bad coremask value */
499         const char *argv3[] = { prgname, prefix, mp_flag, "-n", "3", "-c", "error" };
500         /* sanity check of tests - valid coremask value */
501         const char *argv4[] = { prgname, prefix, mp_flag, "-n", "3", "-c", "1" };
502
503         if (launch_proc(argv1) == 0
504                         || launch_proc(argv2) == 0
505                         || launch_proc(argv3) == 0) {
506                 printf("Error - process ran without error when missing -c flag\n");
507                 return -1;
508         }
509         if (launch_proc(argv4) != 0) {
510                 printf("Error - process did not run ok with valid coremask value\n");
511                 return -1;
512         }
513         return 0;
514 }
515
516 /*
517  * Test that the app doesn't run without the -n flag. In all cases
518  * should give an error and fail to run.
519  * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf
520  * flags.
521  */
522 static int
523 test_missing_n_flag(void)
524 {
525 #ifdef RTE_EXEC_ENV_BSDAPP
526         /* BSD target doesn't support prefixes at this point */
527         const char * prefix = "";
528 #else
529         char prefix[PATH_MAX], tmp[PATH_MAX];
530         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
531                 printf("Error - unable to get current prefix!\n");
532                 return -1;
533         }
534         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
535 #endif
536
537         /* -n flag but no value */
538         const char *argv1[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n"};
539         /* No -n flag at all */
540         const char *argv2[] = { prgname, prefix, no_huge, no_shconf, "-c", "1"};
541         /* bad numeric value */
542         const char *argv3[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "e" };
543         /* out-of-range value */
544         const char *argv4[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "9" };
545         /* sanity test - check with good value */
546         const char *argv5[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "2" };
547
548         if (launch_proc(argv1) == 0
549                         || launch_proc(argv2) == 0
550                         || launch_proc(argv3) == 0
551                         || launch_proc(argv4) == 0) {
552                 printf("Error - process ran without error when missing -n flag\n");
553                 return -1;
554         }
555         if (launch_proc(argv5) != 0) {
556                 printf("Error - process did not run ok with valid num-channel value\n");
557                 return -1;
558         }
559         return 0;
560 }
561
562 /*
563  * Test that the app runs with HPET, and without HPET
564  */
565 static int
566 test_no_hpet_flag(void)
567 {
568         char prefix[PATH_MAX], tmp[PATH_MAX];
569
570 #ifdef RTE_EXEC_ENV_BSDAPP
571         return 0;
572 #endif
573         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
574                 printf("Error - unable to get current prefix!\n");
575                 return -1;
576         }
577         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
578
579         /* With --no-hpet */
580         const char *argv1[] = {prgname, prefix, mp_flag, no_hpet, "-c", "1", "-n", "2"};
581         /* Without --no-hpet */
582         const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-n", "2"};
583
584         if (launch_proc(argv1) != 0) {
585                 printf("Error - process did not run ok with --no-hpet flag\n");
586                 return -1;
587         }
588         if (launch_proc(argv2) != 0) {
589                 printf("Error - process did not run ok without --no-hpet flag\n");
590                 return -1;
591         }
592         return 0;
593 }
594
595 /*
596  * Test that the app runs with --no-huge and doesn't run when either
597  * -m or --socket-mem are specified with --no-huge.
598  */
599 static int
600 test_no_huge_flag(void)
601 {
602 #ifdef RTE_EXEC_ENV_BSDAPP
603         /* BSD target doesn't support prefixes at this point, and we also need to
604          * run another primary process here */
605         const char * prefix = no_shconf;
606 #else
607         const char * prefix = "--file-prefix=nohuge";
608 #endif
609
610         /* With --no-huge */
611         const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2"};
612         /* With --no-huge and -m */
613         const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", "-m", "2"};
614
615         /* With --no-huge and --socket-mem */
616         const char *argv3[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
617                         "--socket-mem=2"};
618         /* With --no-huge, -m and --socket-mem */
619         const char *argv4[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
620                         "-m", "2", "--socket-mem=2"};
621         if (launch_proc(argv1) != 0) {
622                 printf("Error - process did not run ok with --no-huge flag\n");
623                 return -1;
624         }
625         if (launch_proc(argv2) == 0) {
626                 printf("Error - process run ok with --no-huge and -m flags\n");
627                 return -1;
628         }
629 #ifdef RTE_EXEC_ENV_BSDAPP
630         /* BSD target does not support NUMA, hence no --socket-mem tests */
631         return 0;
632 #endif
633
634         if (launch_proc(argv3) == 0) {
635                 printf("Error - process run ok with --no-huge and --socket-mem "
636                                 "flags\n");
637                 return -1;
638         }
639         if (launch_proc(argv4) == 0) {
640                 printf("Error - process run ok with --no-huge, -m and "
641                                 "--socket-mem flags\n");
642                 return -1;
643         }
644         return 0;
645 }
646
647 static int
648 test_misc_flags(void)
649 {
650         char hugepath[PATH_MAX] = {0};
651 #ifdef RTE_EXEC_ENV_BSDAPP
652         /* BSD target doesn't support prefixes at this point */
653         const char * prefix = "";
654         const char * nosh_prefix = "";
655 #else
656         char prefix[PATH_MAX], tmp[PATH_MAX];
657         const char * nosh_prefix = "--file-prefix=noshconf";
658         FILE * hugedir_handle = NULL;
659         char line[PATH_MAX] = {0};
660         unsigned i, isempty = 1;
661         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
662                 printf("Error - unable to get current prefix!\n");
663                 return -1;
664         }
665         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
666
667         /*
668          * get first valid hugepage path
669          */
670
671         /* get hugetlbfs mountpoints from /proc/mounts */
672         hugedir_handle = fopen("/proc/mounts", "r");
673
674         if (hugedir_handle == NULL) {
675                 printf("Error opening /proc/mounts!\n");
676                 return -1;
677         }
678
679         /* read /proc/mounts */
680         while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
681
682                 /* find first valid hugepath */
683                 if (get_hugepage_path(line, sizeof(line), hugepath, sizeof(hugepath)))
684                         break;
685         }
686
687         fclose(hugedir_handle);
688
689         /* check if path is not empty */
690         for (i = 0; i < sizeof(hugepath); i++)
691                 if (hugepath[i] != '\0')
692                         isempty = 0;
693
694         if (isempty) {
695                 printf("No mounted hugepage dir found!\n");
696                 return -1;
697         }
698 #endif
699
700
701         /* check that some general flags don't prevent things from working.
702          * All cases, apart from the first, app should run.
703          * No futher testing of output done.
704          */
705         /* sanity check - failure with invalid option */
706         const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"};
707
708         /* With --no-pci */
709         const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"};
710         /* With -v */
711         const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"};
712         /* With valid --syslog */
713         const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1",
714                         "--syslog", "syslog"};
715         /* With empty --syslog (should fail) */
716         const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"};
717         /* With invalid --syslog */
718         const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
719         /* With no-sh-conf */
720         const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
721                         no_shconf, nosh_prefix };
722
723 #ifdef RTE_EXEC_ENV_BSDAPP
724         return 0;
725 #endif
726         /* With --huge-dir */
727         const char *argv7[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
728                         "--file-prefix=hugedir", "--huge-dir", hugepath};
729         /* With empty --huge-dir (should fail) */
730         const char *argv8[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
731                         "--file-prefix=hugedir", "--huge-dir"};
732         /* With invalid --huge-dir */
733         const char *argv9[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
734                         "--file-prefix=hugedir", "--huge-dir", "invalid"};
735         /* Secondary process with invalid --huge-dir (should run as flag has no
736          * effect on secondary processes) */
737         const char *argv10[] = {prgname, prefix, mp_flag, "-c", "1", "--huge-dir", "invalid"};
738
739
740         if (launch_proc(argv0) == 0) {
741                 printf("Error - process ran ok with invalid flag\n");
742                 return -1;
743         }
744         if (launch_proc(argv1) != 0) {
745                 printf("Error - process did not run ok with --no-pci flag\n");
746                 return -1;
747         }
748         if (launch_proc(argv2) != 0) {
749                 printf("Error - process did not run ok with -v flag\n");
750                 return -1;
751         }
752         if (launch_proc(argv3) != 0) {
753                 printf("Error - process did not run ok with --syslog flag\n");
754                 return -1;
755         }
756         if (launch_proc(argv4) == 0) {
757                 printf("Error - process run ok with empty --syslog flag\n");
758                 return -1;
759         }
760         if (launch_proc(argv5) == 0) {
761                 printf("Error - process run ok with invalid --syslog flag\n");
762                 return -1;
763         }
764         if (launch_proc(argv6) != 0) {
765                 printf("Error - process did not run ok with --no-shconf flag\n");
766                 return -1;
767         }
768 #ifdef RTE_EXEC_ENV_BSDAPP
769         return 0;
770 #endif
771         if (launch_proc(argv7) != 0) {
772                 printf("Error - process did not run ok with --huge-dir flag\n");
773                 return -1;
774         }
775         if (launch_proc(argv8) == 0) {
776                 printf("Error - process run ok with empty --huge-dir flag\n");
777                 return -1;
778         }
779         if (launch_proc(argv9) == 0) {
780                 printf("Error - process run ok with invalid --huge-dir flag\n");
781                 return -1;
782         }
783         if (launch_proc(argv10) != 0) {
784                 printf("Error - secondary process did not run ok with invalid --huge-dir flag\n");
785                 return -1;
786         }
787         return 0;
788 }
789
790 static int
791 test_file_prefix(void)
792 {
793         /*
794          * 1. check if current process hugefiles are locked
795          * 2. try to run secondary process without a corresponding primary process
796          * (while failing to run, it will also remove any unused hugepage files)
797          * 3. check if current process hugefiles are still in place and are locked
798          * 4. run a primary process with memtest1 prefix
799          * 5. check if memtest1 hugefiles are created
800          * 6. run a primary process with memtest2 prefix
801          * 7. check that only memtest2 hugefiles are present in the hugedir
802          */
803
804 #ifdef RTE_EXEC_ENV_BSDAPP
805         return 0;
806 #endif
807
808         /* this should fail unless the test itself is run with "memtest" prefix */
809         const char *argv0[] = {prgname, mp_flag, "-c", "1", "-n", "2", "-m", "2",
810                         "--file-prefix=" memtest };
811
812         /* primary process with memtest1 */
813         const char *argv1[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
814                                 "--file-prefix=" memtest1 };
815
816         /* primary process with memtest2 */
817         const char *argv2[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
818                                 "--file-prefix=" memtest2 };
819
820         char prefix[32];
821         if (get_current_prefix(prefix, sizeof(prefix)) == NULL) {
822                 printf("Error - unable to get current prefix!\n");
823                 return -1;
824         }
825
826         /* check if files for current prefix are present */
827         if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
828                 printf("Error - hugepage files for %s were not created!\n", prefix);
829                 return -1;
830         }
831
832         /* checks if files for current prefix are locked */
833         if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
834                 printf("Error - hugepages for current process aren't locked!\n");
835                 return -1;
836         }
837
838         /* check if files for secondary process are present */
839         if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) {
840                 /* check if they are not locked */
841                 if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) {
842                         printf("Error - hugepages for current process are locked!\n");
843                         return -1;
844                 }
845                 /* they aren't locked, delete them */
846                 else {
847                         if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) {
848                                 printf("Error - deleting hugepages failed!\n");
849                                 return -1;
850                         }
851                 }
852         }
853
854         if (launch_proc(argv0) == 0) {
855                 printf("Error - secondary process ran ok without primary process\n");
856                 return -1;
857         }
858
859         /* check if files for current prefix are present */
860         if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
861                 printf("Error - hugepage files for %s were not created!\n", prefix);
862                 return -1;
863         }
864
865         /* checks if files for current prefix are locked */
866         if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
867                 printf("Error - hugepages for current process aren't locked!\n");
868                 return -1;
869         }
870
871         if (launch_proc(argv1) != 0) {
872                 printf("Error - failed to run with --file-prefix=%s\n", memtest);
873                 return -1;
874         }
875
876         /* check if memtest1_map0 is present */
877         if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) {
878                 printf("Error - hugepage files for %s were not created!\n", memtest1);
879                 return -1;
880         }
881
882         if (launch_proc(argv2) != 0) {
883                 printf("Error - failed to run with --file-prefix=%s\n", memtest2);
884                 return -1;
885         }
886
887         /* check if hugefiles for memtest2 are present */
888         if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) {
889                 printf("Error - hugepage files for %s were not created!\n", memtest2);
890                 return -1;
891         }
892
893         /* check if hugefiles for memtest1 are present */
894         if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
895                 printf("Error - hugepage files for %s were not deleted!\n", memtest1);
896                 return -1;
897         }
898
899         return 0;
900 }
901
902 /*
903  * Tests for correct handling of -m and --socket-mem flags
904  */
905 static int
906 test_memory_flags(void)
907 {
908 #ifdef RTE_EXEC_ENV_BSDAPP
909         /* BSD target doesn't support prefixes at this point */
910         const char * prefix = "";
911 #else
912         char prefix[PATH_MAX], tmp[PATH_MAX];
913         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
914                 printf("Error - unable to get current prefix!\n");
915                 return -1;
916         }
917         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
918 #endif
919         /* valid -m flag */
920         const char *argv0[] = {prgname, "-c", "10", "-n", "2",
921                         "--file-prefix=" memtest, "-m", "2"};
922
923         /* valid -m flag and mp flag */
924         const char *argv1[] = {prgname, prefix, mp_flag, "-c", "10",
925                         "-n", "2", "-m", "2"};
926
927         /* invalid (zero) --socket-mem flag */
928         const char *argv2[] = {prgname, "-c", "10", "-n", "2",
929                         "--file-prefix=" memtest, "--socket-mem=0,0,0,0"};
930
931         /* invalid (incomplete) --socket-mem flag */
932         const char *argv3[] = {prgname, "-c", "10", "-n", "2",
933                         "--file-prefix=" memtest, "--socket-mem=2,2,"};
934
935         /* invalid (mixed with invalid data) --socket-mem flag */
936         const char *argv4[] = {prgname, "-c", "10", "-n", "2",
937                         "--file-prefix=" memtest, "--socket-mem=2,2,Fred"};
938
939         /* invalid (with numeric value as last character) --socket-mem flag */
940         const char *argv5[] = {prgname, "-c", "10", "-n", "2",
941                         "--file-prefix=" memtest, "--socket-mem=2,2,Fred0"};
942
943         /* invalid (with empty socket) --socket-mem flag */
944         const char *argv6[] = {prgname, "-c", "10", "-n", "2",
945                         "--file-prefix=" memtest, "--socket-mem=2,,2"};
946
947         /* invalid (null) --socket-mem flag */
948         const char *argv7[] = {prgname, "-c", "10", "-n", "2",
949                         "--file-prefix=" memtest, "--socket-mem="};
950
951         /* valid --socket-mem specified together with -m flag */
952         const char *argv8[] = {prgname, "-c", "10", "-n", "2",
953                         "--file-prefix=" memtest, "-m", "2", "--socket-mem=2,2"};
954
955         /* construct an invalid socket mask with 2 megs on each socket plus
956          * extra 2 megs on socket that doesn't exist on current system */
957         char invalid_socket_mem[SOCKET_MEM_STRLEN];
958         char buf[SOCKET_MEM_STRLEN];    /* to avoid copying string onto itself */
959
960 #ifdef RTE_EXEC_ENV_BSDAPP
961         int i, num_sockets = 1;
962 #else
963         int i, num_sockets = get_number_of_sockets();
964 #endif
965
966         if (num_sockets <= 0 || num_sockets > RTE_MAX_NUMA_NODES) {
967                 printf("Error - cannot get number of sockets!\n");
968                 return -1;
969         }
970
971         rte_snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "--socket-mem=");
972
973         /* add one extra socket */
974         for (i = 0; i < num_sockets + 1; i++) {
975                 rte_snprintf(buf, sizeof(buf), "%s2", invalid_socket_mem);
976                 rte_snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf);
977
978                 if (num_sockets + 1 - i > 1) {
979                         rte_snprintf(buf, sizeof(buf), "%s,", invalid_socket_mem);
980                         rte_snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf);
981                 }
982         }
983
984         /* construct a valid socket mask with 2 megs on each existing socket */
985         char valid_socket_mem[SOCKET_MEM_STRLEN];
986
987         rte_snprintf(valid_socket_mem, sizeof(valid_socket_mem), "--socket-mem=");
988
989         /* add one extra socket */
990         for (i = 0; i < num_sockets; i++) {
991                 rte_snprintf(buf, sizeof(buf), "%s2", valid_socket_mem);
992                 rte_snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf);
993
994                 if (num_sockets - i > 1) {
995                         rte_snprintf(buf, sizeof(buf), "%s,", valid_socket_mem);
996                         rte_snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf);
997                 }
998         }
999
1000         /* invalid --socket-mem flag (with extra socket) */
1001         const char *argv9[] = {prgname, "-c", "10", "-n", "2",
1002                         "--file-prefix=" memtest, invalid_socket_mem};
1003
1004         /* valid --socket-mem flag */
1005         const char *argv10[] = {prgname, "-c", "10", "-n", "2",
1006                         "--file-prefix=" memtest, valid_socket_mem};
1007
1008         if (launch_proc(argv0) != 0) {
1009                 printf("Error - secondary process failed with valid -m flag !\n");
1010                 return -1;
1011         }
1012
1013 #ifdef RTE_EXEC_ENV_BSDAPP
1014         /* no other tests are applicable to BSD */
1015         return 0;
1016 #endif
1017
1018         if (launch_proc(argv1) != 0) {
1019                 printf("Error - secondary process failed with valid -m flag !\n");
1020                 return -1;
1021         }
1022
1023         if (launch_proc(argv2) == 0) {
1024                 printf("Error - process run ok with invalid (zero) --socket-mem!\n");
1025                 return -1;
1026         }
1027
1028         if (launch_proc(argv3) == 0) {
1029                 printf("Error - process run ok with invalid "
1030                                 "(incomplete) --socket-mem!\n");
1031                 return -1;
1032         }
1033
1034         if (launch_proc(argv4) == 0) {
1035                 printf("Error - process run ok with invalid "
1036                                 "(mixed with invalid input) --socket-mem!\n");
1037                 return -1;
1038         }
1039
1040         if (launch_proc(argv5) == 0) {
1041                 printf("Error - process run ok with invalid "
1042                                 "(mixed with invalid input with a numeric value as "
1043                                 "last character) --socket-mem!\n");
1044                 return -1;
1045         }
1046
1047         if (launch_proc(argv6) == 0) {
1048                 printf("Error - process run ok with invalid "
1049                                 "(with empty socket) --socket-mem!\n");
1050                 return -1;
1051         }
1052
1053         if (launch_proc(argv7) == 0) {
1054                 printf("Error - process run ok with invalid (null) --socket-mem!\n");
1055                 return -1;
1056         }
1057
1058         if (launch_proc(argv8) == 0) {
1059                 printf("Error - process run ok with --socket-mem and -m specified!\n");
1060                 return -1;
1061         }
1062
1063         if (launch_proc(argv9) == 0) {
1064                 printf("Error - process run ok with extra socket in --socket-mem!\n");
1065                 return -1;
1066         }
1067
1068         if (launch_proc(argv10) != 0) {
1069                 printf("Error - process failed with valid --socket-mem!\n");
1070                 return -1;
1071         }
1072
1073         return 0;
1074 }
1075
1076 int
1077 test_eal_flags(void)
1078 {
1079         int ret = 0;
1080
1081         ret = test_missing_c_flag();
1082         if (ret < 0) {
1083                 printf("Error in test_missing_c_flag()\n");
1084                 return ret;
1085         }
1086
1087         ret = test_missing_n_flag();
1088         if (ret < 0) {
1089                 printf("Error in test_missing_n_flag()\n");
1090                 return ret;
1091         }
1092
1093         ret = test_no_hpet_flag();
1094         if (ret < 0) {
1095                 printf("Error in test_no_hpet_flag()\n");
1096                 return ret;
1097         }
1098
1099         ret = test_no_huge_flag();
1100         if (ret < 0) {
1101                 printf("Error in test_no_huge_flag()\n");
1102                 return ret;
1103         }
1104
1105         ret = test_whitelist_flag();
1106         if (ret < 0) {
1107                 printf("Error in test_invalid_whitelist_flag()\n");
1108                 return ret;
1109         }
1110
1111         ret = test_invalid_b_flag();
1112         if (ret < 0) {
1113                 printf("Error in test_invalid_b_flag()\n");
1114                 return ret;
1115         }
1116
1117         ret = test_invalid_r_flag();
1118         if (ret < 0) {
1119                 printf("Error in test_invalid_r_flag()\n");
1120                 return ret;
1121         }
1122
1123         ret = test_memory_flags();
1124         if (ret < 0) {
1125                 printf("Error in test_memory_flags()\n");
1126                 return ret;
1127         }
1128
1129         ret = test_file_prefix();
1130         if (ret < 0) {
1131                 printf("Error in test_file_prefix()\n");
1132                 return ret;
1133         }
1134
1135         ret = test_misc_flags();
1136         if (ret < 0) {
1137                 printf("Error in test_misc_flags()");
1138                 return ret;
1139         }
1140
1141         return ret;
1142 }
1143
1144 #else
1145 /* Baremetal version
1146  * Multiprocess not applicable, so just return 0 always
1147  */
1148 int
1149 test_eal_flags(void)
1150 {
1151         printf("Multi-process not possible for baremetal, cannot test EAL flags\n");
1152         return 0;
1153 }
1154
1155 #endif