static void setup(void) { tst_require_root(NULL); uid = geteuid(); ncpus = tst_ncpus_max(); /* Current mask */ mask = CPU_ALLOC(ncpus); if (mask == NULL) tst_brkm(TBROK | TERRNO, cleanup, "CPU_ALLOC(%ld) failed", ncpus); mask_size = CPU_ALLOC_SIZE(ncpus); if (sched_getaffinity(0, mask_size, mask) < 0) tst_brkm(TBROK | TERRNO, cleanup, "sched_getaffinity() failed"); /* Mask with one more cpu than available on the system */ emask = CPU_ALLOC(ncpus + 1); if (emask == NULL) tst_brkm(TBROK | TERRNO, cleanup, "CPU_ALLOC(%ld) failed", ncpus + 1); emask_size = CPU_ALLOC_SIZE(ncpus + 1); CPU_ZERO_S(emask_size, emask); CPU_SET_S(ncpus, emask_size, emask); privileged_pid = tst_fork(); if (privileged_pid == 0) { pause(); exit(0); } else if (privileged_pid < 0) { tst_brkm(TBROK | TERRNO, cleanup, "fork() failed"); } /* Dropping the root privileges */ ltpuser = getpwnam(nobody_uid); if (ltpuser == NULL) tst_brkm(TBROK | TERRNO, cleanup, "getpwnam failed for user id %s", nobody_uid); SAFE_SETEUID(cleanup, ltpuser->pw_uid); /* this pid is not used by the OS */ free_pid = tst_get_unused_pid(cleanup); }
/* * Function: main - entry point of this program * * Description: Parses the arguments to each command. Most commands have in * common atlest 2 arguments, type of test result, which is one of * TPASS, TFAIL, TBROK, TCONF, etc, and a message that describes * the result. Other arguments are a file, the contents of which * are printed after the type of test result and associated message * is printed, also a cleanup function that will be executed. * Currently this function name is ignored but MUST be provided * for compatability reasons. * * The different commands are actually a hard link to this program * the program invokes the appropriate function based on the * command name with which it was invoked. * * Set the values for TCID to the name of the test case. * set the value for TST_TOTAL for total number of tests this is * required in case one test breaks and all following tests also * should be reported as broken. * Set Tst_count before every individual test. * * Exit: 0 on success * -1 on failure */ int main(int argc, char *argv[]) { int trestype; /* test result type TFAIL, TPASS, TINFO etc */ char *arg_fmt; /* message string printed along with test type */ char *cmd_name; /* name by which this program is invoked tst_brk etc */ char *tst_total; /* total number of tests in the file. */ char *tst_count; /* sets the value of Tst_count with this value */ char *file_name; /* contents of this file are printed; see tst_res() */ arg_fmt = SAFE_MALLOC(NULL, 1024); cmd_name = SAFE_MALLOC(NULL, 1024); strcpy(cmd_name, SAFE_BASENAME(NULL, (argv++)[0])); TCID = getenv("TCID"); tst_total = getenv("TST_TOTAL"); tst_count = getenv("TST_COUNT"); if (TCID == NULL || tst_total == NULL || tst_count == NULL) { if (strcmp(cmd_name, "tst_kvercmp") != 0) { fprintf(stderr, "\nSet variables TCID, TST_TOTAL, and TST_COUNT before each test:\n" "export TCID=<test name>\n" "export TST_TOTAL=<Total Number of Tests >\n" "export TST_COUNT=<Test case number>\n\n"); /* Make sure the user knows there's an error. */ abort(); } } else { TST_TOTAL = atoi(tst_total); Tst_count = atoi(tst_count); if (Tst_count > 0) Tst_count--; if (strcmp(TCID, " ") == 0) { fprintf(stderr, "Variable TCID not set, use: TCID=<test name>\n"); exit(1); } if (TST_TOTAL <= 0) { fprintf(stderr, "Variable TST_TOTAL is set to 0, must be " "greater than zero\n"); exit(1); } } if (strcmp(cmd_name, "tst_brk") == 0) { if (argc < 5) { fprintf(stderr, "Usage: %s TTYPE FNAME FUNC STRING\n" "\tTTYPE - Test Result Type; one of TFAIL, TBROK, TCONF, " "and TRETR.\n" "\tFNAME - Print contents of this file after the message\n" "\tFUNC - Cleanup function (ignored), but MUST be provided\n" "\tSTRING - Message explaining the test result\n", cmd_name); exit(1); } trestype = ident_ttype((argv++)[0]); file_name = (argv++)[0]; argv++; strcpy(arg_fmt, *argv); tst_brk(trestype, file_name, NULL, arg_fmt); } else if (strcmp(cmd_name, "tst_res") == 0) { if (argc < 4) { fprintf(stderr, "Usage: %s TTYPE FNAME STRING\n" "\tTTYPE - Test Result Type; one of TFAIL, TBROK, TCONF, " "and TRETR.\n" "\tFNAME - Print contents of this file after the message\n" "\tSTRING - Message explaining the test result\n", cmd_name); exit(1); } trestype = ident_ttype((argv++)[0]); file_name = (argv++)[0]; strcpy(arg_fmt, *argv); tst_res(trestype, file_name, arg_fmt); } else if (strcmp(cmd_name, "tst_brkm") == 0) { if (argc < 4) { fprintf(stderr, "Usage: %s TTYPE FUNC STRING\n" "\tTTYPE - Test Result Type; one of TFAIL, TBROK, TCONF, " "and TRETR.\n" "\tFUNC - Cleanup function (ignored), but MUST be provided\n" "\tSTRING - Message explaining the test result\n", cmd_name); exit(1); } trestype = ident_ttype((argv++)[0]); argv++; strcpy(arg_fmt, *argv); tst_brkm(trestype, NULL, arg_fmt); } else if (strcmp(cmd_name, "tst_resm") == 0) { if (argc < 3) { fprintf(stderr, "Usage: %s TTYPE STRING\n" "\tTTYPE - Test Result Type; one of TFAIL, TBROK, TCONF, " "and TRETR.\n" "\tSTRING - Message explaining the test result\n", cmd_name); exit(1); } trestype = ident_ttype((argv++)[0]); strcpy(arg_fmt, *argv); tst_resm(trestype, arg_fmt); } else if (strcmp(cmd_name, "tst_exit") == 0) { tst_exit(); } else if (strcmp(cmd_name, "tst_flush") == 0) { tst_flush(); } else if (strcmp(cmd_name, "tst_kvercmp") == 0) { int exit_value; if (argc < 4) { fprintf(stderr, "Usage: %s NUM NUM NUM\n" "Compares to the running kernel version.\n\n" "\tNUM - A positive integer.\n" "\tThe first NUM is the kernel VERSION\n" "\tThe second NUM is the kernel PATCHLEVEL\n" "\tThe third NUM is the kernel SUBLEVEL\n\n" "\tExit status is 0 if the running kernel is older than the\n" "\t\tkernel specified by NUM NUM NUM.\n" "\tExit status is 1 for kernels of the same age.\n" "\tExit status is 2 if the running kernel is newer.\n", cmd_name); exit(1); } exit_value = tst_kvercmp(atoi(argv[0]), atoi(argv[1]), atoi(argv[2])); if (exit_value < 0) exit_value = 0; else if (exit_value == 0) exit_value = 1; else if (exit_value > 0) exit_value = 2; exit(exit_value); } else if (strcmp(cmd_name, "tst_ncpus") == 0) { printf("%li\n", tst_ncpus()); } else if (strcmp(cmd_name, "tst_ncpus_max") == 0) { printf("%li\n", tst_ncpus_max()); } exit(0); }
/* * Function: main - entry point of this program * * Description: Parses the arguments to each command. Most commands have in * common atlest 2 arguments, type of test result, which is one of * TPASS, TFAIL, TBROK, TCONF, etc, and a message that describes * the result. Other arguments are a file, the contents of which * are printed after the type of test result and associated message * is printed, also a cleanup function that will be executed. * Currently this function name is ignored but MUST be provided * for compatability reasons. * * The different commands are actually a hard link to this program * the program invokes the appropriate function based on the * command name with which it was invoked. * * Set the values for TCID to the name of the test case. * set the value for TST_TOTAL for total number of tests this is * required in case one test breaks and all following tests also * should be reported as broken. * Set tst_count before every individual test. * * Exit: 0 on success * -1 on failure */ int main(int argc, char *argv[]) { strcpy(cmd_name, SAFE_BASENAME(NULL, (argv++)[0])); TCID = getenv("TCID"); tst_total = getenv("TST_TOTAL"); tst_cntstr = getenv("TST_COUNT"); if (TCID == NULL || tst_total == NULL || tst_cntstr == NULL) { if (!strcmp(cmd_name, "tst_kvercmp") && !strcmp(cmd_name, "tst_kvercmp2") && !strcmp(cmd_name, "tst_fs_has_free") && !strcmp(cmd_name, "tst_get_unused_port")) { fprintf(stderr, "\nSet variables TCID, TST_TOTAL, and TST_COUNT before each test:\n" "export TCID=<test name>\n" "export TST_TOTAL=<Total Number of Tests >\n" "export TST_COUNT=<Test case number>\n\n"); /* Make sure the user knows there's an error. */ abort(); } } else { TST_TOTAL = atoi(tst_total); tst_count = atoi(tst_cntstr); if (tst_count > 0) tst_count--; if (strcmp(TCID, " ") == 0) { fprintf(stderr, "Variable TCID not set, use: TCID=<test name>\n"); exit(1); } if (TST_TOTAL <= 0) { fprintf(stderr, "Variable TST_TOTAL is set to 0, must be " "greater than zero\n"); exit(1); } } if (strcmp(cmd_name, "tst_brk") == 0) { apicmd_brk(argc, argv); } else if (strcmp(cmd_name, "tst_res") == 0) { apicmd_res(argc, argv); } else if (strcmp(cmd_name, "tst_brkm") == 0) { apicmd_brkm(argc, argv); } else if (strcmp(cmd_name, "tst_resm") == 0) { apicmd_resm(argc, argv); } else if (strcmp(cmd_name, "tst_exit") == 0) { tst_exit(); } else if (strcmp(cmd_name, "tst_flush") == 0) { tst_flush(); } else if (strcmp(cmd_name, "tst_kvercmp") == 0) { apicmd_kvercmp(argc, argv); } else if (strcmp(cmd_name, "tst_kvercmp2") == 0) { apicmd_kvercmp2(argc, argv); } else if (strcmp(cmd_name, "tst_ncpus") == 0) { printf("%li\n", tst_ncpus()); } else if (strcmp(cmd_name, "tst_ncpus_conf") == 0) { printf("%li\n", tst_ncpus_conf()); } else if (strcmp(cmd_name, "tst_ncpus_max") == 0) { printf("%li\n", tst_ncpus_max()); } else if (strcmp(cmd_name, "tst_get_unused_port") == 0) { printf("%u\n", apicmd_get_unused_port(argc, argv)); } else if (strcmp(cmd_name, "tst_fs_has_free") == 0) { apicmd_fs_has_free(argc, argv); } exit(0); }