1 | #!/usr/bin/python |
---|
2 | |
---|
3 | """ |
---|
4 | Copyright (C) International Business Machines Corp., 2005 |
---|
5 | Author: Dan Smith <danms@us.ibm.com> |
---|
6 | |
---|
7 | This program is free software; you can redistribute it and/or modify |
---|
8 | it under the terms of the GNU General Public License as published by |
---|
9 | the Free Software Foundation; under version 2 of the License. |
---|
10 | |
---|
11 | This program is distributed in the hope that it will be useful, |
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
14 | GNU General Public License for more details. |
---|
15 | |
---|
16 | You should have received a copy of the GNU General Public License |
---|
17 | along with this program; if not, write to the Free Software |
---|
18 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
19 | |
---|
20 | |
---|
21 | """ |
---|
22 | |
---|
23 | |
---|
24 | ## |
---|
25 | ## These are miscellaneous utility functions that query xm |
---|
26 | ## |
---|
27 | |
---|
28 | import commands |
---|
29 | import re |
---|
30 | import os |
---|
31 | import time |
---|
32 | |
---|
33 | from Test import *; |
---|
34 | |
---|
35 | class XmError(Exception): |
---|
36 | def __init__(self, msg, trace="", status=0): |
---|
37 | self.msg = msg |
---|
38 | self.trace = trace |
---|
39 | try: |
---|
40 | self.status = int(status) |
---|
41 | except Exception, e: |
---|
42 | self.status = -1 |
---|
43 | |
---|
44 | def __str__(self): |
---|
45 | return trace |
---|
46 | |
---|
47 | def domid(name): |
---|
48 | status, output = traceCommand("xm domid " + name); |
---|
49 | |
---|
50 | if status != 0 or "Traceback" in output: |
---|
51 | return -1 |
---|
52 | if output == "None": |
---|
53 | return -1 |
---|
54 | try: |
---|
55 | return int(output) |
---|
56 | except: |
---|
57 | raise XmError("xm domid failed", trace=output, status=status) |
---|
58 | |
---|
59 | |
---|
60 | def domname(id): |
---|
61 | status, output = traceCommand("xm domname " + str(id)); |
---|
62 | return output; |
---|
63 | |
---|
64 | def isDomainRunning(domain): |
---|
65 | id = domid(domain); |
---|
66 | if id == -1: |
---|
67 | return False; |
---|
68 | else: |
---|
69 | return True; |
---|
70 | |
---|
71 | def getRunningDomains(): |
---|
72 | status, output = traceCommand("xm list"); |
---|
73 | if status != 0 or "Traceback" in output: |
---|
74 | raise XmError("xm failed", trace=output, status=status) |
---|
75 | |
---|
76 | lines = output.splitlines(); |
---|
77 | domains = []; |
---|
78 | for l in lines[1:]: |
---|
79 | elms = l.split(" ", 1); |
---|
80 | domains.append(elms[0]); |
---|
81 | return domains; |
---|
82 | |
---|
83 | def destroyDomU(name): |
---|
84 | status, output = traceCommand("xm destroy " + name, logOutput=False); |
---|
85 | return status; |
---|
86 | |
---|
87 | def destroyAllDomUs(): |
---|
88 | if verbose: |
---|
89 | print "*** Cleaning all running domU's" |
---|
90 | |
---|
91 | attempt = 0 |
---|
92 | trying = True |
---|
93 | |
---|
94 | while trying: |
---|
95 | try: |
---|
96 | attempt += 1 |
---|
97 | domainList = getRunningDomains() |
---|
98 | trying = False |
---|
99 | except XmError, e: |
---|
100 | if attempt >= 10: |
---|
101 | FAIL("XM-TEST: xm list not responding") |
---|
102 | time.sleep(1) |
---|
103 | print e.trace |
---|
104 | print "!!! Trying again to get a clean domain list..." |
---|
105 | |
---|
106 | for d in domainList: |
---|
107 | if not d == "Domain-0": |
---|
108 | destroyDomU(d); |
---|
109 | |
---|
110 | if verbose: |
---|
111 | print "*** Finished cleaning domUs" |
---|
112 | |
---|
113 | def getDomMem(domain): |
---|
114 | status, output = traceCommand("xm list") |
---|
115 | if status != 0: |
---|
116 | if verbose: |
---|
117 | print "xm list failed with %i" % status |
---|
118 | return None |
---|
119 | |
---|
120 | lines = re.split("\n", output) |
---|
121 | for line in lines: |
---|
122 | fields = re.sub(" +", " ", line).split() |
---|
123 | if domain.isdigit(): |
---|
124 | if fields[1] == domain: |
---|
125 | return int(fields[2]) |
---|
126 | else: |
---|
127 | if fields[0] == domain: |
---|
128 | return int(fields[2]) |
---|
129 | if verbose: |
---|
130 | print "Did not find domain " + str(domain) |
---|
131 | return None |
---|
132 | |
---|
133 | def getDomInfo(domain, key, opts=None): |
---|
134 | if opts: |
---|
135 | cmd = "xm list %s" % opts |
---|
136 | else: |
---|
137 | cmd = "xm list" |
---|
138 | |
---|
139 | status, output = traceCommand(cmd) |
---|
140 | |
---|
141 | if status != 0: |
---|
142 | if verbose: |
---|
143 | print "xm list failed with %i" % status |
---|
144 | return None |
---|
145 | |
---|
146 | lines = output.split("\n") |
---|
147 | |
---|
148 | # Get the key values from the first line headers |
---|
149 | cleanHeader = re.sub("\([^\)]+\)", "", lines[0]) |
---|
150 | colHeaders = re.split(" +", cleanHeader) |
---|
151 | |
---|
152 | doms = {} |
---|
153 | |
---|
154 | for line in lines[1:]: |
---|
155 | domValues = {} |
---|
156 | values = re.split(" +", line) |
---|
157 | i = 1 |
---|
158 | for value in values[1:]: |
---|
159 | domValues[colHeaders[i]] = value |
---|
160 | i += 1 |
---|
161 | doms[values[0]] = domValues |
---|
162 | |
---|
163 | |
---|
164 | if doms.has_key(domain) and doms[domain].has_key(key): |
---|
165 | return doms[domain].get(key) |
---|
166 | |
---|
167 | return "" |
---|
168 | |
---|
169 | def getVcpuInfo(domain): |
---|
170 | |
---|
171 | status, output = traceCommand("xm vcpu-list %s" % domain) |
---|
172 | |
---|
173 | lines = output.split("\n") |
---|
174 | |
---|
175 | vcpus = {} |
---|
176 | |
---|
177 | for line in lines[1:]: |
---|
178 | cols = re.split(" +", line) |
---|
179 | if cols[3] == '-': |
---|
180 | vcpus[int(cols[2])] = None |
---|
181 | else: |
---|
182 | vcpus[int(cols[2])] = int(cols[3]) |
---|
183 | |
---|
184 | return vcpus |
---|
185 | |
---|
186 | def getInfo(key): |
---|
187 | |
---|
188 | info = {} |
---|
189 | |
---|
190 | status, output = traceCommand("xm info") |
---|
191 | lines = output.split("\n") |
---|
192 | for line in lines: |
---|
193 | match = re.match("^([A-z_]+)[^:]*: (.*)$", line) |
---|
194 | if match: |
---|
195 | info[match.group(1)] = match.group(2) |
---|
196 | |
---|
197 | if info.has_key(key): |
---|
198 | return info[key] |
---|
199 | else: |
---|
200 | return "" |
---|
201 | |
---|
202 | def restartXend(): |
---|
203 | if verbose: |
---|
204 | print "*** Restarting xend ..." |
---|
205 | |
---|
206 | if os.access("/etc/init.d/xend", os.X_OK): |
---|
207 | status, output = traceCommand("/etc/init.d/xend stop") |
---|
208 | time.sleep(1) |
---|
209 | status, output = traceCommand("/etc/init.d/xend start") |
---|
210 | |
---|
211 | return status |
---|
212 | |
---|
213 | else: |
---|
214 | status, output = traceCommand("xend stop") |
---|
215 | time.sleep(1) |
---|
216 | status, output = traceCommand("xend start") |
---|
217 | |
---|
218 | return status |
---|
219 | |
---|
220 | def smpConcurrencyLevel(): |
---|
221 | cores = int(getInfo("cores_per_socket")) |
---|
222 | threads = int(getInfo("threads_per_core")) |
---|
223 | sockets = int(getInfo("sockets_per_node")) |
---|
224 | |
---|
225 | return cores * sockets * threads |
---|
226 | |
---|
227 | if __name__ == "__main__": |
---|
228 | if isDomainRunning("0"): |
---|
229 | print "Domain-0 is running; I must be working!" |
---|
230 | else: |
---|
231 | print "Domain-0 is not running; I may be broken!" |
---|
232 | |
---|
233 | mem = getDomMem("Domain-0") |
---|
234 | if not mem: |
---|
235 | print "Failed to get memory for Domain-0!" |
---|
236 | else: |
---|
237 | print "Domain-0 mem: %i" % mem |
---|
238 | |
---|
239 | cpu = getDomInfo("Domain-0", "CPU") |
---|
240 | state = getDomInfo("Domain-0", "State") |
---|
241 | |
---|
242 | print "Domain-0 CPU: " + cpu |
---|
243 | print "Domain-0 state: " + state |
---|
244 | |
---|
245 | v = getVcpuInfo("Domain-0") |
---|
246 | for key in v.keys(): |
---|
247 | print "VCPU%i is on CPU %i" % (key, v[key]) |
---|