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>
This commit is contained in:
parent
bfa76d4957
commit
98481e79b6
1 changed files with 41 additions and 12 deletions
|
@ -38,6 +38,8 @@
|
|||
#include <ctype.h>
|
||||
#include <sched.h>
|
||||
#include <cpuid.h>
|
||||
#include <linux/capability.h>
|
||||
#include <errno.h>
|
||||
|
||||
char *proc_stat = "/proc/stat";
|
||||
unsigned 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)
|
|||
sprintf(pathname, "/dev/cpu/%d/msr", cpu);
|
||||
fd = open(pathname, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
|
||||
|
||||
retval = pread(fd, msr, sizeof *msr, offset);
|
||||
close(fd);
|
||||
|
||||
if (retval != sizeof *msr) {
|
||||
fprintf(stderr, "%s offset 0x%llx read failed\n", pathname, (unsigned long long)offset);
|
||||
return -1;
|
||||
}
|
||||
if (retval != sizeof *msr)
|
||||
err(-1, "%s offset 0x%llx read failed", pathname, (unsigned long long)offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1462,10 +1462,40 @@ void check_dev_msr()
|
|||
"Try \"# modprobe msr\"");
|
||||
}
|
||||
|
||||
void check_super_user()
|
||||
void check_permissions()
|
||||
{
|
||||
if (getuid() != 0)
|
||||
errx(-6, "must be root");
|
||||
struct __user_cap_header_struct cap_header_data;
|
||||
cap_user_header_t cap_header = &cap_header_data;
|
||||
struct __user_cap_data_struct cap_data_data;
|
||||
cap_user_data_t cap_data = &cap_data_data;
|
||||
extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
|
||||
int do_exit = 0;
|
||||
|
||||
/* check for CAP_SYS_RAWIO */
|
||||
cap_header->pid = getpid();
|
||||
cap_header->version = _LINUX_CAPABILITY_VERSION;
|
||||
if (capget(cap_header, cap_data) < 0)
|
||||
err(-6, "capget(2) failed");
|
||||
|
||||
if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
|
||||
do_exit++;
|
||||
warnx("capget(CAP_SYS_RAWIO) failed,"
|
||||
" try \"# setcap cap_sys_rawio=ep %s\"", progname);
|
||||
}
|
||||
|
||||
/* test file permissions */
|
||||
if (euidaccess("/dev/cpu/0/msr", R_OK)) {
|
||||
do_exit++;
|
||||
warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
|
||||
}
|
||||
|
||||
/* if all else fails, thell them to be root */
|
||||
if (do_exit)
|
||||
if (getuid() != 0)
|
||||
warnx("Or simply run as root");
|
||||
|
||||
if (do_exit)
|
||||
exit(-6);
|
||||
}
|
||||
|
||||
int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
|
||||
|
@ -2299,10 +2329,9 @@ void setup_all_buffers(void)
|
|||
|
||||
void turbostat_init()
|
||||
{
|
||||
check_cpuid();
|
||||
|
||||
check_dev_msr();
|
||||
check_super_user();
|
||||
check_permissions();
|
||||
check_cpuid();
|
||||
|
||||
setup_all_buffers();
|
||||
|
||||
|
@ -2441,7 +2470,7 @@ int main(int argc, char **argv)
|
|||
cmdline(argc, argv);
|
||||
|
||||
if (verbose)
|
||||
fprintf(stderr, "turbostat v3.7 Feb 6, 2014"
|
||||
fprintf(stderr, "turbostat v3.8 14-Aug 2014"
|
||||
" - Len Brown <lenb@kernel.org>\n");
|
||||
|
||||
turbostat_init();
|
||||
|
|
Loading…
Reference in a new issue