Esempio n. 1
0
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();
}
Esempio n. 2
0
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();
}
Esempio n. 3
0
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();

}
Esempio n. 4
0
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);
}
Esempio n. 5
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;
}