123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- /*
- * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
- *
- * Licensed under the terms of the GNU GPL License version 2.
- *
- * Ideas taken over from the perf userspace tool (included in the Linus
- * kernel git repo): subcommand builtins and param parsing.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/utsname.h>
- #include "builtin.h"
- #include "helpers/helpers.h"
- #include "helpers/bitmask.h"
- #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
- static int cmd_help(int argc, const char **argv);
- /* Global cpu_info object available for all binaries
- * Info only retrieved from CPU 0
- *
- * Values will be zero/unknown on non X86 archs
- */
- struct cpupower_cpu_info cpupower_cpu_info;
- int run_as_root;
- /* Affected cpus chosen by -c/--cpu param */
- struct bitmask *cpus_chosen;
- #ifdef DEBUG
- int be_verbose;
- #endif
- static void print_help(void);
- struct cmd_struct {
- const char *cmd;
- int (*main)(int, const char **);
- int needs_root;
- };
- static struct cmd_struct commands[] = {
- { "frequency-info", cmd_freq_info, 0 },
- { "frequency-set", cmd_freq_set, 1 },
- { "idle-info", cmd_idle_info, 0 },
- { "idle-set", cmd_idle_set, 1 },
- { "set", cmd_set, 1 },
- { "info", cmd_info, 0 },
- { "monitor", cmd_monitor, 0 },
- { "help", cmd_help, 0 },
- /* { "bench", cmd_bench, 1 }, */
- };
- static void print_help(void)
- {
- unsigned int i;
- #ifdef DEBUG
- printf(_("Usage:\tcpupower [-d|--debug] [-c|--cpu cpulist ] <command> [<args>]\n"));
- #else
- printf(_("Usage:\tcpupower [-c|--cpu cpulist ] <command> [<args>]\n"));
- #endif
- printf(_("Supported commands are:\n"));
- for (i = 0; i < ARRAY_SIZE(commands); i++)
- printf("\t%s\n", commands[i].cmd);
- printf(_("\nNot all commands can make use of the -c cpulist option.\n"));
- printf(_("\nUse 'cpupower help <command>' for getting help for above commands.\n"));
- }
- static int print_man_page(const char *subpage)
- {
- int len;
- char *page;
- len = 10; /* enough for "cpupower-" */
- if (subpage != NULL)
- len += strlen(subpage);
- page = malloc(len);
- if (!page)
- return -ENOMEM;
- sprintf(page, "cpupower");
- if ((subpage != NULL) && strcmp(subpage, "help")) {
- strcat(page, "-");
- strcat(page, subpage);
- }
- execlp("man", "man", page, NULL);
- /* should not be reached */
- return -EINVAL;
- }
- static int cmd_help(int argc, const char **argv)
- {
- if (argc > 1) {
- print_man_page(argv[1]); /* exits within execlp() */
- return EXIT_FAILURE;
- }
- print_help();
- return EXIT_SUCCESS;
- }
- static void print_version(void)
- {
- printf(PACKAGE " " VERSION "\n");
- printf(_("Report errors and bugs to %s, please.\n"), PACKAGE_BUGREPORT);
- }
- static void handle_options(int *argc, const char ***argv)
- {
- int ret, x, new_argc = 0;
- if (*argc < 1)
- return;
- for (x = 0; x < *argc && ((*argv)[x])[0] == '-'; x++) {
- const char *param = (*argv)[x];
- if (!strcmp(param, "-h") || !strcmp(param, "--help")) {
- print_help();
- exit(EXIT_SUCCESS);
- } else if (!strcmp(param, "-c") || !strcmp(param, "--cpu")) {
- if (*argc < 2) {
- print_help();
- exit(EXIT_FAILURE);
- }
- if (!strcmp((*argv)[x+1], "all"))
- bitmask_setall(cpus_chosen);
- else {
- ret = bitmask_parselist(
- (*argv)[x+1], cpus_chosen);
- if (ret < 0) {
- fprintf(stderr, _("Error parsing cpu "
- "list\n"));
- exit(EXIT_FAILURE);
- }
- }
- x += 1;
- /* Cut out param: cpupower -c 1 info -> cpupower info */
- new_argc += 2;
- continue;
- } else if (!strcmp(param, "-v") ||
- !strcmp(param, "--version")) {
- print_version();
- exit(EXIT_SUCCESS);
- #ifdef DEBUG
- } else if (!strcmp(param, "-d") || !strcmp(param, "--debug")) {
- be_verbose = 1;
- new_argc++;
- continue;
- #endif
- } else {
- fprintf(stderr, "Unknown option: %s\n", param);
- print_help();
- exit(EXIT_FAILURE);
- }
- }
- *argc -= new_argc;
- *argv += new_argc;
- }
- int main(int argc, const char *argv[])
- {
- const char *cmd;
- unsigned int i, ret;
- struct stat statbuf;
- struct utsname uts;
- cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF));
- argc--;
- argv += 1;
- handle_options(&argc, &argv);
- cmd = argv[0];
- if (argc < 1) {
- print_help();
- return EXIT_FAILURE;
- }
- setlocale(LC_ALL, "");
- textdomain(PACKAGE);
- /* Turn "perf cmd --help" into "perf help cmd" */
- if (argc > 1 && !strcmp(argv[1], "--help")) {
- argv[1] = argv[0];
- argv[0] = cmd = "help";
- }
- get_cpu_info(0, &cpupower_cpu_info);
- run_as_root = !geteuid();
- if (run_as_root) {
- ret = uname(&uts);
- if (!ret && !strcmp(uts.machine, "x86_64") &&
- stat("/dev/cpu/0/msr", &statbuf) != 0) {
- if (system("modprobe msr") == -1)
- fprintf(stderr, _("MSR access not available.\n"));
- }
- }
-
- for (i = 0; i < ARRAY_SIZE(commands); i++) {
- struct cmd_struct *p = commands + i;
- if (strcmp(p->cmd, cmd))
- continue;
- if (!run_as_root && p->needs_root) {
- fprintf(stderr, _("Subcommand %s needs root "
- "privileges\n"), cmd);
- return EXIT_FAILURE;
- }
- ret = p->main(argc, argv);
- if (cpus_chosen)
- bitmask_free(cpus_chosen);
- return ret;
- }
- print_help();
- return EXIT_FAILURE;
- }
|