Ejemplo n.º 1
0
int chrt_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
	pid_t pid = 0;
	unsigned opt;
	struct sched_param sp;
	char *pid_str;
	char *priority = priority; /* for compiler */
	const char *current_new;
	int policy = SCHED_RR;

	/* at least 1 arg; only one policy accepted */
	opt_complementary = "-1:r--fo:f--ro:r--fo";
	opt = getopt32(argv, "+mprfo");
	if (opt & OPT_r)
		policy = SCHED_RR;
	if (opt & OPT_f)
		policy = SCHED_FIFO;
	if (opt & OPT_o)
		policy = SCHED_OTHER;
	if (opt & OPT_m) { /* print min/max */
		show_min_max(SCHED_FIFO);
		show_min_max(SCHED_RR);
		show_min_max(SCHED_OTHER);
		fflush_stdout_and_exit(EXIT_SUCCESS);
	}

	argv += optind; 
	if (opt & OPT_p) {
		pid_str = *argv++;
		if (*argv) { /* "-p <priority> <pid> [...]" */
			priority = pid_str;
			pid_str = *argv;
		}
		/* else "-p <pid>", and *argv == NULL */
		pid = xatoul_range(pid_str, 1, ((unsigned)(pid_t)ULONG_MAX) >> 1);
	} else {
Ejemplo n.º 2
0
int chrt_main(int argc, char **argv)
{
	pid_t pid = 0;
	unsigned opt;
	struct sched_param sp;
	char *p_opt = NULL, *priority = NULL;
	const char *state = "current\0new";
	int prio = 0, policy = SCHED_RR;

	opt_complementary = "r--fo:f--ro:r--fo"; /* only one policy accepted */
	opt = getopt32(argv, "+mp:rfo", &p_opt);
	if (opt & OPT_r)
		policy = SCHED_RR;
	if (opt & OPT_f)
		policy = SCHED_FIFO;
	if (opt & OPT_o)
		policy = SCHED_OTHER;

	if (opt & OPT_m) { /* print min/max */
		show_min_max(SCHED_FIFO);
		show_min_max(SCHED_RR);
		show_min_max(SCHED_OTHER);
		fflush_stdout_and_exit(EXIT_SUCCESS);
	}
	if (opt & OPT_p) {
		if (argc == optind+1) { /* -p <priority> <pid> */
			priority = p_opt;
			p_opt = argv[optind];
		}
		argv += optind; /* me -p <arg> */
		pid = xatoul_range(p_opt, 1, ULONG_MAX); /* -p <pid> */
	} else {
		argv += optind; /* me -p <arg> */
		priority = *argv;
	}
	if (priority) {
		/* from the manpage of sched_getscheduler:
		   [...] sched_priority can have a value
		   in the range 0 to 99.
		   [...] SCHED_OTHER or SCHED_BATCH  must  be  assigned
		   the  static  priority  0. [...] SCHED_FIFO  or
		   SCHED_RR can have a static priority in the range 1 to 99.
		 */
		prio = xstrtol_range(priority, 0, policy == SCHED_OTHER
													 ? 0 : 1, 99);
	}

	if (opt & OPT_p) {
		int pol = 0;
print_rt_info:
		pol = sched_getscheduler(pid);
		if (pol < 0)
			bb_perror_msg_and_die("failed to %cet pid %d's policy", 'g', pid);
		printf("pid %d's %s scheduling policy: %s\n",
				pid, state, policies[pol].name);
		if (sched_getparam(pid, &sp))
			bb_perror_msg_and_die("failed to get pid %d's attributes", pid);
		printf("pid %d's %s scheduling priority: %d\n",
				pid, state, sp.sched_priority);
		if (!*argv) /* no new prio given or we did print already, done. */
			return EXIT_SUCCESS;
	}

	sp.sched_priority = prio;
	if (sched_setscheduler(pid, policy, &sp) < 0)
		bb_perror_msg_and_die("failed to %cet pid %d's policy", 's', pid);
	if (opt & OPT_p) {
		state += 8;
		++argv;
		goto print_rt_info;
	}
	++argv;
	BB_EXECVP(*argv, argv);
	bb_simple_perror_msg_and_die(*argv);
}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
	int i, policy = SCHED_RR, priority = 0, verbose = 0, policy_flag = 0,
	    all_tasks = 0;
	struct sched_param sp;
	pid_t pid = -1;

	static const struct option longopts[] = {
		{ "all-tasks",  0, NULL, 'a' },
		{ "batch",	0, NULL, 'b' },
		{ "fifo",	0, NULL, 'f' },
		{ "idle",	0, NULL, 'i' },
		{ "pid",	0, NULL, 'p' },
		{ "help",	0, NULL, 'h' },
		{ "max",        0, NULL, 'm' },
		{ "other",	0, NULL, 'o' },
		{ "rr",		0, NULL, 'r' },
		{ "reset-on-fork", 0, NULL, 'R' },
		{ "verbose",	0, NULL, 'v' },
		{ "version",	0, NULL, 'V' },
		{ NULL,		0, NULL, 0 }
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	while((i = getopt_long(argc, argv, "+abfiphmoRrvV", longopts, NULL)) != -1)
	{
		int ret = EXIT_FAILURE;

		switch (i) {
		case 'a':
			all_tasks = 1;
			break;
		case 'b':
#ifdef SCHED_BATCH
			policy = SCHED_BATCH;
#endif
			break;
		case 'f':
			policy = SCHED_FIFO;
			break;
		case 'R':
#ifdef SCHED_RESET_ON_FORK
			policy_flag |= SCHED_RESET_ON_FORK;
#endif
			break;
		case 'i':
#ifdef SCHED_IDLE
			policy = SCHED_IDLE;
#endif
			break;
		case 'm':
			show_min_max();
			return EXIT_SUCCESS;
		case 'o':
			policy = SCHED_OTHER;
			break;
		case 'p':
			errno = 0;
			pid = strtol_or_err(argv[argc - 1], _("failed to parse pid"));
			break;
		case 'r':
			policy = SCHED_RR;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'V':
			printf("%s from %s\n", program_invocation_short_name,
					       PACKAGE_STRING);
			return EXIT_SUCCESS;
		case 'h':
			ret = EXIT_SUCCESS;
			/* fallthrough */
		default:
			show_usage(ret);
		}
	}

	if (((pid > -1) && argc - optind < 1) ||
	    ((pid == -1) && argc - optind < 2))
		show_usage(EXIT_FAILURE);

	if ((pid > -1) && (verbose || argc - optind == 1)) {
		if (all_tasks) {
			pid_t tid;
			struct proc_tasks *ts = proc_open_tasks(pid);

			if (!ts)
				err(EXIT_FAILURE, _("cannot obtain the list of tasks"));
			while (!proc_next_tid(ts, &tid))
				show_rt_info(tid, FALSE);
			proc_close_tasks(ts);
		} else
			show_rt_info(pid, FALSE);

		if (argc - optind == 1)
			return EXIT_SUCCESS;
	}

	errno = 0;
	priority = strtol_or_err(argv[optind], _("failed to parse priority"));

#ifdef SCHED_RESET_ON_FORK
	/* sanity check */
	if ((policy_flag & SCHED_RESET_ON_FORK) &&
	    !(policy == SCHED_FIFO || policy == SCHED_RR))
		errx(EXIT_FAILURE, _("SCHED_RESET_ON_FORK flag is suppoted for "
				     "SCHED_FIFO and SCHED_RR policies only"));
#endif

	policy |= policy_flag;

	if (pid == -1)
		pid = 0;
	sp.sched_priority = priority;

	if (all_tasks) {
		pid_t tid;
		struct proc_tasks *ts = proc_open_tasks(pid);

		if (!ts)
			err(EXIT_FAILURE, _("cannot obtain the list of tasks"));
		while (!proc_next_tid(ts, &tid))
			if (sched_setscheduler(tid, policy, &sp) == -1)
				err(EXIT_FAILURE, _("failed to set tid %d's policy"), tid);
		proc_close_tasks(ts);
	} else if (sched_setscheduler(pid, policy, &sp) == -1)
		err(EXIT_FAILURE, _("failed to set pid %d's policy"), pid);

	if (verbose)
		show_rt_info(pid, TRUE);

	if (!pid) {
		argv += optind + 1;
		execvp(argv[0], argv);
		perror("execvp");
		err(EXIT_FAILURE, _("failed to execute %s"), argv[0]);
	}

	return EXIT_SUCCESS;
}
Ejemplo n.º 4
0
static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
{
	struct sched_param sp = { .sched_priority = ctl->priority };
	int policy = ctl->policy;

# ifdef SCHED_RESET_ON_FORK
	if (ctl->reset_on_fork)
		policy |= SCHED_RESET_ON_FORK;
# endif
	return sched_setscheduler(pid, policy, &sp);
}

#else /* !HAVE_SCHED_SETATTR */
static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
{
	/* use main() to check if the setting makes sense */
	struct sched_attr sa = {
		.size		= sizeof(struct sched_attr),
		.sched_policy	= ctl->policy,
		.sched_priority	= ctl->priority,
		.sched_runtime  = ctl->runtime,
		.sched_period   = ctl->period,
		.sched_deadline = ctl->deadline
	};
# ifdef SCHED_RESET_ON_FORK
	if (ctl->reset_on_fork)
		sa.sched_flags |= SCHED_RESET_ON_FORK;
# endif
	return sched_setattr(pid, &sa, 0);
}
#endif /* HAVE_SCHED_SETATTR */

static void set_sched(struct chrt_ctl *ctl)
{
	if (ctl->all_tasks) {
		pid_t tid;
		struct proc_tasks *ts = proc_open_tasks(ctl->pid);

		if (!ts)
			err(EXIT_FAILURE, _("cannot obtain the list of tasks"));

		while (!proc_next_tid(ts, &tid))
			if (set_sched_one(ctl, tid) == -1)
				err(EXIT_FAILURE, _("failed to set tid %d's policy"), tid);

		proc_close_tasks(ts);

	} else if (set_sched_one(ctl, ctl->pid) == -1)
		err(EXIT_FAILURE, _("failed to set pid %d's policy"), ctl->pid);

	ctl->altered = 1;
}

int main(int argc, char **argv)
{
	struct chrt_ctl _ctl = { .pid = -1 }, *ctl = &_ctl;
	int c;

	static const struct option longopts[] = {
		{ "all-tasks",  no_argument, NULL, 'a' },
		{ "batch",	no_argument, NULL, 'b' },
		{ "deadline",   no_argument, NULL, 'd' },
		{ "fifo",	no_argument, NULL, 'f' },
		{ "idle",	no_argument, NULL, 'i' },
		{ "pid",	no_argument, NULL, 'p' },
		{ "help",	no_argument, NULL, 'h' },
		{ "max",        no_argument, NULL, 'm' },
		{ "other",	no_argument, NULL, 'o' },
		{ "rr",		no_argument, NULL, 'r' },
		{ "sched-runtime",  required_argument, NULL, 'T' },
		{ "sched-period",   required_argument, NULL, 'P' },
		{ "sched-deadline", required_argument, NULL, 'D' },
		{ "reset-on-fork",  no_argument,       NULL, 'R' },
		{ "verbose",	no_argument, NULL, 'v' },
		{ "version",	no_argument, NULL, 'V' },
		{ NULL,		no_argument, NULL, 0 }
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	while((c = getopt_long(argc, argv, "+abdDfiphmoPTrRvV", longopts, NULL)) != -1)
	{
		int ret = EXIT_FAILURE;

		switch (c) {
		case 'a':
			ctl->all_tasks = 1;
			break;
		case 'b':
#ifdef SCHED_BATCH
			ctl->policy = SCHED_BATCH;
#endif
			break;

		case 'd':
#ifdef SCHED_DEADLINE
			ctl->policy = SCHED_DEADLINE;
#endif
			break;
		case 'f':
			ctl->policy = SCHED_FIFO;
			break;
		case 'R':
			ctl->reset_on_fork = 1;
			break;
		case 'i':
#ifdef SCHED_IDLE
			ctl->policy = SCHED_IDLE;
#endif
			break;
		case 'm':
			show_min_max();
			return EXIT_SUCCESS;
		case 'o':
			ctl->policy = SCHED_OTHER;
			break;
		case 'p':
			errno = 0;
			ctl->pid = strtos32_or_err(argv[argc - 1], _("invalid PID argument"));
			break;
		case 'r':
			ctl->policy = SCHED_RR;
			break;
		case 'v':
			ctl->verbose = 1;
			break;
		case 'T':
			ctl->runtime = strtou64_or_err(optarg, _("invalid runtime argument"));
			break;
		case 'P':
			ctl->period = strtou64_or_err(optarg, _("invalid period argument"));
			break;
		case 'D':
			ctl->deadline = strtou64_or_err(optarg, _("invalid deadline argument"));
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case 'h':
			ret = EXIT_SUCCESS;
			/* fallthrough */
		default:
			show_usage(ret);
		}
	}

	if (((ctl->pid > -1) && argc - optind < 1) ||
	    ((ctl->pid == -1) && argc - optind < 2))
		show_usage(EXIT_FAILURE);

	if ((ctl->pid > -1) && (ctl->verbose || argc - optind == 1)) {
		show_sched_info(ctl);
		if (argc - optind == 1)
			return EXIT_SUCCESS;
	}

	errno = 0;
	ctl->priority = strtos32_or_err(argv[optind], _("invalid priority argument"));

#ifdef SCHED_RESET_ON_FORK
	if (ctl->reset_on_fork && ctl->policy != SCHED_FIFO && ctl->policy != SCHED_RR)
		errx(EXIT_FAILURE, _("--reset-on-fork option is supported for "
				     "SCHED_FIFO and SCHED_RR policies only"));
#endif
#ifdef SCHED_DEADLINE
	if ((ctl->runtime || ctl->deadline || ctl->period) && ctl->policy != SCHED_DEADLINE)
		errx(EXIT_FAILURE, _("--sched-{runtime,deadline,period} options "
				     "are supported for SCHED_DEADLINE only"));
	if (ctl->policy == SCHED_DEADLINE) {
		/* The basic rule is runtime <= deadline <= period, so we can
		 * make deadline and runtime optional on command line. Note we
		 * don't check any values or set any defaults, it's kernel
		 * responsibility.
		 */
		if (ctl->deadline == 0)
			ctl->deadline = ctl->period;
		if (ctl->runtime == 0)
			ctl->runtime = ctl->deadline;
	}
#else
	if (ctl->runtime || ctl->deadline || ctl->period)
		errx(EXIT_FAILURE, _("SCHED_DEADLINE is unsupported"));
#endif
	if (ctl->pid == -1)
		ctl->pid = 0;

	set_sched(ctl);

	if (ctl->verbose)
		show_sched_info(ctl);

	if (!ctl->pid) {
		argv += optind + 1;
		execvp(argv[0], argv);
		err(EXIT_FAILURE, _("failed to execute %s"), argv[0]);
	}

	return EXIT_SUCCESS;
}
Ejemplo n.º 5
0
int main(int argc, char *argv[])
{
	int i, policy = SCHED_RR, priority = 0, verbose = 0;
	struct sched_param sp;
	pid_t pid = 0;

	struct option longopts[] = {
		{ "fifo",	0, NULL, 'f' },
		{ "pid",	0, NULL, 'p' },
		{ "help",	0, NULL, 'h' },
		{ "max",        0, NULL, 'm' },
		{ "other",	0, NULL, 'o' },
		{ "rr",		0, NULL, 'r' },
		{ "verbose",	0, NULL, 'v' },
		{ "version",	0, NULL, 'V' },
		{ NULL,		0, NULL, 0 }
	};

	while((i = getopt_long(argc, argv, "+fphmorvV", longopts, NULL)) != -1)
	{
		int ret = 1;

		switch (i) {
		case 'f':
			policy = SCHED_FIFO;
			break;
		case 'm':
			show_min_max();
			return 0;
		case 'o':
			policy = SCHED_OTHER;
			break;
		case 'p':
			errno = 0;
			pid = strtol(argv[argc - 1], NULL, 10);
			if (errno) {
				perror("strtol");
				fprintf(stderr, "failed to parse pid!\n");
				return 1;
			}
			break;
		case 'r':
			policy = SCHED_RR;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'V':
			printf("chrt (%s)\n", PACKAGE_STRING);
			return 0;
		case 'h':
			ret = 0;
		default:
			show_usage(argv[0]);
			return ret;
		}
		
	}

	if ((pid && argc - optind < 1) || (!pid && argc - optind < 2)) {
		show_usage(argv[0]);
		return 1;
	}

	if (pid && (verbose || argc - optind == 1)) {
		show_rt_info("current", pid);
		if (argc - optind == 1)
			return 0;
	}

	errno = 0;
	priority = strtol(argv[optind], NULL, 10);
	if (errno) {
		perror("strtol");
		fprintf(stderr, "failed to parse priority!\n");
		return 1;
	}

	sp.sched_priority = priority;
	if (sched_setscheduler(pid, policy, &sp) == -1) {
		perror("sched_setscheduler");
		fprintf(stderr, "failed to set pid %d's policy\n", pid);
		return 1;
	}

	if (verbose)
		show_rt_info("new", pid);

	if (!pid) {
		argv += optind + 1;
		execvp(argv[0], argv);
		perror("execvp");
		fprintf(stderr, "failed to execute %s\n", argv[0]);
		return 1;
	}

	return 0;
}