1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
#!/usr/bin/env python
#
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# This is a script developers can use to set-up their workstation to let
# Telemetry read the CPU's Model Specific Registers in order to get power
# measurements. It can check if reading from MSRs is possible as any user, but
# must run as root to make changes. Not all changes are sticky, so one has to
# re-run this script after each reboot.
#
# This script is currently Debian/Ubuntu specific.
import os
import subprocess
import sys
MSR_DEV_FILE_PATH = '/dev/cpu/0/msr'
RDMSR_PATH = '/usr/sbin/rdmsr'
def _Usage(prog_name):
"""Print a help message."""
print 'Run "%s" as a regular user to check if reading from the MSR ' \
'is possible.' % prog_name
print 'Run "%s enable" as root to automatically set up reading from ' \
'the MSR.' % prog_name
def _CheckMsrKernelModule():
"""Return whether the 'msr' kernel module is loaded."""
proc = subprocess.Popen('/sbin/lsmod', stdout=subprocess.PIPE)
stdout = proc.communicate()[0]
ret = proc.wait()
if ret != 0:
raise OSError('lsmod failed')
if not any([line.startswith('msr ') for line in stdout.splitlines()]):
print 'Error: MSR module not loaded.'
return False
return True
def _CheckMsrDevNodes():
"""Check whether the MSR /dev files have the right permissions."""
if not os.path.exists(MSR_DEV_FILE_PATH):
print 'Error: %s does not exist.' % MSR_DEV_FILE_PATH
return False
if not os.access(MSR_DEV_FILE_PATH, os.R_OK):
print 'Error: Cannot read from %s' % MSR_DEV_FILE_PATH
return False
return True
def _CheckRdmsr():
"""Check and make sure /usr/sbin/rdmsr is set up correctly."""
if not os.access(RDMSR_PATH, os.X_OK):
print 'Error: %s missing or not executable.' % RDMSR_PATH
return False
proc = subprocess.Popen(['/sbin/getcap', RDMSR_PATH], stdout=subprocess.PIPE)
stdout = proc.communicate()[0]
ret = proc.wait()
if ret != 0:
raise OSError('getcap failed')
if not 'cap_sys_rawio+ep' in stdout:
print 'Error: /usr/sbin/rdmsr needs RAWIO capability.'
return False
return True
def _RunAllChecks():
"""Check to make sure it is possible to read from the MSRs."""
if os.geteuid() == 0:
print 'WARNING: Running as root, msr permission check likely inaccurate.'
has_dev_node = _CheckMsrDevNodes() if _CheckMsrKernelModule() else False
has_rdmsr = _CheckRdmsr()
return has_dev_node and has_rdmsr
def _EnableMsr(prog_name):
"""Do all the setup needed to pass _RunAllChecks().
Needs to run as root."""
if os.geteuid() != 0:
print 'Error: Must run "%s enable" as root.' % prog_name
return False
print 'Loading msr kernel module.'
ret = subprocess.call(['/sbin/modprobe', 'msr'])
if ret != 0:
print 'Error: Cannot load msr module.'
return False
print 'Running chmod on %s.' % MSR_DEV_FILE_PATH
ret = subprocess.call(['/bin/chmod', 'a+r', MSR_DEV_FILE_PATH])
if ret != 0:
print 'Error: Cannot chmod %s.' % MSR_DEV_FILE_PATH
return False
if not os.access(RDMSR_PATH, os.F_OK):
print 'Need to install the msr-tools package.'
ret = subprocess.call(['/usr/bin/apt-get', 'install', '-y', 'msr-tools'])
if ret != 0:
print 'Error: Did not successfully install msr-tools.'
return False
print 'Running setcap on %s.' % RDMSR_PATH
ret = subprocess.call(['/sbin/setcap', 'cap_sys_rawio+ep', RDMSR_PATH])
if ret != 0:
print 'Error: Cannot give /usr/sbin/rdmsr RAWIO capability.'
return False
return True
def main(prog_name, argv):
if len(argv) == 0:
if _RunAllChecks():
print 'Check succeeded'
return 0
print 'Check failed, try running "%s enable" as root to fix.' % prog_name
return 1
if len(argv) == 1:
if argv[0] == 'enable':
return 0 if _EnableMsr(prog_name) else 1
print 'Error: Unknown sub-command %s' % argv[0]
_Usage(prog_name)
return 1
print 'Error: Bad number of arguments'
_Usage(prog_name)
return 1
if '__main__' == __name__:
sys.exit(main(os.path.basename(sys.argv[0]), sys.argv[1:]))
|