int main(int ac, char **av) { int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ int new_val = 2; int pid_max = get_pid_max(); /* parse standard options */ if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); /* global setup */ /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; /* * Try to access an invalid process. * This should give an ESRCH error. */ /* call the system call with the TEST() macro */ TEST(setpriority(PRIO_PROCESS, pid_max + 1, new_val)); if (TEST_RETURN == 0) { tst_resm(TFAIL, "call failed to produce expected error " "- errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO)); continue; } TEST_ERROR_LOG(TEST_ERRNO); switch (TEST_ERRNO) { case ESRCH: tst_resm(TPASS, "expected failure - errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO)); break; default: tst_resm(TFAIL, "call failed to produce expected error " "- errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO)); } } cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; char *msg; pid_t epid = get_pid_max() + 1; int status = 1; struct rusage rusage; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { Tst_count = 0; TEST(wait4(epid, &status, 0, &rusage)); if (TEST_RETURN == 0) { tst_brkm(TFAIL, cleanup, "call failed to produce expected error - errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO)); } switch (TEST_ERRNO) { case ECHILD: tst_resm(TPASS, "received expected failure - errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO)); break; default: tst_brkm(TFAIL, cleanup, "call failed to produce expected " "error - errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO)); } } cleanup(); tst_exit(); }
int main(int ac, char **av) { int lc; char *msg; pid_t pid; pid_t epid = get_pid_max() + 1; int status = 1; struct rusage *rusage = NULL; if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); /* global setup */ /* The following loop checks looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; /* * Allocate some space for the rusage structure. */ if ((rusage = (struct rusage *)malloc(sizeof(struct rusage))) == NULL) { tst_brkm(TBROK, cleanup, "malloc() failed"); } pid = FORK_OR_VFORK(); if (pid == -1) { tst_brkm(TBROK, cleanup, "fork() failed"); } if (pid == 0) { /* this is the child */ /* * sleep for a moment to let us do the test */ sleep(2); exit(0); } else { /* this is the parent */ /* * call wait4 with the TEST() macro. epid is set * to an illegal positive value. This should give * an ECHILD error. */ TEST(wait4(epid, &status, 0, rusage)); } if (TEST_RETURN == 0) { tst_brkm(TFAIL, cleanup, "call failed to produce expected error - errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO)); } TEST_ERROR_LOG(TEST_ERRNO); switch (TEST_ERRNO) { case ECHILD: tst_resm(TPASS, "received expected failure - errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO)); break; default: tst_brkm(TFAIL, cleanup, "call failed to produce expected " "error - errno = %d - %s", TEST_ERRNO, strerror(TEST_ERRNO)); } /* * Clean up things in case we are looping. */ free(rusage); rusage = NULL; } cleanup(); tst_exit(); }
int main(int argc, char **argv) { //argument variables const char *exe = NULL; int perclimit = 0; int exe_ok = 0; int pid_ok = 0; int limit_ok = 0; pid_t pid = 0; int include_children = 0; //get program name char *p = (char*)memrchr(argv[0], (unsigned int)'/', strlen(argv[0])); program_name = p==NULL ? argv[0] : (p+1); //get current pid cpulimit_pid = getpid(); //get cpu count NCPU = get_ncpu(); //parse arguments int next_option; int option_index = 0; //A string listing valid short options letters const char* short_options = "+p:e:l:vzih"; //An array describing valid long options const struct option long_options[] = { { "pid", required_argument, NULL, 'p' }, { "exe", required_argument, NULL, 'e' }, { "limit", required_argument, NULL, 'l' }, { "verbose", no_argument, NULL, 'v' }, { "lazy", no_argument, NULL, 'z' }, { "include-children", no_argument, NULL, 'i' }, { "help", no_argument, NULL, 'h' }, { 0, 0, 0, 0 } }; do { next_option = getopt_long(argc, argv, short_options,long_options, &option_index); switch(next_option) { case 'p': pid = atoi(optarg); pid_ok = 1; break; case 'e': exe = optarg; exe_ok = 1; break; case 'l': perclimit = atoi(optarg); limit_ok = 1; break; case 'v': verbose = 1; break; case 'z': lazy = 1; break; case 'i': include_children = 1; break; case 'h': print_usage(stdout, 1); break; case '?': print_usage(stderr, 1); break; case -1: break; default: abort(); } } while(next_option != -1); if (pid_ok && (pid <= 1 || pid >= get_pid_max())) { fprintf(stderr,"Error: Invalid value for argument PID\n"); print_usage(stderr, 1); exit(1); } if (pid != 0) { lazy = 1; } if (!limit_ok) { fprintf(stderr,"Error: You must specify a cpu limit percentage\n"); print_usage(stderr, 1); exit(1); } double limit = perclimit / 100.0; if (limit<0 || limit >NCPU) { fprintf(stderr,"Error: limit must be in the range 0-%d00\n", NCPU); print_usage(stderr, 1); exit(1); } int command_mode = optind < argc; if (exe_ok + pid_ok + command_mode == 0) { fprintf(stderr,"Error: You must specify one target process, either by name, pid, or command line\n"); print_usage(stderr, 1); exit(1); } if (exe_ok + pid_ok + command_mode > 1) { fprintf(stderr,"Error: You must specify exactly one target process, either by name, pid, or command line\n"); print_usage(stderr, 1); exit(1); } //all arguments are ok! signal(SIGINT, quit); signal(SIGTERM, quit); //print the number of available cpu if (verbose) printf("%d cpu detected\n", NCPU); if (command_mode) { int i; //executable file const char *cmd = argv[optind]; //command line arguments char **cmd_args = (char**)malloc((argc-optind + 1) * sizeof(char*)); if (cmd_args==NULL) exit(2); for (i=0; i<argc-optind; i++) { cmd_args[i] = argv[i+optind]; } cmd_args[i] = NULL; if (verbose) { printf("Running command: '%s", cmd); for (i=1; i<argc-optind; i++) { printf(" %s", cmd_args[i]); } printf("'\n"); } int child = fork(); if (child < 0) { exit(EXIT_FAILURE); } else if (child == 0) { //target process code int ret = execvp(cmd, cmd_args); //if we are here there was an error, show it perror("Error"); exit(ret); } else { //parent code free(cmd_args); int limiter = fork(); if (limiter < 0) { exit(EXIT_FAILURE); } else if (limiter > 0) { //parent int status_process; int status_limiter; waitpid(child, &status_process, 0); waitpid(limiter, &status_limiter, 0); if (WIFEXITED(status_process)) { if (verbose) printf("Process %d terminated with exit status %d\n", child, (int)WEXITSTATUS(status_process)); exit(WEXITSTATUS(status_process)); } printf("Process %d terminated abnormally\n", child); exit(status_process); } else { //limiter code if (verbose) printf("Limiting process %d\n",child); limit_process(child, limit, include_children); exit(0); } } } while(1) { //look for the target process..or wait for it pid_t ret = 0; if (pid_ok) { //search by pid ret = find_process_by_pid(pid); if (ret == 0) { printf("No process found\n"); } else if (ret < 0) { printf("Process found but you aren't allowed to control it\n"); } } else { //search by file or path name ret = find_process_by_name(exe); if (ret == 0) { printf("No process found\n"); } else if (ret < 0) { printf("Process found but you aren't allowed to control it\n"); } else { pid = ret; } } if (ret > 0) { if (ret == cpulimit_pid) { printf("Target process %d is cpulimit itself! Aborting because it makes no sense\n", ret); exit(1); } printf("Process %d found\n", pid); //control limit_process(pid, limit, include_children); } if (lazy) break; sleep(2); }; exit(0); }
int main(int argc, char* argv[]) { int c, ret = -1; char* log_file = NULL; char* cpu_mask = NULL; int rc, mode = 0, tid; while ((c = getopt(argc, argv, "c:l:m:")) != -1) { switch(c) { case 'l' : log_file = strdup(optarg); break; case 'c' : cpu_mask = strdup(optarg); break; case 'm' : if (strcmp(optarg, "1") == 0) mode = 1; else if (strcmp(optarg, "2") == 0) mode = 2; else if (strcmp(optarg, "3") == 0) mode = 3; break; default : fprintf(stderr, "unknown option %c\n", c); exit(-1); } } /* * checking an dealing with input parameters */ if (log_file) { if (!(f = fopen(log_file, "w"))) { fprintf(stderr, "cannot open file\n"); goto out; } } else { f = stdout; } if (!mode) { ERROR("must specify mode\n"); goto out; } if (!cpu_mask) { ERROR("need to specify CPU type\n"); goto out; } /* * setting up system stuff */ if ((pid_max = get_pid_max()) < 0) { ERROR("unable to get pid_max\n"); goto out; } PRINTF("pid_max is %d\n", pid_max); signal(SIGINT, sig_int_cb); if ((nl_sd = create_nl_socket(NETLINK_GENERIC)) < 0) { ERROR("error creating Netlink socket\n"); goto out; } /* * register taskstats notifier */ fam_id = __get_family_id(nl_sd); if (!fam_id) { ERROR("Error getting family id, errno %d\n", errno); goto out; } my_pid = getpid(); if ((rc = send_cmd(TASKSTATS_CMD_GET, TASKSTATS_CMD_ATTR_REGISTER_CPUMASK, cpu_mask, strlen(cpu_mask))) < 0) { ERROR("error sending register cpumask\n"); goto out; } /* * now for the main loop * modes of operations * i) get all process stats and print * ii) wait until receive signal (be polling for dead process in meantime) * then get all process stats * iii) get all process stats, then wait for signal and print diff */ if (mode == 1) { fill_infos(infos1); for (tid = 0; tid < pid_max; tid++) { if (!infos1[tid]) continue; print_taskstats(&infos1[tid]->t); } } else if (mode == 2) { PRINTF("waiting for signal\n"); while (!sig_int) sleep(1); fill_infos(infos1); for (tid = 0; tid < pid_max; tid++) { if (!infos1[tid]) continue; print_taskstats(&infos1[tid]->t); } } else if (mode == 3) { struct timeval start_since_epoch; struct timespec start, end; static struct taskstats ts_tot = {0}; if (fill_infos(infos1) < 0) { ERROR("error before start\n"); goto out; } if (clock_gettime(CLOCK_MONOTONIC, &start) < 0) { ERROR("unable to get start time\n"); goto out; } if (gettimeofday(&start_since_epoch, NULL)) { ERROR("unable to get start time since epoch\n"); goto out; } PRINTF("waiting for signal\n"); while (!sig_int) { ret = recv_taskstats(MSG_DONTWAIT, infos2); if (ret == 0 || ret == -EAGAIN) { usleep(10000); continue; } ERROR("unable to recv taskstats, %d\n", ret); goto out; } if (fill_infos(infos2) < 0) { ERROR("error at end\n"); goto out; } if (clock_gettime(CLOCK_MONOTONIC, &end) < 0) { ERROR("unable to get end time\n"); goto out; } PRINTF("--- task dump start ---\n"); for (tid = 0; tid < pid_max; tid++) { struct proc_info* p1 = infos1[tid]; struct proc_info* p2 = infos2[tid]; if (!(p1 || p2)) continue; else if (p1 && p2) { static struct taskstats ts; diff_taskstats(&ts, &p2->t, &p1->t); print_taskstats(&ts); } else if (p2) { print_taskstats(&p2->t); } } PRINTF("--- task dump end ---\n"); PRINTF("Start since epoch (s) %d\n", start_since_epoch.tv_sec); PRINTF("Elapsed time (ns) %llu\n", ((long long)end.tv_sec - start.tv_sec) * 1000000000LL + end.tv_nsec - start.tv_nsec); } out : if (f != stdout) fclose(f); return ret; }