Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  (C) 2010,2011       Thomas Renninger <trenn@suse.de>, Novell Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Ideas taken over from the perf userspace tool (included in the Linus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  kernel git repo): subcommand builtins and param parsing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <sys/utsname.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "builtin.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "helpers/helpers.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "helpers/bitmask.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static int cmd_help(int argc, const char **argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) /* Global cpu_info object available for all binaries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * Info only retrieved from CPU 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  * Values will be zero/unknown on non X86 archs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) struct cpupower_cpu_info cpupower_cpu_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) int run_as_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) int base_cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) /* Affected cpus chosen by -c/--cpu param */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) struct bitmask *cpus_chosen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) int be_verbose;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static void print_help(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) struct cmd_struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	const char *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	int (*main)(int, const char **);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	int needs_root;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) static struct cmd_struct commands[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	{ "frequency-info",	cmd_freq_info,	0	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	{ "frequency-set",	cmd_freq_set,	1	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	{ "idle-info",		cmd_idle_info,	0	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	{ "idle-set",		cmd_idle_set,	1	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	{ "set",		cmd_set,	1	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	{ "info",		cmd_info,	0	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	{ "monitor",		cmd_monitor,	0	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	{ "help",		cmd_help,	0	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	/*	{ "bench",	cmd_bench,	1	}, */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) static void print_help(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	printf(_("Usage:\tcpupower [-d|--debug] [-c|--cpu cpulist ] <command> [<args>]\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	printf(_("Usage:\tcpupower [-c|--cpu cpulist ] <command> [<args>]\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	printf(_("Supported commands are:\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	for (i = 0; i < ARRAY_SIZE(commands); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		printf("\t%s\n", commands[i].cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	printf(_("\nNot all commands can make use of the -c cpulist option.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	printf(_("\nUse 'cpupower help <command>' for getting help for above commands.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) static int print_man_page(const char *subpage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	char *page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	len = 10; /* enough for "cpupower-" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (subpage != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		len += strlen(subpage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	page = malloc(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	sprintf(page, "cpupower");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	if ((subpage != NULL) && strcmp(subpage, "help")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		strcat(page, "-");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		strcat(page, subpage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	execlp("man", "man", page, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	/* should not be reached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int cmd_help(int argc, const char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (argc > 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		print_man_page(argv[1]); /* exits within execlp() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	print_help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	return EXIT_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static void print_version(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	printf(PACKAGE " " VERSION "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	printf(_("Report errors and bugs to %s, please.\n"), PACKAGE_BUGREPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static void handle_options(int *argc, const char ***argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	int ret, x, new_argc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	if (*argc < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	for (x = 0;  x < *argc && ((*argv)[x])[0] == '-'; x++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		const char *param = (*argv)[x];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		if (!strcmp(param, "-h") || !strcmp(param, "--help")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			print_help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			exit(EXIT_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		} else if (!strcmp(param, "-c") || !strcmp(param, "--cpu")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			if (*argc < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 				print_help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 				exit(EXIT_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			if (!strcmp((*argv)[x+1], "all"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 				bitmask_setall(cpus_chosen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 				ret = bitmask_parselist(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 						(*argv)[x+1], cpus_chosen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 				if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 					fprintf(stderr, _("Error parsing cpu "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 							  "list\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 					exit(EXIT_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 			x += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			/* Cut out param: cpupower -c 1 info -> cpupower info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 			new_argc += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		} else if (!strcmp(param, "-v") ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 			!strcmp(param, "--version")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			print_version();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 			exit(EXIT_SUCCESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		} else if (!strcmp(param, "-d") || !strcmp(param, "--debug")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			be_verbose = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			new_argc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			fprintf(stderr, "Unknown option: %s\n", param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 			print_help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			exit(EXIT_FAILURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	*argc -= new_argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	*argv += new_argc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) int main(int argc, const char *argv[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	const char *cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	unsigned int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	struct stat statbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	struct utsname uts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	char pathname[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	argc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	argv += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	handle_options(&argc, &argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	cmd = argv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if (argc < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		print_help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 		return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	setlocale(LC_ALL, "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	textdomain(PACKAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	/* Turn "perf cmd --help" into "perf help cmd" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	if (argc > 1 && !strcmp(argv[1], "--help")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		argv[1] = argv[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		argv[0] = cmd = "help";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	base_cpu = sched_getcpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (base_cpu < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		fprintf(stderr, _("No valid cpus found.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	get_cpu_info(&cpupower_cpu_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	run_as_root = !geteuid();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	if (run_as_root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		ret = uname(&uts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		sprintf(pathname, "/dev/cpu/%d/msr", base_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		if (!ret && !strcmp(uts.machine, "x86_64") &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		    stat(pathname, &statbuf) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 			if (system("modprobe msr") == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	fprintf(stderr, _("MSR access not available.\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	for (i = 0; i < ARRAY_SIZE(commands); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		struct cmd_struct *p = commands + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		if (strcmp(p->cmd, cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		if (!run_as_root && p->needs_root) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 			fprintf(stderr, _("Subcommand %s needs root "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 					  "privileges\n"), cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 			return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		ret = p->main(argc, argv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		if (cpus_chosen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 			bitmask_free(cpus_chosen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	print_help();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	return EXIT_FAILURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }