Revision b255379d lib/hypervisor/hv_xen.py
b/lib/hypervisor/hv_xen.py | ||
---|---|---|
75 | 75 |
return "cpus = [ %s ]" % ", ".join(map(_GetCPUMap, cpu_list)) |
76 | 76 |
|
77 | 77 |
|
78 |
def _RunXmList(fn, xmllist_errors): |
|
79 |
"""Helper function for L{_GetXmList} to run "xm list". |
|
80 |
|
|
81 |
@type fn: callable |
|
82 |
@param fn: Function returning result of running C{xm list} |
|
83 |
@type xmllist_errors: list |
|
84 |
@param xmllist_errors: Error list |
|
85 |
@rtype: list |
|
86 |
|
|
87 |
""" |
|
88 |
result = fn() |
|
89 |
if result.failed: |
|
90 |
logging.error("xm list failed (%s): %s", result.fail_reason, |
|
91 |
result.output) |
|
92 |
xmllist_errors.append(result) |
|
93 |
raise utils.RetryAgain() |
|
94 |
|
|
95 |
# skip over the heading |
|
96 |
return result.stdout.splitlines() |
|
97 |
|
|
98 |
|
|
99 |
def _ParseXmList(lines, include_node): |
|
100 |
"""Parses the output of C{xm list}. |
|
101 |
|
|
102 |
@type lines: list |
|
103 |
@param lines: Output lines of C{xm list} |
|
104 |
@type include_node: boolean |
|
105 |
@param include_node: If True, return information for Dom0 |
|
106 |
@return: list of tuple containing (name, id, memory, vcpus, state, time |
|
107 |
spent) |
|
108 |
|
|
109 |
""" |
|
110 |
result = [] |
|
111 |
|
|
112 |
# Iterate through all lines while ignoring header |
|
113 |
for line in lines[1:]: |
|
114 |
# The format of lines is: |
|
115 |
# Name ID Mem(MiB) VCPUs State Time(s) |
|
116 |
# Domain-0 0 3418 4 r----- 266.2 |
|
117 |
data = line.split() |
|
118 |
if len(data) != 6: |
|
119 |
raise errors.HypervisorError("Can't parse output of xm list," |
|
120 |
" line: %s" % line) |
|
121 |
try: |
|
122 |
data[1] = int(data[1]) |
|
123 |
data[2] = int(data[2]) |
|
124 |
data[3] = int(data[3]) |
|
125 |
data[5] = float(data[5]) |
|
126 |
except (TypeError, ValueError), err: |
|
127 |
raise errors.HypervisorError("Can't parse output of xm list," |
|
128 |
" line: %s, error: %s" % (line, err)) |
|
129 |
|
|
130 |
# skip the Domain-0 (optional) |
|
131 |
if include_node or data[0] != _DOM0_NAME: |
|
132 |
result.append(data) |
|
133 |
|
|
134 |
return result |
|
135 |
|
|
136 |
|
|
137 |
def _GetXmList(fn, include_node, _timeout=5): |
|
138 |
"""Return the list of running instances. |
|
139 |
|
|
140 |
See L{_RunXmList} and L{_ParseXmList} for parameter details. |
|
141 |
|
|
142 |
""" |
|
143 |
xmllist_errors = [] |
|
144 |
try: |
|
145 |
lines = utils.Retry(_RunXmList, (0.3, 1.5, 1.0), _timeout, |
|
146 |
args=(fn, xmllist_errors)) |
|
147 |
except utils.RetryTimeout: |
|
148 |
if xmllist_errors: |
|
149 |
xmlist_result = xmllist_errors.pop() |
|
150 |
|
|
151 |
errmsg = ("xm list failed, timeout exceeded (%s): %s" % |
|
152 |
(xmlist_result.fail_reason, xmlist_result.output)) |
|
153 |
else: |
|
154 |
errmsg = "xm list failed" |
|
155 |
|
|
156 |
raise errors.HypervisorError(errmsg) |
|
157 |
|
|
158 |
return _ParseXmList(lines, include_node) |
|
159 |
|
|
160 |
|
|
78 | 161 |
class XenHypervisor(hv_base.BaseHypervisor): |
79 | 162 |
"""Xen generic hypervisor interface |
80 | 163 |
|
... | ... | |
154 | 237 |
utils.RemoveFile(XenHypervisor._ConfigFileName(instance_name)) |
155 | 238 |
|
156 | 239 |
@staticmethod |
157 |
def _RunXmList(xmlist_errors):
|
|
158 |
"""Helper function for L{_GetXMList} to run "xm list".
|
|
240 |
def _GetXmList(include_node):
|
|
241 |
"""Wrapper around module level L{_GetXmList}.
|
|
159 | 242 |
|
160 | 243 |
""" |
161 |
result = utils.RunCmd([constants.XEN_CMD, "list"]) |
|
162 |
if result.failed: |
|
163 |
logging.error("xm list failed (%s): %s", result.fail_reason, |
|
164 |
result.output) |
|
165 |
xmlist_errors.append(result) |
|
166 |
raise utils.RetryAgain() |
|
167 |
|
|
168 |
# skip over the heading |
|
169 |
return result.stdout.splitlines()[1:] |
|
170 |
|
|
171 |
@classmethod |
|
172 |
def _GetXMList(cls, include_node): |
|
173 |
"""Return the list of running instances. |
|
174 |
|
|
175 |
If the include_node argument is True, then we return information |
|
176 |
for dom0 also, otherwise we filter that from the return value. |
|
177 |
|
|
178 |
@return: list of (name, id, memory, vcpus, state, time spent) |
|
179 |
|
|
180 |
""" |
|
181 |
xmlist_errors = [] |
|
182 |
try: |
|
183 |
lines = utils.Retry(cls._RunXmList, 1, 5, args=(xmlist_errors, )) |
|
184 |
except utils.RetryTimeout: |
|
185 |
if xmlist_errors: |
|
186 |
xmlist_result = xmlist_errors.pop() |
|
187 |
|
|
188 |
errmsg = ("xm list failed, timeout exceeded (%s): %s" % |
|
189 |
(xmlist_result.fail_reason, xmlist_result.output)) |
|
190 |
else: |
|
191 |
errmsg = "xm list failed" |
|
192 |
|
|
193 |
raise errors.HypervisorError(errmsg) |
|
194 |
|
|
195 |
result = [] |
|
196 |
for line in lines: |
|
197 |
# The format of lines is: |
|
198 |
# Name ID Mem(MiB) VCPUs State Time(s) |
|
199 |
# Domain-0 0 3418 4 r----- 266.2 |
|
200 |
data = line.split() |
|
201 |
if len(data) != 6: |
|
202 |
raise errors.HypervisorError("Can't parse output of xm list," |
|
203 |
" line: %s" % line) |
|
204 |
try: |
|
205 |
data[1] = int(data[1]) |
|
206 |
data[2] = int(data[2]) |
|
207 |
data[3] = int(data[3]) |
|
208 |
data[5] = float(data[5]) |
|
209 |
except (TypeError, ValueError), err: |
|
210 |
raise errors.HypervisorError("Can't parse output of xm list," |
|
211 |
" line: %s, error: %s" % (line, err)) |
|
212 |
|
|
213 |
# skip the Domain-0 (optional) |
|
214 |
if include_node or data[0] != _DOM0_NAME: |
|
215 |
result.append(data) |
|
216 |
|
|
217 |
return result |
|
244 |
# TODO: Abstract running Xen command for testing |
|
245 |
return _GetXmList(lambda: utils.RunCmd([constants.XEN_CMD, "list"]), |
|
246 |
include_node) |
|
218 | 247 |
|
219 | 248 |
def ListInstances(self): |
220 | 249 |
"""Get the list of running instances. |
221 | 250 |
|
222 | 251 |
""" |
223 |
xm_list = self._GetXMList(False)
|
|
252 |
xm_list = self._GetXmList(False)
|
|
224 | 253 |
names = [info[0] for info in xm_list] |
225 | 254 |
return names |
226 | 255 |
|
... | ... | |
232 | 261 |
@return: tuple (name, id, memory, vcpus, stat, times) |
233 | 262 |
|
234 | 263 |
""" |
235 |
xm_list = self._GetXMList(instance_name == _DOM0_NAME)
|
|
264 |
xm_list = self._GetXmList(instance_name == _DOM0_NAME)
|
|
236 | 265 |
result = None |
237 | 266 |
for data in xm_list: |
238 | 267 |
if data[0] == instance_name: |
... | ... | |
246 | 275 |
@return: list of tuples (name, id, memory, vcpus, stat, times) |
247 | 276 |
|
248 | 277 |
""" |
249 |
xm_list = self._GetXMList(False)
|
|
278 |
xm_list = self._GetXmList(False)
|
|
250 | 279 |
return xm_list |
251 | 280 |
|
252 | 281 |
def StartInstance(self, instance, block_devices, startup_paused): |
... | ... | |
395 | 424 |
result["cpu_sockets"] = nr_cpus / (cores_per_socket * threads_per_core) |
396 | 425 |
|
397 | 426 |
total_instmem = 0 |
398 |
for (name, _, mem, vcpus, _, _) in self._GetXMList(True):
|
|
427 |
for (name, _, mem, vcpus, _, _) in self._GetXmList(True):
|
|
399 | 428 |
if name == _DOM0_NAME: |
400 | 429 |
result["memory_dom0"] = mem |
401 | 430 |
result["dom0_cpus"] = vcpus |
Also available in: Unified diff