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/file.h> 18 #include <sys/stat.h> 19 #include <sys/wait.h> 20 #include <limits.h> 21 #include <fcntl.h> 22 23 #include <rte_lcore.h> 24 #include <rte_debug.h> 25 #include <rte_string_fns.h> 26 27 #include "process.h" 28 29 #define DEFAULT_MEM_SIZE "18" 30 #define mp_flag "--proc-type=secondary" 31 #define no_hpet "--no-hpet" 32 #define no_huge "--no-huge" 33 #define no_shconf "--no-shconf" 34 #define allow "--allow" 35 #define vdev "--vdev" 36 #define memtest "memtest" 37 #define memtest1 "memtest1" 38 #define memtest2 "memtest2" 39 #define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 20) 40 #define launch_proc(ARGV) process_dup(ARGV, RTE_DIM(ARGV), __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 closedir(hugepage_dir); 129 result = 1; 130 goto end; 131 } 132 break; 133 case HUGEPAGE_DELETE: 134 { 135 char file_path[PATH_MAX] = {0}; 136 137 snprintf(file_path, sizeof(file_path), 138 "%s/%s", hugedir, dirent->d_name); 139 140 /* remove file */ 141 if (remove(file_path) < 0) { 142 printf("Error deleting %s - %s!\n", 143 dirent->d_name, strerror(errno)); 144 closedir(hugepage_dir); 145 result = -1; 146 goto end; 147 } 148 result = 1; 149 } 150 break; 151 case HUGEPAGE_CHECK_LOCKED: 152 { 153 /* try and lock the file */ 154 fd = openat(dirfd(hugepage_dir), dirent->d_name, O_RDONLY); 155 156 /* this shouldn't happen */ 157 if (fd == -1) { 158 printf("Error opening %s - %s!\n", 159 dirent->d_name, strerror(errno)); 160 closedir(hugepage_dir); 161 result = -1; 162 goto end; 163 } 164 165 /* non-blocking lock */ 166 lck_result = flock(fd, LOCK_EX | LOCK_NB); 167 168 /* if lock succeeds, there's something wrong */ 169 if (lck_result != -1) { 170 result = 0; 171 172 /* unlock the resulting lock */ 173 flock(fd, LOCK_UN); 174 close(fd); 175 closedir(hugepage_dir); 176 goto end; 177 } 178 result = 1; 179 close(fd); 180 } 181 break; 182 /* shouldn't happen */ 183 default: 184 goto end; 185 } /* switch */ 186 187 } /* read hugepage directory */ 188 closedir(hugepage_dir); 189 } /* read /proc/mounts */ 190 end: 191 fclose(hugedir_handle); 192 return result; 193 } 194 195 #ifdef RTE_EXEC_ENV_LINUX 196 /* 197 * count the number of "node*" files in /sys/devices/system/node/ 198 */ 199 static int 200 get_number_of_sockets(void) 201 { 202 struct dirent *dirent = NULL; 203 const char * nodedir = "/sys/devices/system/node/"; 204 DIR * dir = NULL; 205 int result = 0; 206 207 /* check if directory exists */ 208 if ((dir = opendir(nodedir)) == NULL) { 209 /* if errno==ENOENT this means we don't have NUMA support */ 210 if (errno == ENOENT) { 211 printf("No NUMA nodes detected: assuming 1 available socket\n"); 212 return 1; 213 } 214 printf("Error opening %s: %s\n", nodedir, strerror(errno)); 215 return -1; 216 } 217 218 while ((dirent = readdir(dir)) != NULL) 219 if (strncmp(dirent->d_name, "node", sizeof("node") - 1) == 0) 220 result++; 221 222 closedir(dir); 223 return result; 224 } 225 #endif 226 227 /* 228 * Test that the app doesn't run with invalid allow option. 229 * Final tests ensures it does run with valid options as sanity check (one 230 * test for with Domain+BDF, second for just with BDF) 231 */ 232 static int 233 test_allow_flag(void) 234 { 235 unsigned i; 236 #ifdef RTE_EXEC_ENV_FREEBSD 237 /* BSD target doesn't support prefixes at this point */ 238 const char * prefix = ""; 239 #else 240 char prefix[PATH_MAX], tmp[PATH_MAX]; 241 if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { 242 printf("Error - unable to get current prefix!\n"); 243 return -1; 244 } 245 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 246 #endif 247 248 const char *wlinval[][7] = { 249 {prgname, prefix, mp_flag, 250 allow, "error", "", ""}, 251 {prgname, prefix, mp_flag, 252 allow, "0:0:0", "", ""}, 253 {prgname, prefix, mp_flag, 254 allow, "0:error:0.1", "", ""}, 255 {prgname, prefix, mp_flag, 256 allow, "0:0:0.1error", "", ""}, 257 {prgname, prefix, mp_flag, 258 allow, "error0:0:0.1", "", ""}, 259 {prgname, prefix, mp_flag, 260 allow, "0:0:0.1.2", "", ""}, 261 }; 262 /* Test with valid allow option */ 263 const char *wlval1[] = {prgname, prefix, mp_flag, 264 allow, "00FF:09:0B.3"}; 265 const char *wlval2[] = {prgname, prefix, mp_flag, 266 allow, "09:0B.3", allow, "0a:0b.1"}; 267 const char *wlval3[] = {prgname, prefix, mp_flag, 268 allow, "09:0B.3,type=test", 269 allow, "08:00.1,type=normal", 270 }; 271 272 for (i = 0; i < RTE_DIM(wlinval); i++) { 273 if (launch_proc(wlinval[i]) == 0) { 274 printf("Error - process did run ok with invalid " 275 "allow parameter\n"); 276 return -1; 277 } 278 } 279 if (launch_proc(wlval1) != 0 ) { 280 printf("Error - process did not run ok with valid allow\n"); 281 return -1; 282 } 283 if (launch_proc(wlval2) != 0 ) { 284 printf("Error - process did not run ok with valid allow value set\n"); 285 return -1; 286 } 287 if (launch_proc(wlval3) != 0 ) { 288 printf("Error - process did not run ok with valid allow + args\n"); 289 return -1; 290 } 291 292 return 0; 293 } 294 295 /* 296 * Test that the app doesn't run with invalid blocklist option. 297 * Final test ensures it does run with valid options as sanity check 298 */ 299 static int 300 test_invalid_b_flag(void) 301 { 302 #ifdef RTE_EXEC_ENV_FREEBSD 303 /* BSD target doesn't support prefixes at this point */ 304 const char * prefix = ""; 305 #else 306 char prefix[PATH_MAX], tmp[PATH_MAX]; 307 if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { 308 printf("Error - unable to get current prefix!\n"); 309 return -1; 310 } 311 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 312 #endif 313 314 const char *blinval[][5] = { 315 {prgname, prefix, mp_flag, "-b", "error"}, 316 {prgname, prefix, mp_flag, "-b", "0:0:0"}, 317 {prgname, prefix, mp_flag, "-b", "0:error:0.1"}, 318 {prgname, prefix, mp_flag, "-b", "0:0:0.1error"}, 319 {prgname, prefix, mp_flag, "-b", "error0:0:0.1"}, 320 {prgname, prefix, mp_flag, "-b", "0:0:0.1.2"}, 321 }; 322 /* Test with valid blocklist option */ 323 const char *blval[] = {prgname, prefix, mp_flag, 324 "-b", "FF:09:0B.3"}; 325 326 int i; 327 328 for (i = 0; i != RTE_DIM(blinval); i++) { 329 if (launch_proc(blinval[i]) == 0) { 330 printf("Error - process did run ok with invalid " 331 "blocklist parameter\n"); 332 return -1; 333 } 334 } 335 if (launch_proc(blval) != 0) { 336 printf("Error - process did not run ok with valid blocklist value\n"); 337 return -1; 338 } 339 return 0; 340 } 341 342 /* 343 * Test that the app doesn't run with invalid vdev option. 344 * Final test ensures it does run with valid options as sanity check 345 */ 346 static int 347 test_invalid_vdev_flag(void) 348 { 349 #ifdef RTE_NET_RING 350 #ifdef RTE_EXEC_ENV_FREEBSD 351 /* BSD target doesn't support prefixes at this point, and we also need to 352 * run another primary process here */ 353 const char * prefix = no_shconf; 354 #else 355 const char * prefix = "--file-prefix=vdev"; 356 #endif 357 358 /* Test with invalid vdev option */ 359 const char *vdevinval[] = {prgname, prefix, no_huge, 360 vdev, "eth_dummy"}; 361 362 /* Test with valid vdev option */ 363 const char *vdevval1[] = {prgname, prefix, no_huge, 364 vdev, "net_ring0"}; 365 366 const char *vdevval2[] = {prgname, prefix, no_huge, 367 vdev, "net_ring0,args=test"}; 368 369 const char *vdevval3[] = {prgname, prefix, no_huge, 370 vdev, "net_ring0,nodeaction=r1:0:CREATE"}; 371 372 if (launch_proc(vdevinval) == 0) { 373 printf("Error - process did run ok with invalid " 374 "vdev parameter\n"); 375 return -1; 376 } 377 378 if (launch_proc(vdevval1) != 0) { 379 printf("Error - process did not run ok with valid vdev value\n"); 380 return -1; 381 } 382 383 if (launch_proc(vdevval2) != 0) { 384 printf("Error - process did not run ok with valid vdev value," 385 "with dummy args\n"); 386 return -1; 387 } 388 389 if (launch_proc(vdevval3) != 0) { 390 printf("Error - process did not run ok with valid vdev value," 391 "with valid args\n"); 392 return -1; 393 } 394 return 0; 395 #else 396 return TEST_SKIPPED; 397 #endif 398 } 399 400 /* 401 * Test that the app doesn't run with invalid -r option. 402 */ 403 static int 404 test_invalid_r_flag(void) 405 { 406 #ifdef RTE_EXEC_ENV_FREEBSD 407 /* BSD target doesn't support prefixes at this point */ 408 const char * prefix = ""; 409 #else 410 char prefix[PATH_MAX], tmp[PATH_MAX]; 411 if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { 412 printf("Error - unable to get current prefix!\n"); 413 return -1; 414 } 415 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 416 #endif 417 418 const char *rinval[][5] = { 419 {prgname, prefix, mp_flag, "-r", "error"}, 420 {prgname, prefix, mp_flag, "-r", "0"}, 421 {prgname, prefix, mp_flag, "-r", "-1"}, 422 {prgname, prefix, mp_flag, "-r", "17"}, 423 }; 424 /* Test with valid blocklist option */ 425 const char *rval[] = {prgname, prefix, mp_flag, "-r", "16"}; 426 427 int i; 428 429 for (i = 0; i != RTE_DIM(rinval); i++) { 430 if (launch_proc(rinval[i]) == 0) { 431 printf("Error - process did run ok with invalid " 432 "-r (rank) parameter\n"); 433 return -1; 434 } 435 } 436 if (launch_proc(rval) != 0) { 437 printf("Error - process did not run ok with valid -r (rank) value\n"); 438 return -1; 439 } 440 return 0; 441 } 442 443 /* 444 * Test that the app doesn't run without the coremask/corelist flags. In all cases 445 * should give an error and fail to run 446 */ 447 static int 448 test_missing_c_flag(void) 449 { 450 #ifdef RTE_EXEC_ENV_FREEBSD 451 /* BSD target doesn't support prefixes at this point */ 452 const char * prefix = ""; 453 #else 454 char prefix[PATH_MAX], tmp[PATH_MAX]; 455 if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { 456 printf("Error - unable to get current prefix!\n"); 457 return -1; 458 } 459 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 460 #endif 461 462 /* -c flag but no coremask value */ 463 const char *argv1[] = { prgname, prefix, mp_flag, "-c"}; 464 /* No -c, -l or --lcores flag at all */ 465 const char *argv2[] = { prgname, prefix, mp_flag}; 466 /* bad coremask value */ 467 const char *argv3[] = { prgname, prefix, mp_flag, 468 "-c", "error" }; 469 /* sanity check of tests - valid coremask value */ 470 const char *argv4[] = { prgname, prefix, mp_flag, 471 "-c", "1" }; 472 /* -l flag but no corelist value */ 473 const char *argv5[] = { prgname, prefix, mp_flag, 474 "-l"}; 475 const char *argv6[] = { prgname, prefix, mp_flag, 476 "-l", " " }; 477 /* bad corelist values */ 478 const char *argv7[] = { prgname, prefix, mp_flag, 479 "-l", "error" }; 480 const char *argv8[] = { prgname, prefix, mp_flag, 481 "-l", "1-" }; 482 const char *argv9[] = { prgname, prefix, mp_flag, 483 "-l", "1," }; 484 const char *argv10[] = { prgname, prefix, mp_flag, 485 "-l", "1#2" }; 486 /* core number is negative value */ 487 const char * const argv11[] = { prgname, prefix, mp_flag, 488 "-l", "-5" }; 489 const char * const argv12[] = { prgname, prefix, mp_flag, 490 "-l", "-5-7" }; 491 /* core number is maximum value */ 492 const char * const argv13[] = { prgname, prefix, mp_flag, 493 "-l", RTE_STR(RTE_MAX_LCORE) }; 494 const char * const argv14[] = { prgname, prefix, mp_flag, 495 "-l", "1-"RTE_STR(RTE_MAX_LCORE) }; 496 /* sanity check test - valid corelist value */ 497 const char * const argv15[] = { prgname, prefix, mp_flag, 498 "-l", "1-2,3" }; 499 500 /* --lcores flag but no lcores value */ 501 const char * const argv16[] = { prgname, prefix, mp_flag, 502 "--lcores" }; 503 const char * const argv17[] = { prgname, prefix, mp_flag, 504 "--lcores", " " }; 505 /* bad lcores value */ 506 const char * const argv18[] = { prgname, prefix, mp_flag, 507 "--lcores", "1-3-5" }; 508 const char * const argv19[] = { prgname, prefix, mp_flag, 509 "--lcores", "0-1,,2" }; 510 const char * const argv20[] = { prgname, prefix, mp_flag, 511 "--lcores", "0-,1" }; 512 const char * const argv21[] = { prgname, prefix, mp_flag, 513 "--lcores", "(0-,2-4)" }; 514 const char * const argv22[] = { prgname, prefix, mp_flag, 515 "--lcores", "(-1,2)" }; 516 const char * const argv23[] = { prgname, prefix, mp_flag, 517 "--lcores", "(2-4)@(2-4-6)" }; 518 const char * const argv24[] = { prgname, prefix, mp_flag, 519 "--lcores", "(a,2)" }; 520 const char * const argv25[] = { prgname, prefix, mp_flag, 521 "--lcores", "1-3@(1,3)" }; 522 const char * const argv26[] = { prgname, prefix, mp_flag, 523 "--lcores", "3@((1,3)" }; 524 const char * const argv27[] = { prgname, prefix, mp_flag, 525 "--lcores", "(4-7)=(1,3)" }; 526 const char * const argv28[] = { prgname, prefix, mp_flag, 527 "--lcores", "[4-7]@(1,3)" }; 528 /* sanity check of tests - valid lcores value */ 529 const char * const argv29[] = { prgname, prefix, mp_flag, 530 "--lcores", 531 "0-1,2@(5-7),(3-5)@(0,2),(0,6),7"}; 532 /* check an invalid cpu value >= CPU_SETSIZE */ 533 const char * const argv30[] = { prgname, prefix, mp_flag, 534 "--lcores", "3@" RTE_STR(CPU_SETSIZE) }; 535 536 if (launch_proc(argv2) != 0) { 537 printf("Error - " 538 "process did not run ok when missing -c flag\n"); 539 return -1; 540 } 541 542 if (launch_proc(argv1) == 0 543 || launch_proc(argv3) == 0) { 544 printf("Error - " 545 "process ran without error with invalid -c flag\n"); 546 return -1; 547 } 548 if (launch_proc(argv4) != 0) { 549 printf("Error - " 550 "process did not run ok with valid coremask value\n"); 551 return -1; 552 } 553 554 /* start -l test */ 555 if (launch_proc(argv5) == 0 556 || launch_proc(argv6) == 0 557 || launch_proc(argv7) == 0 558 || launch_proc(argv8) == 0 559 || launch_proc(argv9) == 0 560 || launch_proc(argv10) == 0 561 || launch_proc(argv11) == 0 562 || launch_proc(argv12) == 0 563 || launch_proc(argv13) == 0 564 || launch_proc(argv14) == 0) { 565 printf("Error - " 566 "process ran without error with invalid -l flag\n"); 567 return -1; 568 } 569 if (rte_lcore_is_enabled(0) && rte_lcore_is_enabled(1) && 570 rte_lcore_is_enabled(2) && rte_lcore_is_enabled(3) && 571 launch_proc(argv15) != 0) { 572 printf("Error - " 573 "process did not run ok with valid corelist value\n"); 574 return -1; 575 } 576 577 /* start --lcores tests */ 578 if (launch_proc(argv16) == 0 || launch_proc(argv17) == 0 || 579 launch_proc(argv18) == 0 || launch_proc(argv19) == 0 || 580 launch_proc(argv20) == 0 || launch_proc(argv21) == 0 || 581 launch_proc(argv22) == 0 || launch_proc(argv23) == 0 || 582 launch_proc(argv24) == 0 || launch_proc(argv25) == 0 || 583 launch_proc(argv26) == 0 || launch_proc(argv27) == 0 || 584 launch_proc(argv28) == 0 || launch_proc(argv30) == 0) { 585 printf("Error - " 586 "process ran without error with invalid --lcore flag\n"); 587 return -1; 588 } 589 590 if (rte_lcore_is_enabled(0) && rte_lcore_is_enabled(1) && 591 rte_lcore_is_enabled(2) && rte_lcore_is_enabled(3) && 592 rte_lcore_is_enabled(3) && rte_lcore_is_enabled(5) && 593 rte_lcore_is_enabled(4) && rte_lcore_is_enabled(7) && 594 launch_proc(argv29) != 0) { 595 printf("Error - " 596 "process did not run ok with valid corelist value\n"); 597 return -1; 598 } 599 600 return 0; 601 } 602 603 /* 604 * Test --main-lcore option with matching coremask 605 */ 606 static int 607 test_main_lcore_flag(void) 608 { 609 #ifdef RTE_EXEC_ENV_FREEBSD 610 /* BSD target doesn't support prefixes at this point */ 611 const char *prefix = ""; 612 #else 613 char prefix[PATH_MAX], tmp[PATH_MAX]; 614 if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { 615 printf("Error - unable to get current prefix!\n"); 616 return -1; 617 } 618 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 619 #endif 620 621 if (!rte_lcore_is_enabled(0) || !rte_lcore_is_enabled(1)) 622 return TEST_SKIPPED; 623 624 /* --main-lcore flag but no value */ 625 const char *argv1[] = { prgname, prefix, mp_flag, 626 "-c", "3", "--main-lcore"}; 627 /* --main-lcore flag with invalid value */ 628 const char *argv2[] = { prgname, prefix, mp_flag, 629 "-c", "3", "--main-lcore", "-1"}; 630 const char *argv3[] = { prgname, prefix, mp_flag, 631 "-c", "3", "--main-lcore", "X"}; 632 /* main lcore not in coremask */ 633 const char *argv4[] = { prgname, prefix, mp_flag, 634 "-c", "3", "--main-lcore", "2"}; 635 /* valid value */ 636 const char *argv5[] = { prgname, prefix, mp_flag, 637 "-c", "3", "--main-lcore", "1"}; 638 /* valid value set before coremask */ 639 const char *argv6[] = { prgname, prefix, mp_flag, 640 "--main-lcore", "1", "-c", "3"}; 641 642 if (launch_proc(argv1) == 0 643 || launch_proc(argv2) == 0 644 || launch_proc(argv3) == 0 645 || launch_proc(argv4) == 0) { 646 printf("Error - process ran without error with wrong --main-lcore\n"); 647 return -1; 648 } 649 if (launch_proc(argv5) != 0 650 || launch_proc(argv6) != 0) { 651 printf("Error - process did not run ok with valid --main-lcore\n"); 652 return -1; 653 } 654 return 0; 655 } 656 657 /* 658 * Test that the app doesn't run with invalid -n flag option. 659 * Final test ensures it does run with valid options as sanity check 660 * Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf 661 * flags. 662 */ 663 static int 664 test_invalid_n_flag(void) 665 { 666 #ifdef RTE_EXEC_ENV_FREEBSD 667 /* BSD target doesn't support prefixes at this point */ 668 const char * prefix = ""; 669 #else 670 char prefix[PATH_MAX], tmp[PATH_MAX]; 671 if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { 672 printf("Error - unable to get current prefix!\n"); 673 return -1; 674 } 675 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 676 #endif 677 678 /* -n flag but no value */ 679 const char *argv1[] = { prgname, prefix, no_huge, no_shconf, 680 "-n"}; 681 /* bad numeric value */ 682 const char *argv2[] = { prgname, prefix, no_huge, no_shconf, 683 "-n", "e" }; 684 /* zero is invalid */ 685 const char *argv3[] = { prgname, prefix, no_huge, no_shconf, 686 "-n", "0" }; 687 /* sanity test - check with good value */ 688 const char *argv4[] = { prgname, prefix, no_huge, no_shconf, 689 "-n", "2" }; 690 /* sanity test - check with no -n flag */ 691 const char *argv5[] = { prgname, prefix, no_huge, no_shconf}; 692 693 if (launch_proc(argv1) == 0 694 || launch_proc(argv2) == 0 695 || launch_proc(argv3) == 0) { 696 printf("Error - process ran without error when" 697 "invalid -n flag\n"); 698 return -1; 699 } 700 if (launch_proc(argv4) != 0) { 701 printf("Error - process did not run ok with valid num-channel value\n"); 702 return -1; 703 } 704 if (launch_proc(argv5) != 0) { 705 printf("Error - process did not run ok without -n flag\n"); 706 return -1; 707 } 708 709 return 0; 710 } 711 712 /* 713 * Test that the app runs with HPET, and without HPET 714 */ 715 static int 716 test_no_hpet_flag(void) 717 { 718 char prefix[PATH_MAX] = ""; 719 720 #ifdef RTE_EXEC_ENV_FREEBSD 721 return 0; 722 #else 723 char tmp[PATH_MAX]; 724 if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { 725 printf("Error - unable to get current prefix!\n"); 726 return -1; 727 } 728 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 729 #endif 730 731 /* With --no-hpet */ 732 const char *argv1[] = {prgname, prefix, mp_flag, no_hpet}; 733 /* Without --no-hpet */ 734 const char *argv2[] = {prgname, prefix, mp_flag}; 735 736 if (launch_proc(argv1) != 0) { 737 printf("Error - process did not run ok with --no-hpet flag\n"); 738 return -1; 739 } 740 if (launch_proc(argv2) != 0) { 741 printf("Error - process did not run ok without --no-hpet flag\n"); 742 return -1; 743 } 744 return 0; 745 } 746 747 /* 748 * Test that the app runs with --no-huge and doesn't run when --socket-mem are 749 * specified with --no-huge. 750 */ 751 static int 752 test_no_huge_flag(void) 753 { 754 #ifdef RTE_EXEC_ENV_FREEBSD 755 /* BSD target doesn't support prefixes at this point, and we also need to 756 * run another primary process here */ 757 const char * prefix = no_shconf; 758 #else 759 const char * prefix = "--file-prefix=nohuge"; 760 #endif 761 762 /* With --no-huge */ 763 const char *argv1[] = {prgname, prefix, no_huge}; 764 /* With --no-huge and -m */ 765 const char *argv2[] = {prgname, prefix, no_huge, 766 "-m", DEFAULT_MEM_SIZE}; 767 768 /* With --no-huge and --socket-mem */ 769 const char *argv3[] = {prgname, prefix, no_huge, 770 "--socket-mem=" DEFAULT_MEM_SIZE}; 771 /* With --no-huge, -m and --socket-mem */ 772 const char *argv4[] = {prgname, prefix, no_huge, 773 "-m", DEFAULT_MEM_SIZE, "--socket-mem=" DEFAULT_MEM_SIZE}; 774 if (launch_proc(argv1) != 0) { 775 printf("Error - process did not run ok with --no-huge flag\n"); 776 return -1; 777 } 778 if (launch_proc(argv2) != 0) { 779 printf("Error - process did not run ok with --no-huge and -m flags\n"); 780 return -1; 781 } 782 #ifdef RTE_EXEC_ENV_FREEBSD 783 /* BSD target does not support NUMA, hence no --socket-mem tests */ 784 return 0; 785 #endif 786 787 if (launch_proc(argv3) == 0) { 788 printf("Error - process run ok with --no-huge and --socket-mem " 789 "flags\n"); 790 return -1; 791 } 792 if (launch_proc(argv4) == 0) { 793 printf("Error - process run ok with --no-huge, -m and " 794 "--socket-mem flags\n"); 795 return -1; 796 } 797 return 0; 798 } 799 800 static int 801 test_misc_flags(void) 802 { 803 char hugepath[PATH_MAX] = {0}; 804 char hugepath_dir[PATH_MAX] = {0}; 805 char hugepath_dir2[PATH_MAX] = {0}; 806 char hugepath_dir3[PATH_MAX] = {0}; 807 #ifdef RTE_EXEC_ENV_FREEBSD 808 /* BSD target doesn't support prefixes at this point */ 809 const char * prefix = ""; 810 const char * nosh_prefix = ""; 811 #else 812 char prefix[PATH_MAX], tmp[PATH_MAX]; 813 const char * nosh_prefix = "--file-prefix=noshconf"; 814 FILE * hugedir_handle = NULL; 815 char line[PATH_MAX] = {0}; 816 unsigned i, isempty = 1; 817 818 if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { 819 printf("Error - unable to get current prefix!\n"); 820 return -1; 821 } 822 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 823 824 /* 825 * get first valid hugepage path 826 */ 827 828 /* get hugetlbfs mountpoints from /proc/mounts */ 829 hugedir_handle = fopen("/proc/mounts", "r"); 830 831 if (hugedir_handle == NULL) { 832 printf("Error opening /proc/mounts!\n"); 833 return -1; 834 } 835 836 /* read /proc/mounts */ 837 while (fgets(line, sizeof(line), hugedir_handle) != NULL) { 838 839 /* find first valid hugepath */ 840 if (get_hugepage_path(line, sizeof(line), hugepath, sizeof(hugepath))) 841 break; 842 } 843 844 fclose(hugedir_handle); 845 846 /* check if path is not empty */ 847 for (i = 0; i < sizeof(hugepath); i++) 848 if (hugepath[i] != '\0') 849 isempty = 0; 850 851 if (isempty) { 852 printf("No mounted hugepage dir found!\n"); 853 return -1; 854 } 855 #endif 856 857 snprintf(hugepath_dir, sizeof(hugepath_dir), "%s/dpdk.missing", hugepath); 858 snprintf(hugepath_dir2, sizeof(hugepath_dir2), "%s/dpdk.dir", hugepath); 859 860 if (mkdir(hugepath_dir2, 0700) != 0 && errno != EEXIST) { 861 printf("Error - failed to mkdir(%s)\n", hugepath_dir2); 862 return -1; 863 } 864 865 snprintf(hugepath_dir3, sizeof(hugepath_dir3), "%s/dpdk.dir/sub", hugepath); 866 867 if (mkdir(hugepath_dir3, 0700) != 0 && errno != EEXIST) { 868 printf("Error - failed to mkdir(%s)\n", hugepath_dir3); 869 goto fail; 870 } 871 872 /* check that some general flags don't prevent things from working. 873 * All cases, apart from the first, app should run. 874 * No further testing of output done. 875 */ 876 /* sanity check - failure with invalid option */ 877 const char *argv0[] = {prgname, prefix, mp_flag, "--invalid-opt"}; 878 879 /* With --no-pci */ 880 const char *argv1[] = {prgname, prefix, mp_flag, "--no-pci"}; 881 /* With -v */ 882 const char *argv2[] = {prgname, prefix, mp_flag, "-v"}; 883 /* With valid --syslog */ 884 const char *argv3[] = {prgname, prefix, mp_flag, 885 "--syslog", "syslog"}; 886 /* With empty --syslog (should fail) */ 887 const char *argv4[] = {prgname, prefix, mp_flag, "--syslog"}; 888 /* With invalid --syslog */ 889 const char *argv5[] = {prgname, prefix, mp_flag, "--syslog", "error"}; 890 /* With no-sh-conf, also use no-huge to ensure this test runs on BSD */ 891 const char *argv6[] = {prgname, "-m", DEFAULT_MEM_SIZE, 892 no_shconf, nosh_prefix, no_huge}; 893 894 /* With --huge-dir */ 895 const char *argv7[] = {prgname, "-m", DEFAULT_MEM_SIZE, 896 "--file-prefix=hugedir", "--huge-dir", hugepath}; 897 /* With empty --huge-dir (should fail) */ 898 const char *argv8[] = {prgname, "-m", DEFAULT_MEM_SIZE, 899 "--file-prefix=hugedir", "--huge-dir"}; 900 /* With invalid --huge-dir */ 901 const char *argv9[] = {prgname, "-m", DEFAULT_MEM_SIZE, 902 "--file-prefix=hugedir", "--huge-dir", "invalid"}; 903 /* With invalid --huge-dir sub-directory */ 904 const char *argv10[] = {prgname, "-m", DEFAULT_MEM_SIZE, 905 "--file-prefix=hugedir", "--huge-dir", hugepath_dir}; 906 /* With valid --huge-dir sub-directory */ 907 const char *argv11[] = {prgname, "-m", DEFAULT_MEM_SIZE, 908 "--file-prefix=hugedir", "--huge-dir", hugepath_dir2}; 909 /* Secondary process with invalid --huge-dir (should run as flag has no 910 * effect on secondary processes) */ 911 const char *argv12[] = {prgname, prefix, mp_flag, 912 "--huge-dir", "invalid"}; 913 914 /* try running with base-virtaddr param */ 915 const char *argv13[] = {prgname, "--file-prefix=virtaddr", 916 "--base-virtaddr=0x12345678"}; 917 918 /* try running with --vfio-intr INTx flag */ 919 const char *argv14[] = {prgname, "--file-prefix=intr", 920 "--vfio-intr=legacy"}; 921 922 /* try running with --vfio-intr MSI flag */ 923 const char *argv15[] = {prgname, "--file-prefix=intr", 924 "--vfio-intr=msi"}; 925 926 /* try running with --vfio-intr MSI-X flag */ 927 const char *argv16[] = {prgname, "--file-prefix=intr", 928 "--vfio-intr=msix"}; 929 930 /* try running with --vfio-intr invalid flag */ 931 const char *argv17[] = {prgname, "--file-prefix=intr", 932 "--vfio-intr=invalid"}; 933 934 /* With process type as auto-detect */ 935 const char * const argv18[] = {prgname, "--file-prefix=auto", 936 "--proc-type=auto"}; 937 938 /* With process type as auto-detect with no-shconf */ 939 const char * const argv19[] = {prgname, "--proc-type=auto", 940 no_shconf, nosh_prefix, no_huge}; 941 942 /* With process type as --create-uio-dev flag */ 943 const char * const argv20[] = {prgname, "--file-prefix=uiodev", 944 "--create-uio-dev"}; 945 946 /* run all tests also applicable to FreeBSD first */ 947 948 if (launch_proc(argv0) == 0) { 949 printf("Error - process ran ok with invalid flag\n"); 950 goto fail; 951 } 952 if (launch_proc(argv1) != 0) { 953 printf("Error - process did not run ok with --no-pci flag\n"); 954 goto fail; 955 } 956 if (launch_proc(argv2) != 0) { 957 printf("Error - process did not run ok with -v flag\n"); 958 goto fail; 959 } 960 if (launch_proc(argv6) != 0) { 961 printf("Error - process did not run ok with --no-shconf flag\n"); 962 goto fail; 963 } 964 965 #ifdef RTE_EXEC_ENV_FREEBSD 966 /* no more tests to be done on FreeBSD */ 967 return 0; 968 #endif 969 970 if (launch_proc(argv3) != 0) { 971 printf("Error - process did not run ok with --syslog flag\n"); 972 goto fail; 973 } 974 if (launch_proc(argv4) == 0) { 975 printf("Error - process run ok with empty --syslog flag\n"); 976 goto fail; 977 } 978 if (launch_proc(argv5) == 0) { 979 printf("Error - process run ok with invalid --syslog flag\n"); 980 goto fail; 981 } 982 if (launch_proc(argv7) != 0) { 983 printf("Error - process did not run ok with --huge-dir flag\n"); 984 goto fail; 985 } 986 if (launch_proc(argv8) == 0) { 987 printf("Error - process run ok with empty --huge-dir flag\n"); 988 goto fail; 989 } 990 if (launch_proc(argv9) == 0) { 991 printf("Error - process run ok with invalid --huge-dir flag\n"); 992 goto fail; 993 } 994 if (launch_proc(argv10) == 0) { 995 printf("Error - process run ok with invalid --huge-dir sub-dir flag\n"); 996 goto fail; 997 } 998 if (launch_proc(argv11) != 0) { 999 printf("Error - process did not run ok with --huge-dir subdir flag\n"); 1000 goto fail; 1001 } 1002 if (launch_proc(argv12) != 0) { 1003 printf("Error - secondary process did not run ok with invalid --huge-dir flag\n"); 1004 goto fail; 1005 } 1006 if (launch_proc(argv13) != 0) { 1007 printf("Error - process did not run ok with --base-virtaddr parameter\n"); 1008 goto fail; 1009 } 1010 if (launch_proc(argv14) != 0) { 1011 printf("Error - process did not run ok with " 1012 "--vfio-intr INTx parameter\n"); 1013 goto fail; 1014 } 1015 if (launch_proc(argv15) != 0) { 1016 printf("Error - process did not run ok with " 1017 "--vfio-intr MSI parameter\n"); 1018 goto fail; 1019 } 1020 if (launch_proc(argv16) != 0) { 1021 printf("Error - process did not run ok with " 1022 "--vfio-intr MSI-X parameter\n"); 1023 goto fail; 1024 } 1025 if (launch_proc(argv17) == 0) { 1026 printf("Error - process run ok with " 1027 "--vfio-intr invalid parameter\n"); 1028 goto fail; 1029 } 1030 if (launch_proc(argv18) != 0) { 1031 printf("Error - process did not run ok with " 1032 "--proc-type as auto parameter\n"); 1033 goto fail; 1034 } 1035 if (launch_proc(argv19) != 0) { 1036 printf("Error - process did not run ok with " 1037 "--proc-type and --no-shconf parameter\n"); 1038 goto fail; 1039 } 1040 if (launch_proc(argv20) != 0) { 1041 printf("Error - process did not run ok with " 1042 "--create-uio-dev parameter\n"); 1043 goto fail; 1044 } 1045 1046 rmdir(hugepath_dir3); 1047 rmdir(hugepath_dir2); 1048 return 0; 1049 1050 fail: 1051 rmdir(hugepath_dir3); 1052 rmdir(hugepath_dir2); 1053 return -1; 1054 } 1055 1056 static int 1057 test_file_prefix(void) 1058 { 1059 /* 1060 * 1. check if current process hugefiles are locked 1061 * 2. try to run secondary process without a corresponding primary process 1062 * (while failing to run, it will also remove any unused hugepage files) 1063 * 3. check if current process hugefiles are still in place and are locked 1064 * 4. run a primary process with memtest1 prefix in default and legacy 1065 * mem mode 1066 * 5. check if memtest1 hugefiles are created in case of legacy mem 1067 * mode, and deleted in case of default mem mode 1068 * 6. run a primary process with memtest2 prefix in default and legacy 1069 * mem modes 1070 * 7. check that memtest2 hugefiles are present in the hugedir after a 1071 * run in legacy mode, and not present at all after run in default 1072 * mem mode 1073 */ 1074 char prefix[PATH_MAX] = ""; 1075 1076 #ifdef RTE_EXEC_ENV_FREEBSD 1077 return 0; 1078 #else 1079 if (get_current_prefix(prefix, sizeof(prefix)) == NULL) { 1080 printf("Error - unable to get current prefix!\n"); 1081 return -1; 1082 } 1083 #endif 1084 1085 /* this should fail unless the test itself is run with "memtest" prefix */ 1086 const char *argv0[] = {prgname, mp_flag, "-m", 1087 DEFAULT_MEM_SIZE, "--file-prefix=" memtest }; 1088 1089 /* primary process with memtest1 and default mem mode */ 1090 const char *argv1[] = {prgname, "-m", 1091 DEFAULT_MEM_SIZE, "--file-prefix=" memtest1 }; 1092 1093 /* primary process with memtest1 and legacy mem mode */ 1094 const char *argv2[] = {prgname, "-m", 1095 DEFAULT_MEM_SIZE, "--file-prefix=" memtest1, 1096 "--legacy-mem" }; 1097 1098 /* primary process with memtest2 and legacy mem mode */ 1099 const char *argv3[] = {prgname, "-m", 1100 DEFAULT_MEM_SIZE, "--file-prefix=" memtest2, 1101 "--legacy-mem" }; 1102 1103 /* primary process with memtest2 and default mem mode */ 1104 const char *argv4[] = {prgname, "-m", 1105 DEFAULT_MEM_SIZE, "--file-prefix=" memtest2 }; 1106 1107 /* primary process with --in-memory mode */ 1108 const char * const argv5[] = {prgname, "-m", 1109 DEFAULT_MEM_SIZE, "--in-memory" }; 1110 1111 /* primary process with memtest1 and --in-memory mode */ 1112 const char * const argv6[] = {prgname, "-m", 1113 DEFAULT_MEM_SIZE, "--in-memory", 1114 "--file-prefix=" memtest1 }; 1115 1116 /* primary process with parent file-prefix and --in-memory mode */ 1117 const char * const argv7[] = {prgname, "-m", 1118 DEFAULT_MEM_SIZE, "--in-memory", "--file-prefix", prefix }; 1119 1120 /* primary process with memtest1 and --single-file-segments mode */ 1121 const char * const argv8[] = {prgname, "-m", 1122 DEFAULT_MEM_SIZE, "--single-file-segments", 1123 "--file-prefix=" memtest1 }; 1124 1125 /* check if files for current prefix are present */ 1126 if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) { 1127 printf("Error - hugepage files for %s were not created!\n", prefix); 1128 return -1; 1129 } 1130 1131 /* checks if files for current prefix are locked */ 1132 if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) { 1133 printf("Error - hugepages for current process aren't locked!\n"); 1134 return -1; 1135 } 1136 1137 /* check if files for secondary process are present */ 1138 if (process_hugefiles(memtest, HUGEPAGE_CHECK_EXISTS) == 1) { 1139 /* check if they are not locked */ 1140 if (process_hugefiles(memtest, HUGEPAGE_CHECK_LOCKED) == 1) { 1141 printf("Error - hugepages for current process are locked!\n"); 1142 return -1; 1143 } 1144 /* they aren't locked, delete them */ 1145 else { 1146 if (process_hugefiles(memtest, HUGEPAGE_DELETE) != 1) { 1147 printf("Error - deleting hugepages failed!\n"); 1148 return -1; 1149 } 1150 } 1151 } 1152 1153 if (launch_proc(argv0) == 0) { 1154 printf("Error - secondary process ran ok without primary process\n"); 1155 return -1; 1156 } 1157 1158 /* check if files for current prefix are present */ 1159 if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) { 1160 printf("Error - hugepage files for %s were not created!\n", prefix); 1161 return -1; 1162 } 1163 1164 /* checks if files for current prefix are locked */ 1165 if (process_hugefiles(prefix, HUGEPAGE_CHECK_LOCKED) != 1) { 1166 printf("Error - hugepages for current process aren't locked!\n"); 1167 return -1; 1168 } 1169 1170 /* we're running this process in default memory mode, which means it 1171 * should clean up after itself on exit and leave no hugepages behind. 1172 */ 1173 if (launch_proc(argv1) != 0) { 1174 printf("Error - failed to run with --file-prefix=%s\n", 1175 memtest1); 1176 return -1; 1177 } 1178 1179 /* check if memtest1_map0 is present */ 1180 if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) { 1181 printf("Error - hugepage files for %s were not deleted!\n", 1182 memtest1); 1183 return -1; 1184 } 1185 1186 /* now, we're running a process under the same prefix, but with legacy 1187 * mem mode - this should leave behind hugepage files. 1188 */ 1189 if (launch_proc(argv2) != 0) { 1190 printf("Error - failed to run with --file-prefix=%s\n", 1191 memtest1); 1192 return -1; 1193 } 1194 1195 /* check if memtest1_map0 is present */ 1196 if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 1) { 1197 printf("Error - hugepage files for %s were not created!\n", 1198 memtest1); 1199 return -1; 1200 } 1201 1202 if (launch_proc(argv3) != 0) { 1203 printf("Error - failed to run with --file-prefix=%s\n", 1204 memtest2); 1205 return -1; 1206 } 1207 1208 /* check if hugefiles for memtest2 are present */ 1209 if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 1) { 1210 printf("Error - hugepage files for %s were not created!\n", 1211 memtest2); 1212 return -1; 1213 } 1214 1215 /* check if hugefiles for memtest1 are present */ 1216 if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) { 1217 printf("Error - hugepage files for %s were not deleted!\n", 1218 memtest1); 1219 return -1; 1220 } 1221 1222 /* this process will run in default mem mode, so it should not leave any 1223 * hugepage files behind. 1224 */ 1225 if (launch_proc(argv4) != 0) { 1226 printf("Error - failed to run with --file-prefix=%s\n", 1227 memtest2); 1228 return -1; 1229 } 1230 1231 /* check if hugefiles for memtest2 are present */ 1232 if (process_hugefiles(memtest2, HUGEPAGE_CHECK_EXISTS) != 0) { 1233 printf("Error - hugepage files for %s were not deleted!\n", 1234 memtest2); 1235 return -1; 1236 } 1237 1238 /* check if hugefiles for memtest1 are present */ 1239 if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) { 1240 printf("Error - hugepage files for %s were not deleted!\n", 1241 memtest1); 1242 return -1; 1243 } 1244 1245 /* this process will run in --in-memory mode, so it should not leave any 1246 * hugepage files behind. 1247 */ 1248 1249 /* test case to check eal-options with --in-memory mode */ 1250 if (launch_proc(argv5) != 0) { 1251 printf("Error - failed to run with --in-memory mode\n"); 1252 return -1; 1253 } 1254 1255 /*test case to check eal-options with --in-memory mode with 1256 * custom file-prefix. 1257 */ 1258 if (launch_proc(argv6) != 0) { 1259 printf("Error - failed to run with --in-memory mode\n"); 1260 return -1; 1261 } 1262 1263 /* check if hugefiles for memtest1 are present */ 1264 if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) { 1265 printf("Error - hugepage files for %s were created and not deleted!\n", 1266 memtest1); 1267 return -1; 1268 } 1269 1270 /* test case to check eal-options with --in-memory mode with 1271 * parent file-prefix. 1272 */ 1273 if (launch_proc(argv7) != 0) { 1274 printf("Error - failed to run with --file-prefix=%s\n", prefix); 1275 return -1; 1276 } 1277 1278 /* this process will run in --single-file-segments mode, 1279 * so it should not leave any hugepage files behind. 1280 */ 1281 if (launch_proc(argv8) != 0) { 1282 printf("Error - failed to run with --single-file-segments mode\n"); 1283 return -1; 1284 } 1285 1286 /* check if hugefiles for memtest1 are present */ 1287 if (process_hugefiles(memtest1, HUGEPAGE_CHECK_EXISTS) != 0) { 1288 printf("Error - hugepage files for %s were not deleted!\n", 1289 memtest1); 1290 return -1; 1291 } 1292 1293 return 0; 1294 } 1295 1296 /* This function writes in passed buf pointer a valid --socket-mem= option 1297 * for num_sockets then concatenates the provided suffix string. 1298 * 1299 * Example for num_sockets 4, mem "2", suffix "plop" 1300 * --socket-mem=2,2,2,2plop 1301 */ 1302 static void 1303 populate_socket_mem_param(int num_sockets, const char *mem, 1304 const char *suffix, char *buf, size_t buf_size) 1305 { 1306 unsigned int offset = 0; 1307 int written; 1308 int i; 1309 1310 written = snprintf(&buf[offset], buf_size - offset, "--socket-mem="); 1311 if (written < 0 || written + offset >= buf_size) 1312 return; 1313 offset += written; 1314 1315 for (i = 0; i < num_sockets - 1; i++) { 1316 written = snprintf(&buf[offset], buf_size - offset, 1317 "%s,", mem); 1318 if (written < 0 || written + offset >= buf_size) 1319 return; 1320 offset += written; 1321 } 1322 1323 written = snprintf(&buf[offset], buf_size - offset, "%s%s", mem, 1324 suffix); 1325 if (written < 0 || written + offset >= buf_size) 1326 return; 1327 offset += written; 1328 } 1329 1330 /* 1331 * Tests for correct handling of -m and --socket-mem flags 1332 */ 1333 static int 1334 test_memory_flags(void) 1335 { 1336 #ifdef RTE_EXEC_ENV_FREEBSD 1337 /* BSD target doesn't support prefixes at this point */ 1338 const char * prefix = ""; 1339 #else 1340 char prefix[PATH_MAX], tmp[PATH_MAX]; 1341 if (get_current_prefix(tmp, sizeof(tmp)) == NULL) { 1342 printf("Error - unable to get current prefix!\n"); 1343 return -1; 1344 } 1345 snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp); 1346 #endif 1347 1348 /* valid -m flag and mp flag */ 1349 const char *argv0[] = {prgname, prefix, mp_flag, 1350 "-m", DEFAULT_MEM_SIZE}; 1351 1352 /* valid -m flag */ 1353 const char *argv1[] = {prgname, 1354 "--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE}; 1355 1356 /* valid (zero) --socket-mem flag */ 1357 char arg2_socket_mem[SOCKET_MEM_STRLEN]; 1358 const char *argv2[] = {prgname, 1359 "--file-prefix=" memtest, arg2_socket_mem}; 1360 1361 /* invalid (incomplete) --socket-mem flag */ 1362 char arg3_socket_mem[SOCKET_MEM_STRLEN]; 1363 const char *argv3[] = {prgname, 1364 "--file-prefix=" memtest, arg3_socket_mem}; 1365 1366 /* invalid (mixed with invalid data) --socket-mem flag */ 1367 char arg4_socket_mem[SOCKET_MEM_STRLEN]; 1368 const char *argv4[] = {prgname, 1369 "--file-prefix=" memtest, arg4_socket_mem}; 1370 1371 /* invalid (with numeric value as last character) --socket-mem flag */ 1372 char arg5_socket_mem[SOCKET_MEM_STRLEN]; 1373 const char *argv5[] = {prgname, 1374 "--file-prefix=" memtest, arg5_socket_mem}; 1375 1376 /* invalid (with empty socket) --socket-mem flag */ 1377 char arg6_socket_mem[SOCKET_MEM_STRLEN]; 1378 const char *argv6[] = {prgname, 1379 "--file-prefix=" memtest, arg6_socket_mem}; 1380 1381 /* invalid (null) --socket-mem flag */ 1382 const char *argv7[] = {prgname, 1383 "--file-prefix=" memtest, "--socket-mem="}; 1384 1385 /* valid --socket-mem specified together with -m flag */ 1386 char arg8_socket_mem[SOCKET_MEM_STRLEN]; 1387 const char *argv8[] = {prgname, 1388 "--file-prefix=" memtest, "-m", DEFAULT_MEM_SIZE, 1389 arg8_socket_mem}; 1390 1391 #ifdef RTE_EXEC_ENV_FREEBSD 1392 int num_sockets = 1; 1393 #else 1394 int num_sockets = RTE_MIN(get_number_of_sockets(), 1395 RTE_MAX_NUMA_NODES); 1396 #endif 1397 1398 if (num_sockets <= 0) { 1399 printf("Error - cannot get number of sockets!\n"); 1400 return -1; 1401 } 1402 1403 /* invalid --socket-mem flag (with extra socket) */ 1404 char invalid_socket_mem[SOCKET_MEM_STRLEN]; 1405 const char *argv9[] = {prgname, 1406 "--file-prefix=" memtest, invalid_socket_mem}; 1407 1408 /* valid --socket-mem flag */ 1409 char valid_socket_mem[SOCKET_MEM_STRLEN]; 1410 const char *argv10[] = {prgname, 1411 "--file-prefix=" memtest, valid_socket_mem}; 1412 1413 if (launch_proc(argv0) != 0) { 1414 printf("Error - secondary process failed with valid -m flag !\n"); 1415 return -1; 1416 } 1417 1418 #ifdef RTE_EXEC_ENV_FREEBSD 1419 /* no other tests are applicable to BSD */ 1420 return 0; 1421 #endif 1422 1423 if (launch_proc(argv1) != 0) { 1424 printf("Error - process failed with valid -m flag!\n"); 1425 return -1; 1426 } 1427 1428 populate_socket_mem_param(num_sockets, "0", "", 1429 arg2_socket_mem, sizeof(arg2_socket_mem)); 1430 if (launch_proc(argv2) != 0) { 1431 printf("Error - process failed with valid (zero) --socket-mem!\n"); 1432 return -1; 1433 } 1434 1435 if (num_sockets > 1) { 1436 populate_socket_mem_param(num_sockets - 1, "2", ",", 1437 arg3_socket_mem, sizeof(arg3_socket_mem)); 1438 if (launch_proc(argv3) == 0) { 1439 printf("Error - process run ok with invalid " 1440 "(incomplete) --socket-mem!\n"); 1441 return -1; 1442 } 1443 1444 populate_socket_mem_param(num_sockets - 1, "2", ",Fred", 1445 arg4_socket_mem, sizeof(arg4_socket_mem)); 1446 if (launch_proc(argv4) == 0) { 1447 printf("Error - process run ok with invalid " 1448 "(mixed with invalid input) --socket-mem!\n"); 1449 return -1; 1450 } 1451 1452 populate_socket_mem_param(num_sockets - 1, "2", ",Fred0", 1453 arg5_socket_mem, sizeof(arg5_socket_mem)); 1454 if (launch_proc(argv5) == 0) { 1455 printf("Error - process run ok with invalid " 1456 "(mixed with invalid input with a numeric value as " 1457 "last character) --socket-mem!\n"); 1458 return -1; 1459 } 1460 } 1461 1462 if (num_sockets > 2) { 1463 populate_socket_mem_param(num_sockets - 2, "2", ",,2", 1464 arg6_socket_mem, sizeof(arg6_socket_mem)); 1465 if (launch_proc(argv6) == 0) { 1466 printf("Error - process run ok with invalid " 1467 "(with empty socket) --socket-mem!\n"); 1468 return -1; 1469 } 1470 } 1471 1472 if (launch_proc(argv7) == 0) { 1473 printf("Error - process run ok with invalid (null) --socket-mem!\n"); 1474 return -1; 1475 } 1476 1477 populate_socket_mem_param(num_sockets, "2", "", 1478 arg8_socket_mem, sizeof(arg8_socket_mem)); 1479 if (launch_proc(argv8) == 0) { 1480 printf("Error - process run ok with --socket-mem and -m specified!\n"); 1481 return -1; 1482 } 1483 1484 populate_socket_mem_param(num_sockets + 1, "2", "", 1485 invalid_socket_mem, sizeof(invalid_socket_mem)); 1486 if (launch_proc(argv9) == 0) { 1487 printf("Error - process run ok with extra socket in --socket-mem!\n"); 1488 return -1; 1489 } 1490 1491 populate_socket_mem_param(num_sockets, "2", "", 1492 valid_socket_mem, sizeof(valid_socket_mem)); 1493 if (launch_proc(argv10) != 0) { 1494 printf("Error - process failed with valid --socket-mem!\n"); 1495 return -1; 1496 } 1497 1498 return 0; 1499 } 1500 1501 static int 1502 test_eal_flags(void) 1503 { 1504 int ret = 0; 1505 1506 ret = test_missing_c_flag(); 1507 if (ret < 0) { 1508 printf("Error in test_missing_c_flag()\n"); 1509 return ret; 1510 } 1511 1512 ret = test_main_lcore_flag(); 1513 if (ret < 0) { 1514 printf("Error in test_main_lcore_flag()\n"); 1515 return ret; 1516 } 1517 1518 ret = test_invalid_n_flag(); 1519 if (ret < 0) { 1520 printf("Error in test_invalid_n_flag()\n"); 1521 return ret; 1522 } 1523 1524 ret = test_no_hpet_flag(); 1525 if (ret < 0) { 1526 printf("Error in test_no_hpet_flag()\n"); 1527 return ret; 1528 } 1529 1530 ret = test_no_huge_flag(); 1531 if (ret < 0) { 1532 printf("Error in test_no_huge_flag()\n"); 1533 return ret; 1534 } 1535 1536 ret = test_allow_flag(); 1537 if (ret < 0) { 1538 printf("Error in test_allow_flag()\n"); 1539 return ret; 1540 } 1541 1542 ret = test_invalid_b_flag(); 1543 if (ret < 0) { 1544 printf("Error in test_invalid_b_flag()\n"); 1545 return ret; 1546 } 1547 1548 #ifdef RTE_NET_RING 1549 ret = test_invalid_vdev_flag(); 1550 if (ret < 0) { 1551 printf("Error in test_invalid_vdev_flag()\n"); 1552 return ret; 1553 } 1554 #endif 1555 ret = test_invalid_r_flag(); 1556 if (ret < 0) { 1557 printf("Error in test_invalid_r_flag()\n"); 1558 return ret; 1559 } 1560 1561 ret = test_memory_flags(); 1562 if (ret < 0) { 1563 printf("Error in test_memory_flags()\n"); 1564 return ret; 1565 } 1566 1567 ret = test_file_prefix(); 1568 if (ret < 0) { 1569 printf("Error in test_file_prefix()\n"); 1570 return ret; 1571 } 1572 1573 ret = test_misc_flags(); 1574 if (ret < 0) { 1575 printf("Error in test_misc_flags()"); 1576 return ret; 1577 } 1578 1579 return ret; 1580 } 1581 1582 REGISTER_TEST_COMMAND(eal_flags_autotest, test_eal_flags); 1583 1584 /* subtests used in meson for CI */ 1585 REGISTER_TEST_COMMAND(eal_flags_c_opt_autotest, test_missing_c_flag); 1586 REGISTER_TEST_COMMAND(eal_flags_main_opt_autotest, test_main_lcore_flag); 1587 REGISTER_TEST_COMMAND(eal_flags_n_opt_autotest, test_invalid_n_flag); 1588 REGISTER_TEST_COMMAND(eal_flags_hpet_autotest, test_no_hpet_flag); 1589 REGISTER_TEST_COMMAND(eal_flags_no_huge_autotest, test_no_huge_flag); 1590 REGISTER_TEST_COMMAND(eal_flags_a_opt_autotest, test_allow_flag); 1591 REGISTER_TEST_COMMAND(eal_flags_b_opt_autotest, test_invalid_b_flag); 1592 REGISTER_TEST_COMMAND(eal_flags_vdev_opt_autotest, test_invalid_vdev_flag); 1593 REGISTER_TEST_COMMAND(eal_flags_r_opt_autotest, test_invalid_r_flag); 1594 REGISTER_TEST_COMMAND(eal_flags_mem_autotest, test_memory_flags); 1595 REGISTER_TEST_COMMAND(eal_flags_file_prefix_autotest, test_file_prefix); 1596 REGISTER_TEST_COMMAND(eal_flags_misc_autotest, test_misc_flags); 1597