doc: whitespace changes in licenses
[dpdk.git] / app / test / test_eal_flags.c
1 /*-
2  *   BSD LICENSE
3  * 
4  *   Copyright(c) 2010-2013 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
51 #include <rte_debug.h>
52 #include <rte_string_fns.h>
53
54 #include "process.h"
55
56 #define mp_flag "--proc-type=secondary"
57 #define no_hpet "--no-hpet"
58 #define no_huge "--no-huge"
59 #define no_shconf "--no-shconf"
60 #define memtest "memtest"
61 #define memtest1 "memtest1"
62 #define memtest2 "memtest2"
63 #define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 10)
64 #define launch_proc(ARGV) process_dup(ARGV, \
65                 sizeof(ARGV)/(sizeof(ARGV[0])), __func__)
66
67 enum hugepage_action {
68         HUGEPAGE_CHECK_EXISTS = 0,
69         HUGEPAGE_CHECK_LOCKED,
70         HUGEPAGE_DELETE,
71         HUGEPAGE_INVALID
72 };
73
74 /* if string contains a hugepage path */
75 static int
76 get_hugepage_path(char * src, int src_len, char * dst, int dst_len)
77 {
78 #define NUM_TOKENS 4
79         char *tokens[NUM_TOKENS];
80
81         /* if we couldn't properly split the string */
82         if (rte_strsplit(src, src_len, tokens, NUM_TOKENS, ' ') < NUM_TOKENS)
83                 return 0;
84
85         if (strncmp(tokens[2], "hugetlbfs", sizeof("hugetlbfs")) == 0) {
86                 rte_snprintf(dst, dst_len, "%s", tokens[1]);
87                 return 1;
88         }
89         return 0;
90 }
91
92 /*
93  * Cycles through hugepage directories and looks for hugepage
94  * files associated with a given prefix. Depending on value of
95  * action, the hugepages are checked if they exist, checked if
96  * they can be locked, or are simply deleted.
97  *
98  * Returns 1 if it finds at least one hugepage matching the action
99  * Returns 0 if no matching hugepages were found
100  * Returns -1 if it encounters an error
101  */
102 static int
103 process_hugefiles(const char * prefix, enum hugepage_action action)
104 {
105         FILE * hugedir_handle = NULL;
106         DIR * hugepage_dir = NULL;
107         struct dirent *dirent = NULL;
108
109         char hugefile_prefix[PATH_MAX] = {0};
110         char hugedir[PATH_MAX] = {0};
111         char line[PATH_MAX] = {0};
112
113         int fd, lck_result, result = 0;
114
115         const int prefix_len = rte_snprintf(hugefile_prefix,
116                         sizeof(hugefile_prefix), "%smap_", prefix);
117         if (prefix_len <= 0 || prefix_len >= (int)sizeof(hugefile_prefix)
118                         || prefix_len >= (int)sizeof(dirent->d_name)) {
119                 printf("Error creating hugefile filename prefix\n");
120                 return -1;
121         }
122
123         /* get hugetlbfs mountpoints from /proc/mounts */
124         hugedir_handle = fopen("/proc/mounts", "r");
125
126         if (hugedir_handle == NULL) {
127                 printf("Error parsing /proc/mounts!\n");
128                 return -1;
129         }
130
131         /* read and parse script output */
132         while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
133
134                 /* check if we have a hugepage filesystem path */
135                 if (!get_hugepage_path(line, sizeof(line), hugedir, sizeof(hugedir)))
136                         continue;
137
138                 /* check if directory exists */
139                 if ((hugepage_dir = opendir(hugedir)) == NULL) {
140                         fclose(hugedir_handle);
141                         printf("Error reading %s: %s\n", hugedir, strerror(errno));
142                         return -1;
143                 }
144
145                 while ((dirent = readdir(hugepage_dir)) != NULL) {
146                         if (memcmp(dirent->d_name, hugefile_prefix, prefix_len) != 0)
147                                 continue;
148
149                         switch (action) {
150                         case HUGEPAGE_CHECK_EXISTS:
151                                 {
152                                         /* file exists, return */
153                                         result = 1;
154                                         goto end;
155                                 }
156                                 break;
157                         case HUGEPAGE_DELETE:
158                                 {
159                                         char file_path[PATH_MAX] = {0};
160
161                                         rte_snprintf(file_path, sizeof(file_path),
162                                                 "%s/%s", hugedir, dirent->d_name);
163                                         
164                                         /* remove file */
165                                         if (remove(file_path) < 0) {
166                                                 printf("Error deleting %s - %s!\n",
167                                                                 dirent->d_name, strerror(errno));
168                                                 closedir(hugepage_dir);
169                                                 result = -1;
170                                                 goto end;
171                                         }
172                                         result = 1;
173                                 }
174                                 break;
175                         case HUGEPAGE_CHECK_LOCKED:
176                                 {
177                                         /* try and lock the file */
178                                         fd = openat(dirfd(hugepage_dir), dirent->d_name, O_RDONLY);
179
180                                         /* this shouldn't happen */
181                                         if (fd == -1) {
182                                                 printf("Error opening %s - %s!\n",
183                                                                 dirent->d_name, strerror(errno));
184                                                 closedir(hugepage_dir);
185                                                 result = -1;
186                                                 goto end;
187                                         }
188
189                                         /* non-blocking lock */
190                                         lck_result = flock(fd, LOCK_EX | LOCK_NB);
191
192                                         /* if lock succeeds, there's something wrong */
193                                         if (lck_result != -1) {
194                                                 result = 0;
195
196                                                 /* unlock the resulting lock */
197                                                 flock(fd, LOCK_UN);
198                                                 close(fd);
199                                                 closedir(hugepage_dir);
200                                                 goto end;
201                                         }
202                                         result = 1;
203                                         close(fd);
204                                 }
205                                 break;
206                                 /* shouldn't happen */
207                         default:
208                                 goto end;
209                         } /* switch */
210
211                 } /* read hugepage directory */
212                 closedir(hugepage_dir);
213         } /* read /proc/mounts */
214 end:
215         fclose(hugedir_handle);
216         return result;
217 }
218
219 /*
220  * count the number of "node*" files in /sys/devices/system/node/
221  */
222 static int
223 get_number_of_sockets(void)
224 {
225         struct dirent *dirent = NULL;
226         const char * nodedir = "/sys/devices/system/node/";
227         DIR * dir = NULL;
228         int result = 0;
229
230         /* check if directory exists */
231         if ((dir = opendir(nodedir)) == NULL) {
232                 /* if errno==ENOENT this means we don't have NUMA support */
233                 if (errno == ENOENT) {
234                         printf("No NUMA nodes detected: assuming 1 available socket\n");
235                         return 1;
236                 }
237                 printf("Error opening %s: %s\n", nodedir, strerror(errno));
238                 return -1;
239         }
240
241         while ((dirent = readdir(dir)) != NULL)
242                 if (strncmp(dirent->d_name, "node", sizeof("node") - 1) == 0)
243                         result++;
244
245         closedir(dir);
246         return result;
247 }
248
249 static char*
250 get_current_prefix(char * prefix, int size)
251 {
252         char path[PATH_MAX] = {0};
253         char buf[PATH_MAX] = {0};
254
255         /* get file for config (fd is always 3) */
256         rte_snprintf(path, sizeof(path), "/proc/self/fd/%d", 3);
257
258         /* return NULL on error */
259         if (readlink(path, buf, sizeof(buf)) == -1)
260                 return NULL;
261
262         /* get the basename */
263         rte_snprintf(buf, sizeof(buf), "%s", basename(buf));
264
265         /* copy string all the way from second char up to start of _config */
266         rte_snprintf(prefix, size, "%.*s",
267                         strnlen(buf, sizeof(buf)) - sizeof("_config"), &buf[1]);
268
269         return prefix;
270 }
271
272 /*
273  * Test that the app doesn't run without invalid blacklist option.
274  * Final test ensures it does run with valid options as sanity check
275  */
276 static int
277 test_invalid_b_flag(void)
278 {
279         char prefix[PATH_MAX], tmp[PATH_MAX];
280         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
281                 printf("Error - unable to get current prefix!\n");
282                 return -1;
283         }
284         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
285
286         const char *blinval[][9] = {
287                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error"},
288                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0"},
289                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:error:0.1"},
290                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1error"},
291                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error0:0:0.1"},
292                 {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1.2"},
293         };
294         /* Test with valid blacklist option */
295         const char *blval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "FF:09:0B.3"};
296
297         int i;
298
299         for (i = 0; i != sizeof (blinval) / sizeof (blinval[0]); i++) {
300                 if (launch_proc(blinval[i]) == 0) {
301                         printf("Error - process did run ok with invalid "
302                             "blacklist parameter\n");
303                         return -1;
304                 }
305         }
306         if (launch_proc(blval) != 0) {
307                 printf("Error - process did not run ok with valid blacklist value\n");
308                 return -1;
309         }
310         return 0;
311 }
312
313
314 /*
315  * Test that the app doesn't run with invalid -r option.
316  */
317 static int
318 test_invalid_r_flag(void)
319 {
320         char prefix[PATH_MAX], tmp[PATH_MAX];
321         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
322                 printf("Error - unable to get current prefix!\n");
323                 return -1;
324         }
325         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
326
327         const char *rinval[][9] = {
328                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "error"},
329                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "0"},
330                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "-1"},
331                         {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "17"},
332         };
333         /* Test with valid blacklist option */
334         const char *rval[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "16"};
335
336         int i;
337
338         for (i = 0; i != sizeof (rinval) / sizeof (rinval[0]); i++) {
339                 if (launch_proc(rinval[i]) == 0) {
340                         printf("Error - process did run ok with invalid "
341                             "-r (rank) parameter\n");
342                         return -1;
343                 }
344         }
345         if (launch_proc(rval) != 0) {
346                 printf("Error - process did not run ok with valid -r (rank) value\n");
347                 return -1;
348         }
349         return 0;
350 }
351
352 /*
353  * Test that the app doesn't run without the coremask flag. In all cases
354  * should give an error and fail to run
355  */
356 static int
357 test_missing_c_flag(void)
358 {
359         char prefix[PATH_MAX], tmp[PATH_MAX];
360         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
361                 printf("Error - unable to get current prefix!\n");
362                 return -1;
363         }
364         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
365
366         /* -c flag but no coremask value */
367         const char *argv1[] = { prgname, prefix, mp_flag, "-n", "3", "-c"};
368         /* No -c flag at all */
369         const char *argv2[] = { prgname, prefix, mp_flag, "-n", "3"};
370         /* bad coremask value */
371         const char *argv3[] = { prgname, prefix, mp_flag, "-n", "3", "-c", "error" };
372         /* sanity check of tests - valid coremask value */
373         const char *argv4[] = { prgname, prefix, mp_flag, "-n", "3", "-c", "1" };
374
375         if (launch_proc(argv1) == 0
376                         || launch_proc(argv2) == 0
377                         || launch_proc(argv3) == 0) {
378                 printf("Error - process ran without error when missing -c flag\n");
379                 return -1;
380         }
381         if (launch_proc(argv4) != 0) {
382                 printf("Error - process did not run ok with valid coremask value\n");
383                 return -1;
384         }
385         return 0;
386 }
387
388 /*
389  * Test that the app doesn't run without the -n flag. In all cases
390  * should give an error and fail to run.
391  * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf
392  * flags.
393  */
394 static int
395 test_missing_n_flag(void)
396 {
397         char prefix[PATH_MAX], tmp[PATH_MAX];
398         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
399                 printf("Error - unable to get current prefix!\n");
400                 return -1;
401         }
402         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
403
404         /* -n flag but no value */
405         const char *argv1[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n"};
406         /* No -n flag at all */
407         const char *argv2[] = { prgname, prefix, no_huge, no_shconf, "-c", "1"};
408         /* bad numeric value */
409         const char *argv3[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "e" };
410         /* out-of-range value */
411         const char *argv4[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "9" };
412         /* sanity test - check with good value */
413         const char *argv5[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n", "2" };
414
415         if (launch_proc(argv1) == 0
416                         || launch_proc(argv2) == 0
417                         || launch_proc(argv3) == 0
418                         || launch_proc(argv4) == 0) {
419                 printf("Error - process ran without error when missing -n flag\n");
420                 return -1;
421         }
422         if (launch_proc(argv5) != 0) {
423                 printf("Error - process did not run ok with valid num-channel value\n");
424                 return -1;
425         }
426         return 0;
427 }
428
429 /*
430  * Test that the app runs with HPET, and without HPET
431  */
432 static int
433 test_no_hpet_flag(void)
434 {
435         char prefix[PATH_MAX], tmp[PATH_MAX];
436         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
437                 printf("Error - unable to get current prefix!\n");
438                 return -1;
439         }
440         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
441
442         /* With --no-hpet */
443         const char *argv1[] = {prgname, prefix, mp_flag, no_hpet, "-c", "1", "-n", "2"};
444         /* Without --no-hpet */
445         const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-n", "2"};
446
447         if (launch_proc(argv1) != 0) {
448                 printf("Error - process did not run ok with --no-hpet flag\n");
449                 return -1;
450         }
451         if (launch_proc(argv2) != 0) {
452                 printf("Error - process did not run ok without --no-hpet flag\n");
453                 return -1;
454         }
455         return 0;
456 }
457
458 /*
459  * Test that the app runs with --no-huge and doesn't run when either
460  * -m or --socket-mem are specified with --no-huge.
461  */
462 static int
463 test_no_huge_flag(void)
464 {
465         char prefix[PATH_MAX], tmp[PATH_MAX];
466         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
467                 printf("Error - unable to get current prefix!\n");
468                 return -1;
469         }
470         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
471
472         /* With --no-huge */
473         const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
474                         "--file-prefix=nohuge"};
475         /* With --no-huge and -m */
476         const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", "-m", "2",
477                         "--file-prefix=nohuge"};
478         /* With --no-huge and --socket-mem */
479         const char *argv3[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
480                         "--socket-mem=2", "--file-prefix=nohuge"};
481         /* With --no-huge, -m and --socket-mem */
482         const char *argv4[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
483                         "-m", "2", "--socket-mem=2", "--file-prefix=nohuge"};
484
485         if (launch_proc(argv1) != 0) {
486                 printf("Error - process did not run ok with --no-huge flag\n");
487                 return -1;
488         }
489         if (launch_proc(argv2) == 0) {
490                 printf("Error - process run ok with --no-huge and -m flags\n");
491                 return -1;
492         }
493         if (launch_proc(argv3) == 0) {
494                 printf("Error - process run ok with --no-huge and --socket-mem "
495                                 "flags\n");
496                 return -1;
497         }
498         if (launch_proc(argv4) == 0) {
499                 printf("Error - process run ok with --no-huge, -m and "
500                                 "--socket-mem flags\n");
501                 return -1;
502         }
503         return 0;
504 }
505
506 static int
507 test_misc_flags(void)
508 {
509         FILE * hugedir_handle = NULL;
510         char line[PATH_MAX] = {0};
511         char hugepath[PATH_MAX] = {0};
512         char prefix[PATH_MAX], tmp[PATH_MAX];
513         unsigned i, isempty = 1;
514
515         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
516                 printf("Error - unable to get current prefix!\n");
517                 return -1;
518         }
519         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
520
521         /*
522          * get first valid hugepage path
523          */
524
525         /* get hugetlbfs mountpoints from /proc/mounts */
526         hugedir_handle = fopen("/proc/mounts", "r");
527
528         if (hugedir_handle == NULL) {
529                 printf("Error opening /proc/mounts!\n");
530                 return -1;
531         }
532
533         /* read /proc/mounts */
534         while (fgets(line, sizeof(line), hugedir_handle) != NULL) {
535
536                 /* find first valid hugepath */
537                 if (get_hugepage_path(line, sizeof(line), hugepath, sizeof(hugepath)))
538                         break;
539         }
540
541         fclose(hugedir_handle);
542
543         /* check if path is not empty */
544         for (i = 0; i < sizeof(hugepath); i++)
545                 if (hugepath[i] != '\0')
546                         isempty = 0;
547
548         if (isempty) {
549                 printf("No mounted hugepage dir found!\n");
550                 return -1;
551         }
552
553
554         /* check that some general flags don't prevent things from working.
555          * All cases, apart from the first, app should run.
556          * No futher testing of output done.
557          */
558         /* sanity check - failure with invalid option */
559         const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"};
560
561         /* With --no-pci */
562         const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"};
563         /* With -v */
564         const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"};
565         /* With valid --syslog */
566         const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1",
567                         "--syslog", "syslog"};
568         /* With empty --syslog (should fail) */
569         const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"};
570         /* With invalid --syslog */
571         const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
572         /* With no-sh-conf */
573         const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
574                         "--no-shconf", "--file-prefix=noshconf" };
575         /* With --huge-dir */
576         const char *argv7[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
577                         "--file-prefix=hugedir", "--huge-dir", hugepath};
578         /* With empty --huge-dir (should fail) */
579         const char *argv8[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
580                         "--file-prefix=hugedir", "--huge-dir"};
581         /* With invalid --huge-dir */
582         const char *argv9[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
583                         "--file-prefix=hugedir", "--huge-dir", "invalid"};
584         /* Secondary process with invalid --huge-dir (should run as flag has no
585          * effect on secondary processes) */
586         const char *argv10[] = {prgname, prefix, mp_flag, "-c", "1", "--huge-dir", "invalid"};
587
588
589         if (launch_proc(argv0) == 0) {
590                 printf("Error - process ran ok with invalid flag\n");
591                 return -1;
592         }
593         if (launch_proc(argv1) != 0) {
594                 printf("Error - process did not run ok with --no-pci flag\n");
595                 return -1;
596         }
597         if (launch_proc(argv2) != 0) {
598                 printf("Error - process did not run ok with -v flag\n");
599                 return -1;
600         }
601         if (launch_proc(argv3) != 0) {
602                 printf("Error - process did not run ok with --syslog flag\n");
603                 return -1;
604         }
605         if (launch_proc(argv4) == 0) {
606                 printf("Error - process run ok with empty --syslog flag\n");
607                 return -1;
608         }
609         if (launch_proc(argv5) == 0) {
610                 printf("Error - process run ok with invalid --syslog flag\n");
611                 return -1;
612         }
613         if (launch_proc(argv6) != 0) {
614                 printf("Error - process did not run ok with --no-shconf flag\n");
615                 return -1;
616         }
617         if (launch_proc(argv7) != 0) {
618                 printf("Error - process did not run ok with --huge-dir flag\n");
619                 return -1;
620         }
621         if (launch_proc(argv8) == 0) {
622                 printf("Error - process run ok with empty --huge-dir flag\n");
623                 return -1;
624         }
625         if (launch_proc(argv9) == 0) {
626                 printf("Error - process run ok with invalid --huge-dir flag\n");
627                 return -1;
628         }
629         if (launch_proc(argv10) != 0) {
630                 printf("Error - secondary process did not run ok with invalid --huge-dir flag\n");
631                 return -1;
632         }
633         return 0;
634 }
635
636 static int
637 test_file_prefix(void)
638 {
639         /*
640          * 1. check if current process hugefiles are locked
641          * 2. try to run secondary process without a corresponding primary process
642          * (while failing to run, it will also remove any unused hugepage files)
643          * 3. check if current process hugefiles are still in place and are locked
644          * 4. run a primary process with memtest1 prefix
645          * 5. check if memtest1 hugefiles are created
646          * 6. run a primary process with memtest2 prefix
647          * 7. check that only memtest2 hugefiles are present in the hugedir
648          */
649
650         /* this should fail unless the test itself is run with "memtest" prefix */
651         const char *argv0[] = {prgname, mp_flag, "-c", "1", "-n", "2", "-m", "2",
652                         "--file-prefix=" memtest };
653
654         /* primary process with memtest1 */
655         const char *argv1[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
656                                 "--file-prefix=" memtest1 };
657
658         /* primary process with memtest2 */
659         const char *argv2[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
660                                 "--file-prefix=" memtest2 };
661
662         char prefix[32];
663         if (get_current_prefix(prefix, sizeof(prefix)) == NULL) {
664                 printf("Error - unable to get current prefix!\n");
665                 return -1;
666         }
667
668         /* check if files for current prefix are present */
669         if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
670                 printf("Error - hugepage files for %s were not created!\n", prefix);
671                 return -1;
672         }
673
674         /* checks if files for current prefix are locked */
675         if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
676                 printf("Error - hugepages for current process aren't locked!\n");
677                 return -1;
678         }
679
680         /* check if files for secondary process are present */
681         if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) {
682                 /* check if they are not locked */
683                 if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) {
684                         printf("Error - hugepages for current process are locked!\n");
685                         return -1;
686                 }
687                 /* they aren't locked, delete them */
688                 else {
689                         if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) {
690                                 printf("Error - deleting hugepages failed!\n");
691                                 return -1;
692                         }
693                 }
694         }
695
696         if (launch_proc(argv0) == 0) {
697                 printf("Error - secondary process ran ok without primary process\n");
698                 return -1;
699         }
700
701         /* check if files for current prefix are present */
702         if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
703                 printf("Error - hugepage files for %s were not created!\n", prefix);
704                 return -1;
705         }
706
707         /* checks if files for current prefix are locked */
708         if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) {
709                 printf("Error - hugepages for current process aren't locked!\n");
710                 return -1;
711         }
712
713         if (launch_proc(argv1) != 0) {
714                 printf("Error - failed to run with --file-prefix=%s\n", memtest);
715                 return -1;
716         }
717
718         /* check if memtest1_map0 is present */
719         if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) {
720                 printf("Error - hugepage files for %s were not created!\n", memtest1);
721                 return -1;
722         }
723
724         if (launch_proc(argv2) != 0) {
725                 printf("Error - failed to run with --file-prefix=%s\n", memtest2);
726                 return -1;
727         }
728
729         /* check if hugefiles for memtest2 are present */
730         if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) {
731                 printf("Error - hugepage files for %s were not created!\n", memtest2);
732                 return -1;
733         }
734
735         /* check if hugefiles for memtest1 are present */
736         if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) {
737                 printf("Error - hugepage files for %s were not deleted!\n", memtest1);
738                 return -1;
739         }
740
741         return 0;
742 }
743
744 /*
745  * Tests for correct handling of -m and --socket-mem flags
746  */
747 static int
748 test_memory_flags(void)
749 {
750         char prefix[PATH_MAX], tmp[PATH_MAX];
751         if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
752                 printf("Error - unable to get current prefix!\n");
753                 return -1;
754         }
755         rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
756
757         /* valid -m flag */
758         const char *argv0[] = {prgname, "-c", "10", "-n", "2",
759                         "--file-prefix=" memtest, "-m", "2"};
760
761         /* valid -m flag and mp flag */
762         const char *argv1[] = {prgname, prefix, mp_flag, "-c", "10",
763                         "-n", "2", "-m", "2"};
764
765         /* invalid (zero) --socket-mem flag */
766         const char *argv2[] = {prgname, "-c", "10", "-n", "2",
767                         "--file-prefix=" memtest, "--socket-mem=0,0,0,0"};
768
769         /* invalid (incomplete) --socket-mem flag */
770         const char *argv3[] = {prgname, "-c", "10", "-n", "2",
771                         "--file-prefix=" memtest, "--socket-mem=2,2,"};
772
773         /* invalid (mixed with invalid data) --socket-mem flag */
774         const char *argv4[] = {prgname, "-c", "10", "-n", "2",
775                         "--file-prefix=" memtest, "--socket-mem=2,2,Fred"};
776
777         /* invalid (with numeric value as last character) --socket-mem flag */
778         const char *argv5[] = {prgname, "-c", "10", "-n", "2",
779                         "--file-prefix=" memtest, "--socket-mem=2,2,Fred0"};
780
781         /* invalid (with empty socket) --socket-mem flag */
782         const char *argv6[] = {prgname, "-c", "10", "-n", "2",
783                         "--file-prefix=" memtest, "--socket-mem=2,,2"};
784
785         /* invalid (null) --socket-mem flag */
786         const char *argv7[] = {prgname, "-c", "10", "-n", "2",
787                         "--file-prefix=" memtest, "--socket-mem="};
788
789         /* valid --socket-mem specified together with -m flag */
790         const char *argv8[] = {prgname, "-c", "10", "-n", "2",
791                         "--file-prefix=" memtest, "-m", "2", "--socket-mem=2,2"};
792
793         /* construct an invalid socket mask with 2 megs on each socket plus
794          * extra 2 megs on socket that doesn't exist on current system */
795         char invalid_socket_mem[SOCKET_MEM_STRLEN];
796         char buf[SOCKET_MEM_STRLEN];    /* to avoid copying string onto itself */
797         int i, num_sockets = get_number_of_sockets();
798
799         if (num_sockets <= 0 || num_sockets > RTE_MAX_NUMA_NODES) {
800                 printf("Error - cannot get number of sockets!\n");
801                 return -1;
802         }
803
804         rte_snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "--socket-mem=");
805
806         /* add one extra socket */
807         for (i = 0; i < num_sockets + 1; i++) {
808                 rte_snprintf(buf, sizeof(buf), "%s2", invalid_socket_mem);
809                 rte_snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf);
810
811                 if (num_sockets + 1 - i > 1) {
812                         rte_snprintf(buf, sizeof(buf), "%s,", invalid_socket_mem);
813                         rte_snprintf(invalid_socket_mem, sizeof(invalid_socket_mem), "%s", buf);
814                 }
815         }
816
817         /* construct a valid socket mask with 2 megs on each existing socket */
818         char valid_socket_mem[SOCKET_MEM_STRLEN];
819
820         rte_snprintf(valid_socket_mem, sizeof(valid_socket_mem), "--socket-mem=");
821
822         /* add one extra socket */
823         for (i = 0; i < num_sockets; i++) {
824                 rte_snprintf(buf, sizeof(buf), "%s2", valid_socket_mem);
825                 rte_snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf);
826
827                 if (num_sockets - i > 1) {
828                         rte_snprintf(buf, sizeof(buf), "%s,", valid_socket_mem);
829                         rte_snprintf(valid_socket_mem, sizeof(valid_socket_mem), "%s", buf);
830                 }
831         }
832
833         /* invalid --socket-mem flag (with extra socket) */
834         const char *argv9[] = {prgname, "-c", "10", "-n", "2",
835                         "--file-prefix=" memtest, invalid_socket_mem};
836
837         /* valid --socket-mem flag */
838         const char *argv10[] = {prgname, "-c", "10", "-n", "2",
839                         "--file-prefix=" memtest, valid_socket_mem};
840
841         if (launch_proc(argv0) != 0) {
842                 printf("Error - process failed with valid -m flag!\n");
843                 return -1;
844         }
845
846         if (launch_proc(argv1) != 0) {
847                 printf("Error - secondary process failed with valid -m flag !\n");
848                 return -1;
849         }
850
851         if (launch_proc(argv2) == 0) {
852                 printf("Error - process run ok with invalid (zero) --socket-mem!\n");
853                 return -1;
854         }
855
856         if (launch_proc(argv3) == 0) {
857                 printf("Error - process run ok with invalid "
858                                 "(incomplete) --socket-mem!\n");
859                 return -1;
860         }
861
862         if (launch_proc(argv4) == 0) {
863                 printf("Error - process run ok with invalid "
864                                 "(mixed with invalid input) --socket-mem!\n");
865                 return -1;
866         }
867
868         if (launch_proc(argv5) == 0) {
869                 printf("Error - process run ok with invalid "
870                                 "(mixed with invalid input with a numeric value as "
871                                 "last character) --socket-mem!\n");
872                 return -1;
873         }
874
875         if (launch_proc(argv6) == 0) {
876                 printf("Error - process run ok with invalid "
877                                 "(with empty socket) --socket-mem!\n");
878                 return -1;
879         }
880
881         if (launch_proc(argv7) == 0) {
882                 printf("Error - process run ok with invalid (null) --socket-mem!\n");
883                 return -1;
884         }
885
886         if (launch_proc(argv8) == 0) {
887                 printf("Error - process run ok with --socket-mem and -m specified!\n");
888                 return -1;
889         }
890
891         if (launch_proc(argv9) == 0) {
892                 printf("Error - process run ok with extra socket in --socket-mem!\n");
893                 return -1;
894         }
895
896         if (launch_proc(argv10) != 0) {
897                 printf("Error - process failed with valid --socket-mem!\n");
898                 return -1;
899         }
900
901         return 0;
902 }
903
904 int
905 test_eal_flags(void)
906 {
907         int ret = 0;
908
909         ret = test_missing_c_flag();
910         if (ret < 0) {
911                 printf("Error in test_missing_c_flag()\n");
912                 return ret;
913         }
914
915         ret = test_missing_n_flag();
916         if (ret < 0) {
917                 printf("Error in test_missing_n_flag()\n");
918                 return ret;
919         }
920
921         ret = test_no_hpet_flag();
922         if (ret < 0) {
923                 printf("Error in test_no_hpet_flag()\n");
924                 return ret;
925         }
926
927         ret = test_no_huge_flag();
928         if (ret < 0) {
929                 printf("Error in test_no_huge_flag()\n");
930                 return ret;
931         }
932
933         ret = test_invalid_b_flag();
934         if (ret < 0) {
935                 printf("Error in test_invalid_b_flag()\n");
936                 return ret;
937         }
938
939         ret = test_invalid_r_flag();
940         if (ret < 0) {
941                 printf("Error in test_invalid_r_flag()\n");
942                 return ret;
943         }
944
945         ret = test_memory_flags();
946         if (ret < 0) {
947                 printf("Error in test_memory_flags()\n");
948                 return ret;
949         }
950
951         ret = test_file_prefix();
952         if (ret < 0) {
953                 printf("Error in test_file_prefix()\n");
954                 return ret;
955         }
956
957         ret = test_misc_flags();
958         if (ret < 0) {
959                 printf("Error in test_misc_flags()");
960                 return ret;
961         }
962
963         return ret;
964 }
965
966 #else
967 /* Baremetal version
968  * Multiprocess not applicable, so just return 0 always
969  */
970 int
971 test_eal_flags(void)
972 {
973         printf("Multi-process not possible for baremetal, cannot test EAL flags\n");
974         return 0;
975 }
976
977 #endif