aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorLen Brown <len.brown@intel.com>2014-08-15 00:36:50 -0400
committerLen Brown <len.brown@intel.com>2015-02-09 16:41:16 -0500
commit98481e79b60a50d699b79292ff1b7e56e7fa8425 (patch)
tree148ec049930bed66b08ccbfa1dcddc11ebd841c4 /tools
parentbfa76d49576599a4b9f9b7a71f23d73d6dcff735 (diff)
tools/power turbostat: relax dependency on root permission
For turbostat to run as non-root, it needs to permissions: 1. read access to /dev/cpu/*/msr via standard user/group/world file permissions 2. CAP_SYS_RAWIO eg. # setcap cap_sys_rawio=ep turbostat Yes, running as root still works. Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/power/x86/turbostat/turbostat.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 5b1b807265a1..6f29fc11fde6 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -38,6 +38,8 @@
38#include <ctype.h> 38#include <ctype.h>
39#include <sched.h> 39#include <sched.h>
40#include <cpuid.h> 40#include <cpuid.h>
41#include <linux/capability.h>
42#include <errno.h>
41 43
42char *proc_stat = "/proc/stat"; 44char *proc_stat = "/proc/stat";
43unsigned int interval_sec = 5; /* set with -i interval_sec */ 45unsigned int interval_sec = 5; /* set with -i interval_sec */
@@ -251,15 +253,13 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
251 sprintf(pathname, "/dev/cpu/%d/msr", cpu); 253 sprintf(pathname, "/dev/cpu/%d/msr", cpu);
252 fd = open(pathname, O_RDONLY); 254 fd = open(pathname, O_RDONLY);
253 if (fd < 0) 255 if (fd < 0)
254 return -1; 256 err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
255 257
256 retval = pread(fd, msr, sizeof *msr, offset); 258 retval = pread(fd, msr, sizeof *msr, offset);
257 close(fd); 259 close(fd);
258 260
259 if (retval != sizeof *msr) { 261 if (retval != sizeof *msr)
260 fprintf(stderr, "%s offset 0x%llx read failed\n", pathname, (unsigned long long)offset); 262 err(-1, "%s offset 0x%llx read failed", pathname, (unsigned long long)offset);
261 return -1;
262 }
263 263
264 return 0; 264 return 0;
265} 265}
@@ -1462,10 +1462,40 @@ void check_dev_msr()
1462 "Try \"# modprobe msr\""); 1462 "Try \"# modprobe msr\"");
1463} 1463}
1464 1464
1465void check_super_user() 1465void check_permissions()
1466{ 1466{
1467 if (getuid() != 0) 1467 struct __user_cap_header_struct cap_header_data;
1468 errx(-6, "must be root"); 1468 cap_user_header_t cap_header = &cap_header_data;
1469 struct __user_cap_data_struct cap_data_data;
1470 cap_user_data_t cap_data = &cap_data_data;
1471 extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
1472 int do_exit = 0;
1473
1474 /* check for CAP_SYS_RAWIO */
1475 cap_header->pid = getpid();
1476 cap_header->version = _LINUX_CAPABILITY_VERSION;
1477 if (capget(cap_header, cap_data) < 0)
1478 err(-6, "capget(2) failed");
1479
1480 if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
1481 do_exit++;
1482 warnx("capget(CAP_SYS_RAWIO) failed,"
1483 " try \"# setcap cap_sys_rawio=ep %s\"", progname);
1484 }
1485
1486 /* test file permissions */
1487 if (euidaccess("/dev/cpu/0/msr", R_OK)) {
1488 do_exit++;
1489 warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
1490 }
1491
1492 /* if all else fails, thell them to be root */
1493 if (do_exit)
1494 if (getuid() != 0)
1495 warnx("Or simply run as root");
1496
1497 if (do_exit)
1498 exit(-6);
1469} 1499}
1470 1500
1471int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) 1501int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
@@ -2299,10 +2329,9 @@ void setup_all_buffers(void)
2299 2329
2300void turbostat_init() 2330void turbostat_init()
2301{ 2331{
2302 check_cpuid();
2303
2304 check_dev_msr(); 2332 check_dev_msr();
2305 check_super_user(); 2333 check_permissions();
2334 check_cpuid();
2306 2335
2307 setup_all_buffers(); 2336 setup_all_buffers();
2308 2337
@@ -2441,7 +2470,7 @@ int main(int argc, char **argv)
2441 cmdline(argc, argv); 2470 cmdline(argc, argv);
2442 2471
2443 if (verbose) 2472 if (verbose)
2444 fprintf(stderr, "turbostat v3.7 Feb 6, 2014" 2473 fprintf(stderr, "turbostat v3.8 14-Aug 2014"
2445 " - Len Brown <lenb@kernel.org>\n"); 2474 " - Len Brown <lenb@kernel.org>\n");
2446 2475
2447 turbostat_init(); 2476 turbostat_init();