root/tools/power/cpupower/utils/cpupower.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. print_help
  2. print_man_page
  3. cmd_help
  4. print_version
  5. handle_options
  6. main

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

/* [<][>][^][v][top][bottom][index][help] */